feat: 新增工厂区域管理页面,修复Sass废弃警告
1. 新增生产配置-工厂模型-工厂区域完整CRUD页面 2. 新增通用表格、弹窗表单、i18n工具组件 3. 升级sass-loader并修复Sass废弃警告 4. 添加文档记录Sass迁移修复细节
This commit is contained in:
424
README.md
424
README.md
@@ -1,192 +1,270 @@
|
|||||||

|
# MES-UI
|
||||||
|
|
||||||
<p align="center">
|
基于 [D2 Admin](https://github.com/d2-projects/d2-admin)(Vue 2 + Element UI)的企业级中后台前端项目。
|
||||||
<a href="https://github.com/d2-projects/d2-admin/stargazers" target="_blank"><img src="https://img.shields.io/github/stars/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/network/members" target="_blank"><img src="https://img.shields.io/github/forks/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/issues" target="_blank"><img src="https://img.shields.io/github/issues/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/issues?q=is%3Aissue+is%3Aclosed" target="_blank"><img src="https://img.shields.io/github/issues-closed/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/pulls" target="_blank"><img src="https://img.shields.io/github/issues-pr/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/pulls?q=is%3Apr+is%3Aclosed" target="_blank"><img src="https://img.shields.io/github/issues-pr-closed/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin" target="_blank"><img src="https://img.shields.io/github/last-commit/d2-projects/d2-admin.svg"></a>
|
|
||||||
</p>
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin" target="_blank"><img src="https://visitor-badge.glitch.me/badge?page_id=d2-projects.d2-admin"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/releases" target="_blank"><img src="https://img.shields.io/github/release/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://deepscan.io/dashboard#view=project&tid=8014&pid=10161&bid=136697"><img src="https://deepscan.io/api/teams/8014/projects/10161/branches/136697/badge/grade.svg" alt="DeepScan grade"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
[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.
|
---
|
||||||
|
|
||||||
[](https://open.vscode.dev/d2-projects/d2-admin)
|
## 项目目录结构
|
||||||
|
|
||||||
[中文](https://github.com/d2-projects/d2-admin/blob/master/README.zh.md) | **English**
|
```
|
||||||
|
mes-ui/
|
||||||
## Preview
|
├── .github/ # GitHub 相关配置
|
||||||
|
├── docs/ # 项目文档
|
||||||

|
├── public/ # 静态资源(不经过 webpack 处理)
|
||||||
[](https://app.netlify.com/sites/d2-admin/deploys)
|
├── src/ # PC 端业务源码
|
||||||
|
│ ├── api/ # 接口请求层
|
||||||
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.
|
│ ├── assets/ # 静态资源(经 webpack 处理)
|
||||||
|
│ ├── components/ # 公共组件
|
||||||
| server | link | server |
|
│ ├── composables/ # 可复用逻辑函数
|
||||||
| --- | --- | --- |
|
│ ├── layout/ # 页面布局
|
||||||
| d2.pub | [Link](https://d2.pub/d2-admin/preview) | China server |
|
│ ├── libs/ # 工具函数
|
||||||
| github | [Link](https://d2-projects.github.io/d2-admin) | GitHub pages |
|
│ ├── locales/ # 国际化语言包
|
||||||
| netlify | [Link](https://d2-admin.netlify.com) | Netlify CDN |
|
│ ├── menu/ # 菜单配置
|
||||||
|
│ ├── plugin/ # Vue 插件
|
||||||
## Document
|
│ ├── router/ # 路由配置
|
||||||
|
│ ├── store/ # Vuex 状态管理
|
||||||
[document on https://d2.pub](https://d2.pub/doc/d2-admin/)
|
│ └── views/ # 业务页面
|
||||||
|
├── src.mobile/ # 移动端业务源码
|
||||||
## Features
|
├── .browserslistrc # 浏览器兼容配置
|
||||||
|
├── .editorconfig # 编辑器统一配置
|
||||||
* Build with vue-cli3
|
├── .env / .env.development / .env.preview # 环境变量
|
||||||
* First screen loading waiting animation
|
├── .eslintignore / .eslintrc.js # ESLint 配置
|
||||||
* Five themes
|
├── .gitignore # Git 忽略配置
|
||||||
* Built-in UEditor rich text editor
|
├── .postcssrc.js # PostCSS 配置
|
||||||
* Detailed documentation
|
├── babel.config.js # Babel 配置
|
||||||
* Login and logout
|
├── jest.config.js # Jest 单元测试配置
|
||||||
* Separate routing and menu settings
|
├── jsconfig.json # VS Code 路径别名提示
|
||||||
* Foldable sidebar
|
├── package.json # 项目依赖与脚本
|
||||||
* Multi-national language
|
├── pnpm-lock.yaml # pnpm 依赖锁定文件
|
||||||
* Rich text editor
|
├── vue.config.js # Vue CLI 构建配置
|
||||||
* Markdown editor
|
└── README.md # 项目说明(本文件)
|
||||||
* 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:
|
|
||||||
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin" target="_blank">
|
|
||||||
<img src="https://raw.githubusercontent.com/d2-projects/d2-admin/master/docs/image/d2-admin@2x.png" width="200">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
Copy the following code into the README to:
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin" target="_blank"><img src="https://raw.githubusercontent.com/d2-projects/d2-admin/master/docs/image/d2-admin@2x.png" width="200"></a>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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)
|
### `.github/`
|
||||||
* [@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)
|
|
||||||
|
|
||||||
## 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/`
|
||||||
|
|
||||||

|
**静态资源目录**,文件会原样复制到构建产物中,不经过 webpack 编译。
|
||||||
|
|
||||||
> Total visitor since 2019.08.27
|
| 子目录 | 作用 |
|
||||||
|
|--------|------|
|
||||||
|
| `lib/UEditor/` | 百度 UEditor 富文本编辑器(第三方库,通过 `<script>` 直接引入) |
|
||||||
|
| `image/theme/` | 各主题的 Logo 图片和预览图(chester / d2 / element / line / star / tomorrow-night-blue / violet) |
|
||||||
|
| `image/loading/` | 页面加载动画的 SVG |
|
||||||
|
| `html/` | 独立 HTML 页面(如 demo.html) |
|
||||||
|
| `index.html` | SPA 入口 HTML 模板 |
|
||||||
|
| `icon.ico` | 网站 Favicon |
|
||||||
|
|
||||||
## Star history
|
### `src/` — PC 端源码
|
||||||
|
|
||||||
[](https://starchart.cc/d2-projects/d2-admin)
|
#### `src/api/`
|
||||||
|
**接口请求层**。封装后端 API 调用,按业务模块拆分为独立文件。
|
||||||
|
- `_service.js` — 基于 axios 的请求服务实例
|
||||||
|
- `_tools.js` — 请求工具函数
|
||||||
|
- `demo.js` — 演示接口
|
||||||
|
- `sys.user.js` — 用户相关接口
|
||||||
|
|
||||||
## License
|
#### `src/assets/`
|
||||||
|
**静态资源**,会被 webpack 处理。
|
||||||
|
|
||||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fd2-projects%2Fd2-admin?ref=badge_large)
|
| 子目录 | 作用 |
|
||||||
|
|--------|------|
|
||||||
|
| `style/unit/color.scss` | 全局颜色变量定义 |
|
||||||
|
| `style/public.scss` | 全局 SCSS 变量、mixin、placeholder(通过 `additionalData` 自动注入每个组件) |
|
||||||
|
| `style/public-class.scss` | 全局通用 CSS class(间距、浮动、文字对齐等工具类) |
|
||||||
|
| `style/fixed/` | 第三方库样式覆盖(element / markdown / n-progress / vue-splitpane 等) |
|
||||||
|
| `style/animate/` | 过渡动画样式(vue-transition) |
|
||||||
|
| `style/theme/` | 主题切换样式,每个主题独立目录,含 `index.scss` + `setting.scss` |
|
||||||
|
| `svg-icons/icons/` | SVG 图标文件,通过 `svg-sprite-loader` 生成雪碧图 |
|
||||||
|
| `svg-icons/index.js` | SVG 图标自动注册脚本 |
|
||||||
|
|
||||||
|
#### `src/components/`
|
||||||
|
**公共组件库**,所有可复用组件集中管理。
|
||||||
|
|
||||||
|
| 组件 | 作用 |
|
||||||
|
|------|------|
|
||||||
|
| `d2-container` | 页面容器组件,提供卡片、全屏、透明等多种布局变体 |
|
||||||
|
| `d2-container-frame` | iframe 嵌套外部页面容器 |
|
||||||
|
| `d2-count-up` | 数字滚动动画组件 |
|
||||||
|
| `d2-highlight` | 代码高亮展示组件 |
|
||||||
|
| `d2-icon` / `d2-icon-svg` | 图标组件(Font Awesome / SVG) |
|
||||||
|
| `d2-icon-select` / `d2-icon-svg-select` | 图标选择器组件 |
|
||||||
|
| `d2-link-btn` | 链接式按钮 |
|
||||||
|
| `d2-markdown` | Markdown 渲染组件 |
|
||||||
|
| `d2-module-index-banner` | 首页 Banner 展示组件 |
|
||||||
|
| `d2-module-index-menu` | 首页菜单组件 |
|
||||||
|
| `d2-quill` | Quill 富文本编辑器封装 |
|
||||||
|
| `d2-scrollbar` | 自定义滚动条组件 |
|
||||||
|
| `d2-ueditor` | 百度 UEditor 编辑器封装 |
|
||||||
|
| `page-table` | **新** CRUD 表格便捷组合体(按钮栏 + 表格 + 分页 + 高度自适应 + 帮助按钮) |
|
||||||
|
| `page-dialog-form` | **新** 增删改查弹框组件(表单渲染 + 校验 + i18n) |
|
||||||
|
|
||||||
|
> `page-table` 和 `page-dialog-form` 的详细用法见:[表格组件使用说明](./docs/表格组件使用说明.md)
|
||||||
|
|
||||||
|
#### `src/composables/`
|
||||||
|
**可复用的逻辑函数(Composition Utilities)**。把散落在各页面中的重复 JS 逻辑抽成纯函数,组件只需调用即可。
|
||||||
|
|
||||||
|
| 文件 | 作用 |
|
||||||
|
|------|------|
|
||||||
|
| `useTableColumns.js` | 列定义工厂,消除手动分配 `idx` 序号;约定 `prop: '_actions'` 为操作列 |
|
||||||
|
| `useTableButtons.js` | 按钮定义工厂,一键生成顶部工具栏 + 行内操作按钮,自动注入权限过滤 |
|
||||||
|
| `useI18n.js` | i18n Mixin 工厂,通过 `i18nMixin(prefix)` 注入 `key()` / `ckey()` 方法,消除每个页面手写 `T` 常量 |
|
||||||
|
|
||||||
|
> **为什么放在 `src/` 根目录?**
|
||||||
|
> composable 不是 UI 组件(不需要 `<template>`),也不属于 `libs/`(通用工具库)。它是介于**组件和逻辑之间**的中间层——被多个组件调用,但本身不渲染 DOM。放在 `src/` 根目录下与 `components/`、`views/` 同级,方便一眼看到项目的公共逻辑层。
|
||||||
|
|
||||||
|
#### `src/layout/`
|
||||||
|
**页面布局**。当前使用 `header-aside` 布局(顶栏 + 侧边栏 + 主内容区)。
|
||||||
|
|
||||||
|
| 子目录 | 作用 |
|
||||||
|
|--------|------|
|
||||||
|
| `layout.vue` | 布局主文件 |
|
||||||
|
| `components/menu-side/` | 侧边菜单组件 |
|
||||||
|
| `components/menu-header/` | 顶部导航菜单组件 |
|
||||||
|
| `components/header-user/` | 顶栏用户信息下拉 |
|
||||||
|
| `components/header-theme/` | 主题切换面板 |
|
||||||
|
| `components/header-color/` | 主题色切换 |
|
||||||
|
| `components/header-locales/` | 多语言切换 |
|
||||||
|
| `components/header-fullscreen/` | 全屏切换 |
|
||||||
|
| `components/header-search/` | 全局搜索 |
|
||||||
|
| `components/header-log/` | 操作日志 |
|
||||||
|
| `components/header-size/` | 字号大小切换 |
|
||||||
|
| `components/tabs/` | 多标签页栏 |
|
||||||
|
| `components/contextmenu/` | 标签页右键菜单 |
|
||||||
|
| `components/panel-search/` | 全局搜索面板 |
|
||||||
|
| `mixins/search.js` | 搜索 mixin |
|
||||||
|
| `mixins/` | 菜单相关 mixin |
|
||||||
|
|
||||||
|
#### `src/libs/`
|
||||||
|
**工具函数库**。
|
||||||
|
- `util.js` — 通用工具方法
|
||||||
|
- `util.cookies.js` — Cookie 操作
|
||||||
|
- `util.db.js` — 本地存储(基于 lowdb)
|
||||||
|
- `util.log.js` — 日志工具
|
||||||
|
- `util.import.development.js` / `util.import.production.js` — 开发/生产环境动态加载
|
||||||
|
|
||||||
|
#### `src/locales/`
|
||||||
|
**国际化(i18n)**。JSON 格式的语言文件,支持:
|
||||||
|
- `zh-chs` — 简体中文
|
||||||
|
- `zh-cht` — 繁体中文
|
||||||
|
- `en` — 英文
|
||||||
|
- `ja` — 日文
|
||||||
|
- `mixin.js` — Vue 国际化 mixin
|
||||||
|
|
||||||
|
#### `src/menu/`
|
||||||
|
**菜单配置**。按业务模块拆分,定义侧边栏菜单结构。`modules/` 下按 demo-components、demo-playground、demo-plugins 组织。
|
||||||
|
|
||||||
|
#### `src/plugin/`
|
||||||
|
**Vue 插件**。
|
||||||
|
- `d2admin/` — D2Admin 核心插件(初始化全局功能)
|
||||||
|
- `error/` — 全局错误捕获
|
||||||
|
- `log/` — 通用日志输出
|
||||||
|
- `open/` — 新窗口打开工具
|
||||||
|
|
||||||
|
#### `src/router/`
|
||||||
|
**路由配置**。`modules/` 下按 components、playground、plugins 拆分路由表。`routes.js` 为汇总路由,`index.js` 创建 Vue Router 实例。
|
||||||
|
|
||||||
|
#### `src/store/`
|
||||||
|
**Vuex 状态管理**。`modules/d2admin/` 下按功能拆分为独立模块:
|
||||||
|
|
||||||
|
| 模块 | 作用 |
|
||||||
|
|------|------|
|
||||||
|
| `account` | 用户账户信息 |
|
||||||
|
| `color` | 主题色管理 |
|
||||||
|
| `db` | 本地数据库状态 |
|
||||||
|
| `fullscreen` | 全屏状态 |
|
||||||
|
| `gray` | 灰度模式 |
|
||||||
|
| `log` | 操作日志 |
|
||||||
|
| `menu` | 菜单状态(展开/收缩/激活项) |
|
||||||
|
| `page` | 页面缓存与标签页 |
|
||||||
|
| `releases` | 版本信息 |
|
||||||
|
| `search` | 全局搜索 |
|
||||||
|
| `size` | 字号大小 |
|
||||||
|
| `theme` | 主题切换 |
|
||||||
|
| `transition` | 页面过渡动画 |
|
||||||
|
| `ua` | 用户代理信息 |
|
||||||
|
| `user` | 用户登录态 |
|
||||||
|
|
||||||
|
#### `src/views/`
|
||||||
|
**页面视图**。
|
||||||
|
- `demo/` — 各功能展示页面(组件演示 / 插件演示 / 功能试验场)
|
||||||
|
- `system/` — 系统级页面(首页 / 登录 / 404 / 日志 / 重定向 / 刷新)
|
||||||
|
- `production-master-data/` — 生产配置模块(工厂区域 / 产线 / 工艺 / 产品 / 物料等)
|
||||||
|
|
||||||
|
> 页面按一级模块 → 二级模块 → 三级模块 三层目录组织,与 [后台Webman界面截图对照表](./后台Webman界面截图对照表.md) 中的英文命名一致。
|
||||||
|
|
||||||
|
#### `src/` 根文件
|
||||||
|
|
||||||
|
| 文件 | 作用 |
|
||||||
|
|------|------|
|
||||||
|
| `main.js` | PC 端应用入口 |
|
||||||
|
| `App.vue` | 根组件 |
|
||||||
|
| `setting.js` | 全局设置(站点标题等) |
|
||||||
|
| `i18n.js` | 国际化初始化 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `src.mobile/` — 移动端源码
|
||||||
|
|
||||||
|
基于 Vant UI 的移动端适配版本,与 PC 端共用部分业务逻辑。
|
||||||
|
|
||||||
|
| 文件/目录 | 作用 |
|
||||||
|
|-----------|------|
|
||||||
|
| `main.js` | 移动端应用入口 |
|
||||||
|
| `App.vue` | 移动端根组件 |
|
||||||
|
| `vant.js` | Vant UI 按需引入配置 |
|
||||||
|
| `router/` | 移动端路由 |
|
||||||
|
| `store/` | 移动端状态管理 |
|
||||||
|
| `views/` | 移动端页面 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 构建配置文件
|
||||||
|
|
||||||
|
| 文件 | 作用 |
|
||||||
|
|------|------|
|
||||||
|
| `vue.config.js` | Vue CLI 构建配置(多页入口、CDN、webpack 插件、主题色替换、SVG sprites、路径别名) |
|
||||||
|
| `babel.config.js` | Babel 转译配置 |
|
||||||
|
| `.postcssrc.js` | PostCSS 自动前缀等配置 |
|
||||||
|
| `.eslintrc.js` | ESLint 代码规范 |
|
||||||
|
| `jest.config.js` | 单元测试框架配置 |
|
||||||
|
| `jsconfig.json` | VS Code 路径别名智能提示(`@` → `src/`) |
|
||||||
|
| `.browserslistrc` | 目标浏览器范围 |
|
||||||
|
| `.editorconfig` | 编辑器缩进/换行风格统一 |
|
||||||
|
|
||||||
|
### 环境变量文件
|
||||||
|
|
||||||
|
| 文件 | 作用 |
|
||||||
|
|------|------|
|
||||||
|
| `.env` | 所有环境通用变量 |
|
||||||
|
| `.env.development` | 开发环境变量 |
|
||||||
|
| `.env.preview` | 预发布环境变量 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 常用命令
|
||||||
|
|
||||||
|
| 命令 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `pnpm serve` | 启动开发服务器 |
|
||||||
|
| `pnpm build` | 生产环境构建 |
|
||||||
|
| `pnpm build:preview` | 预发布环境构建 |
|
||||||
|
| `pnpm lint` | ESLint 检查并自动修复 |
|
||||||
|
| `pnpm test:unit` | 运行单元测试 |
|
||||||
|
|||||||
205
README.zh.md
205
README.zh.md
@@ -1,205 +0,0 @@
|
|||||||

|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/stargazers" target="_blank"><img src="https://img.shields.io/github/stars/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/network/members" target="_blank"><img src="https://img.shields.io/github/forks/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/issues" target="_blank"><img src="https://img.shields.io/github/issues/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/issues?q=is%3Aissue+is%3Aclosed" target="_blank"><img src="https://img.shields.io/github/issues-closed/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/pulls" target="_blank"><img src="https://img.shields.io/github/issues-pr/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/pulls?q=is%3Apr+is%3Aclosed" target="_blank"><img src="https://img.shields.io/github/issues-pr-closed/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin" target="_blank"><img src="https://img.shields.io/github/last-commit/d2-projects/d2-admin.svg"></a>
|
|
||||||
</p>
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin" target="_blank"><img src="https://visitor-badge.glitch.me/badge?page_id=d2-projects.d2-admin"></a>
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin/releases" target="_blank"><img src="https://img.shields.io/github/release/d2-projects/d2-admin.svg"></a>
|
|
||||||
<a href="https://deepscan.io/dashboard#view=project&tid=8014&pid=10161&bid=136697"><img src="https://deepscan.io/api/teams/8014/projects/10161/branches/136697/badge/grade.svg" alt="DeepScan grade"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
[D2Admin](https://github.com/d2-projects/d2-admin) 是一个完全 **开源免费** 的企业中后台产品前端集成方案,使用最新的前端技术栈,小于 60kb 的本地首屏 js 加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助力管理系统敏捷开发。
|
|
||||||
|
|
||||||
[](https://open.vscode.dev/d2-projects/d2-admin)
|
|
||||||
|
|
||||||
**中文** | [English](https://github.com/d2-projects/d2-admin)
|
|
||||||
|
|
||||||
## 预览
|
|
||||||
|
|
||||||

|
|
||||||
[](https://app.netlify.com/sites/d2-admin/deploys)
|
|
||||||
|
|
||||||
下列访问地址均由最新的 master 分支代码同时构建部署,访问效果完全一致,请根据自身网络情况选择合适的访问链接。
|
|
||||||
|
|
||||||
| 位置 | 链接 | 部署位置 |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| d2.pub | [preview](https://d2.pub/d2-admin/preview) | 中国服务器 |
|
|
||||||
| github | [preview](https://d2-projects.github.io/d2-admin) | GitHub pages |
|
|
||||||
| netlify | [preview](https://d2-admin.netlify.com) | Netlify CDN |
|
|
||||||
|
|
||||||
## 文档
|
|
||||||
|
|
||||||
[在 https://d2.pub 上的本项目文档](https://d2.pub/doc/d2-admin/)
|
|
||||||
|
|
||||||
## 功能
|
|
||||||
|
|
||||||
* 使用 vue-cli3 构建
|
|
||||||
* 首屏加载等待动画
|
|
||||||
* 五款主题
|
|
||||||
* 内置 UEditor 富文本编辑器
|
|
||||||
* 详细的文档
|
|
||||||
* 登录和注销
|
|
||||||
* 分离的路由和菜单设置
|
|
||||||
* 可折叠侧边栏
|
|
||||||
* 多国语
|
|
||||||
* 富文本编辑器
|
|
||||||
* Markdown 编辑器
|
|
||||||
* 全屏
|
|
||||||
* Fontawesome 图标库
|
|
||||||
* 图标选择器
|
|
||||||
* 自动注册 SVG 图标
|
|
||||||
* 模拟数据
|
|
||||||
* 剪贴板封装
|
|
||||||
* 图表库
|
|
||||||
* 时间日期计算工具
|
|
||||||
* 导入 Excel ( xlsx + csv )
|
|
||||||
* 数据导出 Excel ( xlsx + csv )
|
|
||||||
* 数据导出文本
|
|
||||||
* 数字动画
|
|
||||||
* 可拖拽调整大小的区块布局
|
|
||||||
* 可拖拽调整大小和位置的网格布局
|
|
||||||
* 开箱即用的页面布局组件
|
|
||||||
* 加载并解析 markdown 文件
|
|
||||||
* GitHub 样式的 markdown 显示组件
|
|
||||||
* markdown 内代码高亮
|
|
||||||
* 为 markdown 扩展了百度云链接解析和优化显示
|
|
||||||
* 右键菜单组件
|
|
||||||
* 自定义滚动条和滚动控制
|
|
||||||
* 公用样式抽离,方便的主题定制
|
|
||||||
* 支持临时菜单配置
|
|
||||||
* 系统功能展示模块 `1.1.4 +`
|
|
||||||
* 多标签页模式 `1.1.4 +`
|
|
||||||
* 美化滚动条 `1.1.4 +`
|
|
||||||
* json view `1.1.4 +`
|
|
||||||
* cookie 封装 `1.1.5 +`
|
|
||||||
* 多标签页全局控制 API `1.1.5 +`
|
|
||||||
* 菜单全局控制 API `1.1.5 +`
|
|
||||||
* 多标签页关闭控制支持右键菜单 `1.1.10 +`
|
|
||||||
* 模块化全局状态管理 `1.2.0 +`
|
|
||||||
* 多种数据持久化方式:区分用户,区分路由,页面数据快照功能 `1.2.0 +`
|
|
||||||
* 支持跳出外部链接的菜单系统 `1.2.0 +`
|
|
||||||
* 支持菜单 svg 图标 `1.3.0 +`
|
|
||||||
* 日志记录和错误捕捉 `1.3.0 +`
|
|
||||||
* 全局菜单搜索 `1.3.0 +`
|
|
||||||
* 自定义登录重定向 `1.3.0 +`
|
|
||||||
* 切换全局基础组件尺寸 `1.4.0 +`
|
|
||||||
* 页面载入进度条 `1.4.1 +`
|
|
||||||
* 自适应的顶部菜单栏 `1.4.7 +`
|
|
||||||
* 数据导出 xslx 时支持合并单元格 `1.5.4 +`
|
|
||||||
* 多标签页支持拖拽排序 `1.8.0 +`
|
|
||||||
* 优化生产环境构建,首页只加载小于 60kb 的本地 js 代码 `1.8.0 +`
|
|
||||||
* 内置了构建文件体积检查工具 `1.8.0 +`
|
|
||||||
* 构建多页面示例 `1.23.0 +`
|
|
||||||
* 分包优化 `1.23.0 +`
|
|
||||||
|
|
||||||
## 其它同步仓库
|
|
||||||
|
|
||||||
| 位置 | 链接 |
|
|
||||||
| --- | --- |
|
|
||||||
| 码云 | [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) |
|
|
||||||
|
|
||||||
> 如果您在 github 仓库下载很慢,可以尝试使用我们的码云仓库克隆代码
|
|
||||||
|
|
||||||
## 其它版本
|
|
||||||
|
|
||||||
| 名称 | 主页 | 预览 | 介绍 |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| 简化版模板 | [Github](https://github.com/d2-projects/d2-admin-start-kit) | [预览](https://d2.pub/d2-admin-start-kit/preview) | 无 |
|
|
||||||
|
|
||||||
## 开源后端实现
|
|
||||||
|
|
||||||
> 后端由开源社区贡献,不保证使用 D2Admin 最新版本,相关使用问题请联系其开源作者。
|
|
||||||
|
|
||||||
| 名称 | 技术 | 主页 | 预览 | 介绍 |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| django-vue-admin-pro | Django | [Github](https://github.com/dvadmin-pro/django-vue-admin-pro) | [预览](http://demo.pro.django-vue-admin.com) | Django + Jwt + D2Admin |
|
|
||||||
| boot-admin | SpringBoot | [Github](https://github.com/hb0730/boot-admin) | [预览](http://admin.hb0730.com/) | 基于 SpringBoot 前后端分离的后台管理系统 |
|
|
||||||
| FlaskPermission | Flask | [Github](https://github.com/huguodong/flask-permission) | [预览](http://47.97.218.139:9999) | 基于 Python Flask 的权限管理 |
|
|
||||||
| CareyShop | ThinkPHP5 | [Github](https://github.com/dnyz520/careyshop-admin) | [预览](https://demo.careyshop.cn/admin/#/index) | 适用于 CareyShop 的高性能商城框架系统 |
|
|
||||||
| jiiiiiin-security | Spring Boot | [Github](https://github.com/Jiiiiiin/jiiiiiin-security) | [预览](https://github.com/Jiiiiiin/jiiiiiin-security) | 前后端分离的内容管理基础项目,注重用户权限管理功能 |
|
|
||||||
| Taroco | Spring Cloud | [Github](https://github.com/liuht777/Taroco) | [预览](http://111.231.192.110/) | 整套微服务企业级解决方案 |
|
|
||||||
| Aooms | Spring Cloud | [码云](https://gitee.com/cyb-javaer/Aooms) | [预览](https://www.yuboon.com/Aooms) | 极速微服务开发,不止像JFinal一样简单 |
|
|
||||||
| GOA | Beego | [Github](https://github.com/Qsnh/goa) | [预览](http://goaio.vip/) | 基于 Beego + Vue 开发的在线问答系统 |
|
|
||||||
| CMDB | Django | [Github](https://github.com/CJFJack/django_vue_cmdb) | [预览](https://mp.weixin.qq.com/s?__biz=MzU1OTYzODA4Mw==&mid=2247484250&idx=1&sn=981024ac0580d8a3eba95742bd32b268) | 分用户加载不同菜单和权限 |
|
|
||||||
|
|
||||||
## 社区项目
|
|
||||||
|
|
||||||
> 这些项目由开源社区贡献,不保证使用 D2Admin 最新版本,相关使用问题请联系其开源作者。
|
|
||||||
|
|
||||||
| 名称 | 主页 | 预览 | 介绍 |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| d2-admin-xiya-go-cms | [Github](https://github.com/d2-projects/d2-admin-xiya-go-cms) | [预览](https://d2.pub/d2-admin-xiya-go-cms/preview) | D2Admin + 权限系统 + 动态路由 |
|
|
||||||
| d2-advance | [Github](https://github.com/d2-projects/d2-advance) | [预览](https://d2.pub/d2-advance/preview) | 由 D2Admin 启发的技术探索 |
|
|
||||||
| d2-crud-plus | [Github](https://github.com/greper/d2-crud-plus) | [预览](http://qiniu.veryreader.com/D2CrudPlusExample/index.html) | 简化d2-crud配置,快速开发crud功能 |
|
|
||||||
| d2-crud | [Github](https://github.com/d2-projects/d2-crud) | [预览]() | 表格常用操作封装 |
|
|
||||||
| d2-admin-pm | [Github](https://github.com/wjkang/d2-admin-pm) | [预览](http://jaycewu.coding.me/d2-admin-pm) | 基于 D2Admin 的 RBAC 权限管理解决方案 |
|
|
||||||
| LanBlog | [Github](https://github.com/sinksmell/LanBlog) | [预览](http://47.101.222.133/) | Vue + Beego restful api 开发的懒人博客 |
|
|
||||||
| d2-admin-start-kit-plus | [Github](https://github.com/hank-cp/d2-admin-start-kit-plus) | [预览](https://github.com/hank-cp/d2-admin-start-kit-plus) | D2Admin 简化版模块化版本 |
|
|
||||||
| d2-ribbons | [Github](https://github.com/d2-projects/d2-ribbons) | [预览](https://github.com/d2-projects/d2-ribbons) | 开源项目徽标库 |
|
|
||||||
|
|
||||||
## 加入我们
|
|
||||||
|
|
||||||
D2Admin 是完全开源免费的项目,旨在帮助开发者更方便地进行管理系统开发,同时也提供 QQ 交流群和微信群,前后端的朋友可以相互答疑,项目组成员全部在内,所有 D2 相关项目使用问题欢迎在群内提问。
|
|
||||||
|
|
||||||
* QQ 1 群 `806395827`
|
|
||||||
* QQ 2 群 `592981556`
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 徽章
|
|
||||||
|
|
||||||
如果您的开源项目基于 D2Admin 开发,请在您的 README 添加下面的徽章:
|
|
||||||
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin" target="_blank">
|
|
||||||
<img src="https://raw.githubusercontent.com/FairyEver/d2-admin/master/docs/image/d2-admin@2x.png" width="200">
|
|
||||||
</a>
|
|
||||||
|
|
||||||
复制下面代码加入到 README 中即可:
|
|
||||||
|
|
||||||
``` html
|
|
||||||
<a href="https://github.com/d2-projects/d2-admin" target="_blank"><img src="https://raw.githubusercontent.com/FairyEver/d2-admin/master/docs/image/d2-admin@2x.png" width="200"></a>
|
|
||||||
```
|
|
||||||
|
|
||||||
同时您可以将您的项目汇报给我们,优秀项目我们会放置在 D2Admin 相关位置并帮助您宣传。
|
|
||||||
|
|
||||||
## 贡献
|
|
||||||
|
|
||||||
* [@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)
|
|
||||||
|
|
||||||
## 成为赞助者
|
|
||||||
|
|
||||||
[在 "爱发电" 上赞助我](https://afdian.net/@fairyever)
|
|
||||||
|
|
||||||
## 赞助
|
|
||||||
|
|
||||||
**cochlea** | **Baron** | **苦行僧** | **吴地安宁** | **KingDong** | **sunyongmofang**
|
|
||||||
|
|
||||||
## 访问统计
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
> 自 2019-08-27 起
|
|
||||||
|
|
||||||
## Star 历史
|
|
||||||
|
|
||||||
[](https://starchart.cc/d2-projects/d2-admin)
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fd2-projects%2Fd2-admin?ref=badge_large)
|
|
||||||
|
|
||||||

|
|
||||||
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>?
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"less": "^3.13.1",
|
"less": "^3.13.1",
|
||||||
"less-loader": "^7.3.0",
|
"less-loader": "^7.3.0",
|
||||||
"sass": "^1.54.5",
|
"sass": "^1.54.5",
|
||||||
"sass-loader": "^10.3.1",
|
"sass-loader": "~10.5.2",
|
||||||
"svg-sprite-loader": "^4.3.0",
|
"svg-sprite-loader": "^4.3.0",
|
||||||
"text-loader": "^0.0.1",
|
"text-loader": "^0.0.1",
|
||||||
"vue-cli-plugin-i18n": "^1.0.1",
|
"vue-cli-plugin-i18n": "^1.0.1",
|
||||||
|
|||||||
15889
pnpm-lock.yaml
generated
Normal file
15889
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
43
src/api/production-master-data/factory-area.js
Normal file
43
src/api/production-master-data/factory-area.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
@use 'sass:list';
|
||||||
@import 'public';
|
@import 'public';
|
||||||
|
|
||||||
// 补丁 base
|
// 补丁 base
|
||||||
@@ -39,17 +40,17 @@
|
|||||||
$sizes: (0, 5, 10, 15, 20);
|
$sizes: (0, 5, 10, 15, 20);
|
||||||
|
|
||||||
@for $index from 1 to 6 {
|
@for $index from 1 to 6 {
|
||||||
.#{$prefix}-m-#{nth($sizes, $index)} { margin: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-m-#{list.nth($sizes, $index)} { margin: #{list.nth($sizes, $index)}px !important; }
|
||||||
.#{$prefix}-mt-#{nth($sizes, $index)} { margin-top: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-mt-#{list.nth($sizes, $index)} { margin-top: #{list.nth($sizes, $index)}px !important; }
|
||||||
.#{$prefix}-mr-#{nth($sizes, $index)} { margin-right: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-mr-#{list.nth($sizes, $index)} { margin-right: #{list.nth($sizes, $index)}px !important; }
|
||||||
.#{$prefix}-mb-#{nth($sizes, $index)} { margin-bottom: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-mb-#{list.nth($sizes, $index)} { margin-bottom: #{list.nth($sizes, $index)}px !important; }
|
||||||
.#{$prefix}-ml-#{nth($sizes, $index)} { margin-left: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-ml-#{list.nth($sizes, $index)} { margin-left: #{list.nth($sizes, $index)}px !important; }
|
||||||
|
|
||||||
.#{$prefix}-p-#{nth($sizes, $index)} { padding: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-p-#{list.nth($sizes, $index)} { padding: #{list.nth($sizes, $index)}px !important; }
|
||||||
.#{$prefix}-pt-#{nth($sizes, $index)} { padding-top: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-pt-#{list.nth($sizes, $index)} { padding-top: #{list.nth($sizes, $index)}px !important; }
|
||||||
.#{$prefix}-pr-#{nth($sizes, $index)} { padding-right: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-pr-#{list.nth($sizes, $index)} { padding-right: #{list.nth($sizes, $index)}px !important; }
|
||||||
.#{$prefix}-pb-#{nth($sizes, $index)} { padding-bottom: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-pb-#{list.nth($sizes, $index)} { padding-bottom: #{list.nth($sizes, $index)}px !important; }
|
||||||
.#{$prefix}-pl-#{nth($sizes, $index)} { padding-left: #{nth($sizes, $index)}px !important; }
|
.#{$prefix}-pl-#{list.nth($sizes, $index)} { padding-left: #{list.nth($sizes, $index)}px !important; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快速使用
|
// 快速使用
|
||||||
|
|||||||
323
src/components/page-dialog-form/index.vue
Normal file
323
src/components/page-dialog-form/index.vue
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
<template>
|
||||||
|
<!--
|
||||||
|
page-dialog-form — 增删改查弹框组件
|
||||||
|
===================================
|
||||||
|
这是一个「带表单验证的弹框」组件,配合 page-table 使用。
|
||||||
|
负责:弹框显隐控制 + 表单渲染 + 表单验证 + 确定/取消按钮。
|
||||||
|
|
||||||
|
不支持复杂表单联动——如有需要,通过默认插槽自定义内容。
|
||||||
|
|
||||||
|
依赖:element-ui 的 <el-dialog> <el-form> <el-input> <el-select>
|
||||||
|
i18n:title / label / placeholder / confirm/cancel 按钮 全部自动 $t() 翻译
|
||||||
|
|
||||||
|
@author 前端团队
|
||||||
|
@since 2026-05
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
el-dialog:
|
||||||
|
visible.sync → 通过 .sync 修饰符双向绑定父组件的 visible prop
|
||||||
|
destroy-on-close → 每次关闭销毁 DOM 重建,避免表单残留上次数据
|
||||||
|
close-on-click-modal → 禁止点击遮罩关闭,防止误操作丢失填写数据
|
||||||
|
-->
|
||||||
|
<el-dialog
|
||||||
|
:visible.sync="visibleProxy"
|
||||||
|
:title="$t(title)"
|
||||||
|
:width="width"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:destroy-on-close="true"
|
||||||
|
@close="onClose"
|
||||||
|
>
|
||||||
|
<!-- ==================== 表单区 ==================== -->
|
||||||
|
<!--
|
||||||
|
el-form:
|
||||||
|
rules 由父组件传入,字段名与 formData 的 key 一一对应
|
||||||
|
label-width 默认 100px,可自定义
|
||||||
|
-->
|
||||||
|
<el-form
|
||||||
|
ref="form"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
:label-width="labelWidth || '100px'"
|
||||||
|
>
|
||||||
|
<!--
|
||||||
|
遍历 formCols 中所有行 → 每行中的每个字段 → 渲染对应的表单项
|
||||||
|
当前支持两种字段类型:
|
||||||
|
- type='input' → <el-input>(支持 textarea、密码等)
|
||||||
|
- type='select' → <el-select> + <el-option>
|
||||||
|
|
||||||
|
label / placeholder 会自动调用 $t() 翻译,传 i18n key 即可
|
||||||
|
-->
|
||||||
|
<el-form-item
|
||||||
|
v-for="col in flatFormCols"
|
||||||
|
:key="col.prop"
|
||||||
|
:label="$t(col.label)"
|
||||||
|
:prop="col.prop"
|
||||||
|
>
|
||||||
|
<!-- ===== 输入框类型 ===== -->
|
||||||
|
<!--
|
||||||
|
input:
|
||||||
|
inputType='textarea' → 多行文本框
|
||||||
|
不传 inputType → 普通文本输入框
|
||||||
|
clearable → 默认 true,传 false 可关闭
|
||||||
|
-->
|
||||||
|
<el-input
|
||||||
|
v-if="col.type === 'input'"
|
||||||
|
v-model="formData[col.prop]"
|
||||||
|
:placeholder="$t(col.placeholder)"
|
||||||
|
:type="col.inputType || 'text'"
|
||||||
|
:autosize="col.autosize"
|
||||||
|
:clearable="col.clearable !== false"
|
||||||
|
:style="col.style"
|
||||||
|
/>
|
||||||
|
<!-- ===== 下拉选择类型 ===== -->
|
||||||
|
<!--
|
||||||
|
select:
|
||||||
|
options → [{ label: '苹果', value: 1 }]
|
||||||
|
filterable → 默认 true,支持搜索过滤
|
||||||
|
-->
|
||||||
|
<el-select
|
||||||
|
v-else-if="col.type === 'select'"
|
||||||
|
v-model="formData[col.prop]"
|
||||||
|
:placeholder="$t(col.placeholder)"
|
||||||
|
:clearable="col.clearable !== false"
|
||||||
|
:style="col.style"
|
||||||
|
:filterable="col.filterable !== false"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="opt in col.options"
|
||||||
|
:key="opt.value"
|
||||||
|
:label="$t(opt.label)"
|
||||||
|
:value="opt.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- ===== 自定义表单内容插槽 ===== -->
|
||||||
|
<!--
|
||||||
|
如果需要超出 input/select 的复杂表单控件
|
||||||
|
父组件可以用此插槽添加任意内容
|
||||||
|
-->
|
||||||
|
<slot />
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- ==================== 底部按钮 ==================== -->
|
||||||
|
<!--
|
||||||
|
确定:type='primary' + submitting loading 状态
|
||||||
|
取消:调用 onClose → 重置表单 + 关闭弹框
|
||||||
|
按钮文字自动 $t() 翻译
|
||||||
|
-->
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="onClose">{{ $t(cancelText) }}</el-button>
|
||||||
|
<el-button type="primary" :loading="submitting" @click="onSubmit">{{ $t(confirmText) }}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* PageDialogForm — 增删改查弹框组件
|
||||||
|
*
|
||||||
|
* 【核心职责】
|
||||||
|
* 1. 管理弹框显隐
|
||||||
|
* 2. 根据 formCols 声明式渲染表单
|
||||||
|
* 3. 表单验证 + 验证失败提示
|
||||||
|
* 4. 提交/取消事件通知父组件
|
||||||
|
*
|
||||||
|
* 【典型用法】
|
||||||
|
* <page-dialog-form
|
||||||
|
* ref="dialogForm"
|
||||||
|
* :visible.sync="dialogVisible"
|
||||||
|
* :title="dialogTitle"
|
||||||
|
* width="35%"
|
||||||
|
* :form-cols="formCols"
|
||||||
|
* :form-data="formData"
|
||||||
|
* :rules="rules"
|
||||||
|
* :submitting="submitting"
|
||||||
|
* @submit="onDialogSubmit"
|
||||||
|
* @close="onDialogClose"
|
||||||
|
* />
|
||||||
|
*
|
||||||
|
* 【父组件调用的方法(通过 ref)】
|
||||||
|
* this.$refs.dialogForm.reset() — 重置表单
|
||||||
|
* this.$refs.dialogForm.validate() — 手动验证,返回 Promise<boolean>
|
||||||
|
*
|
||||||
|
* 【formCols 数据结构说明】
|
||||||
|
* 二维数组:外层是行,里层是该行的字段。大多数场景每行一个字段即可。
|
||||||
|
*
|
||||||
|
* 例:
|
||||||
|
* formCols: [
|
||||||
|
* [ { type: 'input', prop: 'code', label: T+'.code', placeholder: T+'.enter_code' } ],
|
||||||
|
* [ { type: 'input', prop: 'remark', label: T+'.remark', inputType: 'textarea', autosize: { minRows: 2 } } ],
|
||||||
|
* [ { type: 'select', prop: 'area_id', label: T+'.area', options: [{ label: 'A区', value: 1 }] } ]
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* 【表单字段支持的属性】
|
||||||
|
* 基础:type / prop / label / placeholder
|
||||||
|
* input:inputType('textarea' | 'text')/ autosize / clearable
|
||||||
|
* select:options / filterable
|
||||||
|
* 通用:style(如 { width: '90%' })
|
||||||
|
*
|
||||||
|
* 【表单验证(rules)】
|
||||||
|
* rules 与 el-form 的 rules 完全一致:
|
||||||
|
* rules: {
|
||||||
|
* code: [{ required: true, message: '请输入编码', trigger: 'blur' }]
|
||||||
|
* }
|
||||||
|
* 验证失败时,组件会用 $message.warning 显示第一条错误信息
|
||||||
|
* message 字段支持 i18n key,父组件用 this.$t() 传值即可
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'PageDialogForm',
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* 弹框显隐状态,父组件用 .sync 绑定
|
||||||
|
* 例::visible.sync="dialogVisible"
|
||||||
|
*/
|
||||||
|
visible: { type: Boolean, default: false },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹框标题,支持 i18n key(组件自动 $t() 翻译)
|
||||||
|
*/
|
||||||
|
title: { type: String, default: '' },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 弹框宽度,可以是百分比或像素
|
||||||
|
* 例:'35%' / '600px'
|
||||||
|
*/
|
||||||
|
width: { type: String, default: '35%' },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单字段结构,二维数组
|
||||||
|
* 外层数组每一个元素代表表单的一行
|
||||||
|
* 内层数组每个元素代表该行中的一个字段
|
||||||
|
*
|
||||||
|
* 每个字段对象支持的属性见组件顶部的注释
|
||||||
|
*/
|
||||||
|
formCols: { type: Array, default: () => [] },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单数据对象,key 与 formCols 中的 prop 一一对应
|
||||||
|
* 编辑时父组件将 row 数据赋值给 formData
|
||||||
|
*/
|
||||||
|
formData: { type: Object, default: () => ({}) },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单验证规则,与 el-form 的 rules 完全一致
|
||||||
|
* 例:{ code: [{ required: true, message: '请输入编码', trigger: 'blur' }] }
|
||||||
|
*/
|
||||||
|
rules: { type: Object, default: () => ({}) },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单 label 宽度,默认 '100px'
|
||||||
|
*/
|
||||||
|
labelWidth: { type: String, default: '100px' },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交 loading 状态,提交期间显示转圈防止重复点击
|
||||||
|
*/
|
||||||
|
submitting: { type: Boolean, default: false },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定按钮文字,默认 '确定',支持 i18n key
|
||||||
|
*/
|
||||||
|
confirmText: { type: String, default: '确定' },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消按钮文字,默认 '取消',支持 i18n key
|
||||||
|
*/
|
||||||
|
cancelText: { type: String, default: '取消' }
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* visible 代理:用于 .sync 双向绑定
|
||||||
|
* get → 返回父组件传入的 visible
|
||||||
|
* set → emit update:visible 通知父组件
|
||||||
|
*/
|
||||||
|
visibleProxy: {
|
||||||
|
get () { return this.visible },
|
||||||
|
set (val) { this.$emit('update:visible', val) }
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将二维 formCols 打平为一维数组,方便 v-for 遍历
|
||||||
|
* 二维数组 → 一维数组:[ [{a}], [{b},{c}] ] → [a, b, c]
|
||||||
|
*/
|
||||||
|
flatFormCols () {
|
||||||
|
return this.formCols.flat()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 点击确定按钮
|
||||||
|
* 1. 调用 el-form 的 validate 方法验证所有字段
|
||||||
|
* 2. 验证通过 → emit('submit') 通知父组件执行提交逻辑
|
||||||
|
* 3. 验证失败 → 用 $message.warning 显示第一条错误信息
|
||||||
|
*
|
||||||
|
* 注意:rules 中的 message 由父组件传入时已用 $t() 翻译
|
||||||
|
* 这里只负责显示,翻译在父组件或 i18n 语言包中完成
|
||||||
|
*/
|
||||||
|
onSubmit () {
|
||||||
|
this.$refs.form.validate((valid, invalidFields) => {
|
||||||
|
if (!valid) {
|
||||||
|
// 验证失败:取第一条错误信息提示用户
|
||||||
|
const firstKey = Object.keys(invalidFields)[0]
|
||||||
|
if (firstKey && invalidFields[firstKey].length) {
|
||||||
|
const msg = invalidFields[firstKey][0].message
|
||||||
|
this.$message.warning(this.$t(msg) || msg)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$emit('submit')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭弹框
|
||||||
|
* 1. 重置表单清除验证状态和输入内容
|
||||||
|
* 2. emit update:visible 关闭弹框(.sync 机制)
|
||||||
|
* 3. emit close 通知父组件执行清理逻辑
|
||||||
|
*/
|
||||||
|
onClose () {
|
||||||
|
this.$refs.form && this.$refs.form.resetFields()
|
||||||
|
this.$emit('update:visible', false)
|
||||||
|
this.$emit('close')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动验证表单,返回 Promise<boolean>
|
||||||
|
* 主要用于父组件需要自行控制验证时机的场景
|
||||||
|
*
|
||||||
|
* 用法:const ok = await this.$refs.dialogForm.validate()
|
||||||
|
*/
|
||||||
|
validate () {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.$refs.form.validate(valid => resolve(valid))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置表单(清除验证状态和输入值)
|
||||||
|
* 通常在打开新增弹框时调用
|
||||||
|
*/
|
||||||
|
reset () {
|
||||||
|
this.$refs.form && this.$refs.form.resetFields()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 表单项间距固定 22px,不受 Element UI 状态覆盖 */
|
||||||
|
/deep/ .el-form-item {
|
||||||
|
margin-bottom: 22px !important;
|
||||||
|
}
|
||||||
|
/* 错误文字下沉到 margin 间隙中,不挤占表单项自身高度 */
|
||||||
|
/deep/ .el-form-item__error {
|
||||||
|
position: absolute;
|
||||||
|
top: auto;
|
||||||
|
bottom: -18px;
|
||||||
|
}
|
||||||
|
/* textarea 对齐顶部 */
|
||||||
|
/deep/ .el-textarea {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
520
src/components/page-table/index.vue
Normal file
520
src/components/page-table/index.vue
Normal file
@@ -0,0 +1,520 @@
|
|||||||
|
<template>
|
||||||
|
<!--
|
||||||
|
page-table — CRUD 表格便捷组合体
|
||||||
|
================================
|
||||||
|
这是一个把「顶部按钮栏 + 数据表格 + 底部分页」打包在一起的高层组件。
|
||||||
|
适合 80% 的增删改查页面,你只需要传列定义、按钮定义、数据和分页参数即可。
|
||||||
|
|
||||||
|
依赖:element-ui 的 <el-table> <el-button> <el-pagination>
|
||||||
|
i18n:所有 label / 按钮文字 / 列标题 自动调用 $t() 翻译,传 i18n key 即可
|
||||||
|
|
||||||
|
@author 前端团队
|
||||||
|
@since 2026-05
|
||||||
|
-->
|
||||||
|
<div
|
||||||
|
ref="root"
|
||||||
|
class="page-table"
|
||||||
|
:class="{ 'page-table--auto': autoHeight || height === 'auto' }"
|
||||||
|
v-loading="loading"
|
||||||
|
>
|
||||||
|
<!-- ==================== 顶部:工具栏按钮区 ==================== -->
|
||||||
|
<!--
|
||||||
|
toolbarButtons 由 useTableButtons({ toolbar: [...] }) 生成
|
||||||
|
内部自动过滤 hasPermission === false 的按钮(无权限不显示)
|
||||||
|
按钮被 disabled 只在前端计算(如 needSelection 需要选中行),实际权限由后端校验
|
||||||
|
-->
|
||||||
|
<div ref="toolbar" class="page-table__toolbar" v-if="toolbarButtons.length || helpUrl">
|
||||||
|
<div class="page-table__toolbar-left">
|
||||||
|
<el-button
|
||||||
|
v-for="btn in visibleToolbarButtons"
|
||||||
|
:key="btn.key"
|
||||||
|
:type="btn.type"
|
||||||
|
:size="btn.size"
|
||||||
|
:icon="btn.icon"
|
||||||
|
:style="btn.cssStyle"
|
||||||
|
:disabled="btn.needSelection && !selectedCount"
|
||||||
|
@click="btn.onClick"
|
||||||
|
>
|
||||||
|
{{ $t(btn.label) }}
|
||||||
|
</el-button>
|
||||||
|
<!-- 自定义工具栏内容:如打印按钮、列筛选器等 -->
|
||||||
|
<slot name="toolbar-extra" />
|
||||||
|
</div>
|
||||||
|
<!-- 帮助按钮:始终显示在工具栏最右侧,点击新窗口打开帮助文档 -->
|
||||||
|
<el-button
|
||||||
|
v-if="helpUrl"
|
||||||
|
class="page-table__help-btn"
|
||||||
|
size="mini"
|
||||||
|
icon="el-icon-question"
|
||||||
|
@click="openHelp"
|
||||||
|
>
|
||||||
|
{{ $t(helpText) }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ==================== 中部:数据表格 ==================== -->
|
||||||
|
<!--
|
||||||
|
height 由外部传入或自动计算(autoHeight=true 时)
|
||||||
|
v-bind="tableAttrs" / v-on="tableListeners" 透传 el-table 原生属性和事件
|
||||||
|
-->
|
||||||
|
<div ref="tableWrapper" class="page-table__body">
|
||||||
|
<el-table
|
||||||
|
ref="table"
|
||||||
|
:data="tableData"
|
||||||
|
:height="tableHeight"
|
||||||
|
:border="border"
|
||||||
|
:row-key="rowKey"
|
||||||
|
:header-cell-style="headerCellStyle"
|
||||||
|
v-bind="tableAttrs"
|
||||||
|
v-on="tableListeners"
|
||||||
|
@selection-change="onSelectionChange"
|
||||||
|
>
|
||||||
|
<!--
|
||||||
|
遍历 columns,有五种列类型:
|
||||||
|
1. type='selection' → 复选框列
|
||||||
|
2. type='index' → 序号列
|
||||||
|
3. slot='_actions' → 操作列(自动渲染 rowButtons)
|
||||||
|
4. slot/headerSlot → 自定义插槽列
|
||||||
|
5. 其他 → 普通数据列
|
||||||
|
-->
|
||||||
|
<template v-for="col in columns">
|
||||||
|
<!-- 1. 复选框列 -->
|
||||||
|
<el-table-column
|
||||||
|
v-if="col.type === 'selection'"
|
||||||
|
:key="'sel-' + col.idx"
|
||||||
|
type="selection"
|
||||||
|
:width="col.width"
|
||||||
|
/>
|
||||||
|
<!-- 2. 序号列 -->
|
||||||
|
<el-table-column
|
||||||
|
v-else-if="col.type === 'index'"
|
||||||
|
:key="'idx-' + col.idx"
|
||||||
|
type="index"
|
||||||
|
:width="col.width"
|
||||||
|
:label="$t(col.label || '#')"
|
||||||
|
/>
|
||||||
|
<!-- 3. 操作列:自动渲染 rowButtons(编辑/删除等行内按钮) -->
|
||||||
|
<!--
|
||||||
|
约定:columns 中 prop='_actions' 的列会被识别为操作列
|
||||||
|
rowButtons 由 useTableButtons({ row: [...] }) 生成
|
||||||
|
红色按钮通过 color='danger' 控制
|
||||||
|
-->
|
||||||
|
<el-table-column
|
||||||
|
v-else-if="col.slot === '_actions' && rowButtons.length"
|
||||||
|
:key="'act-' + col.idx"
|
||||||
|
v-bind="colAttrs(col)"
|
||||||
|
>
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<span
|
||||||
|
v-for="btn in visibleRowButtons"
|
||||||
|
:key="btn.key"
|
||||||
|
:style="btn.cssStyle"
|
||||||
|
:class="{ 'action-btn--danger': btn.color === 'danger' }"
|
||||||
|
class="action-btn"
|
||||||
|
@click="btn.onClick(row, $index)"
|
||||||
|
>
|
||||||
|
<i v-if="btn.icon" :class="btn.icon" />
|
||||||
|
{{ $t(btn.label) }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 4. 自定义插槽列:列内容或表头可由父组件自定义 -->
|
||||||
|
<!--
|
||||||
|
使用方式:
|
||||||
|
- col.slot='status' → 父组件用 <template #col-status="{ row }">
|
||||||
|
- col.headerSlot='xyz' → 父组件用 <template #xyz> 自定义表头
|
||||||
|
-->
|
||||||
|
<el-table-column
|
||||||
|
v-else-if="col.slot || col.headerSlot"
|
||||||
|
:key="'slot-' + col.idx"
|
||||||
|
v-bind="colAttrs(col)"
|
||||||
|
>
|
||||||
|
<template #header="{ column }">
|
||||||
|
<slot v-if="col.headerSlot" :name="col.headerSlot" :data="col" :column="column">
|
||||||
|
<span>{{ column.label }}</span>
|
||||||
|
</slot>
|
||||||
|
<span v-else>{{ column.label }}</span>
|
||||||
|
</template>
|
||||||
|
<template #default="{ row, $index }">
|
||||||
|
<slot :name="'col-' + col.slot" :row="row" :index="$index">
|
||||||
|
<span>{{ row[col.prop] }}</span>
|
||||||
|
</slot>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<!-- 5. 普通数据列:直接按 prop 取 row 数据 -->
|
||||||
|
<el-table-column
|
||||||
|
v-else
|
||||||
|
:key="'col-' + col.idx"
|
||||||
|
v-bind="colAttrs(col)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<!-- 表格无数据时显示的占位内容 -->
|
||||||
|
<template #empty>
|
||||||
|
<slot name="empty" />
|
||||||
|
</template>
|
||||||
|
<!-- 表格最后一行之后追加的内容 -->
|
||||||
|
<template #append>
|
||||||
|
<slot name="append" />
|
||||||
|
</template>
|
||||||
|
<slot />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ==================== 底部:分页组件 ==================== -->
|
||||||
|
<!--
|
||||||
|
只传 pagination 对象({ current, size, total })才显示分页
|
||||||
|
page-change 事件回传 { current, size, total },父组件更新 pagination 后重新 fetchData
|
||||||
|
-->
|
||||||
|
<div ref="footer" class="page-table__footer" v-if="pagination">
|
||||||
|
<el-pagination
|
||||||
|
:current-page="pagination.current"
|
||||||
|
:page-size="pagination.size || 10"
|
||||||
|
:total="pagination.total"
|
||||||
|
:page-sizes="[10, 25, 50, 100, 250, 500]"
|
||||||
|
:disabled="loading"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="onSizeChange"
|
||||||
|
@current-change="onCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 自定义尾部内容 -->
|
||||||
|
<slot name="extra" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* PageTable — CRUD 表格便捷组合体
|
||||||
|
*
|
||||||
|
* 【核心职责】
|
||||||
|
* 1. 渲染顶部工具栏(增删改查等操作按钮,自动权限过滤)
|
||||||
|
* 2. 渲染数据表格(5 种列类型,自动 i18n 翻译)
|
||||||
|
* 3. 渲染底部分页
|
||||||
|
* 4. 表格高度自适应(可选)
|
||||||
|
*
|
||||||
|
* 【典型用法】
|
||||||
|
* <page-table
|
||||||
|
* :columns="columns"
|
||||||
|
* :data="tableData"
|
||||||
|
* :loading="loading"
|
||||||
|
* :toolbar-buttons="toolbarButtons"
|
||||||
|
* :row-buttons="rowButtons"
|
||||||
|
* :pagination="pagination"
|
||||||
|
* auto-height
|
||||||
|
* @page-change="onPageChange"
|
||||||
|
* @selection-change="onSelect"
|
||||||
|
* />
|
||||||
|
*
|
||||||
|
* 【内部事件流】
|
||||||
|
* toolbarButtons[i].onClick() → 父组件方法 → fetchData → data 更新 → 表格刷新
|
||||||
|
* el-pagination @change → emit('page-change') → 父组件更新 pagination → fetchData
|
||||||
|
* el-table @selection-change → emit('selection-change') → 父组件获取选中行
|
||||||
|
*
|
||||||
|
* 【与 useTableColumns / useTableButtons 配合】
|
||||||
|
* 详见文档:docs/sct-base-table-refactor-design.md
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'PageTable',
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* 列定义,由 useTableColumns() 生成
|
||||||
|
*
|
||||||
|
* 普通列:{ prop: 'code', label: '编码', minWidth: 120 }
|
||||||
|
* 操作列:{ prop: '_actions', label: '操作', width: 160, fixed: 'right' }
|
||||||
|
* 自定义列:{ prop: 'status', label: '状态', slot: true }
|
||||||
|
*
|
||||||
|
* 组件内部会按 type/slot/prop 自动分类渲染不同的 <el-table-column>
|
||||||
|
*/
|
||||||
|
columns: { type: Array, default: () => [] },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格行数据,直接传接口返回的数组
|
||||||
|
*/
|
||||||
|
data: { type: Array, default: () => [] },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示 loading 遮罩,通常在 fetchData 期间为 true
|
||||||
|
*/
|
||||||
|
loading: { type: Boolean, default: false },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格高度,不传则 el-table 按内容撑开
|
||||||
|
* 传 'auto' 或同时传 auto-height 启用自动计算(窗口高度 - 搜索区 - 工具栏 - 分页)
|
||||||
|
* 传数字/字符串(如 '500px')则固定高度
|
||||||
|
*/
|
||||||
|
height: { type: [String, Number], default: undefined },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用表格高度自适应:根据容器可视区域自动计算高度
|
||||||
|
* 启用后 height prop 被忽略,组件内部通过 ResizeObserver 持续计算
|
||||||
|
*/
|
||||||
|
autoHeight: { type: Boolean, default: false },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示表格边框,默认 true
|
||||||
|
*/
|
||||||
|
border: { type: Boolean, default: true },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行数据的唯一 key,默认 'id',用于 el-table 的 row-key
|
||||||
|
* 树形表格或需要保留选中状态时必需
|
||||||
|
*/
|
||||||
|
rowKey: { type: String, default: 'id' },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 顶部工具栏按钮列表,由 useTableButtons({ toolbar: [...] }) 生成
|
||||||
|
*
|
||||||
|
* 每个按钮字段:
|
||||||
|
* key - 唯一标识(必填)
|
||||||
|
* label - 显示文本,支持 i18n key(组件自动 $t() 翻译)
|
||||||
|
* icon - element-ui 图标名('el-icon-plus' 等)
|
||||||
|
* type - 按钮样式类型('primary' | 'success' | 'warning' | 'danger')
|
||||||
|
* auth - 权限 key,传给 useTableButtons 的第二个参数判断
|
||||||
|
* cssStyle - 自定义样式对象
|
||||||
|
* needSelection - true 的话需要表格有选中行才能点击
|
||||||
|
* onClick - 点击回调(由父组件绑定方法)
|
||||||
|
* hasPermission - 自动注入,由 useTableButtons 计算(不要手动设)
|
||||||
|
*/
|
||||||
|
toolbarButtons: { type: Array, default: () => [] },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行内操作按钮列表,由 useTableButtons({ row: [...] }) 生成
|
||||||
|
*
|
||||||
|
* 每个按钮字段:
|
||||||
|
* key / label / icon / auth / onClick — 同 toolbarButtons
|
||||||
|
* color - 'danger' 文字变红,用于删除等危险操作
|
||||||
|
* cssStyle - 默认 { marginRight: '10px', cursor: 'pointer' }
|
||||||
|
*/
|
||||||
|
rowButtons: { type: Array, default: () => [] },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页参数,传此 prop 才显示分页组件
|
||||||
|
*
|
||||||
|
* { current: 1, size: 10, total: 0 }
|
||||||
|
*
|
||||||
|
* total 通常在 getList 接口返回 res.count
|
||||||
|
*/
|
||||||
|
pagination: { type: Object, default: null },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 额外透传给 el-table 的原生属性,如 { stripe: true, size: 'medium' }
|
||||||
|
*/
|
||||||
|
tableAttrs: { type: Object, default: () => ({}) },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 额外透传给 el-table 的原生事件,如 { 'sort-change': handleSort }
|
||||||
|
*/
|
||||||
|
tableListeners: { type: Object, default: () => ({}) },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 帮助文档的跳转 URL。传了才显示工具栏右侧的问号按钮,点击新窗口打开
|
||||||
|
* 例:'/docs/factory-area-help.html'
|
||||||
|
*/
|
||||||
|
helpUrl: { type: String, default: '' },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 帮助按钮的文字,支持 i18n key(组件自动 $t() 翻译)
|
||||||
|
* 默认 '帮助'
|
||||||
|
*/
|
||||||
|
helpText: { type: String, default: '帮助' }
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
tableSelected: [], // 当前选中的行数据
|
||||||
|
computedHeight: null // autoHeight 时动态计算的高度
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
/**
|
||||||
|
* 最终使用的表格高度:
|
||||||
|
* - 用户明确传了 height(非 'auto')→ 直接用
|
||||||
|
* - autoHeight=true 或 height='auto' → 用动态计算的 computedHeight
|
||||||
|
* - 否则 undefined(el-table 按内容自适应)
|
||||||
|
*/
|
||||||
|
tableHeight () {
|
||||||
|
if (this.height && this.height !== 'auto') return this.height
|
||||||
|
if (this.autoHeight || this.height === 'auto') return this.computedHeight || undefined
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤后的工具栏按钮(排除无权限的)
|
||||||
|
*/
|
||||||
|
visibleToolbarButtons () {
|
||||||
|
return this.toolbarButtons.filter(b => b.hasPermission !== false)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤后的行内操作按钮(排除无权限的)
|
||||||
|
*/
|
||||||
|
visibleRowButtons () {
|
||||||
|
return this.rowButtons.filter(b => b.hasPermission !== false)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选中的行数
|
||||||
|
*/
|
||||||
|
selectedCount () {
|
||||||
|
return this.tableSelected.length
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表头样式:浅灰背景 + 黑色加粗文字
|
||||||
|
*/
|
||||||
|
headerCellStyle () {
|
||||||
|
return () => 'background-color: #F8F8F8; color: #000000; font-weight: 500;'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
if (this.autoHeight || this.height === 'auto') {
|
||||||
|
this.startAutoHeight()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
this.stopAutoHeight()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/* ============ 列处理 ============ */
|
||||||
|
|
||||||
|
colAttrs (col) {
|
||||||
|
const attrs = { ...col }
|
||||||
|
delete attrs.idx
|
||||||
|
delete attrs.slot
|
||||||
|
delete attrs.headerSlot
|
||||||
|
if (attrs.label) {
|
||||||
|
attrs.label = this.$t(attrs.label)
|
||||||
|
}
|
||||||
|
return attrs
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ============ 表格事件 ============ */
|
||||||
|
|
||||||
|
onSelectionChange (val) {
|
||||||
|
this.tableSelected = val
|
||||||
|
this.$emit('selection-change', val)
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ============ 帮助按钮 ============ */
|
||||||
|
|
||||||
|
openHelp () {
|
||||||
|
if (this.helpUrl) {
|
||||||
|
window.open(this.helpUrl, '_blank')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ============ 分页事件 ============ */
|
||||||
|
|
||||||
|
onSizeChange (size) {
|
||||||
|
this.$emit('page-change', {
|
||||||
|
current: 1,
|
||||||
|
size,
|
||||||
|
total: this.pagination.total
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onCurrentChange (current) {
|
||||||
|
this.$emit('page-change', {
|
||||||
|
current,
|
||||||
|
size: this.pagination.size,
|
||||||
|
total: this.pagination.total
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/* ============ 自适应高度 ============ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动表格高度自适应
|
||||||
|
*
|
||||||
|
* 原理:
|
||||||
|
* 1. CSS flex 布局让 page-table 占满父容器 100% 高度
|
||||||
|
* 2. 工具栏和分页各占自然高度(flex-shrink: 0)
|
||||||
|
* 3. tableWrapper 中间区域自动填充剩余空间(flex: 1 + min-height: 0)
|
||||||
|
* 4. ResizeObserver 监听 tableWrapper 的实际渲染高度,赋给 el-table
|
||||||
|
*
|
||||||
|
* 这样 el-table 永远精确等于可用空间,不会产生外层滚动条
|
||||||
|
*/
|
||||||
|
startAutoHeight () {
|
||||||
|
this.stopAutoHeight()
|
||||||
|
|
||||||
|
this._resizeObserver = new ResizeObserver(() => {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const wrapper = this.$refs.tableWrapper
|
||||||
|
if (wrapper) {
|
||||||
|
this.computedHeight = wrapper.clientHeight
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.$refs.tableWrapper) {
|
||||||
|
this._resizeObserver.observe(this.$refs.tableWrapper)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const wrapper = this.$refs.tableWrapper
|
||||||
|
if (wrapper) {
|
||||||
|
this.computedHeight = wrapper.clientHeight
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
stopAutoHeight () {
|
||||||
|
if (this._resizeObserver) {
|
||||||
|
this._resizeObserver.disconnect()
|
||||||
|
this._resizeObserver = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.page-table {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
/* 自适应高度模式:占满父容器 100%,禁止自身溢出 */
|
||||||
|
.page-table--auto {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.page-table__toolbar {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.page-table__toolbar-left {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.page-table__help-btn {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
.page-table__body {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.page-table__footer {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.action-btn {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.action-btn--danger {
|
||||||
|
color: #F56C6C;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
28
src/composables/useI18n.js
Normal file
28
src/composables/useI18n.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* i18n Mixin 工厂:消除每个页面重复写 tkey() 方法
|
||||||
|
*
|
||||||
|
* @param {string} prefix 页面的 i18n key 前缀,如 'page.production_master_data.factory_model.factory_area'
|
||||||
|
* @returns {Object} Vue mixin
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* import { i18nMixin } from '@/composables/useI18n'
|
||||||
|
* export default {
|
||||||
|
* mixins: [i18nMixin('page.production_master_data.factory_model.factory_area')],
|
||||||
|
* // 模板中当前页面用 $t(key('code'))
|
||||||
|
* // 公共翻译用 $t(ckey('help')) → 'page.common.help'
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
export function i18nMixin (prefix) {
|
||||||
|
return {
|
||||||
|
methods: {
|
||||||
|
key (suffix) {
|
||||||
|
return prefix + '.' + suffix
|
||||||
|
},
|
||||||
|
ckey (suffix) {
|
||||||
|
return 'page.common.' + suffix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default i18nMixin
|
||||||
48
src/composables/useTableButtons.js
Normal file
48
src/composables/useTableButtons.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* 按钮定义工具:消除 buttonList / tableButtonList 重复定义
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {Array} options.toolbar 顶部工具栏按钮
|
||||||
|
* @param {Array} options.row 行内操作按钮
|
||||||
|
* @param {Function} permissionCheck 权限校验函数,默认 $permission
|
||||||
|
* @returns {{ toolbarButtons: Array, rowButtons: Array }}
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* import useTableButtons from '@/composables/useTableButtons'
|
||||||
|
* // 在组件 data() 或 created() 中调用
|
||||||
|
* const { toolbarButtons, rowButtons } = useTableButtons({
|
||||||
|
* toolbar: [{ key: 'add', label: '新建', type: 'primary', auth: '/xxx/create', onClick: this.openDialog }],
|
||||||
|
* row: [{ key: 'edit', label: '编辑', auth: '/xxx/edit', onClick: this.handleEdit }],
|
||||||
|
* }, this.$permission)
|
||||||
|
*/
|
||||||
|
export function useTableButtons (options = {}, permissionCheck) {
|
||||||
|
const check = permissionCheck || (() => true)
|
||||||
|
|
||||||
|
const toolbarButtons = (options.toolbar || []).map(btn => ({
|
||||||
|
key: btn.key || btn.label,
|
||||||
|
label: btn.label,
|
||||||
|
icon: btn.icon,
|
||||||
|
type: btn.type || '',
|
||||||
|
size: btn.size || 'mini',
|
||||||
|
auth: btn.auth,
|
||||||
|
cssStyle: btn.cssStyle || {},
|
||||||
|
onClick: btn.onClick,
|
||||||
|
hasPermission: btn.auth ? check(btn.auth) : true
|
||||||
|
}))
|
||||||
|
|
||||||
|
const rowButtons = (options.row || []).map(btn => ({
|
||||||
|
key: btn.key || btn.label,
|
||||||
|
label: btn.label,
|
||||||
|
icon: btn.icon,
|
||||||
|
color: btn.color || '',
|
||||||
|
cssStyle: btn.cssStyle || { marginRight: '10px', cursor: 'pointer' },
|
||||||
|
auth: btn.auth,
|
||||||
|
confirm: btn.confirm || false,
|
||||||
|
onClick: btn.onClick,
|
||||||
|
hasPermission: btn.auth ? check(btn.auth) : true
|
||||||
|
}))
|
||||||
|
|
||||||
|
return { toolbarButtons, rowButtons }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useTableButtons
|
||||||
46
src/composables/useTableColumns.js
Normal file
46
src/composables/useTableColumns.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* 列定义工具:消除手动分配 idx,支持 _actions 约定
|
||||||
|
*
|
||||||
|
* @param {Array<Object>} rawColumns 列配置数组
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {number} options.selectionWidth 复选框列宽度,默认 55,传 0 不显示
|
||||||
|
* @param {number} options.indexWidth 序号列宽度,默认 60,传 0 不显示
|
||||||
|
* @returns {Array<Object>} 补齐 idx 后的列数组
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const columns = useTableColumns([
|
||||||
|
* { prop: 'code', label: '编码', minWidth: 120 },
|
||||||
|
* { prop: 'name', label: '名称' },
|
||||||
|
* { prop: '_actions', label: '操作', width: 180, fixed: 'right' },
|
||||||
|
* ])
|
||||||
|
*/
|
||||||
|
export function useTableColumns (rawColumns, options = {}) {
|
||||||
|
const { selectionWidth = 55, indexWidth = 0 } = options
|
||||||
|
|
||||||
|
const result = []
|
||||||
|
|
||||||
|
if (selectionWidth > 0) {
|
||||||
|
result.push({ idx: 0, type: 'selection', width: selectionWidth })
|
||||||
|
}
|
||||||
|
if (indexWidth > 0) {
|
||||||
|
result.push({ idx: result.length, type: 'index', width: indexWidth, label: '#' })
|
||||||
|
}
|
||||||
|
|
||||||
|
let slotIdx = 100
|
||||||
|
rawColumns.forEach((col, i) => {
|
||||||
|
const clean = { ...col }
|
||||||
|
if (clean.prop === '_actions') {
|
||||||
|
clean.slot = '_actions'
|
||||||
|
clean.idx = slotIdx++
|
||||||
|
} else if (clean.slot || clean.headerSlot) {
|
||||||
|
clean.idx = slotIdx++
|
||||||
|
} else {
|
||||||
|
clean.idx = result.length
|
||||||
|
}
|
||||||
|
result.push(clean)
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useTableColumns
|
||||||
@@ -2,12 +2,47 @@
|
|||||||
"_element": "en",
|
"_element": "en",
|
||||||
"_name": "English",
|
"_name": "English",
|
||||||
"page": {
|
"page": {
|
||||||
|
"common": {
|
||||||
|
"help": "Help"
|
||||||
|
},
|
||||||
"demo": {
|
"demo": {
|
||||||
"playground": {
|
"playground": {
|
||||||
"locales": {
|
"locales": {
|
||||||
"text": "D2Admin is a fully open source and free enterprise back-end product front-end integration solution, using the latest front-end technology stack, has prepared most of the project preparations, and with a lot of sample code to help the management system agile development."
|
"text": "D2Admin is a fully open source and free enterprise back-end product front-end integration solution, using the latest front-end technology stack, has prepared most of the project preparations, and with a lot of sample code to help the management system agile development."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"production_master_data": {
|
||||||
|
"factory_model": {
|
||||||
|
"factory_area": {
|
||||||
|
"search": "Search",
|
||||||
|
"reset": "Reset",
|
||||||
|
"enter_code": "Please enter area code",
|
||||||
|
"enter_name": "Please enter area name",
|
||||||
|
"operation_success": "Operation succeeded",
|
||||||
|
"create_success": "Created successfully",
|
||||||
|
"edit_success": "Updated successfully",
|
||||||
|
"delete_success": "Deleted successfully",
|
||||||
|
"sort": "No.",
|
||||||
|
"code": "Area Code",
|
||||||
|
"name": "Area Name",
|
||||||
|
"remark": "Remark",
|
||||||
|
"operation": "Actions",
|
||||||
|
"add": "Add",
|
||||||
|
"edit": "Edit",
|
||||||
|
"delete": "Delete",
|
||||||
|
"remark_required": "Please enter remark",
|
||||||
|
"remark_length": "Length should be 1 to 100 characters",
|
||||||
|
"add_title": "Add Area",
|
||||||
|
"edit_title": "Edit Area",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"tip": "Tip",
|
||||||
|
"confirm_delete": "Are you sure to delete?",
|
||||||
|
"validation_fail": "Validation failed",
|
||||||
|
"please_enter": "Please enter {name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,47 @@
|
|||||||
"_element": "zh-CN",
|
"_element": "zh-CN",
|
||||||
"_name": "简体中文",
|
"_name": "简体中文",
|
||||||
"page": {
|
"page": {
|
||||||
|
"common": {
|
||||||
|
"help": "帮 助"
|
||||||
|
},
|
||||||
"demo": {
|
"demo": {
|
||||||
"playground": {
|
"playground": {
|
||||||
"locales": {
|
"locales": {
|
||||||
"text": "D2Admin 是一个完全 开源免费 的企业中后台产品前端集成方案,使用最新的前端技术栈,已经做好大部分项目前期准备工作,并且带有大量示例代码,助力管理系统敏捷开发。"
|
"text": "D2Admin 是一个完全 开源免费 的企业中后台产品前端集成方案,使用最新的前端技术栈,已经做好大部分项目前期准备工作,并且带有大量示例代码,助力管理系统敏捷开发。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"production_master_data": {
|
||||||
|
"factory_model": {
|
||||||
|
"factory_area": {
|
||||||
|
"search": "查询",
|
||||||
|
"reset": "重置",
|
||||||
|
"enter_code": "请输入所区编码",
|
||||||
|
"enter_name": "请输入所区名称",
|
||||||
|
"operation_success": "操作成功",
|
||||||
|
"create_success": "新增成功",
|
||||||
|
"edit_success": "编辑成功",
|
||||||
|
"delete_success": "删除成功",
|
||||||
|
"sort": "序号",
|
||||||
|
"code": "所区编码",
|
||||||
|
"name": "所区名称",
|
||||||
|
"remark": "备注",
|
||||||
|
"operation": "操作",
|
||||||
|
"add": "新 增",
|
||||||
|
"edit": "编 辑",
|
||||||
|
"delete": "删 除",
|
||||||
|
"remark_required": "请输入备注",
|
||||||
|
"remark_length": "长度在 1 到 100 个字符",
|
||||||
|
"add_title": "新增所区",
|
||||||
|
"edit_title": "编辑所区",
|
||||||
|
"cancel": "取消",
|
||||||
|
"confirm": "确定",
|
||||||
|
"tip": "提示",
|
||||||
|
"confirm_delete": "确定要执行该操作吗?",
|
||||||
|
"validation_fail": "校验失败",
|
||||||
|
"please_enter": "请输入{name}"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/router/modules/production-master-data.js
Normal file
18
src/router/modules/production-master-data.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
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-')
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import playground from './modules/playground'
|
import playground from './modules/playground'
|
||||||
import plugins from './modules/plugins'
|
import plugins from './modules/plugins'
|
||||||
import components from './modules/components'
|
import components from './modules/components'
|
||||||
|
import productionMasterData from './modules/production-master-data'
|
||||||
|
|
||||||
import layoutHeaderAside from '@/layout/header-aside'
|
import layoutHeaderAside from '@/layout/header-aside'
|
||||||
|
|
||||||
@@ -54,7 +55,8 @@ const frameIn = [
|
|||||||
},
|
},
|
||||||
playground,
|
playground,
|
||||||
plugins,
|
plugins,
|
||||||
components
|
components,
|
||||||
|
productionMasterData
|
||||||
]
|
]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,299 @@
|
|||||||
|
<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"
|
||||||
|
:help-text="$t(ckey('help'))"
|
||||||
|
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"
|
||||||
|
:label-width="'100px'"
|
||||||
|
:submitting="submitting"
|
||||||
|
:confirm-text="$t(key('confirm'))"
|
||||||
|
:cancel-text="$t(key('cancel'))"
|
||||||
|
@submit="onDialogSubmit"
|
||||||
|
@close="onDialogClose"
|
||||||
|
/>
|
||||||
|
</d2-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
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: 'production-master-data-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_configuration/factory_model/factory_area/create',
|
||||||
|
onClick: this.openAdd
|
||||||
|
}
|
||||||
|
],
|
||||||
|
row: [
|
||||||
|
{
|
||||||
|
key: 'edit',
|
||||||
|
label: this.key('edit'),
|
||||||
|
icon: 'el-icon-edit',
|
||||||
|
auth: '/production_configuration/factory_model/factory_area/edit',
|
||||||
|
onClick: this.openEdit
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delete',
|
||||||
|
label: this.key('delete'),
|
||||||
|
icon: 'el-icon-delete',
|
||||||
|
color: 'danger',
|
||||||
|
auth: '/production_configuration/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) {
|
||||||
|
// 取消删除 / 请求失败时不处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.search-bar {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
/deep/ .el-form-item--mini.el-form-item {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -85,7 +85,10 @@ module.exports = {
|
|||||||
css: {
|
css: {
|
||||||
loaderOptions: {
|
loaderOptions: {
|
||||||
sass: {
|
sass: {
|
||||||
additionalData: '@use "@/assets/style/public.scss" as *;'
|
additionalData: '@use "@/assets/style/public.scss" as *;',
|
||||||
|
sassOptions: {
|
||||||
|
silenceDeprecations: ['legacy-js-api', 'import']
|
||||||
|
}
|
||||||
},
|
},
|
||||||
less: {
|
less: {
|
||||||
lessOptions: {
|
lessOptions: {
|
||||||
|
|||||||
83
后台Webman界面截图对照表.md
Normal file
83
后台Webman界面截图对照表.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# 系统功能清单 - 界面截图对照表
|
||||||
|
|
||||||
|
| 一级模块 | 二级模块 | 三级模块 | 功能说明 | 备注 | 文档内容情况 | 中文截图 | 英文截图 |
|
||||||
|
|:---|:---|:---|:---|:---|:---|:---|:---|
|
||||||
|
| **系统设置 (System Administration)** | 用户管理 (User Management) | 角色 (Role) | 设置用户组并分配权限(增删改查用户组,并实现权限分配功能) | | √ | √ | √ |
|
||||||
|
| **系统设置 (System Administration)** | 用户管理 (User Management) | 用户 (User) | 管理用户账号并绑定对应角色 | | √ | √ | √|
|
||||||
|
| **系统设置 (System Administration)** | 菜单管理 (Menu Management) | 菜单配置 (Menu Configuration) | 系统菜单配置 | | √ |√ | √|
|
||||||
|
| **系统设置 (System Administration)** | 系统助手 (System Utilities) | 操作日志 (Operation Logs) | 系统操作日志 | | √ |√ | √ |
|
||||||
|
| **系统设置 (System Administration)** | 系统助手 (System Utilities) | 接口日志 (API Logs) | 与设备对接流程交互日志(支持按 IP 和接口名称查询) | | √ |√ | √|
|
||||||
|
| **系统设置 (System Administration)** | 系统监控 (System Monitoring) | 监控设置 (Monitoring Configuration) | 系统监控配置 | | √ | √| √|
|
||||||
|
| **生产配置 (Production Master Data)** | 工厂模型 (Factory Model) | 产线设置 (Production Line) | 管理产线(支持增删改查) | | √ | √ | √|
|
||||||
|
| **生产配置 (Production Master Data)** | 工厂模型 (Factory Model) | 工厂区域 (Factory Area) | 管理工厂区域(支持增删改查) | | √ | √ | √|
|
||||||
|
| **生产配置 (Production Master Data)** | 工艺模型 (Process Model) | 工艺流程类别 (Process Category) | 工艺流程类别的增删改查 | | √| √ | √ |
|
||||||
|
| **生产配置 (Production Master Data)** | 工艺模型 (Process Model) | 工序单元 (Process Step) | 配置工序单元(节点),支持参数预设 | | √ | √| √ |
|
||||||
|
| **生产配置 (Production Master Data)** | 工艺模型 (Process Model) | 工艺流程 (Process Routing) | 设置生产工艺流程并管理流程卡 | | √ | √ | √|
|
||||||
|
| **生产配置 (Production Master Data)** | 产品管理 (Product Management) | 产品列表 (Product List) | 产品管理(增删改查) | | √ | √ | √ |
|
||||||
|
| **生产配置 (Production Master Data)** | 产品管理 (Product Management) | 不良管理 (Defect Management) | 不良代码及描述管理,支持批量导入 | | √ | √ | √ |
|
||||||
|
| **生产配置 (Production Master Data)** | 物料模型 (Material Model) | 物料类别列表 (Material Category) | 区分原材料和半成品 | | √ | √| √ |
|
||||||
|
| **生产配置 (Production Master Data)** | 物料模型 (Material Model) | 物料信息管理 (Material Master) | 维护物料编码、名称、规格等属性 | | √ | √ | √|
|
||||||
|
| **生产配置 (Production Master Data)** | 物料模型 (Material Model) | BOM物料清单 (Bill of Materials) | 产品BOM管理 | | √ | √ | √|
|
||||||
|
| **生产配置 (Production Master Data)** | 物料模型 (Material Model) | 计量单位 (Unit of Measure) | 计量单位配置与管理 | | √ | √ | √|
|
||||||
|
| **生产配置 (Production Master Data)** | SPC采集模型 (SPC Configuration) | SPC采集配置 (Data Collection Configuration) | 配置SPC采集参数 | | √| √ | √ |
|
||||||
|
| **生产配置 (Production Master Data)** | 班组模型 (Team Model) | 班组管理 (Team Management) | 管理生产班组 | | √ | √| √|
|
||||||
|
| **生产配置 (Production Master Data)** | 班组模型 (Team Model) | 班次管理 (Shift Management) | 管理生产班次 | | √ | √ | √|
|
||||||
|
| **生产配置 (Production Master Data)** | 班组模型 (Team Model) | 排班日历 (Scheduling Calendar) | 查看排班日历 | | √ | √ | √|
|
||||||
|
| **设备模型 (Equipment Management)** | 设备类别 (Equipment Category) | 设备类别 (Equipment Category) | 管理设备类别 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备信息 (Equipment Management) | 设备信息 (Equipment Registry) | 管理设备信息 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备点检 (Inspection Management) | 设备点检项目 (Inspection Items) | 点检项目管理 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备点检 (Inspection Management) | 设备点检记录 (Inspection Records) | 点检记录管理 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备点检 (Inspection Management) | 设备点检日志 (Inspection Logs) | 点检日志查询 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备保养 (Maintenance Management) | 设备保养项目 (Maintenance Items) | 保养项目管理 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备保养 (Maintenance Management) | 设备保养详情 (Maintenance Details) | 保养详情管理 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备保养 (Maintenance Management) | 设备保养日志 (Maintenance Logs) | 保养日志查询 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备维修 (Repair Management) | 设备维修管理 (Repair Management) | 维修管理 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备维修 (Repair Management) | 设备维修日志 (Repair Logs) | 维修日志查询 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备损耗品 (Consumables Management) | 设备损耗品类别 (Consumables Category) | 损耗品分类管理 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备损耗品 (Consumables Management) | 设备损耗品项目 (Consumables Items) | 损耗品项目管理 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备损耗品 (Consumables Management) | 设备损耗品寿命管理 (Consumables Lifecycle Management) | 寿命管理 | | √ | √ | √ |
|
||||||
|
| **设备模型 (Equipment Management)** | 设备损耗品 (Consumables Management) | 设备损耗品更换日志 (Replacement Logs) | 更换记录查询 | | √ | √ | √ |
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产批次管理 (Batch Management) | 批次列表 (Batch List) | 批次管理 | | √ | √ | √|
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产批次管理 (Batch Management) | 批次托盘 (Tray Tracking) | 托盘跟踪与操作 | | √ |√ | √|
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产批次管理 (Batch Management) | 生产批次不良报表 (Batch Defect Report) | 不良报表 | | √ | √ | √|
|
||||||
|
| **计划与生产 (Planning & Production)** | 预警中心 (Alert Center) | 预警中心 (Alert Center) | 预警中心 | | √ | √ | √ |
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产监控 (Production Monitoring) | 物料监控 (Material Monitoring) | 物料监控 | | √ | √ | √|
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产监控 (Production Monitoring) | 电池复投管理 (Rework Management) | 返工管理 | | √ | √ | √|
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产监控 (Production Monitoring) | 托盘管理 (Tray Management) | 托盘管理 | | √ | √ | √|
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产监控 (Production Monitoring) | 托盘登录 (Tray Registration) | 托盘登记 | | √ | √ | √|
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产监控 (Production Monitoring) | 设备监控 (Equipment Monitoring) | 设备监控 | | √ | √ |√ |
|
||||||
|
| **计划与生产 (Planning & Production)** | 生产监控 (Production Monitoring) | 电池工序管理 (Process Execution) | 工序管理 | | √ |√ | √|
|
||||||
|
| **质量管理 (Quality Management)** | 过程控制 (Process Control) | 检验类别管理 (Inspection Type Management) | | | √ | √ | √ |
|
||||||
|
| **质量管理 (Quality Management)** | 过程控制 (Process Control) | 首巡检项目配置 (First Article Inspection Configuration) | | | √ | √ | √ |
|
||||||
|
| **质量管理 (Quality Management)** | 过程控制 (Process Control) | 首巡检录入 (First Article Inspection Records) | | | √ | √ | √ |
|
||||||
|
| **质量管理 (Quality Management)** | 过程控制 (Process Control) | 首巡检报表 (First Article Inspection Reports) | | | √ | √ | √ |
|
||||||
|
| **质量管理 (Quality Management)** | 检验控制 (Inspection Management) | 检验单管理 (Inspection Orders) | | |√ |√ | |
|
||||||
|
| **质量管理 (Quality Management)** | 检验控制 (Inspection Management) | 检验标准 (Inspection Standards) | | |√ | √ | |
|
||||||
|
| **质量管理 (Quality Management)** | 检验控制 (Inspection Management) | 接收质量限 (AQL Standards) | | |√ |√ | |
|
||||||
|
| **质量管理 (Quality Management)** | 检验控制 (Inspection Management) | 检测方案维护 (Inspection Plans) | | |√ | √ | |
|
||||||
|
| **质量管理 (Quality Management)** | 检验控制 (Inspection Management) | 检验项目 (Inspection Items) | | |√ | √ | |
|
||||||
|
| **质量管理 (Quality Management)** | 检验控制 (Inspection Management) | 抽样方案配置 (Sampling Plans) | | |√ |√ | |
|
||||||
|
| **质量管理 (Quality Management)** | SPC统计过程控制 (SPC Control) | SPC渲染条件配置 (SPC Configuration) | | |√ | √ | √ |
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | XBar-R (XBar-R Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | XBar-S (XBar-S Chart) | | |√ | √ | √ |
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | I-MR (I-MR Chart) | | |√ | √ | |
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | Levey-Jennings (Levey-Jennings Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | EWMA (EWMA Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | CUSUM (CUSUM Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | MA (Moving Average Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | MAMR (Moving Average MR Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | MAMS (Moving Average S Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计量型报表 (SPC Variable Charts) | CPK (Process Capability Index) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计数型报表 (SPC Attribute Charts) | DPMO (DPMO) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计数型报表 (SPC Attribute Charts) | PChart (P Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计数型报表 (SPC Attribute Charts) | NPChart (NP Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计数型报表 (SPC Attribute Charts) | CChart (C Chart) | | |√ | √ | √|
|
||||||
|
| **质量管理 (Quality Management)** | SPC计数型报表 (SPC Attribute Charts) | UChart (U Chart) | | |√ | √ | √|
|
||||||
|
| **数据中台 (Data Platform)** | 基础追溯 (Traceability) | 反向追溯 (Backward Traceability) | | |√ | √ | √ |
|
||||||
|
| **数据中台 (Data Platform)** | 基础追溯 (Traceability) | 正向追溯 (Forward Traceability) | | |√ | √ | √ |
|
||||||
|
| **数据中台 (Data Platform)** | 基础追溯 (Traceability) | 电池曲线 (Battery Curve) | | | √| √ | √ |
|
||||||
|
| **数据中台 (Data Platform)** | 基础追溯 (Traceability) | 托盘追溯 (Tray Traceability) | | | √ | √ | √ |
|
||||||
|
| **数据中台 (Data Platform)** | 基础追溯 (Traceability) | 电池追溯 (Battery Traceability) | | | √ | √ | √ |
|
||||||
|
| **数据中台 (Data Platform)** | 生产报表 (Production Reports) | 设备履历报表 (Equipment History Report) | | | √ | √ | √ |
|
||||||
|
| **数据中台 (Data Platform)** | 生产报表 (Production Reports) | 电池详情报表 (Battery Detail Report) | | | √ | √ | √ |
|
||||||
|
| **数据中台 (Data Platform)** | 相关性分析 (Correlation Analysis) | 鹰眼 (Hawkeye) | | | √| √ | √ |
|
||||||
Reference in New Issue
Block a user