mirror of
https://github.com/bufanyun/hotgo.git
synced 2026-04-26 13:04:32 +08:00
发布v2.15.7版本,更新内容请查看:https://github.com/bufanyun/hotgo/tree/v2.0/docs/guide-zh-CN/addon-version-upgrade.md
This commit is contained in:
@@ -73,7 +73,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="formParams.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in blacklistOptions"
|
||||
v-for="status in dict.getOptionUnRef('BlacklistStatusOptions')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -98,31 +98,18 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, reactive, ref } from 'vue';
|
||||
import { NTag, useDialog, useMessage } from 'naive-ui';
|
||||
import { h, onMounted, reactive, ref } from 'vue';
|
||||
import { 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 { DeleteOutlined, PlusOutlined } from '@vicons/antd';
|
||||
import { statusActions } from '@/enums/optionsiEnum';
|
||||
import { getOptionLabel, getOptionTag, Option } from '@/utils/hotgo';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
const blacklistOptions: Option[] = [
|
||||
{
|
||||
key: 1,
|
||||
value: 1,
|
||||
label: '封禁中',
|
||||
listClass: 'warning',
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
value: 2,
|
||||
label: '已解封',
|
||||
listClass: 'success',
|
||||
},
|
||||
];
|
||||
|
||||
const dict = useDictStore();
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
@@ -140,19 +127,7 @@
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(blacklistOptions, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(blacklistOptions, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('BlacklistStatusOptions', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -190,7 +165,7 @@
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: blacklistOptions,
|
||||
options: dict.getOption('BlacklistStatusOptions'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -240,13 +215,13 @@
|
||||
sort: 0,
|
||||
status: 1,
|
||||
};
|
||||
let formParams = ref<any>(resetFormParams);
|
||||
const formParams = ref<any>(resetFormParams);
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 220,
|
||||
width: 150,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
// fixed: 'right',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
@@ -260,10 +235,6 @@
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
],
|
||||
dropDownActions: statusActions,
|
||||
select: (key) => {
|
||||
updateStatus(record.id, key);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -284,7 +255,6 @@
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys);
|
||||
batchDeleteDisabled.value = rowKeys.length <= 0;
|
||||
checkedIds.value = rowKeys;
|
||||
}
|
||||
@@ -334,9 +304,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -356,9 +323,6 @@
|
||||
message.error(e.message ?? '操作失败');
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -372,14 +336,9 @@
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
function updateStatus(id, status) {
|
||||
Status({ id: id, status: status }).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
reloadTable();
|
||||
});
|
||||
});
|
||||
}
|
||||
onMounted(() => {
|
||||
dict.loadOptions(['BlacklistStatusOptions']);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -119,7 +119,10 @@
|
||||
class="py-4"
|
||||
>
|
||||
<n-form-item label="事件模板" path="event">
|
||||
<n-select :options="options.config_sms_template" v-model:value="formParams.event" />
|
||||
<n-select
|
||||
:options="dict.getOptionUnRef('config_sms_template')"
|
||||
v-model:value="formParams.event"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="手机号" path="mobile">
|
||||
@@ -153,8 +156,7 @@
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { getConfig, sendTestSms, updateConfig } from '@/api/sys/config';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { Options } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const group = ref('pay');
|
||||
const show = ref(false);
|
||||
@@ -165,11 +167,7 @@
|
||||
const formTestRef = ref<any>();
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
|
||||
const options = ref<Options>({
|
||||
config_sms_template: [],
|
||||
config_sms_drive: [],
|
||||
});
|
||||
const dict = useDictStore();
|
||||
|
||||
const formValue = ref({
|
||||
payDebug: true,
|
||||
@@ -188,11 +186,6 @@
|
||||
payQQPayApiKey: '',
|
||||
});
|
||||
|
||||
function sendTest() {
|
||||
showModal.value = true;
|
||||
formBtnLoading.value = false;
|
||||
}
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
@@ -206,28 +199,20 @@
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load();
|
||||
});
|
||||
|
||||
async function load() {
|
||||
function load() {
|
||||
show.value = true;
|
||||
await loadOptions();
|
||||
new Promise((_resolve, _reject) => {
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
});
|
||||
loadOptions();
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['config_sms_template', 'config_sms_drive'],
|
||||
});
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['config_sms_template', 'config_sms_drive']);
|
||||
}
|
||||
|
||||
function confirmForm(e) {
|
||||
@@ -245,4 +230,8 @@
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
label-placement="top"
|
||||
>
|
||||
<n-divider title-placement="left">基础设置</n-divider>
|
||||
<n-form-item label="默认驱动" path="smsDrive">
|
||||
<n-select
|
||||
placeholder="默认发送驱动"
|
||||
:options="options.config_sms_drive"
|
||||
:options="dict.getOptionUnRef('config_sms_drive')"
|
||||
v-model:value="formValue.smsDrive"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-divider title-placement="left">发信限制</n-divider>
|
||||
<n-form-item label="最小发送间隔" path="smsMinInterval">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
@@ -179,7 +178,10 @@
|
||||
class="py-4"
|
||||
>
|
||||
<n-form-item label="事件模板" path="event">
|
||||
<n-select :options="options.config_sms_template" v-model:value="formParams.event" />
|
||||
<n-select
|
||||
:options="dict.getOptionUnRef('config_sms_template')"
|
||||
v-model:value="formParams.event"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="手机号" path="mobile">
|
||||
@@ -213,17 +215,23 @@
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { getConfig, sendTestSms, updateConfig } from '@/api/sys/config';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { Options } from '@/utils/hotgo';
|
||||
import { GlassesOutline, Glasses } from '@vicons/ionicons5';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const group = ref('sms');
|
||||
const show = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const formParams = ref({ mobile: '', event: '', code: '1234' });
|
||||
const formTestRef = ref<any>();
|
||||
const formRef: any = ref(null);
|
||||
const defaultTabName = 'aliyun';
|
||||
const tabName = ref<string>(defaultTabName);
|
||||
|
||||
const rules = {
|
||||
const rules: FormRules = {
|
||||
smsDrive: {
|
||||
required: true,
|
||||
message: '请输入默认驱动',
|
||||
@@ -231,20 +239,6 @@
|
||||
},
|
||||
};
|
||||
|
||||
const formTestRef = ref<any>();
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
|
||||
const options = ref<Options>({
|
||||
config_sms_template: [],
|
||||
config_sms_drive: [],
|
||||
});
|
||||
|
||||
/** 默认选项卡 */
|
||||
const defaultTabName = 'aliyun';
|
||||
/** 选项卡名称 */
|
||||
const tabName = ref<string>(defaultTabName);
|
||||
|
||||
const formValue = ref({
|
||||
smsDrive: defaultTabName,
|
||||
smsMinInterval: 60,
|
||||
@@ -263,14 +257,6 @@
|
||||
smsTencentTemplate: null,
|
||||
});
|
||||
|
||||
/** 监听类型变化,同步到选项卡中 */
|
||||
watch(
|
||||
() => formValue.value.smsDrive,
|
||||
(smsDrive: string) => {
|
||||
tabName.value = smsDrive;
|
||||
}
|
||||
);
|
||||
|
||||
function sendTest() {
|
||||
showModal.value = true;
|
||||
formBtnLoading.value = false;
|
||||
@@ -289,30 +275,21 @@
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load();
|
||||
});
|
||||
|
||||
async function load() {
|
||||
function load() {
|
||||
show.value = true;
|
||||
await loadOptions();
|
||||
new Promise((_resolve, _reject) => {
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
res.list.smsAliYunTemplate = JSON.parse(res.list.smsAliYunTemplate);
|
||||
res.list.smsTencentTemplate = JSON.parse(res.list.smsTencentTemplate);
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
});
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
res.list.smsAliYunTemplate = JSON.parse(res.list.smsAliYunTemplate);
|
||||
res.list.smsTencentTemplate = JSON.parse(res.list.smsTencentTemplate);
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['config_sms_template', 'config_sms_drive'],
|
||||
});
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['config_sms_template', 'config_sms_drive']);
|
||||
}
|
||||
|
||||
function confirmForm(e) {
|
||||
@@ -330,4 +307,16 @@
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formValue.value.smsDrive,
|
||||
(smsDrive: string) => {
|
||||
tabName.value = smsDrive;
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
loadOptions();
|
||||
load();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
label-placement="top"
|
||||
>
|
||||
<n-divider title-placement="left">基础设置</n-divider>
|
||||
<n-form-item label="默认驱动" path="uploadDrive">
|
||||
<n-select
|
||||
placeholder="默认驱动"
|
||||
:options="options.config_upload_drive"
|
||||
:options="dict.getOptionUnRef('config_upload_drive')"
|
||||
v-model:value="formValue.uploadDrive"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-divider title-placement="left">上传限制</n-divider>
|
||||
<n-form-item label="图片大小限制" path="uploadImageSize">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
@@ -311,15 +310,18 @@
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { getConfig, updateConfig } from '@/api/sys/config';
|
||||
import { Glasses, GlassesOutline } from '@vicons/ionicons5';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { Options } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const group = ref('upload');
|
||||
const show = ref(false);
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
const defaultTabName = 'local';
|
||||
const tabName = ref<string>(defaultTabName);
|
||||
|
||||
const rules = {
|
||||
const rules: FormRules = {
|
||||
uploadDrive: {
|
||||
required: true,
|
||||
message: '请输入默认驱动',
|
||||
@@ -327,15 +329,6 @@
|
||||
},
|
||||
};
|
||||
|
||||
const options = ref<Options>({
|
||||
config_upload_drive: [],
|
||||
});
|
||||
|
||||
/** 默认选项卡 */
|
||||
const defaultTabName = 'local';
|
||||
/** 选项卡名称 */
|
||||
const tabName = ref<string>(defaultTabName);
|
||||
|
||||
const formValue = ref({
|
||||
uploadDrive: defaultTabName,
|
||||
uploadImageSize: 2,
|
||||
@@ -374,14 +367,6 @@
|
||||
uploadMinioDomain: '',
|
||||
});
|
||||
|
||||
/** 监听类型变化,同步到选项卡中 */
|
||||
watch(
|
||||
() => formValue.value.uploadDrive,
|
||||
(uploadDrive: string) => {
|
||||
tabName.value = uploadDrive;
|
||||
}
|
||||
);
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
@@ -395,27 +380,30 @@
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
load();
|
||||
await loadOptions();
|
||||
});
|
||||
|
||||
function load() {
|
||||
show.value = true;
|
||||
new Promise((_resolve, _reject) => {
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
});
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['config_upload_drive'],
|
||||
});
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['config_upload_drive']);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formValue.value.uploadDrive,
|
||||
(uploadDrive: string) => {
|
||||
tabName.value = uploadDrive;
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
load();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<n-drawer v-model:show="isDrawer" :width="width" :placement="placement">
|
||||
<n-drawer
|
||||
v-model:show="isDrawer"
|
||||
:width="dialogWidth"
|
||||
:label-placement="settingStore.isMobile ? 'top' : 'left'"
|
||||
>
|
||||
<n-drawer-content :title="title" closable>
|
||||
<n-form
|
||||
:model="formParams"
|
||||
@@ -28,7 +32,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="formParams.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in statusMap"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -39,34 +43,25 @@
|
||||
|
||||
<template #footer>
|
||||
<n-space>
|
||||
<n-button type="primary" :loading="subLoading" @click="formSubmit">提交</n-button>
|
||||
<n-button @click="handleReset">重置</n-button>
|
||||
<n-button type="primary" :loading="btnLoading" @click="formSubmit">提交</n-button>
|
||||
<n-button @click="closeDrawer">取消</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, toRefs } from 'vue';
|
||||
import { TreeSelectOption, useMessage } from 'naive-ui';
|
||||
import { QuestionCircleOutlined } from '@vicons/antd';
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { EditDict } from '@/api/dict/dict';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
import { State } from '@/views/system/dict/model';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
|
||||
const statusMap = [
|
||||
{
|
||||
value: 0,
|
||||
label: '禁用',
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '启用',
|
||||
},
|
||||
].map((s) => {
|
||||
return s;
|
||||
});
|
||||
|
||||
const rules = {
|
||||
const rules: FormRules = {
|
||||
label: {
|
||||
required: true,
|
||||
message: '请输入标题',
|
||||
@@ -78,96 +73,60 @@
|
||||
trigger: 'blur',
|
||||
},
|
||||
};
|
||||
export default defineComponent({
|
||||
name: 'CreateDrawer',
|
||||
components: {},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '添加顶级菜单',
|
||||
},
|
||||
optionTreeData: {
|
||||
type: Object || Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
emits: ['loadData'],
|
||||
setup(_props, context) {
|
||||
const message = useMessage();
|
||||
const formRef: any = ref(null);
|
||||
const defaultValueRef = () => ({
|
||||
id: 0,
|
||||
pid: 0,
|
||||
type: '',
|
||||
name: '',
|
||||
remark: '',
|
||||
status: 1,
|
||||
sort: 10,
|
||||
});
|
||||
|
||||
const state = reactive<any>({
|
||||
width: 500,
|
||||
isDrawer: false,
|
||||
subLoading: false,
|
||||
formParams: defaultValueRef(),
|
||||
placement: 'right',
|
||||
icon: '',
|
||||
alertText:
|
||||
'该功能主要实时预览各种布局效果,更多完整配置在 projectSetting.ts 中设置,建议在生产环境关闭该布局预览功能。',
|
||||
});
|
||||
interface Props {
|
||||
title: '添加顶级菜单';
|
||||
optionTreeData: [];
|
||||
}
|
||||
|
||||
function openDrawer(form) {
|
||||
if (document.body.clientWidth < 500) {
|
||||
state.width = document.body.clientWidth;
|
||||
}
|
||||
state.isDrawer = true;
|
||||
state.formParams = Object.assign(state.formParams, form);
|
||||
const emit = defineEmits(['loadData']);
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const formRef: any = ref(null);
|
||||
const formParams = ref<State>(new State());
|
||||
const btnLoading = ref(false);
|
||||
const isDrawer = ref(false);
|
||||
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth(500);
|
||||
});
|
||||
|
||||
function openDrawer(state: State) {
|
||||
isDrawer.value = true;
|
||||
formParams.value = state;
|
||||
}
|
||||
|
||||
function closeDrawer() {
|
||||
isDrawer.value = false;
|
||||
}
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
btnLoading.value = true;
|
||||
EditDict(formParams.value)
|
||||
.then(async (_res) => {
|
||||
message.success('操作成功');
|
||||
emit('loadData');
|
||||
closeDrawer();
|
||||
})
|
||||
.finally(() => {
|
||||
btnLoading.value = false;
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function closeDrawer() {
|
||||
state.isDrawer = false;
|
||||
}
|
||||
// 处理选项更新
|
||||
function handleUpdateValue(value: number) {
|
||||
formParams.value.pid = value;
|
||||
}
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
EditDict({ ...state.formParams }).then(async (_res) => {
|
||||
message.success('操作成功');
|
||||
handleReset();
|
||||
await context.emit('loadData');
|
||||
closeDrawer();
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
formRef.value.restoreValidation();
|
||||
state.formParams = Object.assign(state.formParams, defaultValueRef());
|
||||
}
|
||||
|
||||
// 处理选项更新
|
||||
function handleUpdateValue(
|
||||
value: string | number | Array<string | number> | null,
|
||||
_option: TreeSelectOption | null | Array<TreeSelectOption | null>
|
||||
) {
|
||||
state.formParams.pid = value;
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
formRef,
|
||||
rules,
|
||||
formSubmit,
|
||||
handleReset,
|
||||
openDrawer,
|
||||
closeDrawer,
|
||||
statusMap,
|
||||
handleUpdateValue,
|
||||
QuestionCircleOutlined,
|
||||
};
|
||||
},
|
||||
defineExpose({
|
||||
openDrawer,
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</n-space>
|
||||
</template>
|
||||
<div class="w-full menu">
|
||||
<n-input type="input" v-model:value="pattern" placeholder="输入字典名称搜索">
|
||||
<n-input type="text" v-model:value="pattern" placeholder="输入字典名称搜索">
|
||||
<template #suffix>
|
||||
<n-icon size="18" class="cursor-pointer">
|
||||
<SearchOutlined />
|
||||
@@ -111,7 +111,7 @@
|
||||
ref="createDrawerRef"
|
||||
:title="drawerTitle"
|
||||
:optionTreeData="optionTreeData"
|
||||
@loadData="loadData"
|
||||
@load-data="loadData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -129,6 +129,7 @@
|
||||
import CreateDrawer from './CreateDrawer.vue';
|
||||
import List from './list.vue';
|
||||
import { DeleteDict, getDictTree } from '@/api/dict/dict';
|
||||
import { State } from '@/views/system/dict/model';
|
||||
|
||||
const createDrawerRef = ref();
|
||||
const message = useMessage();
|
||||
@@ -143,28 +144,18 @@
|
||||
const pattern = ref('');
|
||||
const drawerTitle = ref('');
|
||||
const optionTreeData = ref([]);
|
||||
const defaultValueRef = () => ({
|
||||
id: 0,
|
||||
pid: 0,
|
||||
type: '',
|
||||
name: '',
|
||||
remark: '',
|
||||
status: 1,
|
||||
sort: 10,
|
||||
});
|
||||
|
||||
const formParams = reactive(defaultValueRef());
|
||||
const formParams = ref<State>(new State());
|
||||
|
||||
function openCreateDrawer() {
|
||||
drawerTitle.value = '添加字典类型';
|
||||
const { openDrawer } = createDrawerRef.value;
|
||||
openDrawer(defaultValueRef());
|
||||
openDrawer(new State());
|
||||
}
|
||||
|
||||
function openEditDrawer() {
|
||||
drawerTitle.value = '编辑字典类型';
|
||||
const { openDrawer } = createDrawerRef.value;
|
||||
openDrawer(formParams);
|
||||
openDrawer(formParams.value);
|
||||
}
|
||||
|
||||
function selectedTree(keys, opts) {
|
||||
@@ -172,7 +163,7 @@
|
||||
const treeItem = opts[0];
|
||||
treeItemKey.value = keys;
|
||||
treeItemTitle.value = treeItem.label;
|
||||
Object.assign(formParams, treeItem);
|
||||
formParams.value = unref(treeItem);
|
||||
isEditMenu.value = true;
|
||||
checkedId.value = treeItem.id;
|
||||
} else {
|
||||
@@ -189,14 +180,11 @@
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
DeleteDict({ ...formParams }).then(async (_res) => {
|
||||
DeleteDict(formParams.value).then(async (_res) => {
|
||||
message.success('操作成功');
|
||||
await loadData();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
message.error('已取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -208,14 +196,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadData();
|
||||
});
|
||||
|
||||
async function loadData() {
|
||||
const treeMenuList = await getDictTree();
|
||||
const keys = treeMenuList.list.map((item) => item.key);
|
||||
Object.assign(formParams, keys);
|
||||
Object.assign(formParams.value, keys);
|
||||
treeData.value = [];
|
||||
optionTreeData.value = [];
|
||||
treeData.value = treeMenuList.list;
|
||||
@@ -226,4 +210,8 @@
|
||||
function onExpandedKeys(keys) {
|
||||
expandedKeys.value = keys;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<n-select
|
||||
:render-tag="renderTag"
|
||||
v-model:value="formParams.listClass"
|
||||
:options="labelOptions"
|
||||
:options="dict.getOptionUnRef('tagTypeOptions')"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="字典键值" path="value">
|
||||
@@ -72,7 +72,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="formParams.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in statusOptions"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -103,17 +103,17 @@
|
||||
import { getDataList, getDictSelect, EditData, DeleteData } from '@/api/dict/dict';
|
||||
import { columns } from './columns';
|
||||
import { PlusOutlined } from '@vicons/antd';
|
||||
import { statusOptions } from '@/enums/optionsiEnum';
|
||||
import { TypeSelect } from '@/api/sys/config';
|
||||
import { Option } from '@/utils/hotgo';
|
||||
import { findTreeNode } from '@/utils';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Option, useDictStore } from '@/store/modules/dict';
|
||||
import { State } from '@/views/system/dict/model';
|
||||
|
||||
interface Props {
|
||||
checkedId?: number;
|
||||
}
|
||||
|
||||
const dict = useDictStore();
|
||||
const props = withDefaults(defineProps<Props>(), { checkedId: 0 });
|
||||
const typeList = ref<any>([]);
|
||||
const rules = {
|
||||
@@ -162,53 +162,22 @@
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: option.type as 'success' | 'warning' | 'error' | 'info' | 'primary' | 'default',
|
||||
type: option.listClass as 'success' | 'warning' | 'error' | 'info' | 'primary' | 'default',
|
||||
},
|
||||
{ default: () => option.label }
|
||||
);
|
||||
};
|
||||
|
||||
const labelOptions = ref([
|
||||
{
|
||||
label: '绿色',
|
||||
value: 'success',
|
||||
type: 'success',
|
||||
},
|
||||
{
|
||||
label: '橙色',
|
||||
value: 'warning',
|
||||
type: 'warning',
|
||||
},
|
||||
{
|
||||
label: '红色',
|
||||
value: 'error',
|
||||
type: 'error',
|
||||
},
|
||||
{
|
||||
label: '蓝色',
|
||||
value: 'info',
|
||||
type: 'info',
|
||||
},
|
||||
{
|
||||
label: '灰色',
|
||||
value: 'default',
|
||||
type: 'default',
|
||||
},
|
||||
{
|
||||
label: '主题色',
|
||||
value: 'primary',
|
||||
type: 'primary',
|
||||
},
|
||||
]);
|
||||
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const actionRef = ref();
|
||||
const showModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const formParams = ref<any>({ typeId: 0 });
|
||||
const formParams = ref<State>(new State());
|
||||
const options = ref<Option>();
|
||||
const typeId = ref(0);
|
||||
|
||||
const params = ref({
|
||||
pageSize: 10,
|
||||
typeId: props.checkedId,
|
||||
@@ -217,7 +186,7 @@
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 120,
|
||||
width: 140,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
@@ -246,16 +215,10 @@
|
||||
|
||||
function addTable() {
|
||||
showModal.value = true;
|
||||
formParams.value = {
|
||||
typeId: props.checkedId,
|
||||
label: '',
|
||||
value: '',
|
||||
listClass: 'default',
|
||||
valueType: 'string',
|
||||
sort: 0,
|
||||
status: 1,
|
||||
remark: '',
|
||||
};
|
||||
formParams.value = new State();
|
||||
if (typeId.value > 0) {
|
||||
formParams.value.typeId = typeId.value;
|
||||
}
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
@@ -272,25 +235,26 @@
|
||||
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
EditData(formParams.value).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
formBtnLoading.value = true;
|
||||
EditData(formParams.value)
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
showModal.value = false;
|
||||
reloadTable();
|
||||
})
|
||||
.finally(() => {
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(record: Recordable) {
|
||||
console.log('点击了删除', record);
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
content: '你确定要删除?',
|
||||
@@ -307,7 +271,7 @@
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
showModal.value = true;
|
||||
formParams.value = cloneDeep(record);
|
||||
formParams.value = cloneDeep(record) as unknown as State;
|
||||
}
|
||||
|
||||
function handleSubmit(_values: Recordable) {
|
||||
@@ -316,16 +280,10 @@
|
||||
|
||||
function handleReset(_values: Recordable) {
|
||||
params.value.label = '';
|
||||
params.value.value = '';
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
watch(props, (newVal, _oldVal) => {
|
||||
params.value.typeId = newVal.checkedId;
|
||||
formParams.value.typeId = newVal.checkedId;
|
||||
actionRef.value.reload();
|
||||
setDictSelect();
|
||||
});
|
||||
|
||||
async function setDictSelect() {
|
||||
const tmp = await getDictSelect({});
|
||||
typeList.value = tmp.list;
|
||||
@@ -344,13 +302,23 @@
|
||||
formParams.value.type = row.type;
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await TypeSelect();
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['sys_normal_disable']);
|
||||
TypeSelect().then((res) => {
|
||||
options.value = res;
|
||||
});
|
||||
}
|
||||
|
||||
watch(props, (newVal, _oldVal) => {
|
||||
params.value.typeId = newVal.checkedId;
|
||||
typeId.value = newVal.checkedId;
|
||||
actionRef.value.reload();
|
||||
setDictSelect();
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
await setDictSelect();
|
||||
await loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
18
web/src/views/system/dict/model.ts
Normal file
18
web/src/views/system/dict/model.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export class State {
|
||||
typeId = 0;
|
||||
key = '';
|
||||
id = 0;
|
||||
label = '';
|
||||
value = '';
|
||||
valueType = 'string';
|
||||
type = '';
|
||||
listClass = 'primary';
|
||||
isDefault = 0;
|
||||
sort = 0;
|
||||
remark = '';
|
||||
status = 1;
|
||||
createdAt = '';
|
||||
updatedAt = '';
|
||||
pid: number | null = 0;
|
||||
name = '';
|
||||
}
|
||||
Reference in New Issue
Block a user