From ce7865320796c329678a5ec087ac714a957f2b07 Mon Sep 17 00:00:00 2001 From: ZhangAo Date: Tue, 11 Aug 2026 16:51:11 +0800 Subject: [PATCH] 20260811165111 --- .../module-management-refactor_1c018c67.md | 253 +++++++ .../plans/模块管理迁移计划_e4a461a6.md | 264 +++++++ .../fms/demos/layout-demo-1-vertical-nav.html | 182 +++++ .../demos/layout-demo-2-scrollable-tabs.html | 190 +++++ code/fms/fms-vue/index.html | 150 +++- code/fms/fms-vue/src/App.vue | 8 + .../fms-vue/src/components/ConfirmDialog.vue | 35 + .../src/components/FmsLoadingOverlay.vue | 27 + code/fms/fms-vue/src/components/FmsTree.vue | 1 + .../fms/fms-vue/src/components/FpsMonitor.vue | 205 ++++++ .../src/components/fms-table/FmsTable.vue | 44 +- .../fms-table/utils/createCellRenderer.js | 41 +- .../fms/fms-vue/src/composables/useConfirm.ts | 50 ++ .../src/layouts/components/AppTabs.vue | 2 +- code/fms/fms-vue/src/main.ts | 29 +- code/fms/fms-vue/src/styles/index.css | 8 + code/fms/fms-vue/src/types/module.ts | 176 +++++ code/fms/fms-vue/src/utils/dataChanges.ts | 96 +++ code/fms/fms-vue/src/utils/i18n.ts | 156 ++++ code/fms/fms-vue/src/utils/tempId.ts | 12 + .../fms/fms-vue/src/views/dashboard/index.vue | 261 ++----- .../views/system/module-management/common.ts | 48 ++ .../components/FieldGroupManager.vue | 325 ++++++++ .../components/I18nQuickSetModal.vue | 138 ++++ .../components/ModuleAutoCodePanel.vue | 44 ++ .../components/ModuleBasicPanel.vue | 59 ++ .../components/ModuleCard.vue | 56 ++ .../components/ModuleEditConfigPanel.vue | 67 ++ .../components/ModuleFieldsPanel.vue | 64 ++ .../components/ModuleI18nPanel.vue | 271 +++++++ .../components/ModuleListConfigPanel.vue | 65 ++ .../components/ModulePowersPanel.vue | 79 ++ .../components/ModuleQueryConfigPanel.vue | 61 ++ .../views/system/module-management/index.vue | 692 +++++++++++++++--- 34 files changed, 3793 insertions(+), 366 deletions(-) create mode 100644 code/fms/.codebuddy/plans/module-management-refactor_1c018c67.md create mode 100644 code/fms/.codebuddy/plans/模块管理迁移计划_e4a461a6.md create mode 100644 code/fms/demos/layout-demo-1-vertical-nav.html create mode 100644 code/fms/demos/layout-demo-2-scrollable-tabs.html create mode 100644 code/fms/fms-vue/src/components/ConfirmDialog.vue create mode 100644 code/fms/fms-vue/src/components/FmsLoadingOverlay.vue create mode 100644 code/fms/fms-vue/src/components/FpsMonitor.vue create mode 100644 code/fms/fms-vue/src/composables/useConfirm.ts create mode 100644 code/fms/fms-vue/src/types/module.ts create mode 100644 code/fms/fms-vue/src/utils/dataChanges.ts create mode 100644 code/fms/fms-vue/src/utils/i18n.ts create mode 100644 code/fms/fms-vue/src/utils/tempId.ts create mode 100644 code/fms/fms-vue/src/views/system/module-management/common.ts create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/FieldGroupManager.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/I18nQuickSetModal.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleAutoCodePanel.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleBasicPanel.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleCard.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleEditConfigPanel.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleFieldsPanel.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleI18nPanel.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleListConfigPanel.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModulePowersPanel.vue create mode 100644 code/fms/fms-vue/src/views/system/module-management/components/ModuleQueryConfigPanel.vue diff --git a/code/fms/.codebuddy/plans/module-management-refactor_1c018c67.md b/code/fms/.codebuddy/plans/module-management-refactor_1c018c67.md new file mode 100644 index 00000000..81ae6469 --- /dev/null +++ b/code/fms/.codebuddy/plans/module-management-refactor_1c018c67.md @@ -0,0 +1,253 @@ +--- +name: module-management-refactor +overview: 参考旧系统(fms-vue2)的 module-management 完整实现,使用 shadcn-vue + Tailwind CSS 重写新系统(fms-vue)的 module-management,补齐缺失的列表配置、编辑配置、查询配置、自动编码、分组管理等面板功能,修复现有样式和交互问题。 +design: + architecture: + framework: vue + styleKeywords: + - 毛玻璃 + - 垂直导航 + - 可拖拽面板 + - 卡片布局 + - 简洁专业 + fontSystem: + fontFamily: Inter + heading: + size: 14px + weight: 600 + subheading: + size: 13px + weight: 500 + body: + size: 13px + weight: 400 + colorSystem: + primary: + - "#0D0D0D" + - "#1A1A1A" + background: + - "#FFFFFF" + - "#F5F5F5" + - "#FAFAFA" + text: + - "#0D0D0D" + - "#71717A" + - "#A1A1AA" + functional: + - "#DC2626" + - "#16A34A" + - "#2563EB" +todos: + - id: rewrite-index + content: 重写主页面 index.vue:实现左侧可拖拽宽度模块树 + 右侧 sticky header + 垂直导航 + 内容区布局,完整的 originals/drafts 数据流,所有面板加载/保存/删除/同步逻辑,以及 diffRows+tableChange+allocateTemporaryIds 保存流程 + status: completed + - id: rewrite-basic-panel + content: 重写 ModuleBasicPanel.vue:补全图标选择器(Popover 虚拟滚动)、上级模块名显示、多语言键快速设置按钮、默认排序字段输入 + status: completed + - id: rewrite-fields-panel + content: 重写 ModuleFieldsPanel.vue:保持 FmsTable 可编辑表格,补全字段同步自动生成 list/edit/query 默认配置的逻辑 + status: completed + - id: rewrite-powers-panel + content: 重写 ModulePowersPanel.vue:保持 FmsTable 可编辑表格 + 批量删除 + 行内编辑,补全多语言键快速设置 + status: completed + - id: rewrite-i18n-panel + content: 重写 ModuleI18nPanel.vue:参考旧系统完整实现,支持受管/非受管键分离、透视表动态语言列、搜索、批量删除、buildSaveRequest/reconcileManagedRows/markSaved/mergeDefaults/removeByManagedIds 暴露方法 + status: completed + - id: create-new-panels + content: 新建 ModuleListConfigPanel、ModuleEditConfigPanel、ModuleQueryConfigPanel、ModuleAutoCodePanel、ModuleCard、FieldGroupManager 六个面板组件,完整实现列表/编辑/查询配置的可编辑表格+行拖拽排序、自动编码规则配置、可折叠卡片容器、分组管理弹窗 + status: completed + dependencies: + - rewrite-index + - rewrite-basic-panel + - id: create-common + content: 新建 common.ts:createAutoCodeDraft 工厂函数 + status: completed +--- + +## 用户需求 + +参考旧系统 (fms-vue2) 的 module-management 完整实现,重构新系统 (fms-vue) 的模块管理页面。新系统代码可以全部删除重写,目标是功能齐全、样式正确。新系统技术栈为 shadcn-vue + Tailwind CSS。 + +## 产品概述 + +模块管理是 FMS 平台的核心元数据管理页面,用于维护系统内的模块树结构(目录、页面、数据模块)、字段定义、列表/编辑/查询配置、自动编码规则、操作权限和多语言翻译。 + +## 核心功能 + +### 布局与交互 + +- 左侧模块树(支持拖拽调整宽度 210-440px)+ 右侧详情区 +- 右侧详情:sticky header(模块名 + 类型标签 + 启用/显示菜单开关 + 保存按钮)+ 左侧垂直导航 + 右侧内容区 +- 垂直导航根据模块类型动态显示:data 类型显示基本信息、字段定义、列表配置、编辑配置、查询配置、自动编码、多语言;page 类型显示基本信息、权限配置、多语言;directory 类型仅显示基本信息 +- 树节点右键菜单:按节点类型和权限动态生成(添加目录、添加页面、添加数据分类、添加数据、删除) + +### 基本信息面板 + +- 编码(必填,小写字母/数字/下划线校验)、名称(必填)、模块类型下拉、排序号、图标(目录/页面)、路由(页面必填)、查询视图(数据必填)、保存表、主键字段、默认排序字段 +- 上级模块名(只读,从树解析) + +### 字段定义面板 + +- 使用 FmsTable 可编辑表格展示字段列表:字段名(只读)、字段名称、控件类型下拉(input/textarea/number/money/date/datetime/checkbox/select)、默认值、多语言键(带快速设置按钮)、启用 +- 同步字段按钮:从查询视图读取列结构,合并/新增/移除字段,自动生成 list/edit/query 默认配置,同步受管多语言键 + +### 列表配置面板(新增) + +- 使用 FmsTable 可编辑表格 + 行拖拽排序 +- 列:字段选择、列宽、分组、显示、排序号 +- 工具栏:分组管理按钮(打开 FieldGroupManager)、同步到编辑显示、同步到查询配置 +- 分组管理弹窗:左侧分组树 + 右侧编辑分组详情 + +### 编辑配置面板(新增) + +- 使用 FmsTable 可编辑表格 + 行拖拽排序 +- 列:字段选择、显示、必填、只读、禁用、编辑分组、排序号 +- 工具栏:分组管理按钮、同步到列表配置、同步到查询配置 + +### 查询配置面板(新增) + +- 使用 FmsTable 可编辑表格 + 行拖拽排序 +- 列:字段选择、查询组件(input/select/date/number-range/radio-group)、操作符(=/like/between/in)、默认值、启用、排序号 +- 新增查询条件按钮 + +### 自动编码面板(新增) + +- 启用/禁用开关 +- 业务编号字段选择、固定前缀、日期格式下拉(10种格式)、分隔符、流水号位数、起始值、重置周期(none/year/month/day) +- 实时编号预览 + +### 权限配置面板 + +- 使用 FmsTable 可编辑表格:操作编码、操作名称、多语言键(带快速设置)、排序、启用 +- 新增权限、批量删除、行内编辑 + +### 多语言面板 + +- 从 b_i18n_type 动态生成语言列 +- 受管行(模块/字段/权限自动生成)只读保护 +- 搜索、新增翻译、批量删除、快速设置弹窗 + +### 数据流 + +- originals(服务器快照)+ drafts(编辑副本)+ diff 模式 +- 保存:一次 saveObjectApi 调用保存 s_module、s_module_field、s_module_field_list、s_module_field_edit、s_module_field_query、s_module_auto_code、s_module_power、b_i18n 所有表变更 +- 删除:级联删除 b_user_module、b_user_power、s_module_field_list、s_module_field_edit、s_module_field_query、s_module_auto_code、s_module_power、s_module_field、s_module_field_group、b_i18n、s_module +- 字段同步:读取视图列结构 → 合并字段 → 自动生成缺失的 list/edit/query 默认配置 → 注入多语言默认值 + +## 技术栈 + +- **前端框架**: Vue 3 + TypeScript + ` + + diff --git a/code/fms/demos/layout-demo-2-scrollable-tabs.html b/code/fms/demos/layout-demo-2-scrollable-tabs.html new file mode 100644 index 00000000..6f62bf83 --- /dev/null +++ b/code/fms/demos/layout-demo-2-scrollable-tabs.html @@ -0,0 +1,190 @@ + + + + + + +模块管理布局 Demo 2 · 顶部可滚动 Tab + + + +
+ + +
+
+
订单数据模块
+
+ + +
+
+ +
+
+
基础信息
+
字段定义
+
列表配置
+
编辑配置
+
查询配置
+
自动编码
+
多语言
+
+ +
+
基础信息
+
字段定义
+
列表配置
+
编辑配置
+
查询配置
+
自动编码
+
多语言
+
+
+ +
+
+

