发布代码生成、更新20+表单组件,优化数据字典,gf版本更新到2.3.1

This commit is contained in:
孟帅
2023-01-18 16:23:39 +08:00
parent 50207ded90
commit 87c27a17a3
386 changed files with 27926 additions and 44297 deletions

View File

@@ -1,41 +0,0 @@
import { h } from 'vue';
import { NTag } from 'naive-ui';
export const columns = [
{
title: 'ID',
key: 'id',
},
{
title: 'IP地址',
key: 'ip',
},
{
title: '备注',
key: 'remark',
},
{
title: '状态',
key: 'status',
render(row) {
return h(
NTag,
{
style: {
marginRight: '6px',
},
type: row.status == 1 ? 'success' : 'warning',
bordered: false,
},
{
default: () => (row.status == 1 ? '正常' : '隐藏'),
}
);
},
},
{
title: '创建时间',
key: 'createdAt',
},
];

View File

@@ -14,6 +14,7 @@
</BasicForm>
<BasicTable
:openChecked="true"
:columns="columns"
:request="loadDataTable"
:row-key="(row) => row.id"
@@ -96,16 +97,60 @@
</template>
<script lang="ts" setup>
import { h, reactive, ref } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import { h, onMounted, reactive, ref } from 'vue';
import { NTag, useDialog, useMessage } from 'naive-ui';
import { BasicTable, TableAction } from '@/components/Table';
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
import { Delete, Edit, List, Status } from '@/api/sys/blacklist';
import { columns } from './columns';
import { DeleteOutlined, PlusOutlined } from '@vicons/antd';
import { statusActions, statusOptions } from '@/enums/optionsiEnum';
import { Dict } from '@/api/dict/dict';
import { getOptionLabel, getOptionTag } from '@/utils/hotgo';
const params = ref({
const options = ref({
status: [],
});
const columns = [
{
title: 'ID',
key: 'id',
},
{
title: 'IP地址',
key: 'ip',
},
{
title: '备注',
key: 'remark',
},
{
title: '状态',
key: 'status',
render(row) {
return h(
NTag,
{
style: {
marginRight: '6px',
},
type: getOptionTag(options.value.status, row.status),
bordered: false,
},
{
default: () => getOptionLabel(options.value.status, row.status),
}
);
},
},
{
title: '创建时间',
key: 'createdAt',
},
];
const params = ref<any>({
pageSize: 10,
title: '',
content: '',
@@ -120,7 +165,7 @@
},
};
const schemas: FormSchema[] = [
const schemas = ref<FormSchema[]>([
{
field: 'ip',
component: 'NInput',
@@ -140,21 +185,21 @@
defaultValue: null,
componentProps: {
placeholder: '请选择类型',
options: statusOptions,
options: [],
onUpdateValue: (e: any) => {
console.log(e);
},
},
},
];
]);
const message = useMessage();
const actionRef = ref();
const dialog = useDialog();
const showModal = ref(false);
const formBtnLoading = ref(false);
const searchFormRef = ref({});
const formRef = ref({});
const searchFormRef = ref<any>({});
const formRef = ref<any>({});
const batchDeleteDisabled = ref(true);
const checkedIds = ref([]);
@@ -165,7 +210,7 @@
sort: 0,
status: 1,
};
let formParams = ref(resetFormParams);
let formParams = ref<any>(resetFormParams);
const actionColumn = reactive({
width: 220,
@@ -205,17 +250,12 @@
}
const loadDataTable = async (res) => {
return await List({ ...params.value, ...res, ...searchFormRef.value.formModel });
return await List({ ...params.value, ...res, ...searchFormRef.value?.formModel });
};
function onCheckedRow(rowKeys) {
console.log(rowKeys);
if (rowKeys.length > 0) {
batchDeleteDisabled.value = false;
} else {
batchDeleteDisabled.value = true;
}
batchDeleteDisabled.value = rowKeys.length <= 0;
checkedIds.value = rowKeys;
}
@@ -228,10 +268,8 @@
formBtnLoading.value = true;
formRef.value.validate((errors) => {
if (!errors) {
console.log('formParams:' + JSON.stringify(formParams.value));
Edit(formParams.value)
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
@@ -250,31 +288,24 @@
}
function handleEdit(record: Recordable) {
console.log('点击了编辑', record);
showModal.value = true;
formParams.value = record;
}
function handleDelete(record: Recordable) {
console.log('点击了删除', record);
dialog.warning({
title: '警告',
content: '你确定要删除?',
positiveText: '确定',
negativeText: '不确定',
negativeText: '取消',
onPositiveClick: () => {
Delete(record)
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
reloadTable();
})
.catch((e: Error) => {
// message.error(e.message ?? '操作失败');
});
Delete(record).then((_res) => {
message.success('操作成功');
reloadTable();
});
},
onNegativeClick: () => {
// message.error('不确定');
// message.error('取消');
},
});
}
@@ -284,11 +315,10 @@
title: '警告',
content: '你确定要删除?',
positiveText: '确定',
negativeText: '不确定',
negativeText: '取消',
onPositiveClick: () => {
Delete({ id: checkedIds.value })
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
reloadTable();
})
@@ -297,13 +327,12 @@
});
},
onNegativeClick: () => {
// message.error('不确定');
// message.error('取消');
},
});
}
function handleSubmit(values: Recordable) {
console.log(values);
params.value = values;
reloadTable();
}
@@ -314,18 +343,26 @@
}
function updateStatus(id, status) {
Status({ id: id, status: status })
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
setTimeout(() => {
reloadTable({});
});
})
.catch((e: Error) => {
message.error(e.message ?? '操作失败');
Status({ id: id, status: status }).then((_res) => {
message.success('操作成功');
setTimeout(() => {
reloadTable();
});
});
}
async function loadOptions() {
options.value.status = await Dict('sys_normal_disable');
for (const item of schemas.value) {
if (item.field === 'status') {
item.componentProps.options = options.value.status;
}
}
}
onMounted(async () => {
await loadOptions();
});
</script>
<style lang="less" scoped></style>

View File

@@ -169,10 +169,6 @@
});
}
function resetForm() {
formRef.value.restoreValidation();
}
function uploadChange(list: string[]) {
// 单图模式,只需要第一个索引
if (list.length > 0) {

View File

@@ -10,7 +10,11 @@
</n-form-item>
<n-form-item label="SMTP端口" path="smtpPort">
<n-input v-model:value="formValue.smtpPort" placeholder="" />
<n-input-number
v-model:value="formValue.smtpPort"
placeholder=""
:show-button="false"
/>
<template #feedback> (不加密默认25,SSL默认465,TLS默认587)</template>
</n-form-item>
<n-form-item label="SMTP用户名" path="smtpUser">
@@ -19,7 +23,7 @@
</n-form-item>
<n-form-item label="SMTP密码" path="smtpPass">
<n-input v-model:value="formValue.smtpPass" placeholder="" />
<n-input v-model:value="formValue.smtpPass" placeholder="" type="password" />
<template #feedback>填写您的密码</template>
</n-form-item>
@@ -117,13 +121,9 @@
console.log('formParams:' + JSON.stringify(formParams.value));
showModal.value = false;
sendTestEmail(formParams.value)
.then((_res) => {
message.success('发送成功');
})
.catch((error) => {
// message.error(error.toString());
});
sendTestEmail(formParams.value).then((_res) => {
message.success('发送成功');
});
} else {
message.error('请填写完整信息');
}

View File

@@ -0,0 +1,87 @@
<template>
<div>
<n-spin :show="show" description="正在获取配置...">
<n-grid cols="2 s:2 m:2 l:2 xl:2 2xl:2" responsive="screen">
<n-grid-item>
<n-form :label-width="100" :model="formValue" :rules="rules" ref="formRef">
<n-form-item label="高德Web服务key" path="geoAmapWebKey">
<n-input v-model:value="formValue.geoAmapWebKey" placeholder="" type="password" />
<template #feedback> 申请地址https://console.amap.com/dev/key/app</template>
</n-form-item>
<div>
<n-space>
<n-button type="primary" @click="formSubmit">保存更新</n-button>
</n-space>
</div>
</n-form>
</n-grid-item>
</n-grid>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { useMessage } from 'naive-ui';
import { getConfig, updateConfig } from '@/api/sys/config';
const group = ref('geo');
const show = ref(false);
const rules = {
geoAmapWebKey: {
required: true,
message: '请输入高德Web服务key',
trigger: 'blur',
},
};
const formRef: any = ref(null);
const message = useMessage();
const formValue = ref({
geoAmapWebKey: '',
});
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
console.log('formValue.value:' + JSON.stringify(formValue.value));
updateConfig({ group: group.value, list: formValue.value })
.then((res) => {
console.log('res:' + JSON.stringify(res));
message.success('更新成功');
load();
})
.catch((error) => {
message.error(error.toString());
});
} else {
message.error('验证失败,请填写完整信息');
}
});
}
onMounted(() => {
load();
});
function load() {
show.value = true;
new Promise((_resolve, _reject) => {
getConfig({ group: group.value })
.then((res) => {
show.value = false;
// state.formValue.watermarkClarity = res;
formValue.value = res.list;
console.log('res:' + JSON.stringify(res));
})
.catch((error) => {
show.value = false;
message.error(error.toString());
});
});
}
</script>

