Files
workspace/code/fms/.codebuddy/plans/module-management-page_6a654c2c.md
T
2026-07-23 17:33:18 +08:00

14 KiB
Raw Blame History

name, overview, design, todos
name overview design todos
module-management-page 基于新数据库结构与开发规范,从零重建 module-management 页面(替换当前占位页),并把路由 /system/metadata 改为 /system/module-management。页面以「左侧模块树 + 右侧多 Tab 配置」组织,覆盖 b_module 及其字段/分组/列表/编辑/查询/权限/多语言配置,复用现有通用接口与工具函数,不新增后端端点与服务文件。
styleKeywords fontSystem colorSystem
Enterprise Admin
Clean Professional
Ant Design Vue
Two-column Tree + Tabs
Subtle Blue Accent
Desktop-first
fontFamily heading subheading body
PingFang SC, Microsoft YaHei
size weight
16px 600
size weight
14px 500
size weight
13px 400
primary background text functional
#1677ff
#4096ff
#0958d9
#ffffff
#f7f8fa
#f0f5ff
#1f2329
#8a8f99
#ffffff
#52c41a
#ff4d4f
#faad14
#e5e7eb
id content status
update-route-menu 修改 routes.js 与 AppSidebar.vue,将路由 /system/metadata 改为 /system/module-management(moduleCode 保留 m_metadata) completed
id content status dependencies
build-view-shell 新建 index.vue 与 composables/useModuleManagement.js:左树右 Tabs 布局、草稿加载/保存编排、权限受控工具条 completed
update-route-menu
id content status dependencies
build-basic-tree 实现 ModuleTreePanel 与 ModuleBasicInfoPanel:模块树增删改、基本信息表单与类型联动校验 completed
build-view-shell
id content status dependencies
build-field-group 实现 ModuleFieldDefinitionPanel(describe 同步合并)与 ModuleGroupPanel(多级分组树) completed
build-view-shell
id content status dependencies
build-list-edit-query 实现 ModuleListPanel/ModuleEditPanel/ModuleQueryPanel,用 FmsTable 配置列表/编辑/查询场景 completed
build-view-shell
id content status dependencies
build-power-i18n 实现 ModulePowerPanel 与 ModuleTranslationsPanel,维护操作权限与多语言文案 completed
build-view-shell
id content status dependencies
polish-verify 用 [skill:antdv-next] 核对组件用法,补全 scoped scss 与空态,说明未执行构建/测试 completed
build-basic-tree
build-field-group
build-list-edit-query
build-power-i18n

用户需求

  • 依据 新数据库结构.md 的 schema 从零重建「模块管理」页面(替换当前占位页 index.vue),覆盖 b_module 及其字段定义、字段分组、列表/编辑/查询配置、操作权限、多语言等完整配置能力。
  • 路由由 /system/metadata 改为 /system/module-management(仅改路径与 menuKey,moduleCode 仍保留 m_metadata 以匹配数据库种子与权限)。
  • 严格遵循既有设计决策:字段定义来自模块查询视图(经 POST /data/describe 同步,不可手工增删);子表新增行用前端本地临时负数 ID(createTempId),主表 b_module 保留 nextIdApi 取号;保存后重建草稿使临时 ID 被真实 ID 覆盖。
  • 复用项目现有通用接口(loadDataApi/saveObjectApi/nextIdApi/describeApi)、FmsTable、antdv-next 组件,以及 utils/dataChanges.js、utils/tempId.js、utils/i18n.js,不新增后端端点与服务文件。
  • 遵守开发规范:表格尽量用 fms-table,桌面端实现,scoped scss 复用现有 --fms-* token,不执行构建/测试。

核心功能

  • 左侧模块树(目录/页面/数据三类,支持增删改与选中)。
  • 右侧多 Tab:基本信息、字段定义(含视图同步)、字段分组、列表配置、编辑配置、查询配置、操作权限、多语言。
  • 顶部工具条(保存/刷新)与权限受控按钮(create/update/delete 来自 b_module_power,sync 为同步字段)。
  • 基于通用接口与工具函数的「按模块加载草稿 → 本地编辑 → 差异保存(整事务)」工作流。

技术栈

  • 前端:Vue 3 <script setup> + Vite + Pinia;UI 组件库 antdv-next(项目已通过 vite.config.js 自动按需引入,禁止手动 import 已由 resolver 处理的组件);表格统一使用项目封装的 FmsTable。
  • 后端:完全复用现有通用端点,不新增任何接口或服务文件。
  • 状态/工具:stores/permissions.js(权限门控)、utils/dataChanges.js、utils/tempId.js、utils/i18n.js。

实施方法