基础信息

+
+
+
+
+
+

字段定义

+ + + + + + + +
字段名称类型必填
b_id主键bigint是
b_name名称nvarchar是
b_status状态int否
+
+

列表配置

列表列 / 分页 / 排序配置区
+

编辑配置

编辑表单字段布局配置区
+

查询配置

查询条件配置区
+

自动编码

编码规则配置区
+

多语言

翻译键 / 多语言文案配置区
+
+
+
+ + + + diff --git a/code/fms/fms-vue/index.html b/code/fms/fms-vue/index.html index 38bab974..b406ad79 100644 --- a/code/fms/fms-vue/index.html +++ b/code/fms/fms-vue/index.html @@ -1,13 +1,159 @@ - + fms-vue + + -
+
+
+
+ + + +
+
+
diff --git a/code/fms/fms-vue/src/App.vue b/code/fms/fms-vue/src/App.vue index c4a6ccda..06842ccd 100644 --- a/code/fms/fms-vue/src/App.vue +++ b/code/fms/fms-vue/src/App.vue @@ -1,8 +1,16 @@ diff --git a/code/fms/fms-vue/src/components/ConfirmDialog.vue b/code/fms/fms-vue/src/components/ConfirmDialog.vue new file mode 100644 index 00000000..ecf2e623 --- /dev/null +++ b/code/fms/fms-vue/src/components/ConfirmDialog.vue @@ -0,0 +1,35 @@ + + + diff --git a/code/fms/fms-vue/src/components/FmsLoadingOverlay.vue b/code/fms/fms-vue/src/components/FmsLoadingOverlay.vue new file mode 100644 index 00000000..97bed559 --- /dev/null +++ b/code/fms/fms-vue/src/components/FmsLoadingOverlay.vue @@ -0,0 +1,27 @@ + + + diff --git a/code/fms/fms-vue/src/components/FmsTree.vue b/code/fms/fms-vue/src/components/FmsTree.vue index 3b713f54..1de7ddbe 100644 --- a/code/fms/fms-vue/src/components/FmsTree.vue +++ b/code/fms/fms-vue/src/components/FmsTree.vue @@ -55,6 +55,7 @@ watch( const virtualRoot = computed(() => ({ key: props.rootKey, title: props.rootTitle, + isFmsRoot: true, children: props.treeData, })); diff --git a/code/fms/fms-vue/src/components/FpsMonitor.vue b/code/fms/fms-vue/src/components/FpsMonitor.vue new file mode 100644 index 00000000..9821ccd8 --- /dev/null +++ b/code/fms/fms-vue/src/components/FpsMonitor.vue @@ -0,0 +1,205 @@ + + + + + diff --git a/code/fms/fms-vue/src/components/fms-table/FmsTable.vue b/code/fms/fms-vue/src/components/fms-table/FmsTable.vue index a846aefb..92e64b3d 100644 --- a/code/fms/fms-vue/src/components/fms-table/FmsTable.vue +++ b/code/fms/fms-vue/src/components/fms-table/FmsTable.vue @@ -237,6 +237,7 @@ const displayColumns = computed(() => { return cols.map((column) => ({ ...column, + className: [column.className, column.editor && "fms-editor-cell"].filter(Boolean).join(" "), headerAlign: getHeaderAlign(column), })); }); @@ -273,15 +274,12 @@ const hasBottomGap = computed(() => { return props.dataSource.length * rowHeight < bodyHeight - 1; }); const customVars = computed(() => { - // 线条只覆盖真实数据行;数据铺满视口时不绘制最后一行,避免与外框底线叠加。 - const lineRowCount = Math.max(props.dataSource.length - (hasBottomGap.value ? 0 : 1), 0); return { "--header-row-height": `${headerRowHeight}px`, "--row-height": `${rowHeight}px`, "--footer-row-height": "36px", "--th-bgc": "var(--background)", "--tf-bgc": "var(--background)", - "--fms-data-line-height": `${lineRowCount * rowHeight}px`, }; }); @@ -374,8 +372,8 @@ function commitPendingEditing() { (item) => item === target.row || String(getRowKey(item)) === String(getRowKey(target.row)), ); if (row) { - activateEditing(row, target.focusCol); tableRef.value?.setCurrentRow?.(row, { silent: true }); + activateEditing(row, target.focusCol); lastEditActivateAt = performance.now(); } } @@ -446,6 +444,7 @@ function handleAreaSelectionChange(ranges) { if (isRepeatNavigation) { pendingEditingTarget = { row, focusCol }; clearActiveEditing(); + // 长按期间由选区高亮跟随目标;松键时再同步活动行,避免每次重复按键重渲染整表。 } else { const now = performance.now(); if (now - lastEditActivateAt >= 150) { @@ -527,7 +526,12 @@ defineExpose({