diff --git a/README.md b/README.md index 455adae6..e78abffb 100644 --- a/README.md +++ b/README.md @@ -1,192 +1,270 @@ -![banner](https://raw.githubusercontent.com/d2-projects/d2-admin/master/docs/image/banner.png) +# MES-UI -

- - - - - - - -

-

- - - DeepScan grade -

+基于 [D2 Admin](https://github.com/d2-projects/d2-admin)(Vue 2 + Element UI)的企业级中后台前端项目。 -[D2Admin](https://github.com/d2-projects/d2-admin) is a fully open source and free enterprise back-end product front-end integration solution, using the latest front-end technology stack, javascript files loading of local first screen less than 60kb, has prepared most of the project preparations, and with a lot of sample code to help the management system agile development. +--- -[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/d2-projects/d2-admin) +## 项目目录结构 -[中文](https://github.com/d2-projects/d2-admin/blob/master/README.zh.md) | **English** - -## Preview - -![Deploy preview](https://github.com/d2-projects/d2-admin/workflows/Deploy%20preview/badge.svg) -[![Netlify Status](https://api.netlify.com/api/v1/badges/a5dd4bbd-da3f-4145-98a9-8012577bdcf5/deploy-status)](https://app.netlify.com/sites/d2-admin/deploys) - -The following access addresses are built and deployed by the latest master branch code at the same time. The access effect is completely consistent. Please select the appropriate access link according to your own network situation. - -| server | link | server | -| --- | --- | --- | -| d2.pub | [Link](https://d2.pub/d2-admin/preview) | China server | -| github | [Link](https://d2-projects.github.io/d2-admin) | GitHub pages | -| netlify | [Link](https://d2-admin.netlify.com) | Netlify CDN | - -## Document - -[document on https://d2.pub](https://d2.pub/doc/d2-admin/) - -## Features - -* Build with vue-cli3 -* First screen loading waiting animation -* Five themes -* Built-in UEditor rich text editor -* Detailed documentation -* Login and logout -* Separate routing and menu settings -* Foldable sidebar -* Multi-national language -* Rich text editor -* Markdown editor -* full screen -* Fontawesome icon library -* Icon selector -* Automatically register SVG icon -* Simulation data -* Clipboard package -* Chart library -* Time and date calculation tool -* Import Excel ( xlsx + csv ) -* Data export Excel ( xlsx + csv ) -* Data export text -* Digital animation -* Drag and drop the size of the block layout -* Grid layout for drag and resize and position -* Out-of-the-box page layout components -* Load and parse markdown files -* GitHub style markdown display component -* markdown internal code highlighting -* Expanded Baidu cloud link resolution and optimized display for markdown -* Right click menu component -* Custom scrollbars and scrolling controls -* Common style extraction, convenient theme customization -* Support temporary menu configuration -* System function display module `1.1.4 +` -* Multi-tab mode `1.1.4 +` -* Beautify the scroll bar `1.1.4 +` -* json view `1.1.4 +` -* cookie wrapper `1.1.5 +` -* Multi-tab global control API `1.1.5 +` -* Menu Global Control API `1.1.5 +` -* Multi-tab page close control support right-click menu `1.1.10 +` -* Modular global state management `1.2.0 +` -* Multiple data persistence methods: distinguish users, distinguish routes, page data snapshot function `1.2.0 +` -* Support for menu system that jumps out of external links `1.2.0 +` -* Support menu svg icon `1.3.0 +` -* Logging and error catching `1.3.0 +` -* Global menu search `1.3.0 +` -* Custom login redirect `1.3.0 +` -* Switch global base component size `1.4.0 +` -* Page loading progress bar `1.4.1 +` -* Adaptive top menu bar `1.4.7 +` -* Support for merging cells when exporting xslx `1.5.4 +` -* Multiple tabs support drag and drop sorting `1.8.0 +` -* load only local JavaScript code less than 60kb on the homepage `1.8.0 +` -* Built in build file volume checking tool `1.8.0 +` -* Example of multi page `1.23.0 +` -* Split chunks `1.23.0 +` - -## Other synchronous repositories - -| type | link | -| --- | --- | -| gitee | [https://gitee.com/d2-projects/d2-admin](https://gitee.com/d2-projects/d2-admin) | -| coding | [https://d2-projects.coding.net/p/d2-projects/d/d2-admin/git](https://d2-projects.coding.net/p/d2-projects/d/d2-admin/git) | - -## Other versions - -| Name | HomePage | Preview | Introduction | -| --- | --- | --- | --- | -| Starter template | [Link](https://github.com/d2-projects/d2-admin-start-kit) | [Link](https://d2.pub/d2-admin-start-kit/preview) | The simplest version | - -## Open source backend implementation - -> The backend is contributed by the open source community. The latest version of D2Admin is not guaranteed. Please contact its open source author for related usage issues. - -| Name | technology | HomePage | Preview | Introduction | -| --- | --- | --- | --- | --- | -| django-vue-admin-pro | Django | [Link](https://github.com/dvadmin-pro/django-vue-admin-pro) | [Link](http://demo.pro.django-vue-admin.com) | Django + Jwt + D2Admin | -| boot-admin | SpringBoot | [Link](https://github.com/hb0730/boot-admin) | [Link](http://admin.hb0730.com/) | Management system based on SpringBoot | -| FlaskPermission | Flask | [Link](https://github.com/huguodong/flask-permission) | [Link](http://47.97.218.139:9999) | Permission management based on Flask | -| CareyShop | ThinkPHP5 | [Link](https://github.com/dnyz520/careyshop-admin) | [Link](https://demo.careyshop.cn/admin/) | High Performance Mall Framework System for CareyShop | -| jiiiiiin-security | Spring Boot | [Link](https://github.com/Jiiiiiin/jiiiiiin-security) | [Link](https://github.com/Jiiiiiin/jiiiiiin-security) | Content management infrastructure projects | -| Taroco | Spring Cloud | [Link](https://github.com/liuht777/Taroco) | [Link](http://111.231.192.110/) | Complete microservice enterprise solution | -| Aooms | Spring Cloud | [Link](https://gitee.com/cyb-javaer/Aooms) | [Link](https://www.yuboon.com/Aooms) | Extremely fast microservice development, not just as simple as JFinal | -| GOA | Beego | [Link](https://github.com/Qsnh/goa) | [Link](http://goaio.vip/) | Online question answering system based on Beego + Vue | -| CMDB | Django | [Link](https://github.com/CJFJack/django_vue_cmdb) | [Link](https://mp.weixin.qq.com/s?__biz=MzU1OTYzODA4Mw==&mid=2247484250&idx=1&sn=981024ac0580d8a3eba95742bd32b268) | authority system with dynamic menu | - -## Community projects - -> These projects are contributed by the open source community and are not guaranteed to use the latest version of D2Admin. Please contact their open source authors for related usage questions. - -| Name | HomePage | Preview | Introduction | -| --- | --- | --- | --- | -| d2-admin-xiya-go-cms | [Link](https://github.com/d2-projects/d2-admin-xiya-go-cms) | [Link](https://d2.pub/d2-admin-xiya-go-cms/preview) | D2Admin + authority system + dynamic router | -| d2-advance | [Link](https://github.com/d2-projects/d2-advance) | [Link](https://d2.pub/d2-advance/preview) | Technical exploration inspired by D2Admin | -| d2-crud-plus | [Link](https://github.com/greper/d2-crud-plus) | [Link](http://qiniu.veryreader.com/D2CrudPlusExample/index.html) | Easy development of crud function | -| d2-crud | [Link](https://github.com/d2-projects/d2-crud) | [Link]() | Encapsulation of common operations in tables | -| d2-admin-pm | [Link](https://github.com/wjkang/d2-admin-pm) | [Link](http://jaycewu.coding.me/d2-admin-pm) | RBAC privilege management solution based on D2Admin | -| LanBlog | [Link](https://github.com/sinksmell/LanBlog) | [Link](http://47.101.222.133/) | Vue + Beego restful api personal blog system | -| d2-admin-start-kit-plus | [Link](https://github.com/hank-cp/d2-admin-start-kit-plus) | [Link](https://github.com/hank-cp/d2-admin-start-kit-plus) | D2Admin Start kit modular version | -| d2-ribbons | [Link](https://github.com/d2-projects/d2-ribbons) | [Link](https://github.com/d2-projects/d2-ribbons) | Open source project logo Library | - -## Badge - -If your open source project is based on D2Admin development, please add the following badge to your README: - - - - - -Copy the following code into the README to: - -``` html - +``` +mes-ui/ +├── .github/ # GitHub 相关配置 +├── docs/ # 项目文档 +├── public/ # 静态资源(不经过 webpack 处理) +├── src/ # PC 端业务源码 +│ ├── api/ # 接口请求层 +│ ├── assets/ # 静态资源(经 webpack 处理) +│ ├── components/ # 公共组件 +│ ├── composables/ # 可复用逻辑函数 +│ ├── layout/ # 页面布局 +│ ├── libs/ # 工具函数 +│ ├── locales/ # 国际化语言包 +│ ├── menu/ # 菜单配置 +│ ├── plugin/ # Vue 插件 +│ ├── router/ # 路由配置 +│ ├── store/ # Vuex 状态管理 +│ └── views/ # 业务页面 +├── src.mobile/ # 移动端业务源码 +├── .browserslistrc # 浏览器兼容配置 +├── .editorconfig # 编辑器统一配置 +├── .env / .env.development / .env.preview # 环境变量 +├── .eslintignore / .eslintrc.js # ESLint 配置 +├── .gitignore # Git 忽略配置 +├── .postcssrc.js # PostCSS 配置 +├── babel.config.js # Babel 配置 +├── jest.config.js # Jest 单元测试配置 +├── jsconfig.json # VS Code 路径别名提示 +├── package.json # 项目依赖与脚本 +├── pnpm-lock.yaml # pnpm 依赖锁定文件 +├── vue.config.js # Vue CLI 构建配置 +└── README.md # 项目说明(本文件) ``` -At the same time, you can report your project to us. We will place the excellent project in D2Admin and help you publicize it. +--- -## Contributor +## 各目录详解 -* [@FairyEver](https://github.com/FairyEver) -* [@sunhaoxiang](https://github.com/sunhaoxiang) -* [@Aysnine](https://github.com/Aysnine) -* [@luchaohai](https://github.com/luchaohai) -* [@han-feng](https://github.com/han-feng) -* [@rongxingsun](https://github.com/rongxingsun) -* [@dnyz520](https://github.com/dnyz520) +### `.github/` -## Become a sponsor +GitHub 相关配置,包含 Issue 模板和 CI/CD 工作流(`workflows/`)。 -[Sponsor me on afdian.net](https://afdian.net/@fairyever) +### `docs/` -## Sponsor +项目文档目录,存放变更日志、修复记录等 Markdown 文档。子目录 `image/` 存放文档引用的图片。 -**cochlea** | **Baron** | **苦行僧** | **吴地安宁** | **KingDong** | **sunyongmofang** +| 文档 | 说明 | +|------|------| +| [表格组件使用说明](./docs/表格组件使用说明.md) | page-table / page-dialog-form 的完整使用手册 | +| [sct-base-table 重构方案](./docs/sct-base-table-refactor-design.md) | 旧 sct-base-table → 新架构的设计文档 | +| [sass-deprecation-fixes.md](./docs/sass-deprecation-fixes.md) | Sass 废弃警告修复记录 | +| [CHANGELOG.md](./docs/CHANGELOG.md) | 项目变更日志 | -## Visitor +### `public/` -![Total visitor](https://visitor-badge.glitch.me/badge?page_id=d2-projects.d2-admin) +**静态资源目录**,文件会原样复制到构建产物中,不经过 webpack 编译。 -> Total visitor since 2019.08.27 +| 子目录 | 作用 | +|--------|------| +| `lib/UEditor/` | 百度 UEditor 富文本编辑器(第三方库,通过 ` +``` + +#### 新代码(使用 `page-table` 便捷组合体) + +```vue + + + +``` + +### 5.2 复杂自定义页面(检验单管理) + +> 源文件:`views/quality_control/xqc/inspection_order_manage/components/PageMain/index.vue` + +这个页面工具栏有 10 个自定义按钮 + 列筛选器 + 多处自定义事件,旧代码直接用了 `vxe-table` 绕过了 `sct-base-table`。 + +#### 新代码(使用底层组件自由组合) + +```vue + +``` + +### 5.3 带展开行的页面(库位管理) + +```vue + +``` + +--- + +## 6. 文件清单 + +### 6.1 新增文件 + +| 文件 | 类型 | 行数估计 | 说明 | +|------|:---:|:---:|------| +| `src/composables/useTableColumns.js` | 逻辑 | ~40 | 列定义工厂,自动补 idx | +| `src/composables/useTableButtons.js` | 逻辑 | ~60 | 按钮定义工厂,自动权限过滤 | +| `src/composables/useTableSelection.js` | 逻辑 | ~35 | 选中行管理 | +| `src/composables/usePagination.js` | 逻辑 | ~50 | 分页逻辑 | +| `src/composables/usePageTable.js` | 逻辑 | ~70 | 表格数据+分页+刷新一站式 | +| `src/composables/index.js` | 逻辑 | ~10 | 统一导出 | +| `src/components/sct-table/index.vue` | 组件 | ~60 | 纯表格 | +| `src/components/sct-toolbar/index.vue` | 组件 | ~80 | 工具栏 | +| `src/components/sct-action-buttons/index.vue` | 组件 | ~50 | 行内操作按钮 | +| `src/components/sct-expand/index.vue` | 组件 | ~50 | 展开行详情 | +| `src/components/sct-batch-actions/index.vue` | 组件 | ~40 | 批量操作栏 | +| `src/components/page-dialog-form/index.vue` | 组件 | ~100 | 增删改查弹框一体 | +| `src/components/page-table/index.vue` | 组件 | ~100 | 便捷组合体(80% 页面用这个) | + +**总计:约 745 行新代码**(旧 sct-base-table 215 行,删除 ~100 行死代码后实际上只有 ~100 行有效代码) + +### 6.2 修改文件 + +| 文件 | 修改内容 | +|------|---------| +| `src/components/sct-base-table/index.vue` | 删除或标记 `@deprecated`,重定向到新组件 | +| 100+ 个 PageMain/index.vue | 按页面类型批量替换为 page-table / sct-table+toolbar | + +--- + +## 7. 风险与回滚策略 + +### 7.1 风险 + +| 风险 | 概率 | 影响 | 缓解措施 | +|------|:---:|:---:|------| +| 新组件 bug 影响线上 | 低 | 高 | 分模块灰度迁移,先迁移"系统设置"模块验证 | +| 性能回退(多一层组件) | 极低 | 低 | 新组件均为无渲染函数式组件,零额外开销 | +| 开发者学习成本 | 中 | 中 | `page-table` API 刻意靠近旧组件,降低迁移心智负担 | + +### 7.2 回滚策略 + +- 旧 `sct-base-table` 保留不删,标记 `@deprecated` +- 每个模块迁移后在路由配置中可独立切回旧组件 +- 使用 Vue 的 `defineAsyncComponent` 做新旧切换的 feature flag + +--- + +## 8. 工时估算 + +| 阶段 | 内容 | 预估时间 | +|------|------|:---:| +| 阶段 0 | 创建 composables + 核心组件 | 0.5 天 | +| 阶段 1 | 创建 page-table 便捷组合体 | 0.5 天 | +| 阶段 2 | 迁移「系统设置」模块(6 页)验证 | 0.5 天 | +| 阶段 3 | 迁移「生产配置」(15 页) | 1 天 | +| 阶段 4 | 迁移「设备模型」(14 页) | 1 天 | +| 阶段 5 | 迁移「计划与生产」(10 页) | 1 天 | +| 阶段 6 | 迁移「质量管理」(26 页) | 2 天 | +| 阶段 7 | 迁移「数据中台」(8 页) | 0.5 天 | +| 阶段 8 | 迁移「仓储管理」(25 页) | 2 天 | +| 阶段 9 | 迁移「SCADA 管理」(10 页) | 1 天 | +| 阶段 10 | 迁移特殊页面(检验单、鹰眼等) | 1 天 | +| **合计** | | **约 11 天** | + +> 注:与搬迁工作并行进行,每个模块搬迁时顺便替换。 + +--- + +## 附录 A:完整的 buttonList 到 toolbarButtons 映射 + +```js +// 旧 buttonList 结构 +buttonList: [ + { + label: '新增', + size: 'mini', + icon: 'el-icon-plus', + type: 'primary', + auth: '/xxx/create', + handle: this.openDialog, + cssStyle: { background: '#3CBA92' }, + noShow: this.someCondition, + } +] + +// 新 toolbarButtons 结构 +toolbarButtons: [ + { + key: 'add', + label: this.$t('新增'), + icon: 'el-icon-plus', + type: 'primary', + auth: '/xxx/create', + onClick: openDialog, + // cssStyle 通过 type 预设色系,自定义色系用 color prop + visible: computed(() => someCondition), + } +] +``` + +## 附录 B:完整的 columns 结构变化 + +```js +// 旧 —— 命令式 +{ idx: 0, attrs: { prop: 'sort', label: '排序' } } +{ idx: 5, slot: 'handle', attrs: { label: '操作' } } +{ idx: 3, slot: 'status', headerSlot: 'status_header', attrs: { prop: 'status', label: '状态' } } + +// 新 —— 声明式 +{ prop: 'sort', label: '排序' } +{ prop: '_actions', label: '操作' } // _actions 约定为操作列 +{ prop: 'status', label: '状态', slot: true, headerSlot: 'status_header' } // slot: true 启用插槽 +``` + +--- + +## 📖 使用指南 + +> 本节基于已落地的实际代码编写。源码位置:`src/components/page-table/`、`src/components/page-dialog-form/`、`src/composables/`。 +> +> 完整可运行示例参考:`src/views/production-configuration/factory-model/factory-area/index.vue` + +--- + +### 快速开始(三步走) + +**第一步**:在 `created()` 中用 `useTableColumns` 声明列、`useTableButtons` 声明按钮: + +```js +import { useTableColumns } from '@/composables/useTableColumns' +import { useTableButtons } from '@/composables/useTableButtons' + +created () { + // 列定义 —— 不再手动分配 idx + this.columns = useTableColumns([ + { prop: 'sort', label: '排序', width: 80 }, + { prop: 'code', label: '编码', minWidth: 120 }, + { prop: 'name', label: '名称', minWidth: 120 }, + { prop: 'remark', label: '备注' }, + { prop: '_actions', label: '操作', width: 160, fixed: 'right' } // ← 操作列 + ]) + + // 按钮定义 —— 不再分开写 buttonList / tableButtonList + 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) + this.toolbarButtons = btns.toolbarButtons + this.rowButtons = btns.rowButtons +} +``` + +**第二步**:模板中直接用 `` + ``: + +```vue + +``` + +**第三步**:写业务方法(fetchData / 增删改),和旧代码完全一致: + +```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 } + }, + + onPageChange (page) { + this.pagination.current = page.current + this.pagination.size = page.size + this.fetchData() + }, + + // 新增 + openAdd () { + this.handleType = 'create' + this.dialogTitle = '新 增' + this.$nextTick(() => { + this.$refs.dialogForm.reset() + this.formData = { code: '', name: '' } + this.dialogVisible = true + }) + }, + + // 编辑 + openEdit (row) { + this.handleType = 'edit' + this.dialogTitle = '编 辑' + 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 create(this.formData) + } else { + await edit({ ...this.formData, id: this.editId }) + } + this.$message.success('操作成功') + this.dialogVisible = false + this.fetchData() + } finally { this.submitting = false } + }, + + // 删除 + async handleDelete (row) { + try { + await this.$confirm('确定要执行该操作吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }) + await del({ id: [row.id] }) + this.$message.success('操作成功') + this.fetchData() + } catch (e) { /* 用户取消不处理 */ } + } +} +``` + +--- + +### 完整可运行示例 + +> 📁 `src/views/production-configuration/factory-model/factory-area/index.vue` + +```vue + + + +``` + +--- + +### API 速查 + +#### `useTableColumns(rawColumns, options?)` + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| rawColumns | Array | — | 列定义,字段同 `el-table-column` 属性 | +| options.selectionWidth | number | 55 | 复选框列宽,传 0 不显示 | +| options.indexWidth | number | 0 | 序号列宽,传 0 不显示 | + +**约定**:`prop: '_actions'` 自动映射为操作列插槽,由 `page-table` 自动渲染 `rowButtons`。 + +#### `useTableButtons(options, permissionCheck?)` + +| 参数 | 类型 | 说明 | +|------|------|------| +| options.toolbar | Array | 顶部工具栏按钮 | +| options.row | Array | 行内操作按钮 | +| permissionCheck | Function | 权限函数,默认 `() => true`,通常传 `this.$permission` | + +返回值 `{ toolbarButtons, rowButtons }`。 + +**按钮字段**: + +| 字段 | 说明 | +|------|------| +| key | 唯一标识 | +| label | 显示文本 | +| icon | Element UI 图标名 | +| type | `primary` / `success` / `warning` / `danger` | +| color | 行内按钮专用:`'danger'` 显示红色 | +| auth | 权限 key(传给 `$permission` 检查) | +| onClick | 点击回调 | +| hasPermission | **自动注入**,由 `permissionCheck(auth)` 计算 | + +#### `page-table` — 组件 Props + +| Prop | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| columns | Array | `[]` | 列定义(由 useTableColumns 生成) | +| data | Array | `[]` | 表格数据 | +| loading | Boolean | false | loading 遮罩 | +| height | String/Number | — | 表格高度 | +| toolbarButtons | Array | `[]` | 顶部按钮(由 useTableButtons 生成) | +| rowButtons | Array | `[]` | 行内按钮(由 useTableButtons 生成) | +| pagination | Object | null | 传 `{ current, size, total }` 才显示分页 | +| border | Boolean | true | 是否带边框 | +| rowKey | String | `'id'` | 行 key | + +**事件**:`@page-change`、`@selection-change`,同时透传 `el-table` 原生事件。 + +**插槽**:`#col-{prop}` 自定义列渲染、`#toolbar-extra` 工具栏追加、`#empty` / `#append` / `#extra`。 + +#### `page-dialog-form` — 组件 Props + +| Prop | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| visible | Boolean | false | `.sync` 绑定 | +| title | String | `''` | 弹框标题 | +| width | String | `'35%'` | 弹框宽度 | +| formCols | Array | `[]` | 表单字段(二维数组,每行一个子数组) | +| formData | Object | `{}` | 表单数据 | +| rules | Object | `{}` | 校验规则(el-form rules) | +| labelWidth | String | `'100px'` | label 宽度 | +| submitting | Boolean | false | 提交中 loading | +| confirmText | String | `'确定'` | 确认按钮文字 | +| cancelText | String | `'取消'` | 取消按钮文字 | + +**方法**(通过 `ref` 调用):`reset()` 重置表单、`validate()` 返回 Promise。 + +**formCols 字段项**: + +| 字段 | 说明 | +|------|------| +| type | `'input'`(默认 input)/ `'select'` | +| prop | 绑定 `formData.prop` 的 key | +| label | 表单项标签 | +| placeholder | 占位文本 | +| inputType | `textarea` 时启用多行输入 | +| autosize | textarea 的 `{ minRows, maxRows }` | +| style | 样式对象,如 `{ width: '90%' }` | +| options | type 为 `'select'` 时的选项数组 `[{ label, value }]` | + +--- + +### 常用场景速查 + +**场景 1:自定义列渲染(如状态显示 tag)** + +```vue + + + +``` + +列定义中加入 `slot: true`: + +```js +useTableColumns([ + { prop: 'status', label: '状态', slot: true, width: 100 }, +]) +``` + +**场景 2:工具栏追加自定义内容** + +```vue + + + +``` + +**场景 3:序号列** + +```js +useTableColumns( + [{ prop: 'code', label: '编码' }], + { selectionWidth: 55, indexWidth: 60 } // 开启复选框 + 序号列 +) +``` + +### 路由配置 + +```js +// src/router/modules/production-configuration.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_configuration', + component: layoutHeaderAside, + children: (pre => [ + { + path: 'factory_model/factory_area', + name: `${pre}factory_model-factory_area`, + meta: { ...meta, cache: true, title: '工厂区域' }, + component: _import('production-configuration/factory-model/factory-area') + } + ])('production_configuration-') +} +``` + +### 旧代码迁移对照 + +| 旧写法 | 新写法 | +|--------|--------| +| 手动 `columns: [{ idx: 0, attrs: { prop, label } }]` | `useTableColumns([{ prop, label }])` | +| `buttonList: [...]` + `tableButtonList: [...]` 分两套 | `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` 组件 | 需要时自行添加 | +| 分页需额外 `page-footer` 组件 | `page-table` 内置分页 | + +--- + +### 国际化 (i18n) 使用说明 + +**组件层自动翻译**:`page-table` 和 `page-dialog-form` 对所有 `label`、`placeholder`、`title` 等文本属性自动调用 `$t()` 翻译。因此页面只需传入 i18n key,组件会自动渲染翻译后的文本。如果传入的是普通字符串(非 i18n key),`$t()` 会原样返回,不会报错。 + +**页面层用法**: + +```js +// 约定:每个页面定义一个 T 常量作为该页面的 i18n key 前缀 +const T = 'page.production_configuration.factory_model.factory_area' + +// 列定义 —— 传 i18n key,组件自动翻译 +columns = useTableColumns([ + { prop: 'sort', label: T + '.sort', width: 80 }, + { prop: 'code', label: T + '.code', minWidth: 120 }, + { prop: '_actions', label: T + '.operation', width: 160, fixed: 'right' } +]) + +// 按钮定义 —— 传 i18n key +const btns = useTableButtons({ + toolbar: [{ key: 'add', label: T + '.add', icon: 'el-icon-plus', ... }], + row: [{ key: 'edit', label: T + '.edit', ... }] +}) + +// 表单定义 —— 传 i18n key +formCols: [ + [{ type: 'input', prop: 'code', label: T + '.code', placeholder: T + '.enter_code' }] +] + +// 模板中直接用 $t() 或 $t(tkey('key')) +methods: { + tkey (key) { return T + '.' + key } +} +``` + +```vue + +``` + +**语言包文件**:在 `src/locales/zh-chs.json` 和 `src/locales/en.json` 中按页面维护: + +```json +{ + "page": { + "production_configuration": { + "factory_model": { + "factory_area": { + "search": "查询", + "code": "所区编码", + "name": "所区名称", + "add": "新 增", + "edit": "编 辑", + "delete": "删 除", + "operation_success": "操作成功" + } + } + } + } +} +``` + +**语言包目录命名规则**: + +| 语言 | 文件名 | +|------|--------| +| 简体中文 | `src/locales/zh-chs.json` | +| 繁体中文 | `src/locales/zh-cht.json` | +| 英文 | `src/locales/en.json` | +| 日文 | `src/locales/ja.json` | + +> 注意:`page-table` 和 `page-dialog-form` 已内置 `$t()` 调用,页面传 i18n key 即可自动翻译。搜索区等其他 UI 文字需要用 `$t(tkey('...'))` 手动处理。 diff --git a/docs/表格组件使用说明.md b/docs/表格组件使用说明.md new file mode 100644 index 00000000..ab01b04c --- /dev/null +++ b/docs/表格组件使用说明.md @@ -0,0 +1,953 @@ +# 表格组件使用说明 + +> 基于 `page-table` + `page-dialog-form` 的新一?CRUD 表格方案? +> 源码位置:`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-参? +4. [Composable API 参考](#4-composable-api-参? +5. [i18n 国际化方案](#5-i18n-国际化方? +6. [常用场景速查](#6-常用场景速查) +7. [路由配置](#7-路由配置) +8. [API 文件写法](#8-api-文件写法) +9. [旧代码迁移对照](#9-旧代码迁移对? +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.模块?二级模块.三级模块')], + + created () { + // --- 列定?--- + // 只需声明 prop ?label,idx 自动补齐 + // prop: '_actions' 约定为操作列,自动渲?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' } + ]) + + // --- 按钮定义 --- + // 不再分开?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) // ?第二个参数传入权限校验函? + this.toolbarButtons = btns.toolbarButtons + this.rowButtons = btns.rowButtons + } +} +``` + +### 第二步:写模板(`