View File

@@ -90,7 +90,7 @@
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import { useMessage } from 'naive-ui';
const rules = {
name: {
@@ -156,8 +156,6 @@
setup() {
const formRef: any = ref(null);
const message = useMessage();
const dialog = useDialog();
const state = reactive({
formValue: {
bigWidth: '',
@@ -171,23 +169,6 @@
},
});
function systemOpenChange(value) {
if (!value) {
dialog.warning({
title: '提示',
content: '您确定要关闭系统访问吗?该操作立马生效,请慎重操作!',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
message.success('操作成功');
},
onNegativeClick: () => {
state.formValue.systemOpen = true;
},
});
}
}
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
@@ -211,7 +192,6 @@
rules,
formSubmit,
resetForm,
systemOpenChange,
};
},
});

View File

@@ -0,0 +1,167 @@
<template>
<div>
<n-spin :show="show" description="正在获取配置...">
<n-grid cols="2 s:2 m:2 l:2 xl:2 2xl:2" responsive="screen">
<n-grid-item>
<n-divider title-placement="left">通用配置</n-divider>
<n-form :label-width="100" :model="formValue" :rules="rules" ref="formRef">
<n-form-item label="默认驱动" path="smsDrive">
<n-select
placeholder="默认发送驱动"
:options="driveList"
v-model:value="formValue.smsDrive"
/>
</n-form-item>
<n-form-item label="最小发送间隔" path="smsMinInterval">
<n-input-number
:show-button="false"
placeholder="请输入"
v-model:value="formValue.smsMinInterval"
>
<template #suffix> </template>
</n-input-number>
<template #feedback> 同号码</template>
</n-form-item>
<n-form-item label="IP最大发送次数" path="smsMaxIpLimit">
<n-input-number v-model:value="formValue.smsMaxIpLimit" placeholder="" />
<template #feedback> 同IP每天最大允许发送次数 </template>
</n-form-item>
<n-form-item label="验证码有效期" path="smsCodeExpire">
<n-input-number
:show-button="false"
placeholder="请输入"
v-model:value="formValue.smsCodeExpire"
>
<template #suffix> </template>
</n-input-number>
</n-form-item>
<n-divider title-placement="left">阿里云</n-divider>
<n-form-item label="AccessKeyID" path="smsAliyunAccessKeyID">
<n-input
v-model:value="formValue.smsAliyunAccessKeyID"
placeholder=""
type="password"
/>
<template #feedback
>应用key和密钥你可以通过 https://ram.console.aliyun.com/manage/ak 获取</template
>
</n-form-item>
<n-form-item label="AccessKeySecret" path="smsAliyunAccessKeySecret">
<n-input
type="password"
v-model:value="formValue.smsAliyunAccessKeySecret"
placeholder=""
/>
</n-form-item>
<n-form-item label="签名" path="smsAliyunSign">
<n-input v-model:value="formValue.smsAliyunSign" placeholder="" />
<template #feedback
>申请地址https://dysms.console.aliyun.com/domestic/text/sign</template
>
</n-form-item>
<n-form-item label="短信模板" path="smsAliyunTemplate">
<n-dynamic-input
v-model:value="formValue.smsAliyunTemplate"
preset="pair"
key-placeholder="key"
value-placeholder="模板CODE"
/>
</n-form-item>
<div>
<n-space>
<n-button type="primary" @click="formSubmit">保存更新</n-button>
</n-space>
</div>
</n-form>
</n-grid-item>
</n-grid>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { useMessage } from 'naive-ui';
import { getConfig, updateConfig } from '@/api/sys/config';
const group = ref('sms');
const show = ref(false);
const rules = {
smsDrive: {
required: true,
message: '请输入默认驱动',
trigger: 'blur',
},
};
const driveList = [
{
label: '阿里云',
value: 'aliyun',
},
{
label: '腾讯云',
value: 'tencent',
},
];
const formRef: any = ref(null);
const message = useMessage();
const formValue = ref({
smsDrive: 'aliyun',
smsAliyunAccessKeyID: '',
smsAliyunAccessKeySecret: '',
smsAliyunSign: '',
smsAliyunTemplate: null,
smsMinInterval: 60,
smsMaxIpLimit: 10,
smsCodeExpire: 600,
});
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
console.log('formValue.value:' + JSON.stringify(formValue.value));
updateConfig({ group: group.value, list: formValue.value })
.then((res) => {
console.log('res:' + JSON.stringify(res));
message.success('更新成功');
load();
})
.catch((error) => {
message.error(error.toString());
});
} else {
message.error('验证失败,请填写完整信息');
}
});
}
onMounted(() => {
load();
});
function load() {
show.value = true;
new Promise((_resolve, _reject) => {
getConfig({ group: group.value })
.then((res) => {
show.value = false;
res.list.smsAliyunTemplate = JSON.parse(res.list.smsAliyunTemplate);
formValue.value = res.list;
})
.catch((error) => {
show.value = false;
message.error(error.toString());
});
});
}
</script>

