diff --git a/src/service/api/sys/core/dictionary.ts b/src/service/api/sys/core/dictionary.ts index ce861e0e..848ce09f 100644 --- a/src/service/api/sys/core/dictionary.ts +++ b/src/service/api/sys/core/dictionary.ts @@ -1,26 +1,26 @@ import { request } from '../../../request'; -export function fetchPageDictionary(pageRequest: Api.Sys.Core.DictionaryQueryPageRequest) { - return request>({ +export function fetchDictionaryPaginate(pageRequest: Api.Common.PageRequest) { + return request>({ url: '/dictionary/paginate', method: 'post', data: pageRequest }); } -export function fetchDictionaryAdd(dictionaryOp: Api.Sys.Core.DictionaryOp) { +export function fetchDictionaryInsert(dictionaryDTO: Api.Sys.Core.DictionaryDTO) { return request({ url: '/dictionary/insert', method: 'post', - data: dictionaryOp + data: dictionaryDTO }); } -export function fetchDictionaryEdit(dictionaryOp: Api.Sys.Core.DictionaryOp) { +export function fetchDictionaryUpdate(dictionaryDTO: Api.Sys.Core.DictionaryDTO) { return request({ url: '/dictionary/update', method: 'post', - data: dictionaryOp + data: dictionaryDTO }); } @@ -44,8 +44,8 @@ export function fetchDictionaryDeleteBatch(ids: string[]) { }); } -export function fetchTreeDictionaryItem(dictionaryId: string) { - return request({ +export function fetchDictionaryItemTreeList(dictionaryId: string) { + return request({ url: '/dictionaryItem/tree', method: 'post', data: { @@ -54,19 +54,19 @@ export function fetchTreeDictionaryItem(dictionaryId: string) { }); } -export function fetchDictionaryItemAdd(dictionaryOp: Api.Sys.Core.DictionaryItemOp) { +export function fetchDictionaryItemInsert(dictionaryItemDTO: Api.Sys.Core.DictionaryItemDTO) { return request({ url: '/dictionaryItem/insert', method: 'post', - data: dictionaryOp + data: dictionaryItemDTO }); } -export function fetchDictionaryItemEdit(dictionaryOp: Api.Sys.Core.DictionaryItemOp) { +export function fetchDictionaryItemUpdate(dictionaryItemDTO: Api.Sys.Core.DictionaryItemDTO) { return request({ url: '/dictionaryItem/update', method: 'post', - data: dictionaryOp + data: dictionaryItemDTO }); } diff --git a/src/typings/api/sys/core.d.ts b/src/typings/api/sys/core.d.ts index ce547f62..fa864867 100644 --- a/src/typings/api/sys/core.d.ts +++ b/src/typings/api/sys/core.d.ts @@ -3,7 +3,7 @@ declare namespace Api { namespace Core { // ******************** sys_core_dictionary ******************** type DictionaryType = 'enum' | 'tree'; - interface Dictionary { + interface DictionaryVO { id: string; name: string; code: string; @@ -12,30 +12,25 @@ declare namespace Api { createTime: string; updateTime: string; } - interface DictionaryQuery { + interface DictionaryDTO { + id: string | null; name: string | null; code: string | null; - type: string | null; - } - type DictionaryQueryPageRequest = Api.Common.PageRequest; - interface DictionaryOp { - id: string | null; - name: string; - code: string; - type: DictionaryType; + type: DictionaryType | null; description: string | null; } - interface DictionaryItem { + interface DictionaryItemVO { id: string; + dictionaryId: string | null; name: string; code: string; sort: number; description: string | null; - createTime: string | null; - updateTime: string | null; - children: DictionaryItem[]; + createTime: string; + updateTime: string; + children: DictionaryItemVO[]; } - interface DictionaryItemOp { + interface DictionaryItemDTO { id: string | null; dictionaryId: string; name: string; diff --git a/src/views/sys/core/dictionary/index.vue b/src/views/sys/core/dictionary/index.vue index f0726cd5..964f60b4 100644 --- a/src/views/sys/core/dictionary/index.vue +++ b/src/views/sys/core/dictionary/index.vue @@ -2,27 +2,34 @@ import { reactive } from 'vue'; import { NButton, NPopconfirm, NTag } from 'naive-ui'; import { dictionaryTypeRecord } from '@/constants/sys/core/dictionary'; -import { fetchDictionaryDelete, fetchDictionaryDeleteBatch, fetchPageDictionary } from '@/service/api'; +import { fetchDictionaryDelete, fetchDictionaryDeleteBatch, fetchDictionaryPaginate } from '@/service/api'; import { useAppStore } from '@/store/modules/app'; import { defaultTransform, useNaivePaginatedTable, useTableOperate } from '@/hooks/common/table'; import { $t } from '@/locales'; import DictionarySearch from '@/views/sys/core/dictionary/modules/dictionary-search.vue'; import DictionaryOperateDrawer from '@/views/sys/core/dictionary/modules/dictionary-operate-drawer.vue'; +import DictionaryDTO = Api.Sys.Core.DictionaryDTO; + +// ******************** 数据定义 ******************** const appStore = useAppStore(); -const pageRequest: Api.Sys.Core.DictionaryQueryPageRequest = reactive({ +// 表格分页请求 +const pageRequest: Api.Common.PageRequest = reactive({ pageIndex: 1, pageSize: 10, query: { + id: null, name: null, code: null, - type: null + type: null, + description: null } }); -const { columns, columnChecks, data, loading, getData, getDataByPage, mobilePagination } = useNaivePaginatedTable({ - api: () => fetchPageDictionary(pageRequest), +// 表格数据 +const { columns, columnChecks, data, loading, getData, getDataByPage, pagination } = useNaivePaginatedTable({ + api: () => fetchDictionaryPaginate(pageRequest), transform: response => defaultTransform(response), onPaginationParamsChange: params => { pageRequest.pageIndex = params.page || 1; @@ -100,10 +107,12 @@ const { columns, columnChecks, data, loading, getData, getDataByPage, mobilePagi } ] }); - +// 表格操作 const { drawerVisible, operateType, editingData, handleAdd, handleEdit, checkedRowKeys, onBatchDeleted, onDeleted } = useTableOperate(data, 'id', getData); +// ******************** 触发事件 ******************** + async function handleBatchDelete() { fetchDictionaryDeleteBatch(checkedRowKeys.value).then(() => { onBatchDeleted(); @@ -151,7 +160,7 @@ function edit(id: string) { :loading="loading" remote :row-key="row => row.id" - :pagination="mobilePagination" + :pagination="pagination" class="sm:h-full" /> -import { computed } from 'vue'; -import { $t } from '@/locales'; - -defineOptions({ - name: 'DictionaryOperateDialog' -}); - -const props = defineProps<{ - /** the type of operation */ - operateType: NaiveUI.TableOperateType; - /** the edit row data */ - // rowData?: Api.Sys.Core.Dictionary | null; -}>(); - -const emit = defineEmits<{ - (e: 'submitted'): void; -}>(); - -const visible = defineModel('visible', { - default: false -}); - -const title = computed(() => { - const titles: Record = { - add: $t('common.add'), - edit: $t('common.edit') - }; - return titles[props.operateType]; -}); - -function closeDialog(): void { - visible.value = false; -} - -function handleSubmit() { - window.$message?.success($t('common.updateSuccess')); - closeDialog(); - emit('submitted'); -} - - - - - diff --git a/src/views/sys/core/dictionary/modules/dictionary-operate-drawer.vue b/src/views/sys/core/dictionary/modules/dictionary-operate-drawer.vue index 8ffce02c..25a76194 100644 --- a/src/views/sys/core/dictionary/modules/dictionary-operate-drawer.vue +++ b/src/views/sys/core/dictionary/modules/dictionary-operate-drawer.vue @@ -4,43 +4,56 @@ import type { DataTableColumns } from 'naive-ui'; import { jsonClone } from '@sa/utils'; import { dictionaryTypeOptions } from '@/constants/sys/core/dictionary'; import { - fetchDictionaryAdd, - fetchDictionaryEdit, - fetchDictionaryItemAdd, + fetchDictionaryInsert, fetchDictionaryItemDelete, - fetchDictionaryItemEdit, - fetchTreeDictionaryItem + fetchDictionaryItemInsert, + fetchDictionaryItemTreeList, + fetchDictionaryItemUpdate, + fetchDictionaryUpdate } from '@/service/api'; import { useFormRules, useNaiveForm } from '@/hooks/common/form'; import { $t } from '@/locales'; -import DictionaryItem = Api.Sys.Core.DictionaryItem; +// ******************** 数据定义 ******************** + +// 组件定义 defineOptions({ name: 'DictionaryOperateDrawer' }); +// 属性定义 interface Props { /** the type of operation */ operateType: NaiveUI.TableOperateType; /** the edit row data */ - rowData?: Api.Sys.Core.Dictionary | null; + rowData?: Api.Sys.Core.DictionaryVO | null; } - const props = defineProps(); +// 事件定义 interface Emits { (e: 'submitted'): void; } - const emit = defineEmits(); +// 可见性定义 const visible = defineModel('visible', { default: false }); -const { formRef, validate, restoreValidation } = useNaiveForm(); -const { defaultRequiredRule } = useFormRules(); +// Model +const model = ref(createDefaultModel()); +function createDefaultModel(): Api.Sys.Core.DictionaryDTO { + return { + id: null, + name: null, + code: null, + type: null, + description: null + }; +} +// 抽屉标题 const title = computed(() => { const titles: Record = { add: $t('common.add'), @@ -49,41 +62,54 @@ const title = computed(() => { return titles[props.operateType]; }); -interface Model { - name: string; - code: string; - type: Api.Sys.Core.DictionaryType; - description: string | null; - children: Api.Sys.Core.DictionaryItem[]; -} +// Form校验规则 +const { formRef, validate, restoreValidation } = useNaiveForm(); +const { defaultRequiredRule } = useFormRules(); +type RuleKey = 'name' | 'code' | 'type'; +const rules: Record = { + name: defaultRequiredRule, + code: defaultRequiredRule, + type: defaultRequiredRule +}; -interface ChildrenOperateModel { - id: string | null; - name: string; - code: string; - sort: number; - description: string | null; -} +// ******************** 事件定义 ******************** -const model = ref(createDefaultModel()); +function handleInitModel() { + model.value = createDefaultModel(); -const childrenOperateModel = ref(createDefaultModel2()); - -const childrenModelVisible = ref(false); -const childrenTitle = ref(''); -const childrenModelOperateType = ref(''); - -function showChildrenModel(operateType: NaiveUI.TableOperateType, row: DictionaryItem | null = null) { - childrenModelOperateType.value = operateType; - childrenTitle.value = operateType === 'edit' ? $t('common.edit') : $t('common.add'); - childrenModelVisible.value = true; - childrenOperateModel.value = createDefaultModel2(); - if (row) { - Object.assign(childrenOperateModel.value, jsonClone(row)); + if (props.operateType === 'edit' && props.rowData) { + Object.assign(model.value, jsonClone(props.rowData)); } } -const childrenColumns: DataTableColumns = [ +async function handleSubmit() { + await validate(); + + const isEdit = props.operateType === 'edit'; + const opFunc = isEdit ? fetchDictionaryUpdate : fetchDictionaryInsert; + opFunc(model.value).then(() => { + window.$message?.success($t('common.updateSuccess')); + visible.value = false; + emit('submitted'); + }); +} + +// ******************** 子项数据定义 ******************** + +// Model +const childrenModel = ref(createChildrenModel()); +function createChildrenModel(): Api.Sys.Core.DictionaryItemDTO { + return { + id: null, + dictionaryId: '', + name: '', + code: '', + sort: 0, + description: null + }; +} +// Column +const childrenColumns: DataTableColumns = [ { key: 'name', title: $t('page.sys.core.dictionary.item.fields.name'), @@ -143,113 +169,80 @@ const childrenColumns: DataTableColumns = [ } } ]; - -function createDefaultModel(): Model { +// Data +const childrenData = ref(createChildrenData()); +interface ChildrenData { + records: Api.Sys.Core.DictionaryItemVO[]; +} +function createChildrenData(): ChildrenData { return { - name: '', - code: '', - type: 'enum', - description: null, - children: [] + records: [] }; } +// 标题 +const childrenModelTitle = ref(''); +const childrenModelVisible = ref(false); +const childrenModelOperateType = ref(''); -function createDefaultModel2(): ChildrenOperateModel { - return { - id: null, - name: '', - code: '', - sort: 0, - description: null - }; -} +// ******************** 子项事件定义 ******************** -type RuleKey = 'name' | 'code' | 'type'; - -const rules: Record = { - name: defaultRequiredRule, - code: defaultRequiredRule, - type: defaultRequiredRule -}; - -function handleInitModel() { - model.value = createDefaultModel(); - - if (props.operateType === 'edit' && props.rowData) { - Object.assign(model.value, jsonClone(props.rowData)); - } -} - -function handleInitChildrenModel() { +function handleInitChildrenData() { if (props.operateType !== 'edit' || !props.rowData?.id) { return; } - fetchTreeDictionaryItem(props.rowData.id).then(res => { + fetchDictionaryItemTreeList(props.rowData.id).then(res => { if (res.data) { - model.value.children = res.data ? res.data : []; + childrenData.value.records = res.data ? res.data : []; } }); } +function showChildrenModel(operateType: NaiveUI.TableOperateType, row: Api.Sys.Core.DictionaryItemVO | null) { + childrenModelOperateType.value = operateType; + childrenModelTitle.value = operateType === 'edit' ? $t('common.edit') : $t('common.add'); + childrenModelVisible.value = true; + childrenModel.value = createChildrenModel(); + if (row) { + Object.assign(childrenModel.value, jsonClone(row)); + } +} + function handleChildrenSubmit() { - const apiParams: Api.Sys.Core.DictionaryItemOp = { - dictionaryId: props.rowData?.id || '', - ...childrenOperateModel.value - }; + const apiParams = childrenModel.value; if (childrenModelOperateType.value === 'edit') { // 编辑 - fetchDictionaryItemEdit(apiParams).then(() => { + fetchDictionaryItemUpdate(apiParams).then(() => { window.$message?.success($t('common.updateSuccess')); childrenModelVisible.value = false; - handleInitChildrenModel(); + handleInitChildrenData(); }); } else { // 新增 - fetchDictionaryItemAdd(apiParams).then(() => { + fetchDictionaryItemInsert(apiParams).then(() => { window.$message?.success($t('common.updateSuccess')); childrenModelVisible.value = false; - handleInitChildrenModel(); + handleInitChildrenData(); }); } } -function handleChildrenDelete(row: DictionaryItem, index: number) { +function handleChildrenDelete(row: Api.Sys.Core.DictionaryItemVO, index: number) { if (row.id) { // 执行删除 fetchDictionaryItemDelete(row.id).then(() => { window.$message?.success($t('common.deleteSuccess')); - handleInitChildrenModel(); + handleInitChildrenData(); }); - } else { - model.value.children = model.value.children.splice(index); + } else if (childrenData.value.records) { + childrenData.value.records = childrenData.value.records.splice(index); } } -function closeDrawer() { - visible.value = false; -} - -async function handleSubmit() { - await validate(); - - const isEdit = props.operateType === 'edit'; - const opFunc = isEdit ? fetchDictionaryEdit : fetchDictionaryAdd; - const opData: Api.Sys.Core.DictionaryOp = { - id: props.rowData?.id || null, - ...model.value - }; - opFunc(opData).then(() => { - window.$message?.success($t('common.updateSuccess')); - closeDrawer(); - emit('submitted'); - }); -} - watch(visible, () => { if (visible.value) { handleInitModel(); + handleInitChildrenData(); restoreValidation(); - handleInitChildrenModel(); } }); @@ -286,43 +279,43 @@ watch(visible, () => { - + - + @@ -333,7 +326,7 @@ watch(visible, () => { diff --git a/src/views/sys/core/dictionary/modules/dictionary-search.vue b/src/views/sys/core/dictionary/modules/dictionary-search.vue index 574c76b7..26e477b1 100644 --- a/src/views/sys/core/dictionary/modules/dictionary-search.vue +++ b/src/views/sys/core/dictionary/modules/dictionary-search.vue @@ -5,20 +5,24 @@ import { dictionaryTypeOptions } from '@/constants/sys/core/dictionary'; import { translateOptions } from '@/utils/common'; import { $t } from '@/locales'; +// ******************** 数据定义 ******************** + +// 定义组件 defineOptions({ name: 'DictionarySearch' }); - +// 定义触发 interface Emits { (e: 'search'): void; } - const emit = defineEmits(); -const model = defineModel('model', { required: true }); - +// 定义数据 +const model = defineModel>('model', { required: true }); const defaultModel = jsonClone(toRaw(model.value)); +// ******************** 触发事件 ******************** + function resetModel() { Object.assign(model.value, defaultModel); }