diff --git a/code/fms/fms-vue/src/views/system/module-management/components/ModuleOverviewChecklist.vue b/code/fms/fms-vue/src/views/system/module-management/components/ModuleOverviewChecklist.vue new file mode 100644 index 00000000..e62d436c --- /dev/null +++ b/code/fms/fms-vue/src/views/system/module-management/components/ModuleOverviewChecklist.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/code/fms/fms-vue/src/views/system/module-management/index.vue b/code/fms/fms-vue/src/views/system/module-management/index.vue index c8fa8bed..c9046c97 100644 --- a/code/fms/fms-vue/src/views/system/module-management/index.vue +++ b/code/fms/fms-vue/src/views/system/module-management/index.vue @@ -40,6 +40,7 @@ import { useModuleTree, findModuleNode } from './composables/useModuleTree' import { useModuleConfig } from './composables/useModuleConfig' import { useModuleSave } from './composables/useModuleSave' import ModuleBasicPanel from './components/ModuleBasicPanel.vue' +import ModuleOverviewChecklist from './components/ModuleOverviewChecklist.vue' import ModuleFieldsPanel from './components/ModuleFieldsPanel.vue' import ModuleListConfigPanel from './components/ModuleListConfigPanel.vue' import ModuleFormEditPanel from './components/form-edit/FormEditPanel.vue' @@ -215,6 +216,16 @@ const dirtyTabKeys = computed(() => { return keys }) +/* 概览 checklist 统计(由 drafts 派生):字段/列表/权限计数,表单与查询缺配复用 + useModuleConfig 的 missingEditCount / missingQueryCount */ +const fieldsEnabledCount = computed( + () => (drafts.value?.fields || []).filter((field) => Number(field.b_canuse) === 1).length, +) +const listVisibleCount = computed( + () => (drafts.value?.listConfig || []).filter((row) => Number(row.b_visible) === 1).length, +) +const powersCount = computed(() => (drafts.value?.powers || []).length) + /* ================= composables ================= */ const { saveModule } = useModuleSave({ selectedModule, @@ -491,6 +502,18 @@ loadModuleTree()
+ + item.text().includes(label)) +} + +describe('ModuleOverviewChecklist', () => { + it('data 模块渲染全部条目,按依赖顺序排列', () => { + const wrapper = mountList({}) + const labels = wrapper.findAll('.mm-checklist__label').map((el) => el.text()) + expect(labels).toEqual(['字段定义', '表单设计', '列表配置', '查询配置', '权限']) + }) + + it('query 模块不渲染表单设计条目', () => { + const wrapper = mountList({ moduleType: 'query' }) + const labels = wrapper.findAll('.mm-checklist__label').map((el) => el.text()) + expect(labels).toEqual(['字段定义', '列表配置', '查询配置', '权限']) + }) + + it('缺配状态以文案表达:表单缺 N、查询缺 N 且提供一键补充', () => { + const wrapper = mountList({ editMissingCount: 2, queryMissingCount: 3 }) + expect(rowOf(wrapper, '表单设计').text()).toContain('缺 2 项未布局') + const queryRow = rowOf(wrapper, '查询配置') + expect(queryRow.text()).toContain('缺 3 项') + expect(queryRow.find('button').exists()).toBe(true) + }) + + it('完整状态文案与无补充按钮', () => { + const wrapper = mountList({}) + expect(rowOf(wrapper, '表单设计').text()).toContain('均已布局') + expect(rowOf(wrapper, '查询配置').text()).toContain('完整') + expect(wrapper.find('button').exists()).toBe(false) + }) + + it('空态提示:无启用字段时引导先定义字段', () => { + const wrapper = mountList({ fieldsEnabledCount: 0, editMissingCount: 0, listVisibleCount: 0, powersCount: 0 }) + expect(rowOf(wrapper, '字段定义').text()).toContain('先去定义字段') + expect(rowOf(wrapper, '列表配置').text()).toContain('暂无可见列') + expect(rowOf(wrapper, '权限').text()).toContain('尚未配置权限') + }) + + it('条目点击与 Enter 均触发 navigate,携带对应分节 key', async () => { + const wrapper = mountList({}) + await rowOf(wrapper, '字段定义').trigger('click') + await rowOf(wrapper, '查询配置').trigger('keydown', { key: 'Enter' }) + expect(wrapper.emitted('navigate')).toEqual([['fields'], ['query']]) + }) + + it('一键补充按钮触发 fill-missing 且不触发 navigate', async () => { + const wrapper = mountList({ queryMissingCount: 3 }) + await rowOf(wrapper, '查询配置').find('button').trigger('click') + expect(wrapper.emitted('fill-missing')).toHaveLength(1) + expect(wrapper.emitted('navigate')).toBeUndefined() + }) +})