View File

@@ -0,0 +1,177 @@
<template>
<div>
<n-spin :show="show" description="正在获取配置...">
<n-grid cols="2 s:2 m:2 l:2 xl:2 2xl:2" responsive="screen">
<n-grid-item>
<n-divider title-placement="left">通用配置</n-divider>
<n-form :label-width="100" :model="formValue" :rules="rules" ref="formRef">
<n-form-item label="默认驱动" path="uploadDrive">
<n-select
placeholder="默认驱动"
:options="uploadDriveList"
v-model:value="formValue.uploadDrive"
/>
</n-form-item>
<n-form-item label="图片大小限制" path="uploadImageSize">
<n-input-number
:show-button="false"
placeholder="请输入"
v-model:value="formValue.uploadImageSize"
>
<template #suffix> MB </template>
</n-input-number>
</n-form-item>
<n-form-item label="图片类型限制" path="uploadImageType">
<n-input v-model:value="formValue.uploadImageType" placeholder="" />
</n-form-item>
<n-form-item label="文件大小限制" path="uploadFileSize">
<n-input-number
:show-button="false"
placeholder="请输入"
v-model:value="formValue.uploadFileSize"
>
<template #suffix> MB </template>
</n-input-number>
</n-form-item>
<n-form-item label="文件类型限制" path="uploadFileType">
<n-input v-model:value="formValue.uploadFileType" placeholder="" />
</n-form-item>
<n-divider title-placement="left">本地存储</n-divider>
<n-form-item label="本地存储路径" path="uploadLocalPath">
<n-input v-model:value="formValue.uploadLocalPath" placeholder="" />
<template #feedback>填对外访问的相对路径</template>
</n-form-item>
<n-divider title-placement="left">UCloud存储</n-divider>
<n-form-item label="公钥" path="uploadUCloudPublicKey">
<n-input
v-model:value="formValue.uploadUCloudPublicKey"
placeholder=""
type="password"
/>
<template #feedback>获取地址https://console.ucloud.cn/ufile/token</template>
</n-form-item>
<n-form-item label="私钥" path="uploadUCloudPrivateKey">
<n-input
v-model:value="formValue.uploadUCloudPrivateKey"
placeholder=""
type="password"
/>
</n-form-item>
<n-form-item label="存储路径" path="uploadUCloudPath">
<n-input v-model:value="formValue.uploadUCloudPath" placeholder="" />
<template #feedback>填对对象存储中的相对路径</template>
</n-form-item>
<n-form-item label="地域API" path="uploadUCloudBucketHost">
<n-input v-model:value="formValue.uploadUCloudBucketHost" placeholder="" />
</n-form-item>
<n-form-item label="存储桶名称" path="uploadUCloudBucketName">
<n-input v-model:value="formValue.uploadUCloudBucketName" placeholder="" />
<template #feedback>存储空间名称</template>
</n-form-item>
<n-form-item label="存储桶地域host" path="uploadUCloudFileHost">
<n-input v-model:value="formValue.uploadUCloudFileHost" placeholder="" />
<template #feedback>不需要包含桶名称</template>
</n-form-item>
<n-form-item label="访问域名" path="uploadUCloudEndpoint">
<n-input v-model:value="formValue.uploadUCloudEndpoint" placeholder="" />
<template #feedback>格式http://abc.com 或 https://abc.com不可为空</template>
</n-form-item>
<div>
<n-space>
<n-button type="primary" @click="formSubmit">保存更新</n-button>
</n-space>
</div>
</n-form>
</n-grid-item>
</n-grid>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { useMessage } from 'naive-ui';
import { getConfig, updateConfig } from '@/api/sys/config';
const group = ref('upload');
const show = ref(false);
const rules = {
uploadDrive: {
required: true,
message: '请输入默认驱动',
trigger: 'blur',
},
};
const uploadDriveList = [
{
label: '本地存储',
value: 'local',
},
{
label: 'UC云存储',
value: 'ucloud',
},
];
const formRef: any = ref(null);
const message = useMessage();
const formValue = ref({
uploadDrive: 'local',
uploadImageSize: 2,
uploadImageType: '',
uploadFileSize: 10,
uploadFileType: '',
uploadLocalPath: '',
uploadUCloudPath: '',
uploadUCloudPublicKey: '',
uploadUCloudPrivateKey: '',
uploadUCloudBucketHost: 'api.ucloud.cn',
uploadUCloudBucketName: '',
uploadUCloudFileHost: 'cn-bj.ufileos.com',
uploadUCloudEndpoint: '',
});
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
console.log('formValue.value:' + JSON.stringify(formValue.value));
updateConfig({ group: group.value, list: formValue.value }).then((res) => {
console.log('res:' + JSON.stringify(res));
message.success('更新成功');
load();
});
} else {
message.error('验证失败,请填写完整信息');
}
});
}
onMounted(() => {
load();
});
function load() {
show.value = true;
new Promise((_resolve, _reject) => {
getConfig({ group: group.value })
.then((res) => {
show.value = false;
formValue.value = res.list;
console.log('res:' + JSON.stringify(res));
})
.catch((error) => {
show.value = false;
message.error(error.toString());
});
});
}
</script>

