From 29f98494af90035df78cc21cfa4b8e1ebf963653 Mon Sep 17 00:00:00 2001 From: oneao Date: Sun, 30 Aug 2026 20:10:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(module-management):=20=E5=AF=BC=E8=88=AA?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8C=96=E9=98=B6=E6=AE=B5=E4=B8=89=E2=80=94?= =?UTF-8?q?=E2=80=94=E6=A6=82=E8=A7=88=E9=85=8D=E7=BD=AE=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=BA=A6=20checklist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新组件 ModuleOverviewChecklist:字段/表单/列表/查询/权限按依赖顺序排列, 状态以文案表达(缺 N/已配置 N,不只靠颜色),空态给引导文案 - 条目点击与 Enter 跳转对应分节;查询缺配提供「一键补充」 (复用 fillMissingConfigs,不冒泡为跳转);仅数据/查询模块渲染 - index.vue 补 fieldsEnabledCount/listVisibleCount/powersCount 派生统计; 表单/查询缺配复用阶段二/既有的 missingEditCount/missingQueryCount - 新 spec module-overview-checklist 7 用例:条目显隐、缺配/完整/空态文案、 跳转与一键补充事件 --- .../components/ModuleOverviewChecklist.vue | 173 ++++++++++++++++++ .../views/system/module-management/index.vue | 23 +++ .../unit/module-overview-checklist.spec.js | 77 ++++++++ 3 files changed, 273 insertions(+) create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleOverviewChecklist.vue create mode 100644 code/fms/fms-vue/tests/unit/module-overview-checklist.spec.js 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() + }) +})