feat: 新增工厂区域管理页面,修复Sass废弃警告
1. 新增生产配置-工厂模型-工厂区域完整CRUD页面 2. 新增通用表格、弹窗表单、i18n工具组件 3. 升级sass-loader并修复Sass废弃警告 4. 添加文档记录Sass迁移修复细节
This commit is contained in:
424
docs/migration-task-list.md
Normal file
424
docs/migration-task-list.md
Normal file
@@ -0,0 +1,424 @@
|
||||
# MES-UI 搬迁任务列表
|
||||
|
||||
> 从旧项目 `D:\code\company\SCTMES_MES_V5\vue-app` 搬迁至本项目 `d:\code\mes\mes-ui`
|
||||
|
||||
## 搬迁规则
|
||||
|
||||
| 规则 | 说明 |
|
||||
|------|------|
|
||||
| 目录结构 | 按 `后台Webman界面截图对照表.md` 中的 一级→二级→三级 模块层级创建 |
|
||||
| 页面视图 | `src/views/{一级}/{二级}/{三级}/index.vue` |
|
||||
| API 接口 | `src/api/{一级}/{二级}.js` |
|
||||
| Vuex Store | `src/store/modules/{一级}/{二级}.js` |
|
||||
| 路由 | `src/router/modules/{一级}.js`,汇总到 `routes.js` |
|
||||
| 组件 | 公用组件放 `src/components/`,模块内组件放 `views` 下的 `components/` |
|
||||
| 表格 | 搬迁时统一替换为 `page-table` 或 `sct-table` + `sct-toolbar`(见 [重构方案](./sct-base-table-refactor-design.md)),不再使用旧的 `sct-base-table` |
|
||||
| 代码审查 | 搬迁前检查旧代码中的不合理处(见下方「代码审查与改进清单」),搬迁时一并修复 |
|
||||
|
||||
---
|
||||
|
||||
## 预览:前置准备
|
||||
|
||||
| ID | 任务 | 源文件 | 目标位置 | 状态 |
|
||||
|----|------|--------|----------|:----:|
|
||||
| P0 | 创建目标目录结构(所有一级/二级/三级空文件夹) | — | `src/views/` | ⬜ |
|
||||
| P1 | 迁移公共服务层(axios 实例、工具函数等) | `src/api/service.js` `src/api/tools.js` `src/api/index.js` `src/libs/` | `src/api/` `src/libs/` | ⬜ |
|
||||
| P2 | 迁移登录页面、首页、404/刷新/重定向等系统通用页面 | `src/views/system_settings/system_monitoring/system/` `src/views/system_settings/home_page/` | `src/views/system-settings/` | ⬜ |
|
||||
| P3 | 迁移路由入口和 routes.js 汇总 | `src/router/index.js` `src/router/routes.js` | `src/router/` | ⬜ |
|
||||
| P4 | 迁移全局 Store(d2admin) | `src/store/modules/d2admin/` | `src/store/modules/d2admin/` | ⬜ |
|
||||
| P5 | 迁移布局组件(header-aside)及菜单配置 | `src/layout/` `src/menu/` | `src/layout/` `src/menu/` | ⬜ |
|
||||
| P6 | 迁移第三方依赖(main.js 中的插件、组件注册) | `src/main.js` `src/App.vue` `src/plugin/` | `src/main.js` `src/App.vue` `src/plugin/` | ⬜ |
|
||||
| P7 | 迁移本地化文件(i18n) | `src/locales/` `src/i18n.js` | `src/locales/` `src/i18n.js` | ⬜ |
|
||||
| P8 | 迁移全局设置 | `src/setting.js` `.env` 系列 | `src/setting.js` `.env` 系列 | ⬜ |
|
||||
| P9 | 移植旧项目专用组件(form、sct-ace 等) | `src/components/battery/` `src/components/calculation/` `src/components/device-monitor/` `src/components/dm-print/` `src/components/form/` `src/components/menu-tree/` `src/components/sct-ace/` `src/components/sct-ace-editor/` `src/components/OCR/` | `src/components/` | ⬜ |
|
||||
| P10 | 迁移旧项目 public 目录下的静态资源 | `public/` | `public/` | ⬜ |
|
||||
| P11 | 迁移旧项目 assets 资源 | `src/assets/` | `src/assets/` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 一、系统设置 (System Administration)
|
||||
|
||||
> 目标目录根:`src/views/system-settings/`
|
||||
|
||||
### 1.1 用户管理 (User Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| S1 | 角色 (Role) | `system_settings/user_management/role/` | `system_settings/user_management/role.js` | `sctmesadmin/modules/role.js` | `system-settings/user-management/role/` | ⬜ |
|
||||
| S2 | 用户 (User) | `system_settings/user_management/user/` | `system_settings/user_management/user.js` | `sctmesadmin/modules/user.js` | `system-settings/user-management/user/` | ⬜ |
|
||||
|
||||
### 1.2 菜单管理 (Menu Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| S3 | 菜单配置 | `system_settings/menu_configuration/menu/` | `system_settings/menu_configuration/menu.js` | `system-settings/menu-management/menu-configuration/` | ⬜ |
|
||||
|
||||
### 1.3 系统助手 (System Utilities)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| S4 | 操作日志 | `system_settings/system_assistant/operate_log/` | `system_settings/system_assistant/operate_log.js` | `system-settings/system-utilities/operation-logs/` | ⬜ |
|
||||
| S5 | 接口日志 | `system_settings/system_assistant/interface_log/` | `system_settings/system_assistant/interface_log.js` | `system-settings/system-utilities/api-logs/` | ⬜ |
|
||||
|
||||
### 1.4 系统监控 (System Monitoring)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| S6 | 监控设置 | `system_settings/system_monitoring/setting/` | `system_settings/system_monitor/setting.js` | `system-settings/system-monitoring/monitoring-configuration/` | ⬜ |
|
||||
|
||||
### 1.5 系统设置 - 路由汇总
|
||||
|
||||
| ID | 任务 | 源文件 | 目标位置 | 状态 |
|
||||
|----|------|--------|----------|:----:|
|
||||
| S7 | 系统设置路由 | `router/system_settings/system.js` | `router/modules/system-settings.js` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 二、生产配置 (Production Master Data)
|
||||
|
||||
> 目标目录根:`src/views/production-configuration/`
|
||||
|
||||
### 2.1 工厂模型 (Factory Model)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| P1 | 产线设置 | `production_configuration/factory_model/factory_line/` | 需从路由确认 | `sctmesadmin/modules/line.js` | `production-configuration/factory-model/production-line/` | ⬜ |
|
||||
| P2 | 工厂区域 | `production_configuration/factory_model/factory_area/` | 需从路由确认 | `sctmesadmin/modules/area.js` | `production-configuration/factory-model/factory-area/` | ⬜ |
|
||||
|
||||
### 2.2 工艺模型 (Process Model)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| P3 | 工艺流程类别 | `production_configuration/technology_model/technology_flow_category/` | 需从路由确认 | `sctmesadmin/modules/technology_category.js` | `production-configuration/process-model/process-category/` | ⬜ |
|
||||
| P4 | 工序单元 | 需确认 | `production_configuration/workerman/workermanSet.js` | `sctmesadmin/modules/steps.js` | `production-configuration/process-model/process-step/` | ⬜ |
|
||||
| P5 | 工艺流程 | `production_configuration/technology_model/technology_flow/` | 需从路由确认 | `sctmesadmin/modules/technologyflow.js` | `production-configuration/process-model/process-routing/` | ⬜ |
|
||||
|
||||
### 2.3 产品管理 (Product Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| P6 | 产品列表 | `production_configuration/product_model/battery_model/` | 需从路由确认 | `sctmesadmin/modules/product_battery.js` | `production-configuration/product-management/product-list/` | ⬜ |
|
||||
| P7 | 不良管理 | `production_configuration/product_model/product_ng_info/` | 需从路由确认 | `sctmesadmin/modules/product_ng_info.js` | `production-configuration/product-management/defect-management/` | ⬜ |
|
||||
|
||||
### 2.4 物料模型 (Material Model)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| P8 | 物料类别列表 | `production_configuration/matetial_model/matetial_category/` | `warehouse/basic/material_category.js` | `sctmesadmin/modules/material_category.js` | `production-configuration/material-model/material-category/` | ⬜ |
|
||||
| P9 | 物料信息管理 | `production_configuration/matetial_model/matetial_management/` | `warehouse/basic/material.js` | — | `production-configuration/material-model/material-master/` | ⬜ |
|
||||
| P10 | BOM物料清单 | `production_configuration/matetial_model/bom/` | `production_configuration/matetial_model/bom.js` | — | `production-configuration/material-model/bom/` | ⬜ |
|
||||
| P11 | 计量单位 | `production_configuration/matetial_model/unit/` | `production_configuration/matetial_model/unit.js` | `sctmesadmin/modules/unit.js` | `production-configuration/material-model/unit-of-measure/` | ⬜ |
|
||||
|
||||
### 2.5 SPC采集模型 (SPC Configuration)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| P12 | SPC采集配置 | `production_configuration/spc_configuration/binding_scada_node/` | 需从路由确认 | `production-configuration/spc-configuration/spc-data-collection/` | ⬜ |
|
||||
|
||||
### 2.6 班组模型 (Team Model)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| P13 | 班组管理 | `system_settings/organization/production_team_manage/` | 需从路由确认 | `sctmesadmin/modules/production_team_manage.js` | `production-configuration/team-model/team-management/` | ⬜ |
|
||||
| P14 | 班次管理 | `system_settings/organization/production_shift_management/` | 需从路由确认 | — | `production-configuration/team-model/shift-management/` | ⬜ |
|
||||
| P15 | 排班日历 | `system_settings/organization/production_shift_calender/` | 需从路由确认 | — | `production-configuration/team-model/scheduling-calendar/` | ⬜ |
|
||||
|
||||
### 2.7 生产配置 - 路由汇总
|
||||
|
||||
| ID | 任务 | 源文件 | 目标位置 | 状态 |
|
||||
|----|------|--------|----------|:----:|
|
||||
| P16 | 生产配置路由 | `router/production_configuration/index.js` | `router/modules/production-configuration.js` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 三、设备模型 (Equipment Management)
|
||||
|
||||
> 目标目录根:`src/views/equipment-management/`
|
||||
|
||||
### 3.1 设备类别 (Equipment Category)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| E1 | 设备类别 | `production_configuration/device_model/device_category/` | 需从路由确认 | `sctmesadmin/modules/device_category.js` | `equipment-management/equipment-category/` | ⬜ |
|
||||
|
||||
### 3.2 设备信息 (Equipment Info)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| E2 | 设备信息 | `production_configuration/device_model/device_management/` | 需从路由确认 | `sctmesadmin/modules/device.js` | `equipment-management/equipment-info/` | ⬜ |
|
||||
|
||||
### 3.3 设备点检 (Inspection Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| E3 | 设备点检项目 | `device_management/device_check/device_check_items/` | 需从路由确认 | `sctmesadmin/modules/device_check_items.js` | `equipment-management/inspection-management/inspection-items/` | ⬜ |
|
||||
| E4 | 设备点检记录 | `device_management/device_check/device_check_record/` | 需从路由确认 | — | `equipment-management/inspection-management/inspection-records/` | ⬜ |
|
||||
| E5 | 设备点检日志 | `device_management/device_check/device_check_items_log/` | 需从路由确认 | — | `equipment-management/inspection-management/inspection-logs/` | ⬜ |
|
||||
|
||||
### 3.4 设备保养 (Maintenance Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| E6 | 设备保养项目 | `device_management/device_maintain/device_maintain_items/` | 需从路由确认 | `sctmesadmin/modules/device_maintain_items.js` | `equipment-management/maintenance-management/maintenance-items/` | ⬜ |
|
||||
| E7 | 设备保养详情 | `device_management/device_maintain/device_maintain_items_details/` | 需从路由确认 | — | `equipment-management/maintenance-management/maintenance-details/` | ⬜ |
|
||||
| E8 | 设备保养日志 | `device_management/device_maintain/device_maintain_items_log/` | 需从路由确认 | — | `equipment-management/maintenance-management/maintenance-logs/` | ⬜ |
|
||||
|
||||
### 3.5 设备维修 (Repair Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| E9 | 设备维修管理 | `device_management/device_repair/device_repair_management/` | 需从路由确认 | `equipment-management/repair-management/repair-management/` | ⬜ |
|
||||
| E10 | 设备维修日志 | `device_management/device_repair/device_repair_log/` | 需从路由确认 | `equipment-management/repair-management/repair-logs/` | ⬜ |
|
||||
|
||||
### 3.6 设备损耗品 (Consumables Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| E11 | 设备损耗品类别 | `device_management/device_consumables/device_consumables_category/` | 需从路由确认 | `sctmesadmin/modules/device_consumables_category.js` | `equipment-management/consumables/consumables-category/` | ⬜ |
|
||||
| E12 | 设备损耗品项目 | `device_management/device_consumables/device_consumables_items/` | 需从路由确认 | `sctmesadmin/modules/device_consumables_items.js` | `equipment-management/consumables/consumables-items/` | ⬜ |
|
||||
| E13 | 设备损耗品寿命管理 | 需确认 | 需从路由确认 | `sctmesadmin/modules/device_consumables_lifetime_management.js` | `equipment-management/consumables/consumables-lifecycle/` | ⬜ |
|
||||
| E14 | 设备损耗品更换日志 | `device_management/device_consumables/device_consumables_replace_log/` | 需从路由确认 | — | `equipment-management/consumables/replacement-logs/` | ⬜ |
|
||||
|
||||
### 3.7 设备模型 - 路由汇总
|
||||
|
||||
| ID | 任务 | 源文件 | 目标位置 | 状态 |
|
||||
|----|------|--------|----------|:----:|
|
||||
| E15 | 设备模型路由 | `router/device_management/device.js` | `router/modules/equipment-management.js` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 四、计划与生产 (Planning & Production)
|
||||
|
||||
> 目标目录根:`src/views/planning-production/`
|
||||
|
||||
### 4.1 生产批次管理 (Batch Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| B1 | 批次列表 | `planning_production/production_batch_management/batch/` | `data_dashboards/produce/batch.js` | `sctmesadmin/modules/batch.js` | `planning-production/batch-management/batch-list/` | ⬜ |
|
||||
| B2 | 批次托盘 | `planning_production/production_batch_management/batch_tray/` | 需从路由确认 | — | `planning-production/batch-management/tray-tracking/` | ⬜ |
|
||||
| B3 | 生产批次不良报表 | `planning_production/production_batch_management/bad/` | 需从路由确认 | — | `planning-production/batch-management/batch-defect-report/` | ⬜ |
|
||||
|
||||
### 4.2 预警中心 (Alert Center)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| B4 | 预警中心 | 需确认(可能在 pannel/index) | `planning_production/pannel/index.js` | `planning-production/alert-center/` | ⬜ |
|
||||
|
||||
### 4.3 生产监控 (Production Monitoring)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|-----------|:----:|
|
||||
| B5 | 物料监控 | `planning_production/produce/monitor/wareroom/ic/` 或 WIP | `data_dashboards/produce/material/wip.js` | — | `planning-production/production-monitoring/material-monitoring/` | ⬜ |
|
||||
| B6 | 电池复投管理 | 需确认 | `data_dashboards/produce/battery/replace.js` | — | `planning-production/production-monitoring/rework-management/` | ⬜ |
|
||||
| B7 | 托盘管理 | `planning_production/produce/monitor/tray_manage/` | `data_dashboards/produce/tray/list.js` `planning_production/produce/tray_manage.js` | — | `planning-production/production-monitoring/tray-management/` | ⬜ |
|
||||
| B8 | 托盘登录 | `planning_production/produce/monitor/tray_login/` | `planning_production/battery/login.js` `planning_production/produce/tray_login.js` | — | `planning-production/production-monitoring/tray-registration/` | ⬜ |
|
||||
| B9 | 设备监控 | `planning_production/produce/monitor/device/` | `data_dashboards/produce/report/device.js` | — | `planning-production/production-monitoring/equipment-monitoring/` | ⬜ |
|
||||
| B10 | 电池工序管理 | `planning_production/produce/monitor/batch_battery/` 等 | `planning_production/produce/batch_battery.js` | `sctmesadmin/modules/batch_battery.js` | `planning-production/production-monitoring/process-execution/` | ⬜ |
|
||||
|
||||
### 4.4 计划与生产 - 路由汇总
|
||||
|
||||
| ID | 任务 | 源文件 | 目标位置 | 状态 |
|
||||
|----|------|--------|----------|:----:|
|
||||
| B11 | 计划与生产路由 | `router/planning_production/index.js` | `router/modules/planning-production.js` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 五、质量管理 (Quality Management)
|
||||
|
||||
> 目标目录根:`src/views/quality-management/`
|
||||
|
||||
### 5.1 过程控制 (Process Control)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| Q1 | 检验类别管理 | `quality_control/first_inspection/category/` | `quality_control/xqc/inspection_category.js` | `quality-management/process-control/inspection-type/` | ⬜ |
|
||||
| Q2 | 首巡检项目配置 | `quality_control/first_inspection/setting/` | 需从路由确认 | `quality-management/process-control/first-article-inspection-config/` | ⬜ |
|
||||
| Q3 | 首巡检录入 | `quality_control/first_inspection/input/` | 需从路由确认 | `quality-management/process-control/first-article-inspection-records/` | ⬜ |
|
||||
| Q4 | 首巡检报表 | `quality_control/first_inspection/report/` | 需从路由确认 | `quality-management/process-control/first-article-inspection-reports/` | ⬜ |
|
||||
|
||||
### 5.2 检验控制 (Inspection Management)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| Q5 | 检验单管理 | `quality_control/xqc/inspection_order_manage/` | `quality_control/xqc/inspection_order_manage.js` | `quality-management/inspection-control/inspection-orders/` | ⬜ |
|
||||
| Q6 | 检验标准 | `quality_control/xqc/inspection_standard/` | `quality_control/xqc/inspection_standard.js` | `quality-management/inspection-control/inspection-standards/` | ⬜ |
|
||||
| Q7 | 接收质量限 (AQL) | `quality_control/xqc/aql_config/` `quality_control/xqc/aql_sample/` | `quality_control/xqc/aql_config.js` `quality_control/xqc/aql_sample.js` | `quality-management/inspection-control/aql-standards/` | ⬜ |
|
||||
| Q8 | 检测方案维护 | `quality_control/xqc/inspection_plan/` | `quality_control/xqc/inspection_plan.js` | `quality-management/inspection-control/inspection-plans/` | ⬜ |
|
||||
| Q9 | 检验项目 | `quality_control/xqc/inspection_item/` | `quality_control/xqc/inspection_item.js` | `quality-management/inspection-control/inspection-items/` | ⬜ |
|
||||
| Q10 | 抽样方案配置 | `quality_control/xqc/sampling_plan/` | `quality_control/xqc/sampling_plan.js` | `quality-management/inspection-control/sampling-plans/` | ⬜ |
|
||||
|
||||
### 5.3 SPC统计过程控制 (SPC Control)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| Q11 | SPC渲染条件配置 | `spc/manage/` | `spc/index.js` | `quality-management/spc-control/spc-configuration/` | ⬜ |
|
||||
|
||||
### 5.4 SPC计量型报表 (SPC Variable Charts)
|
||||
|
||||
| ID | 图表 | 源 views | 目标 views | 状态 |
|
||||
|----|------|---------|----------|:----:|
|
||||
| Q12 | XBar-R | `spc/spc_chart/xbar-r/` | `quality-management/spc-variable-charts/xbar-r/` | ⬜ |
|
||||
| Q13 | XBar-S | `spc/spc_chart/xbar-s/` | `quality-management/spc-variable-charts/xbar-s/` | ⬜ |
|
||||
| Q14 | I-MR | `spc/spc_chart/i-mr/` | `quality-management/spc-variable-charts/i-mr/` | ⬜ |
|
||||
| Q15 | Levey-Jennings | `spc/spc_chart/levey-jennings/` | `quality-management/spc-variable-charts/levey-jennings/` | ⬜ |
|
||||
| Q16 | EWMA | `spc/spc_chart/ewma/` | `quality-management/spc-variable-charts/ewma/` | ⬜ |
|
||||
| Q17 | CUSUM | `spc/spc_chart/cusum/` | `quality-management/spc-variable-charts/cusum/` | ⬜ |
|
||||
| Q18 | MA | `spc/spc_chart/ma/` | `quality-management/spc-variable-charts/ma/` | ⬜ |
|
||||
| Q19 | MAMR | `spc/spc_chart/mamr/` | `quality-management/spc-variable-charts/mamr/` | ⬜ |
|
||||
| Q20 | MAMS | `spc/spc_chart/mams/` | `quality-management/spc-variable-charts/mams/` | ⬜ |
|
||||
| Q21 | CPK | `spc/spc_chart/Cpk/` | `quality-management/spc-variable-charts/cpk/` | ⬜ |
|
||||
|
||||
### 5.5 SPC计数型报表 (SPC Attribute Charts)
|
||||
|
||||
| ID | 图表 | 源 views | 目标 views | 状态 |
|
||||
|----|------|---------|----------|:----:|
|
||||
| Q22 | DPMO | `spc/spc_chart/dpmo/` | `quality-management/spc-attribute-charts/dpmo/` | ⬜ |
|
||||
| Q23 | PChart | `spc/spc_chart/p-chart/` | `quality-management/spc-attribute-charts/p-chart/` | ⬜ |
|
||||
| Q24 | NPChart | `spc/spc_chart/np-chart/` | `quality-management/spc-attribute-charts/np-chart/` | ⬜ |
|
||||
| Q25 | CChart | `spc/spc_chart/c-chart/` | `quality-management/spc-attribute-charts/c-chart/` | ⬜ |
|
||||
| Q26 | UChart | `spc/spc_chart/u-chart/` | `quality-management/spc-attribute-charts/u-chart/` | ⬜ |
|
||||
|
||||
### 5.6 质量管理 - 路由汇总
|
||||
|
||||
| ID | 任务 | 源文件 | 目标位置 | 状态 |
|
||||
|----|------|--------|----------|:----:|
|
||||
| Q27 | 质量管理路由 | `router/quality_control/quality.js` | `router/modules/quality-management.js` | ⬜ |
|
||||
| Q28 | SPC路由 | `router/spc/index.js` | 合并到 `router/modules/quality-management.js` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 六、数据中台 (Data Platform)
|
||||
|
||||
> 目标目录根:`src/views/data-platform/`
|
||||
|
||||
### 6.1 基础追溯 (Traceability)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| D1 | 反向追溯 | `data_middleground/basic_traceability/reverse_direction_traceability/` 或正向追溯 | `data_dashboards/produce/traceability/battery.js` | `data-platform/traceability/backward/` | ⬜ |
|
||||
| D2 | 正向追溯 | `data_middleground/basic_traceability/` 下确认 | `data_dashboards/produce/traceability/bom_batch.js` | `data-platform/traceability/forward/` | ⬜ |
|
||||
| D3 | 电池曲线 | `planning_production/produce/traceability/curve/` | `data_dashboards/produce/traceability/curve.js` | `data-platform/traceability/battery-curve/` | ⬜ |
|
||||
| D4 | 托盘追溯 | `planning_production/produce/traceability/tray/` | `data_dashboards/produce/traceability/tray.js` | `data-platform/traceability/tray/` | ⬜ |
|
||||
| D5 | 电池追溯 | `planning_production/produce/traceability/battery/` | `data_dashboards/produce/traceability/battery.js` | `data-platform/traceability/battery/` | ⬜ |
|
||||
|
||||
### 6.2 生产报表 (Production Reports)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| D6 | 设备履历报表 | `planning_production/produce/report/battery/` 或设备报告 | `data_dashboards/produce/report/all_report.js` `data_dashboards/produce/report/device.js` | `data-platform/production-reports/equipment-history/` | ⬜ |
|
||||
| D7 | 电池详情报表 | `planning_production/produce/report/battery_details_report/` 或电池报告 | `data_dashboards/produce/report/battery.js` | `data-platform/production-reports/battery-detail/` | ⬜ |
|
||||
|
||||
### 6.3 相关性分析 (Correlation Analysis)
|
||||
|
||||
| ID | 三级模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|---------|---------|--------|----------|:----:|
|
||||
| D8 | 鹰眼 (Hawkeye) | `data_middleground/eagle_eyes/` | `data_middle_office/eagle_eyes/index.js` | `data-platform/correlation-analysis/hawkeye/` | ⬜ |
|
||||
|
||||
### 6.4 数据中台 - 路由汇总
|
||||
|
||||
| ID | 任务 | 源文件 | 目标位置 | 状态 |
|
||||
|----|------|--------|----------|:----:|
|
||||
| D9 | 数据中台路由 | `router/data_middleground/index.js` | `router/modules/data-platform.js` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 七、仓储管理 (Warehouse)
|
||||
|
||||
> 目标目录根:`src/views/warehouse/`
|
||||
|
||||
| ID | 模块 | 源 views | 源 api | 源 store | 目标 views | 状态 |
|
||||
|----|------|---------|--------|----------|-----------|:----:|
|
||||
| W1 | 仓库设置(业务类型/单据类型/仓库/库区/库位/货架) | `warehouse/setting/` | `warehouse/setting/` | `warehouse/modules/` | `warehouse/settings/` | ⬜ |
|
||||
| W2 | 基础数据(客户/物料类别/物料/供应商/领料单) | `warehouse/basic/` | `warehouse/basic/` | `warehouse/modules/` | `warehouse/basic/` | ⬜ |
|
||||
| W3 | ERP接口(接口/采购订单/产品出库/发送日志) | `warehouse/erp/` | `warehouse/erp/` | — | `warehouse/erp/` | ⬜ |
|
||||
| W4 | 收货管理(采购入库/打印/来料检验/上架等) | `warehouse/receiving_management/` | `warehouse/receiving_management/` | — | `warehouse/receiving/` | ⬜ |
|
||||
| W5 | 发货管理(出库/委外出库等) | `warehouse/shipping_management/` | 需确认 | — | `warehouse/shipping/` | ⬜ |
|
||||
| W6 | 库存管理(库存/冻结/锁定/操作日志) | `warehouse/stock_management/` | `warehouse/stock_management/` | — | `warehouse/stock/` | ⬜ |
|
||||
| W7 | 作业管理(库存移动/盘点) | `warehouse/working/` | `warehouse/working/` | — | `warehouse/operations/` | ⬜ |
|
||||
| W8 | 仓储路由 | `router/warehouse/index.js` | — | — | `router/modules/warehouse.js` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 八、SCADA管理(保留旧模块,不在主文档中)
|
||||
|
||||
> 目标目录根:`src/views/scada-management/`
|
||||
|
||||
| ID | 模块 | 源 views | 源 api | 目标 views | 状态 |
|
||||
|----|------|---------|--------|----------|:----:|
|
||||
| SC1 | 车间管理(配置/点位) | `scada_manage/workshop_manage/` | `scada_manage/workshop_manage/` | `scada-management/workshop/` | ⬜ |
|
||||
| SC2 | 基础配置(SCADA配置/查询/节点映射/EMS) | `scada_manage/basic_configuration/` | `modules/scada.configure.api.js` | `scada-management/basic-config/` | ⬜ |
|
||||
| SC3 | 边缘服务器(配置/监控/日志) | `scada_manage/lecpserver/` `scada_manage/EdgeProcessorsManage/` | `modules/edgeServer.api.js` | `scada-management/edge-server/` | ⬜ |
|
||||
| SC4 | 设备采集监控 | `scada_manage/device_gather/` | `scada_manage/huankong_management/` | `scada-management/device-gather/` | ⬜ |
|
||||
| SC5 | SCADA路由 | `router/scada_management/scada.js` | — | `router/modules/scada-management.js` | ⬜ |
|
||||
|
||||
---
|
||||
|
||||
## 代码审查与改进清单
|
||||
|
||||
> 在搬迁过程中,逐项检查旧代码中的不合理之处,搬迁时一并修复。每个问题标注 **发现时间** 和 **处理状态**。
|
||||
|
||||
### 🔴 严重问题(必须修复)
|
||||
|
||||
| # | 问题描述 | 影响范围 | 改进方案 | 状态 |
|
||||
|---|---------|---------|---------|:--:|
|
||||
| CR01 | **拼写错误遍布路由和目录名**:`matetial`→应为`material`,`freezeunfreeze`→`freeze-unfreeze`,出现 23+ 处 | `router/production_configuration/index.js`<br>`views/production_configuration/matetial_model/` | 搬迁时统一修正为正确拼写,路由 path 也一并修正 | ⬜ |
|
||||
| CR02 | **生产代码残留 `console.log`**:285+ 处 `console.log/warn/error` 分布在 100+ 个文件中 | `src/views/` 几乎所有模块 | 移除所有调试用 `console.log`,仅保留关键 `console.error` 并使用统一日志工具 `util.log` | ⬜ |
|
||||
| CR03 | **重复/拷贝目录残留**:`scada_query copy/` 显式拷贝备份目录 | `views/scada_manage/basic_configuration/scada_query copy/` | 删除该拷贝目录,如需要保留则合并到正式目录 | ⬜ |
|
||||
|
||||
### 🟡 中等问题(建议修复)
|
||||
|
||||
| # | 问题描述 | 影响范围 | 改进方案 | 状态 |
|
||||
|---|---------|---------|---------|:--:|
|
||||
| CR04 | **API 注入模式混乱**:旧模式用 `require.context` 动态注入(`api/modules/*.api.js`),新模式用直接 `import`(`api/system_settings/`),两套并存 | `api/index.js` + `api/modules/` | 统一为直接 `import` 模式,移除 `require.context` 动态注入和 `api/modules/` 目录 | ⬜ |
|
||||
| CR05 | **`let` 滥用**:API 文件中大量 `let url = urls + 'xxx'`,URL 拼接后从不重新赋值 | `api/` 下所有文件 | 全部改为 `const` | ⬜ |
|
||||
| CR06 | **Store 初始化直接用 `localStorage` 无容错**:`JSON.parse(localStorage.getItem('roleData'))` 放在 state 声明顶层,解析失败会导致模块加载崩溃 | `store/modules/sctmesadmin/modules/role.js` 等 36 个模块 | 改为在 getter 或 action 中惰性读取,并用 try-catch 包裹 `JSON.parse` | ⬜ |
|
||||
| CR07 | **每个 API 函数都手动传 `method` 和 `platform` 参数**,冗余且容易遗漏 | `api/` 下 80+ 文件 | 在 `request` 公共层统一注入 `platform: 'background'`;`method` 参数通过约定 url 自动映射 | ⬜ |
|
||||
| CR08 | **axios 拦截器 `switch-case` 冗长**:响应拦截器整段 switch-case 映射 HTTP 状态码到错误消息 | `api/service.js` | 改用 Map 结构 | error.message = statusMessages[status] \|\| error.message,更简洁 | ⬜ |
|
||||
| CR09 | **路由文件命名不一致**:有 `system.js`、`device.js`、`scada.js`、`index.js` 混用 | `router/` 所有文件 | 统一为 `index.js`,按文件夹区分模块 | ⬜ |
|
||||
| CR10 | **`system_Assistant` 大小写不一致**:路由 path 中是 `system_Assistant`(大写A),目录名是 `system_assistant`(小写a) | `router/system_settings/system.js` | 统一为 `system-assistant`(kebab-case) | ⬜ |
|
||||
| CR11 | **Store 模块 `namespaced: true` 命名不规范**:部分模块路径很深 `sctmesadmin/modules/xxx`,难以维护 | `store/modules/sctmesadmin/` | 按功能打平为 `store/modules/{功能名}.js`,去掉多余嵌套 | ⬜ |
|
||||
|
||||
### 🟢 建议优化(可选)
|
||||
|
||||
| # | 问题描述 | 影响范围 | 改进方案 | 状态 |
|
||||
|---|---------|---------|---------|:--:|
|
||||
| CR12 | **页面组件 `PageHeader/PageMain` 内联模式冗余**:绝大多数页面都是 `index.vue` + `components/PageHeader/index.vue` + `components/PageMain/index.vue` 三层结构,PageHeader 大多只传几个 props | 所有 views | 评估是否可将简单的 PageHeader/PageMain 合并为单文件组件,减少目录嵌套 | ⬜ |
|
||||
| CR13 | **`Promise.resolve(...)` 包裹 sync 数据**:Store actions 中 `return Promise.resolve(res.data)` 在 `async` 函数里是多余的 | `store/modules/` 所有 actions | 直接 `return res.data`,`async` 函数自动包装返回值 | ⬜ |
|
||||
| CR14 | **国际化键名硬编码**:大量组件中 `$t('xxx')` 的 key 没有类型约束,容易拼错 | 所有 Vue 组件 | 搬迁后统一整理 i18n key,考虑用常量池管理 | ⬜ |
|
||||
| CR15 | **公共组件未按功能分组**:`components/` 下散落 `battery/`、`calculation/`、`tray/`、`technology/` 等多个业务组件与通用组件混放 | `src/components/` | 业务组件迁入对应模块 views 的 `components/`,公共组件保留并文档化 | ⬜ |
|
||||
| CR16 | **`sct-base-table` 组件架构臃肿**:215 行代码包含致命 bug(引入 yargs)、60% 死代码、buttonList/columns 在 100+ 页面中重复定义 | `components/sct-base-table/` 及所有引用页面 | 📄 详见 [sct-base-table 重构方案](./sct-base-table-refactor-design.md):拆分为 7 个小组件 + 5 个 composable 函数,消除重复,迁移与搬迁同步进行 | ⬜ |
|
||||
|
||||
### 📄 专项重构方案
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| [sct-base-table 重构方案](./sct-base-table-refactor-design.md) | 组合式重构:拆组件+composable,消除 buttonList/columns 手动定义,覆盖 100+ 页面 |
|
||||
|
||||
---
|
||||
|
||||
## 搬迁统计
|
||||
|
||||
| 一级模块 | 三级页面数 | 路由文件 | API文件 | Store模块 | 已完成 |
|
||||
|---------|-----------|---------|---------|----------|:----:|
|
||||
| 系统设置 | 6 | 1 | 5 | 2 | 0/13 |
|
||||
| 生产配置 | 15 | 1 | ~10 | 12 | 0/37 |
|
||||
| 设备模型 | 14 | 1 | ~10 | 7 | 0/31 |
|
||||
| 计划与生产 | 10 | 1 | ~8 | 3 | 0/21 |
|
||||
| 质量管理 | 26 | 2 | ~15 | 0 | 0/43 |
|
||||
| 数据中台 | 8 | 1 | ~8 | 0 | 0/17 |
|
||||
| 仓储管理 | 25+ | 1 | ~20 | 11 | 0/56 |
|
||||
| SCADA管理 | 10+ | 1 | ~6 | 0 | 0/16 |
|
||||
| 前置准备 | — | 2 | — | 1 | 0/11 |
|
||||
| **合计** | **114+** | **11** | **82+** | **36** | **0/245** |
|
||||
|
||||
---
|
||||
|
||||
## 搬迁流程说明
|
||||
|
||||
每条 ID 任务完成后,将状态从 ⬜ 改为 ✅,并在下方补充日期和备注。
|
||||
|
||||
示例:
|
||||
```
|
||||
| S1 | 角色 (Role) | `...` | `...` | `...` | ✅ |
|
||||
```
|
||||
146
docs/sass-deprecation-fixes.md
Normal file
146
docs/sass-deprecation-fixes.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Sass 废弃警告修复记录
|
||||
|
||||
> 项目运行 `pnpm serve` 时,Dart Sass 输出了多类废弃 API 警告。本文档记录问题现象、根因及修复方案。
|
||||
|
||||
---
|
||||
|
||||
## 1. `legacy-js-api` — Sass Loader 旧 JS API 警告
|
||||
|
||||
### 问题现象
|
||||
|
||||
```
|
||||
Deprecation Warning [legacy-js-api]: The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0.
|
||||
```
|
||||
|
||||
### 根因
|
||||
|
||||
`sass-loader` 旧版本默认通过旧版 JS API 调用 Dart Sass。Dart Sass 计划在 2.0 中移除该 API。
|
||||
|
||||
### 修复
|
||||
|
||||
**文件:`package.json`**
|
||||
|
||||
将 `sass-loader` 升级到 `10.5.2`(v10 最后一个稳定版,兼容 Webpack 4),该版本支持 `silenceDeprecations` 选项。
|
||||
|
||||
```diff
|
||||
- "sass-loader": "^10.3.1",
|
||||
+ "sass-loader": "~10.5.2",
|
||||
```
|
||||
|
||||
**文件:`vue.config.js`**
|
||||
|
||||
在 `css.loaderOptions.sass` 中添加 `silenceDeprecations` 配置。
|
||||
|
||||
```js
|
||||
sass: {
|
||||
additionalData: '@use "@/assets/style/public.scss" as *;',
|
||||
sassOptions: {
|
||||
silenceDeprecations: ['legacy-js-api', 'import']
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. `import` — Sass `@import` 废弃警告
|
||||
|
||||
### 问题现象
|
||||
|
||||
```
|
||||
DEPRECATION WARNING [import]: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.
|
||||
|
||||
╷
|
||||
1 │ @import '~@/assets/style/unit/color.scss';
|
||||
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
╵
|
||||
src\assets\style\public.scss 1:9 @use
|
||||
```
|
||||
|
||||
### 根因
|
||||
|
||||
`public.scss` 通过 `@import '~@/assets/style/unit/color.scss'` 引入颜色变量文件。Dart Sass 正在推动从 `@import` 迁移到 `@use` / `@forward` 模块系统。
|
||||
|
||||
### 为何不改成 `@use`
|
||||
|
||||
该 `@import` 使用了 Webpack 专有的 `~` 前缀做模块路径解析(`~@/assets/...`),`@use` 对此机制支持不稳定,直接替换可能导致构建失败。
|
||||
|
||||
### 修复
|
||||
|
||||
在上述 `silenceDeprecations` 数组中追加 `'import'`,静默该警告。
|
||||
|
||||
---
|
||||
|
||||
## 3. `global-builtin` — 全局内置函数 `nth()` 废弃警告
|
||||
|
||||
### 问题现象
|
||||
|
||||
```
|
||||
Deprecation Warning [global-builtin]: Global built-in functions are deprecated and will be removed in Dart Sass 3.0.0.
|
||||
Use list.nth instead.
|
||||
|
||||
╷
|
||||
42 │ .#{$prefix}-m-#{nth($sizes, $index)} { margin: #{nth($sizes, $index)}px !important; }
|
||||
│ ^^^^^^^^^^^^^^^^^^^
|
||||
╵
|
||||
src\assets\style\public-class.scss 42:19 @import
|
||||
src\App.vue 3:9 root stylesheet
|
||||
```
|
||||
|
||||
### 根因
|
||||
|
||||
Dart Sass 正在将全局内置函数迁移到命名空间模块。`nth()` 属于 `sass:list` 模块,不应再作为全局函数直接调用。
|
||||
|
||||
### 修复(从源码根治)
|
||||
|
||||
**文件:`src/assets/style/public-class.scss`**
|
||||
|
||||
**步骤 1** — 文件顶部引入 `sass:list` 模块:
|
||||
|
||||
```diff
|
||||
+ @use 'sass:list';
|
||||
@import 'public';
|
||||
```
|
||||
|
||||
**步骤 2** — 将 `@for` 循环中所有 `nth()` 替换为 `list.nth()`:
|
||||
|
||||
```diff
|
||||
@for $index from 1 to 6 {
|
||||
- .#{$prefix}-m-#{nth($sizes, $index)} { margin: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-mt-#{nth($sizes, $index)} { margin-top: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-mr-#{nth($sizes, $index)} { margin-right: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-mb-#{nth($sizes, $index)} { margin-bottom: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-ml-#{nth($sizes, $index)} { margin-left: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-p-#{nth($sizes, $index)} { padding: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-pt-#{nth($sizes, $index)} { padding-top: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-pr-#{nth($sizes, $index)} { padding-right: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-pb-#{nth($sizes, $index)} { padding-bottom: #{nth($sizes, $index)}px !important; }
|
||||
- .#{$prefix}-pl-#{nth($sizes, $index)} { padding-left: #{nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-m-#{list.nth($sizes, $index)} { margin: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-mt-#{list.nth($sizes, $index)} { margin-top: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-mr-#{list.nth($sizes, $index)} { margin-right: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-mb-#{list.nth($sizes, $index)} { margin-bottom: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-ml-#{list.nth($sizes, $index)} { margin-left: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-p-#{list.nth($sizes, $index)} { padding: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-pt-#{list.nth($sizes, $index)} { padding-top: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-pr-#{list.nth($sizes, $index)} { padding-right: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-pb-#{list.nth($sizes, $index)} { padding-bottom: #{list.nth($sizes, $index)}px !important; }
|
||||
+ .#{$prefix}-pl-#{list.nth($sizes, $index)} { padding-left: #{list.nth($sizes, $index)}px !important; }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 涉及文件汇总
|
||||
|
||||
| 文件 | 修改内容 |
|
||||
|------|---------|
|
||||
| `package.json` | `sass-loader` 版本 `^10.3.1` → `~10.5.2` |
|
||||
| `vue.config.js` | 添加 `sassOptions.silenceDeprecations` 配置 |
|
||||
| `src/assets/style/public-class.scss` | 引入 `sass:list` 模块,`nth()` → `list.nth()` |
|
||||
|
||||
---
|
||||
|
||||
## 后续建议
|
||||
|
||||
- 当项目未来升级到 Vue CLI 5 / Webpack 5 时,可考虑将 `public.scss` 中的 `@import` 改为 `@use`(届时 `~` 前缀路径的兼容方案需要重新评估)。
|
||||
- `silenceDeprecations` 中的 `'import'` 为临时静默方案,待 `@import` 改造完成后移除。
|
||||
1241
docs/sct-base-table-refactor-design.md
Normal file
1241
docs/sct-base-table-refactor-design.md
Normal file
File diff suppressed because it is too large
Load Diff
953
docs/表格组件使用说明.md
Normal file
953
docs/表格组件使用说明.md
Normal file
@@ -0,0 +1,953 @@
|
||||
# 表格组件使用说明
|
||||
|
||||
> 基于 `page-table` + `page-dialog-form` 的新一<E696B0><E4B880>?CRUD 表格方案<E696B9><E6A188>?
|
||||
> 源码位置:`src/components/page-table/`、`src/components/page-dialog-form/`、`src/composables/`
|
||||
> 完整可运行示例:`src/views/production-master-data/factory-model/factory-area/index.vue`
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [快速开始(三步走)](#1-快速开始三步走)
|
||||
2. [完整示例代码](#2-完整示例代码)
|
||||
3. [组件 API 参考](#3-组件-api-参<><E58F82>?
|
||||
4. [Composable API 参考](#4-composable-api-参<><E58F82>?
|
||||
5. [i18n 国际化方案](#5-i18n-国际化方<E58C96><E696B9>?
|
||||
6. [常用场景速查](#6-常用场景速查)
|
||||
7. [路由配置](#7-路由配置)
|
||||
8. [API 文件写法](#8-api-文件写法)
|
||||
9. [旧代码迁移对照](#9-旧代码迁移对<E7A7BB><E5AFB9>?
|
||||
10. [常见问题排查](#10-常见问题排查)
|
||||
|
||||
---
|
||||
|
||||
## 1. 快速开始(三步走)
|
||||
|
||||
### 第一步:定义列和按钮(`created()` 中)
|
||||
|
||||
```js
|
||||
import { useTableColumns } from '@/composables/useTableColumns'
|
||||
import { useTableButtons } from '@/composables/useTableButtons'
|
||||
import { i18nMixin } from '@/composables/useI18n'
|
||||
|
||||
export default {
|
||||
mixins: [i18nMixin('page.模块<E6A8A1><E59D97>?二级模块.三级模块')],
|
||||
|
||||
created () {
|
||||
// --- 列定<E58897><E5AE9A>?---
|
||||
// 只需声明 prop <20><>?label,idx 自动补齐
|
||||
// prop: '_actions' 约定为操作列,自动渲<E58AA8><E6B8B2>?rowButtons
|
||||
this.columns = useTableColumns([
|
||||
{ prop: 'sort', label: this.key('sort'), width: 80 },
|
||||
{ prop: 'code', label: this.key('code'), minWidth: 120 },
|
||||
{ prop: 'name', label: this.key('name') },
|
||||
{ prop: '_actions', label: this.key('operation'), width: 160, fixed: 'right' }
|
||||
])
|
||||
|
||||
// --- 按钮定义 ---
|
||||
// 不再分开<E58886><E5BC80>?buttonList / tableButtonList
|
||||
const btns = useTableButtons({
|
||||
toolbar: [
|
||||
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus',
|
||||
type: 'primary', auth: '/xxx/create', onClick: this.openAdd }
|
||||
],
|
||||
row: [
|
||||
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit',
|
||||
auth: '/xxx/edit', onClick: this.openEdit },
|
||||
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete',
|
||||
color: 'danger', auth: '/xxx/delete', onClick: this.handleDelete }
|
||||
]
|
||||
}, this.$permission) // <20><>?第二个参数传入权限校验函<E9AA8C><E587BD>?
|
||||
this.toolbarButtons = btns.toolbarButtons
|
||||
this.rowButtons = btns.rowButtons
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 第二步:写模板(`<template>` 中)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<d2-container>
|
||||
<!-- 搜索<EFBFBD><EFBFBD>?-->
|
||||
<template #header>
|
||||
<el-form :inline="true" size="mini">
|
||||
<el-form-item :label="$t(key('code'))">
|
||||
<el-input v-model="search.code" :placeholder="$t(key('enter_code'))"
|
||||
clearable style="width:200px" @keyup.enter.native="onSearch" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="onSearch">
|
||||
{{ $t(key('search')) }}
|
||||
</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="onReset">
|
||||
{{ $t(key('reset')) }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<!-- 表格 + 按钮<EFBFBD><EFBFBD>?+ 分页 -->
|
||||
<page-table
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:loading="loading"
|
||||
:toolbar-buttons="toolbarButtons"
|
||||
:row-buttons="rowButtons"
|
||||
:pagination="pagination"
|
||||
help-url="/help/your-page"
|
||||
auto-height
|
||||
@page-change="onPageChange"
|
||||
@selection-change="onSelect"
|
||||
/>
|
||||
|
||||
<!-- 新增/编辑弹框 -->
|
||||
<page-dialog-form
|
||||
ref="dialogForm"
|
||||
:visible.sync="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="35%"
|
||||
:form-cols="formCols"
|
||||
:form-data="formData"
|
||||
:rules="rules"
|
||||
:submitting="submitting"
|
||||
:confirm-text="$t(key('confirm'))"
|
||||
:cancel-text="$t(key('cancel'))"
|
||||
@submit="onDialogSubmit"
|
||||
@close="onDialogClose"
|
||||
/>
|
||||
</d2-container>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 第三步:写业务方法(增删改查<E694B9><E69FA5>?
|
||||
```js
|
||||
methods: {
|
||||
// 获取列表数据
|
||||
async fetchData () {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await getList({
|
||||
...this.search,
|
||||
page_no: this.pagination.current,
|
||||
page_size: this.pagination.size
|
||||
})
|
||||
this.tableData = res.data || []
|
||||
this.pagination.total = res.count || 0
|
||||
} finally { this.loading = false }
|
||||
},
|
||||
|
||||
// 搜索 / 重置
|
||||
onSearch () { this.pagination.current = 1; this.fetchData() },
|
||||
onReset () { this.search = { code: '', name: '' }; this.pagination.current = 1; this.fetchData() },
|
||||
|
||||
// 分页变化
|
||||
onPageChange (page) {
|
||||
this.pagination.current = page.current
|
||||
this.pagination.size = page.size
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
// 新增:打开弹窗
|
||||
openAdd () {
|
||||
this.handleType = 'create'
|
||||
this.dialogTitle = this.key('add_title')
|
||||
this.$nextTick(() => {
|
||||
this.$refs.dialogForm.reset()
|
||||
this.resetForm()
|
||||
this.dialogVisible = true
|
||||
})
|
||||
},
|
||||
|
||||
// 编辑:回填表<E5A1AB><E8A1A8>? openEdit (row) {
|
||||
this.handleType = 'edit'
|
||||
this.dialogTitle = this.key('edit_title')
|
||||
this.editId = row.id
|
||||
this.formData = { code: row.code, name: row.name }
|
||||
this.dialogVisible = true
|
||||
},
|
||||
|
||||
// 提交表单
|
||||
async onDialogSubmit () {
|
||||
this.submitting = true
|
||||
try {
|
||||
if (this.handleType === 'create') {
|
||||
await createApi(this.formData)
|
||||
} else {
|
||||
await editApi({ ...this.formData, id: this.editId })
|
||||
}
|
||||
this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.dialogVisible = false
|
||||
this.fetchData()
|
||||
} finally { this.submitting = false }
|
||||
},
|
||||
|
||||
// 关闭弹窗
|
||||
onDialogClose () { this.resetForm() },
|
||||
|
||||
// 删除
|
||||
async handleDelete (row) {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t(this.key('confirm_delete')),
|
||||
this.$t(this.key('tip')),
|
||||
{ confirmButtonText: this.$t(this.key('confirm')),
|
||||
cancelButtonText: this.$t(this.key('cancel')),
|
||||
type: 'warning', closeOnClickModal: false }
|
||||
)
|
||||
await deleteApi({ id: [row.id] })
|
||||
this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.fetchData()
|
||||
} catch (e) { /* 取消或失<E68896><E5A4B1>?*/ }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 完整示例代码
|
||||
|
||||
> 📁 `src/views/production-master-data/factory-model/factory-area/index.vue`
|
||||
> 这是一<EFBFBD><EFBFBD>?*可直接运行的完整 CRUD 页面**,包含搜索栏、表格、分页、新<E38081><E696B0>?编辑弹框、删除确认<E7A1AE><E8AEA4>?
|
||||
### 模板部分
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<d2-container>
|
||||
<template #header>
|
||||
<div class="search-bar">
|
||||
<el-form :inline="true" size="mini">
|
||||
<el-form-item :label="$t(key('code'))">
|
||||
<el-input v-model="search.code" :placeholder="$t(key('enter_code'))"
|
||||
clearable style="width:200px" @keyup.enter.native="onSearch" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t(key('name'))">
|
||||
<el-input v-model="search.name" :placeholder="$t(key('enter_name'))"
|
||||
clearable style="width:200px" @keyup.enter.native="onSearch" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="onSearch">
|
||||
{{ $t(key('search')) }}
|
||||
</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="onReset">
|
||||
{{ $t(key('reset')) }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<page-table
|
||||
ref="pageTable"
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:loading="loading"
|
||||
:toolbar-buttons="toolbarButtons"
|
||||
:row-buttons="rowButtons"
|
||||
:pagination="pagination"
|
||||
help-url="/help/factory-area"
|
||||
auto-height
|
||||
@page-change="onPageChange"
|
||||
@selection-change="onSelect"
|
||||
/>
|
||||
|
||||
<page-dialog-form
|
||||
ref="dialogForm"
|
||||
:visible.sync="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="35%"
|
||||
:form-cols="formCols"
|
||||
:form-data="formData"
|
||||
:rules="rules"
|
||||
:submitting="submitting"
|
||||
:confirm-text="$t(key('confirm'))"
|
||||
:cancel-text="$t(key('cancel'))"
|
||||
@submit="onDialogSubmit"
|
||||
@close="onDialogClose"
|
||||
/>
|
||||
</d2-container>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Script 部分
|
||||
|
||||
```js
|
||||
import { useTableColumns } from '@/composables/useTableColumns'
|
||||
import { useTableButtons } from '@/composables/useTableButtons'
|
||||
import { i18nMixin } from '@/composables/useI18n'
|
||||
import { getFactoryAreaList, createFactoryArea, editFactoryArea, deleteFactoryArea }
|
||||
from '@/api/production-master-data/factory-area'
|
||||
import PageTable from '@/components/page-table'
|
||||
import PageDialogForm from '@/components/page-dialog-form'
|
||||
|
||||
export default {
|
||||
name: 'factory-area',
|
||||
components: { PageTable, PageDialogForm },
|
||||
mixins: [i18nMixin('page.production_master_data.factory_model.factory_area')],
|
||||
|
||||
data () {
|
||||
const t = this.$t.bind(this)
|
||||
const k = (s) => t(this.key(s))
|
||||
return {
|
||||
loading: false,
|
||||
submitting: false,
|
||||
tableData: [],
|
||||
selectedRows: [],
|
||||
dialogVisible: false,
|
||||
dialogTitle: '',
|
||||
editId: '',
|
||||
handleType: 'create',
|
||||
search: { code: '', name: '' },
|
||||
pagination: { current: 1, size: 10, total: 0 },
|
||||
formData: { code: '', name: '', remark: '' },
|
||||
rules: {
|
||||
code: [
|
||||
{ required: true, message: k('enter_code'), trigger: 'blur' },
|
||||
{ min: 1, max: 100, message: k('remark_length'), trigger: 'blur' }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: k('enter_name'), trigger: 'blur' },
|
||||
{ min: 1, max: 100, message: k('remark_length'), trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
columns: [],
|
||||
toolbarButtons: [],
|
||||
rowButtons: [],
|
||||
formCols: [
|
||||
[
|
||||
{ type: 'input', prop: 'code',
|
||||
label: k('code'), placeholder: k('enter_code'),
|
||||
clearable: true, style: { width: '90%' } }
|
||||
],
|
||||
[
|
||||
{ type: 'input', prop: 'name',
|
||||
label: k('name'), placeholder: k('enter_name'),
|
||||
clearable: true, style: { width: '90%' } }
|
||||
],
|
||||
[
|
||||
{ type: 'input', prop: 'remark', inputType: 'textarea',
|
||||
autosize: { minRows: 2, maxRows: 6 },
|
||||
label: k('remark'), placeholder: k('remark_required'),
|
||||
clearable: true, style: { width: '90%' } }
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.columns = useTableColumns([
|
||||
{ prop: 'sort', label: this.key('sort'), width: 80 },
|
||||
{ prop: 'code', label: this.key('code'), minWidth: 120 },
|
||||
{ prop: 'name', label: this.key('name'), minWidth: 120 },
|
||||
{ prop: 'remark', label: this.key('remark') },
|
||||
{ prop: '_actions', label: this.key('operation'), width: 160, fixed: 'right' }
|
||||
])
|
||||
const btns = useTableButtons({
|
||||
toolbar: [
|
||||
{ key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary',
|
||||
auth: '/production_master_data/factory_model/factory_area/create',
|
||||
onClick: this.openAdd }
|
||||
],
|
||||
row: [
|
||||
{ key: 'edit', label: this.key('edit'), icon: 'el-icon-edit',
|
||||
auth: '/production_master_data/factory_model/factory_area/edit',
|
||||
onClick: this.openEdit },
|
||||
{ key: 'delete', label: this.key('delete'), icon: 'el-icon-delete',
|
||||
color: 'danger',
|
||||
auth: '/production_master_data/factory_model/factory_area/delete',
|
||||
onClick: this.handleDelete }
|
||||
]
|
||||
}, this.$permission)
|
||||
this.toolbarButtons = btns.toolbarButtons
|
||||
this.rowButtons = btns.rowButtons
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
async fetchData () {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await getFactoryAreaList({
|
||||
...this.search, page_no: this.pagination.current, page_size: this.pagination.size
|
||||
})
|
||||
this.tableData = res.data || []
|
||||
this.pagination.total = res.count || 0
|
||||
} finally { this.loading = false }
|
||||
},
|
||||
|
||||
onSearch () { this.pagination.current = 1; this.fetchData() },
|
||||
onReset () { this.search = { code: '', name: '' }; this.pagination.current = 1; this.fetchData() },
|
||||
onPageChange (page) {
|
||||
this.pagination.current = page.current
|
||||
this.pagination.size = page.size
|
||||
this.fetchData()
|
||||
},
|
||||
onSelect (rows) { this.selectedRows = rows },
|
||||
|
||||
resetForm () { this.formData = { code: '', name: '', remark: '' }; this.editId = '' },
|
||||
|
||||
openAdd () {
|
||||
this.handleType = 'create'
|
||||
this.dialogTitle = this.key('add_title')
|
||||
this.$nextTick(() => {
|
||||
this.$refs.dialogForm && this.$refs.dialogForm.reset()
|
||||
this.resetForm()
|
||||
this.dialogVisible = true
|
||||
})
|
||||
},
|
||||
|
||||
openEdit (row) {
|
||||
this.handleType = 'edit'
|
||||
this.dialogTitle = this.key('edit_title')
|
||||
this.editId = row.id
|
||||
this.formData = { code: row.code, name: row.name, remark: row.remark || '' }
|
||||
this.dialogVisible = true
|
||||
},
|
||||
|
||||
async onDialogSubmit () {
|
||||
this.submitting = true
|
||||
try {
|
||||
if (this.handleType === 'create') {
|
||||
await createFactoryArea(this.formData)
|
||||
} else {
|
||||
await editFactoryArea({ ...this.formData, id: this.editId })
|
||||
}
|
||||
this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.dialogVisible = false
|
||||
this.fetchData()
|
||||
} finally { this.submitting = false }
|
||||
},
|
||||
|
||||
onDialogClose () { this.resetForm() },
|
||||
|
||||
async handleDelete (row) {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t(this.key('confirm_delete')),
|
||||
this.$t(this.key('tip')),
|
||||
{ confirmButtonText: this.$t(this.key('confirm')),
|
||||
cancelButtonText: this.$t(this.key('cancel')),
|
||||
type: 'warning', closeOnClickModal: false }
|
||||
)
|
||||
await deleteFactoryArea({ id: [row.id] })
|
||||
this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.pagination.current = Math.min(
|
||||
this.pagination.current,
|
||||
Math.ceil((this.pagination.total - 1) / this.pagination.size) || 1
|
||||
)
|
||||
this.fetchData()
|
||||
} catch (e) { /* 取消删除 / 请求失败不处<E4B88D><E5A484>?*/ }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 组件 API 参<><E58F82>?
|
||||
### 3.1 `page-table` <20><>?表格 + 按钮<E68C89><E992AE>?+ 分页
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | 类型 | 默认<E9BB98><E8AEA4>?| 说明 |
|
||||
|------|------|--------|------|
|
||||
| `columns` | `Array` | `[]` | 列定义,<E4B989><EFBC8C>?`useTableColumns()` 生成 |
|
||||
| `data` | `Array` | `[]` | 表格行数<E8A18C><E695B0>?|
|
||||
| `loading` | `Boolean` | `false` | 是否显示 loading 遮罩 |
|
||||
| `height` | `String/Number` | <20><>?| 表格高度。不传则随内容撑开;传具体数值固定高度;<E5BAA6><EFBC9B>?`'auto'` 启用自适应 |
|
||||
| `auto-height` | `Boolean` | `false` | 启用高度自适应,表格自动填满可用空<E794A8><E7A9BA>?|
|
||||
| `border` | `Boolean` | `true` | 是否带边<E5B8A6><E8BEB9>?|
|
||||
| `row-key` | `String` | `'id'` | 行唯一 key |
|
||||
| `toolbar-buttons` | `Array` | `[]` | 顶部工具栏按钮,<E992AE><EFBC8C>?`useTableButtons()` 生成 |
|
||||
| `row-buttons` | `Array` | `[]` | 行内操作按钮,由 `useTableButtons()` 生成 |
|
||||
| `pagination` | `Object` | `null` | 分页参数 `{ current, size, total }`,传了才显示分页 |
|
||||
| `table-attrs` | `Object` | `{}` | 额外透传<E9808F><E4BCA0>?`el-table` 的属<E79A84><E5B19E>?|
|
||||
| `table-listeners` | `Object` | `{}` | 额外透传<E9808F><E4BCA0>?`el-table` 的事<E79A84><E4BA8B>?|
|
||||
| `help-url` | `String` | `''` | 帮助文档跳转 URL。传了才显示工具栏右侧的问号按钮,点击新窗口打开 |
|
||||
| `help-text` | `String` | `'帮助'` | 帮助按钮文字,支<EFBC8C><E694AF>?i18n key(组件自<E4BBB6><E887AA>?`$t()` 翻译<E7BFBB><E8AF91>?|
|
||||
|
||||
#### 事件
|
||||
|
||||
| 事件<E4BA8B><E4BBB6>?| 参数 | 说明 |
|
||||
|--------|------|------|
|
||||
| `@page-change` | `{ current, size, total }` | 分页变化(切换页<E68DA2><E9A1B5>?条数<E69DA1><E695B0>?|
|
||||
| `@selection-change` | `rows: Array` | 选中行变<E8A18C><E58F98>?|
|
||||
| `@sort-change` | 透传 el-table 原生事件 | 排序变化 |
|
||||
|
||||
#### 插槽
|
||||
|
||||
| 插槽<E68F92><E6A7BD>?| 作用<E4BD9C><E794A8>?| 说明 |
|
||||
|--------|--------|------|
|
||||
| `#col-{prop}` | `{ row, index }` | 自定义列的渲染(列定义中 prop 需<><E99C80>?`slot: true`<EFBFBD><EFBFBD>?|
|
||||
| `#toolbar-extra` | <20><>?| 工具栏区域追加自定义内容 |
|
||||
| `#empty` | <20><>?| 表格空数据时的占<E79A84><E58DA0>?|
|
||||
| `#append` | <20><>?| 表格最后一行后追加 |
|
||||
| `#extra` | <20><>?| 页面底部追加区域 |
|
||||
|
||||
#### 列定义规<E4B989><E8A784>?
|
||||
```js
|
||||
// 普通列
|
||||
{ prop: 'code', label: '编码', minWidth: 120 }
|
||||
|
||||
// 操作列(约定:prop === '_actions'<27><>?{ prop: '_actions', label: '操作', width: 160, fixed: 'right' }
|
||||
|
||||
// 自定义插槽列(slot: true<75><65>?{ prop: 'status', label: '状<><E78AB6>?, slot: true, width: 100 }
|
||||
|
||||
// 复选框<E98089><E6A186>?+ 序号列(通过 useTableColumns 第二个参数)
|
||||
useTableColumns([...], { selectionWidth: 55, indexWidth: 60 })
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.2 `page-dialog-form` <20><>?增删改查弹框
|
||||
|
||||
#### Props
|
||||
|
||||
| Prop | 类型 | 默认<E9BB98><E8AEA4>?| 说明 |
|
||||
|------|------|--------|------|
|
||||
| `visible` | `Boolean` | `false` | 弹框显隐,使<EFBC8C><E4BDBF>?`.sync` 修饰<E4BFAE><E9A5B0>?|
|
||||
| `title` | `String` | `''` | 弹框标题,支<EFBC8C><E694AF>?i18n key |
|
||||
| `width` | `String` | `'35%'` | 弹框宽度 |
|
||||
| `form-cols` | `Array` | `[]` | 表单字段结构(二维数组,见下方) |
|
||||
| `form-data` | `Object` | `{}` | 表单数据对象 |
|
||||
| `rules` | `Object` | `{}` | 校验规则,与 `el-form` rules 一<><E4B880>?|
|
||||
| `label-width` | `String` | `'100px'` | label 宽度 |
|
||||
| `submitting` | `Boolean` | `false` | 提交 loading 状<><E78AB6>?|
|
||||
| `confirm-text` | `String` | `'确定'` | 确定按钮文字 |
|
||||
| `cancel-text` | `String` | `'取消'` | 取消按钮文字 |
|
||||
|
||||
#### 事件
|
||||
|
||||
| 事件<E4BA8B><E4BBB6>?| 说明 |
|
||||
|--------|------|
|
||||
| `@submit` | 表单验证通过后触发,父组件执行提交逻辑 |
|
||||
| `@close` | 弹框关闭后触<E5908E><E8A7A6>?|
|
||||
|
||||
#### 方法(通过 ref 调用<E8B083><E794A8>?
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `reset()` | 重置表单 |
|
||||
| `validate()` | 手动验证,返<EFBC8C><E8BF94>?`Promise<boolean>` |
|
||||
|
||||
#### formCols 数据结构
|
||||
|
||||
**注意:需<EFBC9A><E99C80>?`data()` 中用 `k(prop)` 提前完成 i18n 翻译**,不要传 raw key<65><79>?
|
||||
```js
|
||||
// 例:两个普通输入框 + 一个多行文本框
|
||||
formCols: [
|
||||
[
|
||||
{ type: 'input', prop: 'code',
|
||||
label: k('code'), placeholder: k('enter_code'),
|
||||
clearable: true, style: { width: '90%' } }
|
||||
],
|
||||
[
|
||||
{ type: 'input', prop: 'name',
|
||||
label: k('name'), placeholder: k('enter_name'),
|
||||
clearable: true, style: { width: '90%' } }
|
||||
],
|
||||
[
|
||||
{ type: 'input', prop: 'remark', inputType: 'textarea',
|
||||
autosize: { minRows: 2, maxRows: 6 },
|
||||
label: k('remark'), placeholder: k('remark_required'),
|
||||
clearable: true, style: { width: '90%' } }
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
**字段支持的属性:**
|
||||
|
||||
| 属<><E5B19E>?| 适用类型 | 说明 |
|
||||
|------|---------|------|
|
||||
| `type` | 全部 | `'input'`(文本输入)/ `'select'`(下拉) |
|
||||
| `prop` | 全部 | 绑定 `formData` 中的 key |
|
||||
| `label` | 全部 | 表单项标<E9A1B9><E6A087>?|
|
||||
| `placeholder` | 全部 | 占位提示 |
|
||||
| `inputType` | `input` | `'textarea'` 多行 / 不传为普<E4B8BA><E699AE>?text |
|
||||
| `autosize` | `input` | textarea <20><>?`{ minRows, maxRows }` |
|
||||
| `clearable` | 全部 | 是否可清空,默认 `true` |
|
||||
| `style` | 全部 | 样式对象 |
|
||||
| `options` | `select` | 选项数组 `[{ label, value }]` |
|
||||
| `filterable` | `select` | 是否可搜索,默认 `true` |
|
||||
|
||||
---
|
||||
|
||||
## 4. Composable API 参<><E58F82>?
|
||||
### 4.1 `useTableColumns(rawColumns, options?)`
|
||||
|
||||
**作用**:消除手动分<EFBFBD><EFBFBD>?`idx` 序号,自动识别操作列和插槽列<E6A7BD><E58897>?
|
||||
| 参数 | 类型 | 默认<E9BB98><E8AEA4>?| 说明 |
|
||||
|------|------|--------|------|
|
||||
| `rawColumns` | `Array` | <20><>?| 列定<E58897><E5AE9A>?|
|
||||
| `options.selectionWidth` | `number` | `55` | 复选框列宽,传 `0` 隐藏 |
|
||||
| `options.indexWidth` | `number` | `0` | 序号列宽,传 `0` 隐藏 |
|
||||
|
||||
```js
|
||||
const columns = useTableColumns([
|
||||
{ prop: 'code', label: '编码', width: 120 },
|
||||
{ prop: 'name', label: '名称' },
|
||||
{ prop: '_actions', label: '操作', width: 160, fixed: 'right' } // <20><>?操作<E6938D><E4BD9C>?])
|
||||
```
|
||||
|
||||
**内部约定**:`prop === '_actions'` 自动标记<E6A087><E8AEB0>?`slot: '_actions'`,由 `page-table` 渲染为操作列<E4BD9C><E58897>?
|
||||
---
|
||||
|
||||
### 4.2 `useTableButtons(options, permissionCheck?)`
|
||||
|
||||
**作用**:统一生成工具栏按钮和行内操作按钮,自动注入权限校验结果<EFBFBD><EFBFBD>?
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `options.toolbar` | `Array` | 顶部按钮列表 |
|
||||
| `options.row` | `Array` | 行内按钮列表 |
|
||||
| `permissionCheck` | `Function` | 权限函数,通常<E9809A><E5B8B8>?`this.$permission` |
|
||||
|
||||
**返回<E8BF94><E59B9E>?*:`{ toolbarButtons, rowButtons }`
|
||||
|
||||
**按钮字段<E5AD97><E6AEB5>?*
|
||||
|
||||
| 字段 | toolbar | row | 说明 |
|
||||
|------|:---:|:---:|------|
|
||||
| `key` | <20><>?| <20><>?| 唯一标识 |
|
||||
| `label` | <20><>?| <20><>?| 显示文本 |
|
||||
| `icon` | <20><>?| <20><>?| Element UI 图标 |
|
||||
| `type` | <20><>?| <20><>?| `primary`/`success`/`warning`/`danger` |
|
||||
| `color` | <20><>?| <20><>?| `'danger'` 使文字变<E5AD97><E58F98>?|
|
||||
| `auth` | <20><>?| <20><>?| 权限 key |
|
||||
| `cssStyle` | <20><>?| <20><>?| 自定义样<E4B989><E6A0B7>?|
|
||||
| `onClick` | <20><>?| <20><>?| 点击回调 |
|
||||
| `hasPermission` | <20><>?| <20><>?| **自动注入**,由权限函数计算 |
|
||||
| `needSelection` | <20><>?| <20><>?| 需选中行才能点<E883BD><E782B9>?|
|
||||
|
||||
```js
|
||||
const btns = useTableButtons({
|
||||
toolbar: [
|
||||
{ key: 'add', label: '新增', icon: 'el-icon-plus', type: 'primary',
|
||||
auth: '/xxx/create', onClick: this.openAdd }
|
||||
],
|
||||
row: [
|
||||
{ key: 'edit', label: '编辑', icon: 'el-icon-edit',
|
||||
auth: '/xxx/edit', onClick: this.openEdit },
|
||||
{ key: 'delete', label: '删除', icon: 'el-icon-delete',
|
||||
color: 'danger', auth: '/xxx/delete', onClick: this.handleDelete }
|
||||
]
|
||||
}, this.$permission)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.3 `i18nMixin(prefix)`
|
||||
|
||||
**作用**:注<EFBFBD><EFBFBD>?`key(suffix)` <20><>?`ckey(suffix)` 两个方法,消除每个页面手<E99DA2><E6898B>?`T` 常量<E5B8B8><E9878F>?`tkey` 方法<E696B9><E6B395>?
|
||||
| 方法 | 返回<E8BF94><E59B9E>?| 说明 |
|
||||
|------|--------|------|
|
||||
| `key(suffix)` | `prefix.suffix` | 当前页面<E9A1B5><E99DA2>?i18n key |
|
||||
| `ckey(suffix)` | `page.common.suffix` | 公共 i18n key(如"帮助"<22><>?确定"<22><>?取消"<22><>?|
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `prefix` | `String` | 该页面的 i18n key 前缀,如 `'page.production_master_data.factory_model.factory_area'` |
|
||||
|
||||
```js
|
||||
import { i18nMixin } from '@/composables/useI18n'
|
||||
|
||||
export default {
|
||||
mixins: [i18nMixin('page.production_master_data.factory_model.factory_area')],
|
||||
// 此后模板中用 $t(key('code')) 访问当前页面的翻<E79A84><E7BFBB>? // <20><>?$t(ckey('help')) 访问公共翻译 'page.common.help'
|
||||
// JS 中用 this.$t(this.key('code')) / this.$t(this.ckey('help'))
|
||||
}
|
||||
```
|
||||
|
||||
**`data()` 中翻译文本的技<E79A84><E68A80>?*<2A><>?
|
||||
```js
|
||||
data () {
|
||||
const t = this.$t.bind(this) // 绑定 i18n 翻译函数
|
||||
const k = (s) => t(this.key(s)) // 当前页面翻译:key + translate
|
||||
const ck = (s) => t(this.ckey(s)) // 公共翻译:ckey + translate
|
||||
|
||||
return {
|
||||
formCols: [
|
||||
[{ label: k('code'), placeholder: k('enter_code') }] // 页面<E9A1B5><E99DA2>?key
|
||||
],
|
||||
helpText: ck('help') // 公共 key
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. i18n 国际化方<E58C96><E696B9>?
|
||||
### 5.1 语言包文<E58C85><E69687>?
|
||||
| 语言 | 文件路径 |
|
||||
|------|---------|
|
||||
| 简体中<E4BD93><E4B8AD>?| `src/locales/zh-chs.json` |
|
||||
| 繁体中文 | `src/locales/zh-cht.json` |
|
||||
| 英文 | `src/locales/en.json` |
|
||||
| 日文 | `src/locales/ja.json` |
|
||||
|
||||
### 5.2 语言包结<E58C85><E7BB93>?
|
||||
<EFBFBD><EFBFBD>?`一级模<E7BAA7><E6A8A1>?<3F><>?二级模块 <20><>?三级模块` 三层嵌套<E5B58C><E5A597>?
|
||||
```json
|
||||
{
|
||||
"page": {
|
||||
"production_master_data": {
|
||||
"factory_model": {
|
||||
"factory_area": {
|
||||
"search": "查询",
|
||||
"reset": "重置",
|
||||
"code": "所区编<E58CBA><E7BC96>?,
|
||||
"name": "所区名<EFBFBD><EFBFBD>?,
|
||||
"add": "<22><>?<3F><>?,
|
||||
"edit": "<EFBFBD><EFBFBD>?<3F><>?,
|
||||
"delete": "<22><>?<3F><>?,
|
||||
"enter_code": "请输入所区编<EFBFBD><EFBFBD>?,
|
||||
"enter_name": "请输入所区名<E58CBA><E5908D>?,
|
||||
"add_title": "新增所<EFBFBD><EFBFBD>?,
|
||||
"edit_title": "编辑所<E8BE91><E68980>?,
|
||||
"confirm": "确定",
|
||||
"cancel": "取消",
|
||||
"operation_success": "操作成功"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 组件自动翻译
|
||||
|
||||
`page-table` <20><>?`page-dialog-form` 内置 `$t()`<EFBFBD><EFBFBD>?
|
||||
- **<2A><>?label** <20><>?自动翻译
|
||||
- **按钮 label** <20><>?自动翻译
|
||||
- **表单 label / placeholder** <20><>?自动翻译
|
||||
- **弹框 title / confirm / cancel** <20><>?自动翻译
|
||||
|
||||
因此页面只需传入 i18n key 字符串,组件渲染时自动替换为当前语言的文本<E69687><E69CAC>?
|
||||
### 5.4 页面中手动翻<E58AA8><E7BFBB>?
|
||||
搜索区、校验消息、`$confirm` <20><>?UI 文字需手动<E6898B><E58AA8>?`$t()`<EFBFBD><EFBFBD>?
|
||||
```vue
|
||||
<!-- 模板<EFBFBD><EFBFBD>?<EFBFBD><EFBFBD>?key() 返回 i18n key -->
|
||||
<el-form-item :label="$t(key('code'))">
|
||||
<el-input :placeholder="$t(key('enter_code'))" />
|
||||
</el-form-item>
|
||||
<el-button>{{ $t(key('search')) }}</el-button>
|
||||
```
|
||||
|
||||
```js
|
||||
// JS <20><>?this.$message.success(this.$t(this.key('operation_success')))
|
||||
this.$confirm(this.$t(this.key('confirm_delete')), this.$t(this.key('tip')), { ... })
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 常用场景速查
|
||||
|
||||
### 场景 1:自定义列渲染(状<EFBC88><E78AB6>?tag<61><67>?
|
||||
列定义加<EFBFBD><EFBFBD>?`slot: true`<EFBFBD><EFBFBD>?
|
||||
```js
|
||||
useTableColumns([
|
||||
{ prop: 'status', label: '状<EFBFBD><EFBFBD>?, slot: true, width: 100 }
|
||||
])
|
||||
```
|
||||
|
||||
模板中用 `#col-status` 插槽<E68F92><E6A7BD>?
|
||||
```vue
|
||||
<page-table :columns="columns" :data="tableData">
|
||||
<template #col-status="{ row }">
|
||||
<el-tag :type="row.status === 1 ? 'success' : 'danger'">
|
||||
{{ row.status === 1 ? '启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</page-table>
|
||||
```
|
||||
|
||||
### 场景 2:工具栏追加自定义按<E4B989><E68C89>?
|
||||
```vue
|
||||
<page-table :columns="columns" :toolbar-buttons="toolbarButtons">
|
||||
<template #toolbar-extra>
|
||||
<el-button size="mini" icon="el-icon-printer" @click="print">打印</el-button>
|
||||
</template>
|
||||
</page-table>
|
||||
```
|
||||
|
||||
### 场景 3:复选框<E98089><E6A186>?+ 序号<E5BA8F><E58FB7>?
|
||||
```js
|
||||
useTableColumns(
|
||||
[
|
||||
{ prop: 'code', label: '编码' },
|
||||
{ prop: 'name', label: '名称' }
|
||||
],
|
||||
{ selectionWidth: 55, indexWidth: 60 }
|
||||
)
|
||||
```
|
||||
|
||||
### 场景 4:带下拉选择的表<E79A84><E8A1A8>?
|
||||
```js
|
||||
formCols: [
|
||||
[
|
||||
{ type: 'select', prop: 'area_id',
|
||||
label: k('area'), placeholder: k('select_area'),
|
||||
options: [{ label: 'A厂区', value: 1 }, { label: 'B厂区', value: 2 }],
|
||||
clearable: true, style: { width: '90%' } }
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
### 场景 5:批量删除(工具<E5B7A5><E585B7>?+ 需要选中行)
|
||||
|
||||
```js
|
||||
useTableButtons({
|
||||
toolbar: [
|
||||
{ key: 'batchDelete', label: '批量删除', icon: 'el-icon-delete',
|
||||
type: 'danger', auth: '/xxx/batch-delete',
|
||||
needSelection: true, // <20><>?需要选中行才能点<E883BD><E782B9>? onClick: this.batchDelete }
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
### 场景 6:表格自适应高度
|
||||
|
||||
只需<EFBFBD><EFBFBD>?`auto-height` 属性:
|
||||
|
||||
```vue
|
||||
<page-table ... auto-height />
|
||||
```
|
||||
|
||||
表格高度会自动填<EFBFBD><EFBFBD>?`d2-container` <20><>?body 区域剩余空间,窗<EFBC8C><E7AA97>?resize / 侧栏折叠时自动重算<E9878D><E7AE97>?
|
||||
### 场景 7:帮助按<E58AA9><E68C89>?
|
||||
<EFBFBD><EFBFBD>?`help-url` 传值即可在工具栏最右侧显示问号帮助按钮,点击在新窗口打开帮助文档<E69687><E6A1A3>?
|
||||
```vue
|
||||
<page-table ... help-url="/help/factory-area" :help-text="$t(ckey('help'))" />
|
||||
```
|
||||
|
||||
按钮文字通过 `help-text` prop 支持 i18n。推荐使用公<E794A8><E585AC>?key `page.common.help`(模板中<EFBFBD><EFBFBD>?`$t(ckey('help'))`),所有页面共享,无需每个模块重复定义<EFBFBD><EFBFBD>?
|
||||
不传 `help-url` 或传空字符串则不显示帮助按钮<E68C89><E992AE>?
|
||||
---
|
||||
|
||||
## 7. 路由配置
|
||||
|
||||
```js
|
||||
// src/router/modules/production-master-data.js
|
||||
import layoutHeaderAside from '@/layout/header-aside'
|
||||
|
||||
const meta = { auth: true }
|
||||
const _import = require('@/libs/util.import.' + process.env.NODE_ENV)
|
||||
|
||||
export default {
|
||||
path: '/production_master_data',
|
||||
component: layoutHeaderAside,
|
||||
children: (pre => [
|
||||
{
|
||||
path: 'factory_model/factory_area',
|
||||
name: `${pre}factory_model-factory_area`,
|
||||
meta: { ...meta, cache: true, title: '工厂区域' },
|
||||
component: _import('production-master-data/factory-model/factory-area')
|
||||
}
|
||||
])('production_master_data-')
|
||||
}
|
||||
```
|
||||
|
||||
之后<EFBFBD><EFBFBD>?`src/router/routes.js` 中引入该模块并加<E5B9B6><E58AA0>?`frameIn` 数组<E695B0><E7BB84>?
|
||||
```js
|
||||
import productionConfiguration from './modules/production-master-data'
|
||||
|
||||
const frameIn = [
|
||||
// ... 其他路由 ...
|
||||
productionConfiguration
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. API 文件写法
|
||||
|
||||
```js
|
||||
// src/api/production-master-data/factory-area.js
|
||||
import { request } from '@/api/_service'
|
||||
|
||||
const BASE = 'production_master_data/factory_model/factory_area/'
|
||||
|
||||
function apiParams (method, data = {}) {
|
||||
return {
|
||||
method: `production_master_data_factory_model_factory_area_${method}`,
|
||||
platform: 'background',
|
||||
...data
|
||||
}
|
||||
}
|
||||
|
||||
export function getFactoryAreaList (data) {
|
||||
return request({
|
||||
url: BASE + 'list',
|
||||
method: 'get',
|
||||
params: apiParams('list', data)
|
||||
})
|
||||
}
|
||||
|
||||
export function createFactoryArea (data) {
|
||||
return request({
|
||||
url: BASE + 'create',
|
||||
method: 'post',
|
||||
data: apiParams('create', data)
|
||||
})
|
||||
}
|
||||
|
||||
export function editFactoryArea (data) {
|
||||
return request({
|
||||
url: BASE + 'edit',
|
||||
method: 'put',
|
||||
data: apiParams('edit', data)
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteFactoryArea (data) {
|
||||
return request({
|
||||
url: BASE + 'delete',
|
||||
method: 'delete',
|
||||
data: apiParams('delete', data)
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 旧代码迁移对<E7A7BB><E5AFB9>?
|
||||
| 旧写<E697A7><E58699>?| 新写<E696B0><E58699>?|
|
||||
|--------|--------|
|
||||
| 手动构建 `columns: [{ idx: 0, attrs: { prop, label } }]` | `useTableColumns([{ prop, label }])` |
|
||||
| `buttonList: [...]` + `tableButtonList: [...]` 分两<E58886><E4B8A4>?| `useTableButtons({ toolbar: [...], row: [...] })` |
|
||||
| `<sct-base-table>` + `<sct-base-dialog>` + `<SctBaseForm>` 三层 | `<page-table>` + `<page-dialog-form>` 两层 |
|
||||
| `<sct-form-search>` 组件 | 原生 `<el-form :inline>` |
|
||||
| `<sct-back-to-top>` 组件 | 需要时自行添加 |
|
||||
| 分页需要额<E8A681><E9A29D>?`<page-footer>` | `page-table` 内置分页 |
|
||||
| 每个页面定义 `T` 常量 + `tkey()` 方法 | `mixins: [i18nMixin(prefix)]`,使<EFBFBD><EFBFBD>?`this.key('xxx')` |
|
||||
| 表单字段<E5AD97><E6AEB5>?i18n raw key,子组件翻译 | `data()` 中用 `k(prop)` 提前翻译 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 常见问题排查
|
||||
|
||||
### Q1:弹框打开后不显示内容<E58685><E5AEB9>?
|
||||
确认 `formCols` 中的 `label` <20><>?`placeholder` 是否<E698AF><E590A6>?`data()` 阶段已翻译。子组件 `page-dialog-form` 会调<E4BC9A><E8B083>?`$t()` 处理 label,但建议<E5BBBA><E8AEAE>?`data()` 阶段就用 `k()` 提前翻译好,避免 webpack HMR 缓存问题<E997AE><E9A298>?
|
||||
### Q2:表格高度自适应不生效?
|
||||
|
||||
确认 `d2-container` <20><>?body 区域高度被正确约束(flex 填充)。如<E38082><E5A682>?`d2-container` 本身<E69CAC><E8BAAB>?`overflow: auto` 或其他高度约束问题,`page-table` <20><>?`height: 100%` 会失效。给 `d2-container` <20><>?body 部分<E983A8><E58886>?`overflow: hidden` 通常可解决<E8A7A3><E586B3>?
|
||||
### Q3:权限校验有按钮不显示?
|
||||
|
||||
`useTableButtons` 的第二个参数必须<E5BF85><E9A1BB>?`this.$permission`。如果项目没有注册这个全局方法,可以在 `useTableButtons` 中传入一个返<E4B8AA><E8BF94>?`true` 的占位函数:`() => true`<EFBFBD><EFBFBD>?
|
||||
### Q4:新增一条后页码不跳回第一页?
|
||||
|
||||
<EFBFBD><EFBFBD>?`onDialogSubmit` 成功后调<E5908E><E8B083>?`this.fetchData()` 前,如果删除了当前页最后一行导<E8A18C><E5AFBC>?`total - 1` 超出范围,需手动修正页码<E9A1B5><E7A081>?
|
||||
```js
|
||||
this.pagination.current = Math.min(
|
||||
this.pagination.current,
|
||||
Math.ceil((this.pagination.total - 1) / this.pagination.size) || 1
|
||||
)
|
||||
```
|
||||
|
||||
### Q5:表单验证不提示错误文字<E69687><E5AD97>?
|
||||
确认 `page-dialog-form` <20><>?`<style>` 块存在(默认 22px `margin-bottom` + `position: absolute` 错误文字)。如果表单项之间被其他样式覆盖,检查是否有全局 CSS 重置<E9878D><E7BDAE>?`.el-form-item` <20><>?margin<69><6E>?
|
||||
### Q6:如何新增一<E5A29E><E4B880>?CRUD 页面最快?
|
||||
|
||||
1. 复制 `src/views/production-master-data/factory-model/factory-area/index.vue`
|
||||
2. 替换 API 引用(`import { getList, create, edit, ... } from '@/api/xxx'`<EFBFBD><EFBFBD>?3. 修改 `i18nMixin` 参数、`columns`、`formCols`、`rules`
|
||||
4. <20><>?`zh-chs.json` <20><>?`en.json` 中添加语言<E8AFAD><E8A880>?5. 添加路由配置
|
||||
|
||||
平均 10 分钟即可完成一个标<E4B8AA><E6A087>?CRUD 页面<E9A1B5><E99DA2>?
|
||||
Reference in New Issue
Block a user