View File

@@ -21,6 +21,9 @@
<ThemeSetting v-if="type === 2" />
<RevealSetting v-if="type === 3" />
<EmailSetting v-if="type === 4" />
<UploadSetting v-if="type === 8" />
<GeoSetting v-if="type === 9" />
<SmsSetting v-if="type === 10" />
</n-card>
</n-grid-item>
</n-grid>
@@ -32,7 +35,9 @@
import RevealSetting from './RevealSetting.vue';
import EmailSetting from './EmailSetting.vue';
import ThemeSetting from './ThemeSetting.vue';
import UploadSetting from './UploadSetting.vue';
import GeoSetting from './GeoSetting.vue';
import SmsSetting from './SmsSetting.vue';
const typeTabList = [
{
name: '基本设置',
@@ -54,9 +59,47 @@
desc: '系统邮件设置',
key: 4,
},
// {
// name: '客服设置',
// desc: '系统客服设置',
// key: 5,
// },
// {
// name: '下游配置',
// desc: '默认设置和权限屏蔽',
// key: 6,
// },
// {
// name: '提现配置',
// desc: '提现规则配置',
// key: 7,
// },
{
name: '云存储',
desc: '配置上传文件驱动',
key: 8,
},
{
name: '地理位置',
desc: '配置地理位置工具',
key: 9,
},
{
name: '短信配置',
desc: '短信验证码平台',
key: 10,
},
];
export default defineComponent({
components: { BasicSetting, RevealSetting, EmailSetting, ThemeSetting },
components: {
BasicSetting,
RevealSetting,
EmailSetting,
ThemeSetting,
UploadSetting,
GeoSetting,
SmsSetting,
},
setup() {
const state = reactive({
type: 1,

View File

@@ -14,6 +14,7 @@
</BasicForm>
<BasicTable
:openChecked="true"
:columns="columns"
:request="loadDataTable"
:row-key="(row) => row.id"
@@ -149,7 +150,7 @@
</template>
<script lang="ts" setup>
import { h, onMounted, reactive, ref, onBeforeMount } from 'vue';
import { h, reactive, ref, onBeforeMount } from 'vue';
import { TreeSelectOption, useDialog, useMessage } from 'naive-ui';
import { BasicTable, TableAction } from '@/components/Table';
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
@@ -159,7 +160,7 @@
import { statusActions } from '@/enums/optionsiEnum';
import GroupModal from './modal/modal.vue';
const optionTreeData = ref([]);
const optionTreeData = ref<any>([]);
const defaultValueRef = () => ({
id: 0,
groupId: 0,
@@ -172,7 +173,7 @@
remark: '',
status: 1,
});
const params = ref({
const params = ref<any>({
pageSize: 10,
title: '',
content: '',
@@ -221,7 +222,7 @@
return s;
});
const groupOptions = ref([]);
const groupOptions = ref<any>([]);
const schemas: FormSchema[] = [
{
@@ -282,11 +283,11 @@
const dialog = useDialog();
const showModal = ref(false);
const formBtnLoading = ref(false);
const searchFormRef = ref({});
const formRef = ref({});
const searchFormRef = ref<any>({});
const formRef = ref<any>({});
const batchDeleteDisabled = ref(true);
const checkedIds = ref([]);
let formParams = ref(defaultValueRef());
let formParams = ref<any>(defaultValueRef());
const actionColumn = reactive({
width: 320,
@@ -330,17 +331,11 @@
}
const loadDataTable = async (res) => {
return await List({ ...params.value, ...res, ...searchFormRef.value.formModel });
return await List({ ...params.value, ...res, ...searchFormRef.value?.formModel });
};
function onCheckedRow(rowKeys) {
console.log(rowKeys);
if (rowKeys.length > 0) {
batchDeleteDisabled.value = false;
} else {
batchDeleteDisabled.value = true;
}
batchDeleteDisabled.value = rowKeys.length <= 0;
checkedIds.value = rowKeys;
}
@@ -353,20 +348,14 @@
formBtnLoading.value = true;
formRef.value.validate((errors) => {
if (!errors) {
console.log('formParams:' + JSON.stringify(formParams.value));
Edit(formParams.value)
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
formParams.value = ref(defaultValueRef());
});
})
.catch((_e: Error) => {
// message.error(e.message ?? '操作失败');
Edit(formParams.value).then((_res) => {
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
formParams.value = ref(defaultValueRef());
});
});
} else {
message.error('请填写完整信息');
}
@@ -375,35 +364,29 @@
}
function handleEdit(record: Recordable) {
console.log('点击了编辑', record);
showModal.value = true;
formParams.value = record;
}
function handleExecute(record: Recordable) {
console.log('点击了handleExecute', record);
message.error('暂未配置');
}
function handleDelete(record: Recordable) {
console.log('点击了删除', record);
dialog.warning({
title: '警告',
content: '你确定要删除?',
positiveText: '确定',
negativeText: '不确定',
negativeText: '取消',
onPositiveClick: () => {
Delete(record)
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
reloadTable();
})
.catch((e: Error) => {
// message.error(e.message ?? '操作失败');
});
Delete(record).then((_res) => {
message.success('操作成功');
reloadTable();
});
},
onNegativeClick: () => {
// message.error('不确定');
// message.error('取消');
},
});
}
@@ -413,26 +396,20 @@
title: '警告',
content: '你确定要删除?',
positiveText: '确定',
negativeText: '不确定',
negativeText: '取消',
onPositiveClick: () => {
Delete({ id: checkedIds.value })
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
reloadTable();
})
.catch((e: Error) => {
message.error(e.message ?? '操作失败');
});
Delete({ id: checkedIds.value }).then((_res) => {
message.success('操作成功');
reloadTable();
});
},
onNegativeClick: () => {
// message.error('不确定');
// message.error('取消');
},
});
}
function handleSubmit(values: Recordable) {
console.log(values);
params.value = values;
reloadTable();
}
@@ -448,7 +425,7 @@
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
setTimeout(() => {
reloadTable({});
reloadTable();
});
})
.catch((e: Error) => {
@@ -485,9 +462,8 @@
// 处理选项更新
function handleUpdateValue(
value: string | number | Array<string | number> | null,
option: TreeSelectOption | null | Array<TreeSelectOption | null>
_option: TreeSelectOption | null | Array<TreeSelectOption | null>
) {
console.log(value, option);
formParams.value.groupId = value;
}
</script>

View File

@@ -78,12 +78,12 @@
<script lang="ts" setup>
import { h, reactive, ref, onMounted } from 'vue';
import { SelectOption, TreeSelectOption, useDialog, useMessage } from 'naive-ui';
import { TreeSelectOption, useDialog, useMessage } from 'naive-ui';
import { BasicTable, TableAction } from '@/components/Table';
import { columns } from './columns';
import { PlusOutlined } from '@vicons/antd';
import { GroupDelete, GroupEdit, GroupList, GroupStatus, getSelect } from '@/api/sys/cron';
import { statusActions, statusOptions } from '@/enums/optionsiEnum';
import { GroupDelete, GroupEdit, GroupList, getSelect } from '@/api/sys/cron';
import { statusOptions } from '@/enums/optionsiEnum';
const optionTreeData = ref([]);
const message = useMessage();
@@ -118,18 +118,12 @@
formBtnLoading.value = true;
formRef.value.validate((errors) => {
if (!errors) {
console.log('formParams.value:' + JSON.stringify(formParams.value));
GroupEdit(formParams.value)
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
})
.catch((e: Error) => {
message.error(e.message ?? '操作失败');
GroupEdit(formParams.value).then((_res) => {
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
});
setTimeout(() => {
showModal.value = false;
reloadTable();
});
} else {
message.error('请填写完整信息');
@@ -140,12 +134,9 @@
const dialog = useDialog();
const actionRef = ref();
const formParams = ref<any>(defaultValueRef);
const formRef = ref<any>({});
const formParams = ref(defaultValueRef);
const params = ref(defaultValueRef);
const formRef = ref({});
const actionColumn = reactive({
width: 220,
title: '操作',
@@ -169,7 +160,6 @@
});
function handleEdit(record: Recordable) {
console.log('handleEdit', record);
showModal.value = true;
modalTitle.value = '编辑分组 ID' + record.id;
formParams.value = {
@@ -183,25 +173,20 @@
}
function handleDelete(record: Recordable) {
console.log('点击了删除', record);
dialog.warning({
title: '警告',
content: '你确定要删除?',
positiveText: '确定',
negativeText: '不确定',
negativeText: '取消',
onPositiveClick: () => {
GroupDelete(record)
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
reloadTable();
})
.catch((_e: Error) => {
// message.error(e.message ?? '操作失败');
});
},
onNegativeClick: () => {
// message.error('不确定');
// message.error('取消');
},
});
}
@@ -232,15 +217,14 @@
}
onMounted(async () => {
setDictSelect();
await setDictSelect();
});
// 处理选项更新
function handleUpdateValue(
value: string | number | Array<string | number> | null,
option: TreeSelectOption | null | Array<TreeSelectOption | null>
_option: TreeSelectOption | null | Array<TreeSelectOption | null>
) {
console.log(value, option);
formParams.value.pid = value;
}
</script>

View File

@@ -87,8 +87,7 @@
default: '添加顶级菜单',
},
optionTreeData: {
type: Object,
// eslint-disable-next-line vue/require-valid-default-prop
type: Object || Array,
default: [],
},
},
@@ -106,7 +105,7 @@
sort: 10,
});
const state = reactive({
const state = reactive<any>({
width: 500,
isDrawer: false,
subLoading: false,
@@ -122,7 +121,6 @@
state.width = document.body.clientWidth;
}
state.isDrawer = true;
console.log('form:' + JSON.stringify(form));
state.formParams = Object.assign(state.formParams, form);
}
@@ -133,18 +131,12 @@
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
console.log('state.formParams:' + JSON.stringify(state.formParams));
EditDict({ ...state.formParams })
.then(async (_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
handleReset();
await context.emit('loadData');
closeDrawer();
})
.catch((e: Error) => {
message.error(e.message ?? '操作失败');
});
EditDict({ ...state.formParams }).then(async (_res) => {
message.success('操作成功');
handleReset();
await context.emit('loadData');
closeDrawer();
});
} else {
message.error('请填写完整信息');
}
@@ -159,9 +151,8 @@
// 处理选项更新
function handleUpdateValue(
value: string | number | Array<string | number> | null,
option: TreeSelectOption | null | Array<TreeSelectOption | null>
_option: TreeSelectOption | null | Array<TreeSelectOption | null>
) {
console.log(value, option);
state.formParams.pid = value;
}

View File

@@ -12,17 +12,46 @@ export const columns = [
},
{
title: '字典标签',
key: 'label',
key: 'type',
render(row) {
return h(
NTag,
{
style: {
marginRight: '6px',
},
type: row.listClass,
bordered: false,
},
{
default: () => row.label,
}
);
},
},
{
title: '字典键值',
key: 'value',
},
// {
// title: '备注',
// key: 'remark',
// },
{
title: '键值类型',
key: 'valueType',
render(row) {
return h(
NTag,
{
style: {
marginRight: '6px',
},
type: 'default',
bordered: false,
},
{
default: () => row.valueType,
}
);
},
},
{
title: '状态',
key: 'status',
@@ -42,9 +71,4 @@ export const columns = [
);
},
},
// {
// title: '创建时间',
// key: 'createdAt',
// width: 100,
// },
];