整体采用「单一编排视图 + 子面板」架构:ModuleManagementView(index.vue)负责选中模块、加载全量草稿、保存编排;各 components/*.vue 面板只负责自身区块的展示与编辑,所有可变数据集中在视图层响应式 draft 中,保存时由编排层统一 diffRows + saveObjectApi。

数据编排(核心)

  1. 加载草稿 loadDraft(moduleId):并发 loadDataApi 拉取该模块相关的 8 张表:b_module(按 id)、b_module_field、b_module_field_group、b_module_field_list、b_module_field_edit、b_module_field_query、b_module_power,以及 b_i18n(按 module./字段键前缀过滤)。结果存入响应式 draft,并深拷贝一份 snapshot 供保存时差异比对。
  2. 本地编辑:面板直接 push/splice/Object.assign 修改 draft 中的数组与对象;子表新增行 b_id = createTempId()(负数字符串)。
  3. 保存 saveDraft():
  • 主表 b_module 新增:先 nextIdApi() 取真实 ID 写入 draft.b_module.b_id。
  • 对每张表 diffRows(draft[table], snapshot[table]) → tableChange(table, diff),汇聚为 requests[]。
  • 子表 insert 含临时负数 ID 时,调用 allocateTemporaryIds([...所有子表 insert 行]) 由后端生成真实 ID 并就地替换;随后 remapForeignKeys 把 b_field_id/b_group_id 指向的临时 ID 同步映射到真实 ID。
  • 单事务 saveObjectApi(requests);成功后 snapshot = cloneData(draft),临时 ID 已被真实 ID 覆盖。
  1. 视图同步 syncFields(module):describeApi(module.b_viewtable) 返回列 [{name,type,nullable,size}];按 (b_module_id,b_field) 合并——视图已有列保留原 b_name/b_type/b_options/b_default_value 不覆盖;视图新增列追加默认行(createTempId,b_type 由 SQL 类型映射:字符串→input、长文本→textarea、数值→number、金额→money、date→date、datetime→datetime、bit→switch);视图已删列保留配置但 b_canuse=0。该按钮受 canPower('m_metadata','sync') 门控,仅 data 且配置了 b_viewtable 时可用。

关键设计决策与权衡

  • 集中草稿 + 差异保存:复用现有 dataChanges.js,避免各面板各自拼请求,降低出错面;保存走 saveobjt 整事务,任一表失败全回滚,符合设计决策。
  • 临时 ID 策略:严格遵循记忆决策——子表用 createTempId,主表用 nextIdApi;FK 映射在保存前完成,杜绝脏引用。
  • FmsTable 复用:列表/编辑/查询/权限/多语言等表格统一用 FmsTable,单元格编辑沿用 TableDemo.vue 的 makeCellEditor 模式(编辑行渲染控件、其余行纯文本),不重复实现表格能力,契合新规范。
  • 约束校验前置:b_module_type 与字段联动校验在表单层做(directory 不可配 route/viewtable/savetable;page 必配 route;data 不可菜单/不可 route 且必配 viewtable),保存前校验 b_code 正则 `^[a-z][a-z0-9_]{1,49},减少后端往返报错。
  • 性能:每模块仅加载自身数据,树节点选中才加载草稿;describe 仅在点击同步时调用;表格虚拟滚动(FmsTable 默认开启)支撑大数据量。

架构关系

flowchart TD
  View[ModuleManagementView index.vue] -->|load/save 编排| Draft[(响应式 draft + snapshot)]
  View --> Tree[ModuleTreePanel]
  View --> Tabs[Tab 区]
  Tabs --> Basic[ModuleBasicInfoPanel]
  Tabs --> Field[ModuleFieldDefinitionPanel 含 sync]
  Tabs --> Group[ModuleGroupPanel]
  Tabs --> List[ModuleListPanel]
  Tabs --> Edit[ModuleEditPanel]
  Tabs --> Query[ModuleQueryPanel]
  Tabs --> Power[ModulePowerPanel]
  Tabs --> I18n[ModuleTranslationsPanel]
  Draft -.diffRows/tableChange.-> Save[saveObjectApi 单事务]
  Field -.describeApi.-> Sync[视图列合并]

目录结构

仅修改 2 个文件、新建 1 个视图与 8 个面板组件(含 1 个编排 composable):

fms-vue/src/
├── router/routes.js                              # [MODIFY] path "/system/metadata"→"/system/module-management",
│                                                #   name→system-module-management,meta.menuKey 同步,moduleCode 保留 "m_metadata"
├── layouts/components/AppSidebar.vue            # [MODIFY] systemPages 的 key 改为 "/system/module-management"
└── views/module-management/
    ├── index.vue                               # [NEW] ModuleManagementView:左树+右 Tabs 布局、工具条、
    │                                         #   草稿加载/保存编排、权限受控按钮(create/update/delete/sync)
    ├── composables/useModuleManagement.js      # [NEW] 编排逻辑:loadDraft/saveDraft/syncFields、
    │                                         #   diffRows+tableChange+allocateTemporaryIds+remapForeignKeys、SQL 类型→b_type 映射
    └── components/
        ├── ModuleTreePanel.vue                # [NEW] 模块树(目录/页面/数据),选中/新增/删除,b_xh 排序
        ├── ModuleBasicInfoPanel.vue           # [NEW] 基本信息表单:b_code/b_name/b_module_type/b_route/
        │                                         #   b_viewtable/b_savetable/b_keyfield/b_orderfield/b_canmenu/b_canuse/b_xh
        │                                         #   + 类型联动校验
        ├── ModuleFieldDefinitionPanel.vue      # [NEW] 字段定义 FmsTable + 「同步字段」按钮(describe 合并)
        ├── ModuleGroupPanel.vue               # [NEW] 字段分组树(b_module_field_group 自引用),列表/编辑共用
        ├── ModuleListPanel.vue                # [NEW] 列表配置 FmsTable(b_module_field_list,引用 group)
        ├── ModuleEditPanel.vue                # [NEW] 编辑配置 FmsTable(b_module_field_edit,required/readonly/disabled/group)
        ├── ModuleQueryPanel.vue              # [NEW] 查询配置 FmsTable(b_module_field_query,component/operator)
        ├── ModulePowerPanel.vue              # [NEW] 操作权限 FmsTable(b_module_power)
        └── ModuleTranslationsPanel.vue       # [NEW] 多语言 FmsTable(b_i18n,按 locale 分列编辑)

关键代码结构

  • 编排 composable 暴露:loadDraft(moduleId)、saveDraft()、syncFields()、draft(响应式)、currentModuleId、permissions(canPower 结果);各面板通过 props 接收对应数组、emits 回传变更,避免跨面板直接耦合。
  • b_type SQL 类型映射函数(放置于 composable):mapSqlTypeToFieldType(typeName) → 'input'|'textarea'|'number'|'money'|'date'|'datetime'|'switch'。

设计风格

企业级元数据管理后台,采用「左侧模块树 + 右侧多 Tab 配置」的经典后台布局,桌面端优先。视觉以 Ant Design Vue 设计语言为基底,主色沿用项目侧栏蓝 #1677ff,辅以 --fms-* 设计变量(边框 #e5e7eb、正文 #1f2329、次要文字 #8a8f99、表面 #ffffff/#f7f8fa)。整体克制、清晰、信息密度适中,重点突出当前选中模块与可编辑表格,hover/选中态用浅蓝底与蓝色描边强化。

页面结构(自上而下分区)

  1. 顶栏工具条:左侧显示当前模块名与 b_code 面包屑;右侧权限受控按钮——新增模块(create)、保存(update)、同步字段(sync)、删除(delete),按钮按 m_metadata 的 b_module_power 与 canPower 显隐禁用。
  2. 主体双栏:
  • 左栏 ModuleTreePanel:模块树(目录可展开,页面/数据为叶子),顶部「新建目录/页面/数据」入口,节点 hover 显示删除。选中节点高亮蓝底。
  • 右栏 Tab 区:基本信息 / 字段定义 / 字段分组 / 列表配置 / 编辑配置 / 查询配置 / 操作权限 / 多语言,共 8 个标签页,内容区统一白底卡片 + FmsTable。
  1. 表单与表格:基本信息用 antdv-next Form(标签右对齐、栅格两列);各配置 Tab 用 FmsTable,编辑行内联控件(Input/InputNumber/Select/Switch),非编辑行纯文本;分组树用 FmsTree 或 Tree 组件展示多级 b_module_field_group。
  2. 空态:未选中模块时主区展示引导空态(图标 + 「请选择或新建模块」),不显示报错。

交互与动效

  • 树节点选中平滑高亮;Tab 切换保留各面板本地编辑(草稿集中在视图层,不随 Tab 卸载丢失)。
  • 表格编辑行浅蓝底(rgba(22,119,255,0.08)),hover 行浅灰底;按钮、输入框 focus 蓝色描边过渡 0.2s。
  • 保存成功 message.success 轻提示;删除/同步等有副作用操作使用 Popconfirm 二次确认。
  • 响应式:固定双栏,左栏 260px 可随侧栏收起;右栏内容随容器宽度自适应,表格横向虚拟滚动。

可复用的智能体扩展

Skill

  • antdv-next
  • 目的:在编写 ModuleBasicInfoPanel 表单、FmsTable 单元格编辑器、树与弹窗等 UI 时,查询 antdv-next 组件的 API、props/events/slots 与用法示例,确保组件用法正确。
  • 预期结果:各面板正确使用 antdv-next 组件(Form/Select/Switch/Tree/Popconfirm/Tabs 等),避免属性误用;保证 UI 实现符合组件库规范且与项目自动引入配置兼容。