10 KiB
10 KiB
任务:迁移旧 CRUD 页面到新版 page-table + page-dialog-form 方案
输入
用户会提供一个旧 CRUD 页面的文件路径列表和对照表信息。
迁移规则(必须严格遵守)
1. 组件方案
- 使用
<page-table>+<page-dialog-form>替代旧版<sct-base-table>+<sct-base-dialog>+<SctBaseForm> - 使用
useTableColumns()生成列定义(不再手动分配 idx) - 使用
useTableButtons()生成工具栏按钮和行内按钮(不再分开写 buttonList / tableButtonList) - 使用
i18nMixin(prefix)注入key()和ckey()方法 - 参考文档:表格组件使用说明.md
- 参考示例:
src/views/production-master-data/factory-model/factory-area/index.vue
1.1 特殊弹出框组件迁移(重要)
当旧页面中存在超出 page-dialog-form 能力的弹出框时(权限分配树、批量导入、关联选择器、详情查看、多步骤向导等),必须遵循以下流程:
第一步:分析旧代码
- 仔细阅读旧项目的弹出框代码,理解其数据结构、交互逻辑、API 调用
- 关注旧代码的数据来源路径(如
row.menu_admin直接从列表获取、还是额外调 API) - 记录旧的参数名、method 名,确保迁移时不遗漏
第二步:提出优化方案
迁移时不能简单照搬旧代码,必须结合新版能力提出优化:
| 旧写法 | 优化方向 |
|---|---|
el-dialog 内联在页面中 |
抽离为独立组件 → components/ |
sct-base-dialog + 内联表单 |
独立组件 + el-drawer(抽屉式体验更佳) |
| 额外调 API 获取数据(如行数据已包含) | 直接从 row.xxx 取值,减少请求 |
setTimeout 硬编码延迟 |
提出来讨论,结合 v-if + $nextTick 优化 |
$parent / $refs 跨组件通信 |
改为 props + $emit |
示例:角色权限分配迁移优化方案
旧方案 优化方案
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
el-dialog 内联 42 行代码 → 独立 PermDrawer 组件(components/PermDrawer/index.vue)
getRoleMenu API 额外请求 → 直接从 row.menu_admin JSON.parse 获取(列表自带)
setTimeout 1000ms 关闭 → 保留(树渲染需要等待),但抽取到子组件内部
索引页 data 6 个 perm 字段 → 仅 2 个(permVisible + permRole)
第三步:按标准实现
参考 表格组件使用说明.md 第 13 节,严格遵循:
| 规则 | 说明 |
|---|---|
| 目录位置 | src/views/{模块}/{功能}/components/{英文PascalCase}/index.vue |
| 文件夹命名 | 英文 PascalCase,描述功能(如 PermDrawer、ImportDialog) |
| 组件通信 | 父→子 props(含 .sync),子→父 $emit('saved'),禁止 $parent / $refs |
| 主页面数据 | 只存 visible Boolean + 业务对象,其余状态在子组件内部 |
第四步:完整案例
参考角色权限分配抽屉的完整迁移:
- 旧代码:
D:\code\company\SCTMES_MES_V5\vue-app\src\views\system_settings\user_management\role\components\PageMain\index.vue(dialogVisibleGive+el-tree) - 新代码:
src/views/system-administration/user-management/role/components/PermDrawer/index.vue - 主页面引用:
src/views/system-administration/user-management/role/index.vue
2. i18n 国际化(重要)
- 使用
mixins: [i18nMixin('完整i18n前缀')],不要在每个页面手动定义T常量和tkey()方法 data()中用this.key('xxx')传完整 i18n key,不要用k()提前翻译(翻译由 page-table / page-dialog-form 内部处理,切换语言自动响应)- 模板搜索区用
$t(key('xxx')),公共 key 用$t(ckey('xxx')) - 语言包必须中英文同步添加(
zh-chs.json+en.json) - 参考文档:国际化规则.md
3. 文件夹命名(重要)
- 文件夹名称遵循 后台Webman界面截图对照表 的 snake_case/kebab-case 命名
- 目录示例:
src/views/production-master-data/factory-model/factory-area/ - 路由模块:
src/router/modules/production-master-data.js - API 文件:
src/api/production-master-data/factory-area.js
4. 路由 path 和 API BASE URL(重要 — 临时方案)
- 路由 path 和 API BASE URL 暂时保留旧项目的命名,因为后台数据库的路由表还未更新
- 示例:目录按对照表叫
production-master-data,但路由 path 保持旧值production_configuration// src/router/modules/production-master-data.js path: '/production_configuration', // 旧值暂留// src/api/production-master-data/factory-area.js const BASE = 'production_configuration/factory_model/factory_area/' // 旧值暂留 - 后续统一修改路由后再批量替换
4.1 API 参数名必须对齐旧项目(重要)
- API 函数入参的 key 名称必须与旧项目保持一致,不能自行发明参数名
- 例如:旧项目角色菜单接口参数是
role_id,不能写成id// ❌ 错误 — 自行发明参数名 getRoleMenu({ id: this.roleId }) // ✅ 正确 — 与旧项目参数名一致 getRoleMenu({ role_id: this.roleId }) - 迁移 API 时必须仔细阅读旧项目接口代码,逐个核对每个接口的入参 key 名称
- 如果后端报「xxx 不能为空」,首先检查参数 key 是否与旧项目一致
5. 旧 key → 新 key 映射
如果用户提供的是旧页面代码,需要根据对照表做 key 映射。已知映射如下(持续补充):
| 旧 key 前缀 | 新 key 前缀 |
|---|---|
page.production_configuration.factory_model.factory_area |
page.production_master_data.factory_model.factory_area |
page.system_settings.user_management.role |
page.system_administration.user_management.role |
page.system_settings.user_management.user |
page.system_administration.user_management.user |
page.system_settings.menu_configuration.menu |
page.system_administration.menu_management.menu_configuration |
page.system_settings.system_assistant.operate_log |
page.system_administration.system_utilities.operation_logs |
page.system_settings.system_assistant.api_log |
page.system_administration.system_utilities.api_logs |
page.system_settings.system_assistant.problem_help |
page.system_administration.system_utilities.problem_help |
page.system_settings.system_monitoring.system.login |
page.system_administration.system_monitoring.login |
page.production_configuration.matetial_model.* |
page.production_master_data.material_model.* |
page.planning_production.production_batch_management.batch |
page.planning_production.batch_management.batch_list |
page.data_middleground.basic_traceability.* |
page.data_platform.traceability.* |
6. 处理流程(每迁移一个页面执行以下步骤)
- 确定对照表位置:从 后台Webman界面截图对照表 找到对应行的英文名,转换为 snake_case
- 创建目录结构:
src/views/{一级snake_case}/{二级snake_case}/{三级snake_case}/ - 创建 API 文件:
src/api/{一级snake_case}/{二级snake_case}/{三级snake_case}.js,BASE URL 暂用旧值 - 添加路由模块:
src/router/modules/{一级snake_case}.js,path 暂用旧值 - 编写页面代码:使用 page-table + page-dialog-form 方案
- 添加 i18n:在
zh-chs.json和en.json中添加对应 key - 验证 JSON 合法性:
node -e "JSON.parse(require('fs').readFileSync('src/locales/zh-chs.json','utf8'))"
页面模板(通用 CRUD 页面骨架)
参考 src/views/production-master-data/factory-model/factory-area/index.vue 的结构,核心模式:
- Script:
mixins: [i18nMixin('page.{一}.{二}.{三}')]+data()中用this.key('xxx')传 key - Template:
<page-table>传 columns/data/loading/toolbarButtons/rowButtons/pagination +<page-dialog-form>传 formCols/formData/rules/title - Buttons:
useTableButtons({ toolbar: [...], row: [...] }, this.$permission) - Columns:
useTableColumns([...]) - Methods:
fetchData / onSearch / onReset / onPageChange / openAdd / openEdit / onDialogSubmit / handleDelete - i18n key 模板(每个页面至少要有这些):
search / reset / add / edit / delete / operation / add_title / edit_title / code / name / remark / enter_code / enter_name / remark_length / operation_success / confirm / cancel / tip / confirm_delete - 搜索条件过多时参考 表格组件使用说明.md - 场景 8,使用
searchExpanded+v-show实现折叠式搜索区,需额外添加 i18n key:expand(展开更多/Expand)、collapse(收起/Collapse)
6.1 依赖安装
当迁移涉及新的第三方库时:
- 包管理器:本项目使用 pnpm,安装命令为
pnpm add <package-name> - 安装前检查:先在
package.json中确认依赖是否已存在,避免重复安装 - 版本兼容:确保安装的包支持 Vue 2.x(本项目为 Vue 2.7)
- 参考标准:表格组件使用说明.md - 第 11 节
输出要求
- 创建完整的页面文件、路由模块、API 文件
- 在
zh-chs.json和en.json中添加对应 i18n key(中文和英文同步) - 完成后提醒用户验证 JSON 合法性
- 如涉及对照表中已有映射的 key 前缀变更,自动纠正为新的 key 前缀