View File

@@ -28,7 +28,12 @@
</template>
</BasicTable>
<n-modal v-model:show="showModal" :show-icon="false" preset="dialog" title="新建">
<n-modal
v-model:show="showModal"
:show-icon="false"
preset="dialog"
:title="formParams?.id > 0 ? '编辑' : '新建'"
>
<n-form
:model="formParams"
:rules="rules"
@@ -51,11 +56,14 @@
<n-form-item label="字典键值" path="value">
<n-input placeholder="请输入键值" v-model:value="formParams.value" />
</n-form-item>
<n-form-item label="表格回显" path="listClass">
<n-input placeholder="请输入表格回显样式" v-model:value="formParams.listClass" />
<n-form-item label="键值类型" path="valueType">
<n-select v-model:value="formParams.valueType" :options="options" />
</n-form-item>
<n-form-item label="标签样式" path="listClass">
<n-select v-model:value="formParams.listClass" :options="tagOptions" />
</n-form-item>
<n-form-item label="排序" path="sort">
<n-input placeholder="请输入" v-model:value="formParams.sort" />
<n-input-number placeholder="请输入" v-model:value="formParams.sort" />
</n-form-item>
<n-form-item label="状态" path="status">
<n-radio-group v-model:value="formParams.status" name="status">
@@ -91,8 +99,10 @@
import { getDataList, getDictSelect, EditData, DeleteData } from '@/api/dict/dict';
import { columns } from './columns';
import { PlusOutlined } from '@vicons/antd';
import { statusOptions } from '@/enums/optionsiEnum';
import { statusOptions, tagOptions } from '@/enums/optionsiEnum';
import { TypeSelect } from '@/api/sys/config';
import { Option } from '@/utils/hotgo';
const options = ref<Option>();
interface Props {
checkedId?: number;
}
@@ -115,7 +125,6 @@
const schemas: FormSchema[] = [
{
field: 'label',
// labelMessage: '请输入字典标签名称',
component: 'NInput',
label: '标签',
componentProps: {
@@ -135,18 +144,7 @@
const actionRef = ref();
const showModal = ref(false);
const formBtnLoading = ref(false);
const resetFormParams = {
typeId: props.checkedId,
label: '',
value: '',
listClass: '',
sort: 0,
status: 1,
remark: '',
};
const formParams = ref(resetFormParams);
const formParams = ref<any>({ typeId: 0 });
const params = ref({
pageSize: 10,
typeId: props.checkedId,
@@ -162,14 +160,14 @@
return h(TableAction as any, {
style: 'button',
actions: [
{
label: '删除',
onClick: handleDelete.bind(null, record),
},
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
onClick: handleDelete.bind(null, record),
},
],
});
},
@@ -183,7 +181,16 @@
function addTable() {
showModal.value = true;
formParams.value = resetFormParams;
formParams.value = {
typeId: props.checkedId,
label: '',
value: '',
listClass: 'default',
valueType: 'string',
sort: 0,
status: 1,
remark: '',
};
}
const loadDataTable = async (res) => {
@@ -203,20 +210,13 @@
formBtnLoading.value = true;
formRef.value.validate((errors) => {
if (!errors) {
console.log('formParams:' + JSON.stringify(formParams.value));
EditData(formParams.value)
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
formParams.value = ref(resetFormParams);
});
})
.catch((e: Error) => {
message.error(e.message ?? '操作失败');
EditData(formParams.value).then((_res) => {
message.success('操作成功');
setTimeout(() => {
showModal.value = false;
reloadTable();
});
});
} else {
message.error('请填写完整信息');
}
@@ -230,47 +230,37 @@
title: '警告',
content: '你确定要删除?',
positiveText: '确定',
negativeText: '不确定',
negativeText: '取消',
onPositiveClick: () => {
DeleteData(record)
.then((_res) => {
console.log('_res:' + JSON.stringify(_res));
message.success('操作成功');
reloadTable();
})
.catch((e: Error) => {
// message.error(e.message ?? '操作失败');
});
DeleteData(record).then((_res) => {
message.success('操作成功');
reloadTable();
});
},
onNegativeClick: () => {
// message.error('不确定');
// message.error('取消');
},
});
}
function handleEdit(record: Recordable) {
console.log('点击了编辑', record);
showModal.value = true;
formParams.value = record;
}
function handleSubmit(values: Recordable) {
console.log(values);
function handleSubmit(_values: Recordable) {
reloadTable();
}
function handleReset(values: Recordable) {
console.log(values);
function handleReset(_values: Recordable) {
params.value.label = '';
reloadTable();
}
watch(props, (_newVal, _oldVal) => {
console.log('_newVal:' + JSON.stringify(_newVal));
params.value.typeId = _newVal.checkedId;
formParams.value.typeId = _newVal.checkedId;
actionRef.value.reload();
setDictSelect();
});
@@ -283,15 +273,18 @@
function handleUpdateTypeIdValue(
value: string | number | Array<string | number> | null,
option: TreeSelectOption | null | Array<TreeSelectOption | null>
_option: TreeSelectOption | null | Array<TreeSelectOption | null>
) {
console.log(value, option);
formParams.value.typeId = value;
}
onMounted(() => {
setDictSelect();
async function loadOptions() {
options.value = await TypeSelect();
}
onMounted(async () => {
await setDictSelect();
await loadOptions();
});
</script>