commit content
This commit is contained in:
147
.cursor/plans/mbom_editable_material_list_1f6749a4.plan.md
Normal file
147
.cursor/plans/mbom_editable_material_list_1f6749a4.plan.md
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
name: Mbom editable material list
|
||||
overview: 在生产计划单表单的物料清单区域中,将供应方式、下发车间、下发时间、下发状态等列从只读改为可编辑,并在后端新增 issue_date 字段,前端对接已有的 updateMbom 和 issueToWorkshop 接口。
|
||||
todos:
|
||||
- id: db-migration
|
||||
content: 新建 SQL 脚本,在 erp_mp_mbom 表新增 issue_date 列
|
||||
status: completed
|
||||
- id: backend-entity
|
||||
content: 修改 MpMbom.java 新增 issueDate 字段及 getter/setter
|
||||
status: completed
|
||||
- id: backend-mapper
|
||||
content: 修改 MpMbomMapper.xml 新增 issue_date 列映射、插入、更新
|
||||
status: completed
|
||||
- id: frontend-types
|
||||
content: 更新 productionPlan.ts 和 mbom.ts 的接口定义,新增 mbomId、workshopId、issueDate
|
||||
status: completed
|
||||
- id: frontend-form
|
||||
content: 改造 form.vue 物料清单表格:供应方式/下发车间/下发时间/下发状态改为可编辑
|
||||
status: completed
|
||||
- id: frontend-save
|
||||
content: 新增物料清单行级别保存逻辑,对接 updateMbom/issueToWorkshop API
|
||||
status: completed
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# 生产计划单 - 物料清单可编辑功能
|
||||
|
||||
## 现状分析
|
||||
|
||||
生产计划单表单 [form.vue](erp-frontend-vue/src/views/Production/PlanOrder/form.vue) 中的"物料清单"区域(第 240-283 行)目前所有列均为只读展示。
|
||||
|
||||
后端已有的接口能力:
|
||||
|
||||
- `PUT /erp/mp/mbom` — 更新物料清单整体(含 supplyType、workshopId、workshopName、issueStatus)
|
||||
- `PUT /erp/mp/mbom/issue/{mbomId}/{workshopId}/{workshopName}` — 下发到车间
|
||||
- 车间列表 API:`GET /mes/md/workshop/list`
|
||||
|
||||
**缺失**:后端 `MpMbom` 实体和数据库表 `erp_mp_mbom` 中没有 `issue_date`(下发时间)字段。
|
||||
|
||||
## 修改方案
|
||||
|
||||
### 第一部分:后端 - 新增 issue_date 字段
|
||||
|
||||
**1. 数据库 SQL**
|
||||
|
||||
新建迁移脚本,在 `erp_mp_mbom` 表新增 `issue_date` 列:
|
||||
|
||||
```sql
|
||||
ALTER TABLE erp_mp_mbom ADD COLUMN issue_date datetime DEFAULT NULL COMMENT '下发时间' AFTER issue_status;
|
||||
```
|
||||
|
||||
**2. Java 实体 [MpMbom.java**](mom-backend/ktg-mes/src/main/java/com/ktg/mes/mp/domain/MpMbom.java)
|
||||
|
||||
在 `issueStatus` 字段后新增:
|
||||
|
||||
```java
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "下发时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date issueDate;
|
||||
```
|
||||
|
||||
及对应的 getter/setter。
|
||||
|
||||
**3. MyBatis Mapper [MpMbomMapper.xml**](mom-backend/ktg-mes/src/main/resources/mapper/mp/MpMbomMapper.xml)
|
||||
|
||||
- `resultMap` 增加 `<result property="issueDate" column="issue_date" />`
|
||||
- `selectMpMbomVo` SQL 的列列表中增加 `issue_date`
|
||||
- `insertMpMbom` 增加 issueDate 的插入
|
||||
- `updateMpMbom` 增加 issueDate 的更新
|
||||
|
||||
**4. issueToWorkshop 方法更新**
|
||||
|
||||
在 [MpMbomController.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/mp/controller/MpMbomController.java) 的 `issueToWorkshop` 方法中,下发时自动设置 `issueDate = new Date()`。或者保持不变,由前端通过 `PUT /erp/mp/mbom` 自行设置 issueDate。
|
||||
|
||||
### 第二部分:前端 - 物料清单表格可编辑
|
||||
|
||||
**5. 更新 TypeScript 接口**
|
||||
|
||||
在 [productionPlan.ts](erp-frontend-vue/src/api/productionPlan.ts) 的 `MbomLine` 接口中增加:
|
||||
|
||||
```typescript
|
||||
export interface MbomLine {
|
||||
mbomId?: number // 新增
|
||||
mbomCode?: string
|
||||
mbomStatus?: string
|
||||
businessType?: string
|
||||
issueStatus?: string
|
||||
itemCode?: string
|
||||
itemName?: string
|
||||
unitName?: string
|
||||
supplyType?: string
|
||||
productionQty?: number
|
||||
workshopId?: number // 新增
|
||||
workshopName?: string
|
||||
issueDate?: string // 新增
|
||||
}
|
||||
```
|
||||
|
||||
在 [mbom.ts](erp-frontend-vue/src/api/mbom.ts) 的 `Mbom` 接口中增加 `issueDate?: string`。
|
||||
|
||||
**6. 修改 [form.vue](erp-frontend-vue/src/views/Production/PlanOrder/form.vue) 物料清单表格**
|
||||
|
||||
将第 250-282 行的物料清单 `<el-table>` 中以下列从纯文本改为可编辑组件:
|
||||
|
||||
- **供应方式 (supplyType)** — 改为 `el-select`,选项:`生产/加工/采购/委外`(对应 SELF_MADE/PROCESSING/PURCHASE/OUTSOURCE),并增加"转委外"快捷操作链接
|
||||
- **下发车间 (workshopName)** — 改为 `el-select`,数据源为车间列表(调用 `listWorkshop` API),选中后同时保存 `workshopId` 和 `workshopName`
|
||||
- **下发时间 (issueDate)** — 新增列,使用 `el-date-picker` 组件
|
||||
- **下发状态 (issueStatus)** — 改为 `el-switch` 组件,开 = "ISSUED" / 关 = "" 或 "PENDING"
|
||||
|
||||
参考截图中的交互方式:
|
||||
|
||||
```
|
||||
| 供应方式 | 生产数量 | 下发车间 | 操作 |
|
||||
| 生产 [转委外] | 970 | 加工车间 [开关] 2026-02-10 | 齐套/BOM/生产 |
|
||||
| 加工 [转委外] | 970 | 装配车间 [开关] 2026-02-11 | 齐套/BOM/生产 |
|
||||
```
|
||||
|
||||
**7. 新增数据和方法**
|
||||
|
||||
- 在 `<script setup>` 中引入 `listWorkshop` API 并加载车间列表
|
||||
- 引入 `updateMbom` 和 `issueToWorkshop` API
|
||||
- 新增 `handleMbomSupplyTypeChange(row, val)` — 调用 updateMbom 保存供应方式
|
||||
- 新增 `handleMbomWorkshopChange(row, workshop)` — 更新 workshopId/workshopName
|
||||
- 新增 `handleMbomIssueToggle(row)` — 切换下发状态,开时调用 issueToWorkshop + 设置 issueDate
|
||||
- 新增 `handleMbomIssueDateChange(row, date)` — 更新 issueDate
|
||||
- 新增 `saveMbomRow(row)` — 通用保存方法,调用 `updateMbom`
|
||||
- 编辑条件判断:仅当生产计划已审核 (`isOrderApproved`) 且物料清单存在时允许编辑
|
||||
|
||||
**8. 更新 loadPlanData 中 mbomList 映射**
|
||||
|
||||
在 `loadPlanData()` 方法(第 677 行)中映射 mbomList 时,确保 `mbomId`、`workshopId`、`issueDate` 等新字段被正确保留。
|
||||
|
||||
## 涉及的文件
|
||||
|
||||
后端:
|
||||
|
||||
- [MpMbom.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/mp/domain/MpMbom.java) — 新增 issueDate 字段和 getter/setter
|
||||
- [MpMbomMapper.xml](mom-backend/ktg-mes/src/main/resources/mapper/mp/MpMbomMapper.xml) — 新增 issue_date 列映射
|
||||
- [MpMbomController.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/mp/controller/MpMbomController.java) — issueToWorkshop 方法设置 issueDate(可选)
|
||||
- 新建 SQL 迁移脚本
|
||||
|
||||
前端:
|
||||
|
||||
- [productionPlan.ts](erp-frontend-vue/src/api/productionPlan.ts) — MbomLine 接口扩展
|
||||
- [mbom.ts](erp-frontend-vue/src/api/mbom.ts) — Mbom 接口扩展
|
||||
- [form.vue](erp-frontend-vue/src/views/Production/PlanOrder/form.vue) — 物料清单表格改为可编辑 + 新增保存逻辑
|
||||
|
||||
446
.cursor/plans/mom-ui_tech_stack_migration_ddb51afc.plan.md
Normal file
446
.cursor/plans/mom-ui_tech_stack_migration_ddb51afc.plan.md
Normal file
@@ -0,0 +1,446 @@
|
||||
---
|
||||
name: MOM-UI Tech Stack Migration
|
||||
overview: 将 mom-backend-ui 从 Vue CLI + Vue 2 + Element UI 渐进式升级到 Vite + Vue 3 + Element Plus,与 erp-frontend-vue 技术栈保持一致,方便后续合并。
|
||||
todos:
|
||||
- id: phase1-vite-setup
|
||||
content: "Phase 1: 创建 vite.config.js,移动 index.html 到根目录,更新 package.json scripts,安装 Vite + Vue 3 + @vue/compat 依赖,移除 Vue CLI/Webpack 依赖"
|
||||
status: completed
|
||||
- id: phase2-core-modules
|
||||
content: "Phase 2: 更新 main.js (createApp),升级 Vue Router 4,升级 Vuex 4,替换 SVG 图标系统 (vite-plugin-svg-icons),修改 permission.js"
|
||||
status: completed
|
||||
- id: phase3a-element-plus-deps
|
||||
content: "Phase 3a: 替换 Element Plus 依赖 + 更新 main.js 导入 + 迁移公共组件 (31 个 dialog 组件) + 迁移采购入库页面 (4 个 Vue 文件) 作为验证试点"
|
||||
status: in_progress
|
||||
- id: phase3a-2-layout-components
|
||||
content: "Phase 3a-2: 迁移 src/layout/ + src/components/ 中非 dialog 组件 (~38 个 Vue 文件),确保公共组件完全脱离 Element UI"
|
||||
status: completed
|
||||
- id: phase3b-wm-module
|
||||
content: "Phase 3b: 迁移仓库管理模块其余页面 (wm, 64 个 Vue 文件),验证整个模块功能正常"
|
||||
status: pending
|
||||
- id: phase3c-remaining-pages
|
||||
content: "Phase 3c: 迁移其余所有页面 (MES 其他 98 + system 19 + monitor 8 + tool 12 + print 6 + 其他 5 = ~148 个 Vue 文件) + 全局样式修正"
|
||||
status: pending
|
||||
- id: phase4-third-party
|
||||
content: "Phase 4: 更新第三方依赖为 Vue 3 兼容版本 (vuedraggable, vue-cropper, echarts, quill, axios 等)"
|
||||
status: completed
|
||||
- id: phase5-cleanup
|
||||
content: "Phase 5: 删除旧配置文件,迁移环境变量 (VUE_APP_ -> VITE_),移除 @vue/compat,最终清理"
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# mom-backend-ui 技术栈升级计划
|
||||
|
||||
## 当前差异对比
|
||||
|
||||
|
||||
| 维度 | mom-backend-ui (当前) | erp-frontend-vue (目标) |
|
||||
| ------ | ----------------------------------- | -------------------------------- |
|
||||
| 构建工具 | Vue CLI 4 (Webpack) | Vite 7 |
|
||||
| 框架 | Vue 2.6 | Vue 3.5 |
|
||||
| UI 库 | Element UI 2.15 | Element Plus 2.x |
|
||||
| 路由 | Vue Router 3.4 | Vue Router 4.6 |
|
||||
| 状态管理 | Vuex 3.6 | 自定义 reactive store |
|
||||
| 语言 | JavaScript | TypeScript (暂保留 JS) |
|
||||
| 组件风格 | Options API | Composition API `<script setup>` |
|
||||
| SVG 图标 | svg-sprite-loader + require.context | @element-plus/icons-vue |
|
||||
|
||||
|
||||
## 核心挑战
|
||||
|
||||
项目有 **305 个 Vue 文件 + 225 个 JS 文件**,无法一步到位。采用 **Vue 3 兼容模式 (`@vue/compat`)** 进行渐进式迁移,确保大部分 Vue 2 代码可以在 Vue 3 下运行,然后逐步修复。
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Vite 构建工具替换 + Vue 3 兼容模式
|
||||
|
||||
### 1.1 创建 Vite 配置
|
||||
|
||||
在 [mom-backend-ui/](mom-backend-ui/) 根目录创建 `vite.config.js`,参考 [erp-frontend-vue/vite.config.ts](erp-frontend-vue/vite.config.ts) 的结构:
|
||||
|
||||
```javascript
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import path from 'path'
|
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
createSvgIconsPlugin({
|
||||
iconDirs: [path.resolve(__dirname, 'src/assets/icons/svg')],
|
||||
symbolId: 'icon-[name]'
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
alias: { '@': path.resolve(__dirname, './src') },
|
||||
// Vue 3 compat mode
|
||||
dedupe: ['vue']
|
||||
},
|
||||
server: {
|
||||
port: 80,
|
||||
proxy: {
|
||||
'/dev-api': {
|
||||
target: 'http://localhost:8080',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/dev-api/, '')
|
||||
},
|
||||
'/ureport': {
|
||||
target: 'http://localhost:8080',
|
||||
changeOrigin: true
|
||||
}
|
||||
}
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: { api: 'modern-compiler' }
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 1.2 移动并更新 index.html
|
||||
|
||||
将 [mom-backend-ui/public/index.html](mom-backend-ui/public/index.html) 移到项目根目录,移除 Webpack 模板语法:
|
||||
|
||||
- `<%= BASE_URL %>` 改为 `/`
|
||||
- `<%= webpackConfig.name %>` 改为固定标题
|
||||
- 添加 `<script type="module" src="/src/main.js"></script>`
|
||||
|
||||
### 1.3 更新 package.json
|
||||
|
||||
- 添加 `"type": "module"`
|
||||
- 更新 scripts:
|
||||
- `"dev": "vite"`
|
||||
- `"build": "vite build"`
|
||||
- `"preview": "vite preview"`
|
||||
|
||||
### 1.4 安装新依赖,移除旧依赖
|
||||
|
||||
**安装:**
|
||||
|
||||
- `vue@^3.5` + `@vue/compat@^3.5`(兼容模式)
|
||||
- `vite` + `@vitejs/plugin-vue`
|
||||
- `vite-plugin-svg-icons` + `fast-glob`(替代 svg-sprite-loader)
|
||||
- `sass-embedded`(替代 sass + sass-loader)
|
||||
|
||||
**移除:**
|
||||
|
||||
- `@vue/cli-service`, `@vue/cli-plugin-babel`, `@vue/cli-plugin-eslint`
|
||||
- `vue-template-compiler`
|
||||
- `webpack` 相关: `compression-webpack-plugin`, `script-ext-html-webpack-plugin`, `svg-sprite-loader`, `sass-loader`, `less-loader`
|
||||
- `babel-eslint`, `babel-plugin-dynamic-import-node`, `cross-env`
|
||||
- `core-js`
|
||||
|
||||
### 1.5 配置 @vue/compat
|
||||
|
||||
在 `vite.config.js` 中配置别名,让 `vue` 指向兼容构建:
|
||||
|
||||
```javascript
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
'vue': '@vue/compat'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
同时需要配置 `@vitejs/plugin-vue` 的 compat 编译器选项:
|
||||
|
||||
```javascript
|
||||
vue({
|
||||
template: {
|
||||
compilerOptions: {
|
||||
compatConfig: { MODE: 2 }
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: 更新入口文件和核心模块
|
||||
|
||||
### 2.1 更新 main.js
|
||||
|
||||
将 [mom-backend-ui/src/main.js](mom-backend-ui/src/main.js) 从 `new Vue()` 改为 `createApp()`:
|
||||
|
||||
- `import { createApp } from 'vue'` 替代 `import Vue from 'vue'`
|
||||
- `const app = createApp(App)` 替代 `new Vue({...})`
|
||||
- `Vue.prototype.xxx` 改为 `app.config.globalProperties.xxx`
|
||||
- `Vue.component(...)` 改为 `app.component(...)`
|
||||
- `Vue.use(...)` 改为 `app.use(...)`
|
||||
- `app.use(store).use(router).mount('#app')`
|
||||
|
||||
### 2.2 更新 SVG 图标系统
|
||||
|
||||
将 [mom-backend-ui/src/assets/icons/index.js](mom-backend-ui/src/assets/icons/index.js) 中的 `require.context` 替换为 Vite 的 `import.meta.glob`:
|
||||
|
||||
```javascript
|
||||
import 'virtual:svg-icons-register'
|
||||
// SvgIcon 组件需要在 main.js 中用 app.component 注册
|
||||
```
|
||||
|
||||
### 2.3 升级 Vue Router 3 -> 4
|
||||
|
||||
修改 [mom-backend-ui/src/router/index.js](mom-backend-ui/src/router/index.js):
|
||||
|
||||
- `import { createRouter, createWebHistory } from 'vue-router'`
|
||||
- `new Router({mode: 'history', ...})` 改为 `createRouter({ history: createWebHistory(), ... })`
|
||||
- 移除 `Vue.use(Router)`
|
||||
- `scrollBehavior: () => ({ y: 0 })` 改为 `scrollBehavior: () => ({ top: 0 })`
|
||||
|
||||
修改 [mom-backend-ui/src/permission.js](mom-backend-ui/src/permission.js):
|
||||
|
||||
- `router.addRoutes(accessRoutes)` 改为循环调用 `router.addRoute(route)`
|
||||
- `Message` 从 Element Plus 导入
|
||||
|
||||
### 2.4 升级 Vuex 3 -> 4
|
||||
|
||||
修改 [mom-backend-ui/src/store/index.js](mom-backend-ui/src/store/index.js):
|
||||
|
||||
- `import { createStore } from 'vuex'`
|
||||
- `new Vuex.Store({...})` 改为 `createStore({...})`
|
||||
- 移除 `Vue.use(Vuex)`
|
||||
- 各 modules 文件暂时不动(Vuex 4 向后兼容 module 写法)
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Element UI -> Element Plus 迁移(分步进行)
|
||||
|
||||
这是工作量最大的部分,影响所有 306 个 Vue 文件。为保证项目平稳升级,拆分为 **3a → 3b → 3c** 三步,先拿采购入库页面做试点验证,确认方案可行后再逐步扩展到全模块。
|
||||
|
||||
### Element UI -> Element Plus 通用变更清单
|
||||
|
||||
以下变更适用于所有步骤,每步迁移页面时需逐项检查:
|
||||
|
||||
- **size 属性**: `size="mini"` -> `size="small"`, `size="medium"` -> `size="default"`
|
||||
- **图标**: `<i class="el-icon-xxx">` -> `<el-icon><Xxx /></el-icon>` 或对应 Element Plus 图标组件
|
||||
- **v-model 变更**: `.sync` 修饰符移除,改用 `v-model:propName`
|
||||
- `:visible.sync` -> `v-model`(Dialog)
|
||||
- `:current-page.sync` -> `v-model:current-page`(Pagination)
|
||||
- `:page-size.sync` -> `v-model:page-size`(Pagination)
|
||||
- **事件名变更**: `@current-change` 等部分组件事件保持不变;`.native` 修饰符移除
|
||||
- **Slot 变更**: 部分具名插槽名称变化
|
||||
- **移除的属性**: `el-button` 的 `type="text"` 改为 `link` 或 `text` 属性
|
||||
- **DatePicker**: `value-format` 格式字符串变更 (如 `yyyy-MM-dd` -> `YYYY-MM-DD`)
|
||||
|
||||
---
|
||||
|
||||
### Phase 3a: 替换依赖 + 迁移公共组件 + 采购入库页面试点
|
||||
|
||||
**目标**: 完成 Element Plus 基础切换,优先迁移 `src/components` 中的公共组件(避免页面迁移时遇到依赖问题),再以采购入库页面(`itemrecpt`)作为验证试点。
|
||||
|
||||
#### 3a.1 替换依赖
|
||||
|
||||
- 卸载 `element-ui`
|
||||
- 安装 `element-plus` + `@element-plus/icons-vue`
|
||||
- 删除 [mom-backend-ui/src/assets/styles/element-variables.scss](mom-backend-ui/src/assets/styles/element-variables.scss),改用 Element Plus 主题配置
|
||||
|
||||
#### 3a.2 更新 main.js 中的 Element 导入
|
||||
|
||||
```javascript
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
|
||||
// 注册图标
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
}
|
||||
app.use(ElementPlus, { locale: zhCn, size: 'default' })
|
||||
```
|
||||
|
||||
#### 3a.3 更新 plugins/modal.js 中的 Element 导入
|
||||
|
||||
将 `import { Message, MessageBox, Notification, Loading } from 'element-ui'` 改为 `import { ElMessage, ElMessageBox, ElNotification, ElLoading } from 'element-plus'`,并更新对应的 API 调用。
|
||||
|
||||
同时更新 `permission.js` 中的 `Message` 导入。
|
||||
|
||||
#### 3a.4 迁移公共组件(31 个包含 Dialog 的组件,优先处理)
|
||||
|
||||
**目标**: 修复所有 `src/components` 中使用 `:visible.sync` 的组件,避免页面迁移时遇到 `[ElOnlyChild]` 错误。
|
||||
|
||||
需要迁移的组件列表(按目录分组):
|
||||
|
||||
|
||||
| 组件分类 | 文件路径 | 数量 |
|
||||
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
|
||||
| Select 组件 | vendorSelect, iqcSelect, noticeSelect, itemSelect, clientSelect, batchSelect, userSelect, stockSelect, machinerySelect, warehouseSelect, workstationSelect, workorderSelect, procardSelect, qcindexSelect, reportSelect, TaskSelect, defectSelect, dvsubjectSelect, calTeamSelect, oqcSelect, itemBomSelect, dvplanSelect, stocktakingplanSelect, package | 31 |
|
||||
| 其他 | DictSelect, ImageUpload | 2 |
|
||||
|
||||
|
||||
**关键变更点**(适用所有组件):
|
||||
|
||||
- `:visible.sync="showFlag"` -> `v-model="showFlag"`
|
||||
- 移除 `v-if="showFlag"`(Element Plus dialog 自带显示控制)
|
||||
- `<el-dialog>` 必须有单个根元素:添加 `<div class="dialog-content-wrapper">` 包裹所有 slot 默认内容
|
||||
- `<div slot="footer">` -> `<template #footer>`
|
||||
|
||||
**当前进度**(已完成部分):
|
||||
|
||||
- ✅ vendorSelect/single.vue
|
||||
- ✅ iqcSelect/single.vue
|
||||
- ✅ noticeSelect/single.vue
|
||||
- ⏳ noticeSelect/lineSingle.vue (进行中)
|
||||
- ⏳ itemSelect/single.vue (进行中)
|
||||
- 🔲 其余 26 个组件待迁移
|
||||
|
||||
#### 3a.5 迁移采购入库页面(试点验证)
|
||||
|
||||
逐一修改以下 4 个文件,按照通用变更清单做 Element Plus 适配:
|
||||
|
||||
|
||||
| 文件 | 说明 |
|
||||
| --------------------------------------- | ------- |
|
||||
| `src/views/mes/wm/itemrecpt/index.vue` | 采购入库列表页 |
|
||||
| `src/views/mes/wm/itemrecpt/form.vue` | 采购入库表单页 |
|
||||
| `src/views/mes/wm/itemrecpt/line.vue` | 采购入库明细行 |
|
||||
| `src/views/mes/wm/itemrecpt/detail.vue` | 采购入库详情页 |
|
||||
|
||||
|
||||
**验收标准**: 启动 `vite dev`,能正常访问采购入库列表、新增、编辑、查看详情,无控制台报错。
|
||||
|
||||
---
|
||||
|
||||
### Phase 3a-2: 迁移公共布局和非 Dialog 组件(~38 个 Vue 文件)
|
||||
|
||||
**目标**: 完成 `src/layout/` 和 `src/components/` 中剩余的非 dialog 组件迁移,确保所有公共组件脱离 Element UI。
|
||||
|
||||
#### 需要迁移的文件类型
|
||||
|
||||
**Layout 组件** (`src/layout/`):
|
||||
|
||||
- Layout 主布局组件
|
||||
- Navbar, Sidebar, TagsView 等导航组件
|
||||
- AppMain, Settings 等布局子组件
|
||||
- 约 10-15 个文件
|
||||
|
||||
**非 Dialog 公共组件** (`src/components/`):
|
||||
|
||||
- Pagination(分页组件)
|
||||
- FileUpload(文件上传)
|
||||
- Editor(富文本编辑器,可能使用 Element UI 依赖)
|
||||
- Breadcrumb(面包屑)
|
||||
- SvgIcon(SVG 图标,已迁移)
|
||||
- Dict 相关组件(数据字典)
|
||||
- TreeSelect, Cascader 等表单组件
|
||||
- 其他工具类组件(约 20-25 个文件)
|
||||
|
||||
**迁移要点**:
|
||||
|
||||
- 替换所有 Element UI 组件为 Element Plus
|
||||
- 更新 `size="mini"` -> `size="small"`
|
||||
- 移除 `.native` 修饰符
|
||||
- 更新图标引用方式
|
||||
- 检查并修复任何使用 `$message`, `$alert` 等全局方法的调用
|
||||
|
||||
**验收标准**: 所有 `src/components/` 和 `src/layout/` 文件中不再有 `element-ui` 导入,项目启动无 Element UI 相关警告。
|
||||
|
||||
---
|
||||
|
||||
### Phase 3b: 仓库管理模块其余页面(64 个 Vue 文件)
|
||||
|
||||
**目标**: 确认试点方案可行后,将整个仓库管理模块(`views/mes/wm/`)全部迁移完成。
|
||||
|
||||
需要迁移的子模块(按业务分组):
|
||||
|
||||
|
||||
| 分组 | 子模块 | 文件数 |
|
||||
| --- | -------------------------------------------------------------------------------------------------------- | --- |
|
||||
| 入库 | arrivalnotice (到货通知), itemrecpt (采购入库✅已完成), outsourcerecpt (委外入库), productrecpt (产品入库), miscrecpt (其他入库) | ~15 |
|
||||
| 出库 | issue (生产领料), productsales (销售出库), outsourceissue (委外出库), miscissue (其他出库), itemconsume (物料消耗) | ~15 |
|
||||
| 退料 | rtissue (生产退料), rtsales (销售退货), rtvendor (供应商退货) | ~9 |
|
||||
| 库存 | wmstock (库存查询), stocktaking (盘点), stocktakingplan (盘点计划), transfer (调拨) | ~10 |
|
||||
| 基础 | warehouse (仓库), location (库区), area (库位), barcode (条码), batch (批次), sn (序列号), package (包装) | ~13 |
|
||||
| 通知 | salesnotice (销售通知), mrnotice (物料需求通知) | ~5 |
|
||||
|
||||
|
||||
**验收标准**: 仓库管理菜单下所有页面(列表/表单/详情)均可正常操作,无控制台 Element 组件报错。
|
||||
|
||||
---
|
||||
|
||||
### Phase 3c: 其余所有页面(~148 个 Vue 文件)+ 全局样式修正
|
||||
|
||||
**目标**: 完成所有剩余页面的迁移,项目彻底脱离 Element UI。
|
||||
|
||||
|
||||
| 分组 | 范围 | 文件数 |
|
||||
| ------ | ------------------------------------------------------------ | --- |
|
||||
| MES 其他 | `views/mes/` 除 wm 外 (md, pro, dv, qc, report 等) | ~98 |
|
||||
| 系统管理 | `views/system/` (user, role, menu, dept, dict 等) | ~19 |
|
||||
| 监控 | `views/monitor/` (online, job, server, cache 等) | ~8 |
|
||||
| 工具 | `views/tool/` (gen, build 等) | ~12 |
|
||||
| 打印 | `views/print/` | ~6 |
|
||||
| 其他 | `views/login.vue`, `views/register.vue`, `views/index.vue` 等 | ~5 |
|
||||
|
||||
|
||||
#### 3c.1 全局样式文件更新
|
||||
|
||||
- 更新 [mom-backend-ui/src/assets/styles/](mom-backend-ui/src/assets/styles/) 下的 SCSS 文件中引用 Element UI 类名的部分
|
||||
- Element Plus 的 CSS 变量命名有差异(如 `--el-color-primary` 等)
|
||||
- `el-icon-loading` spinner 等全局引用需更新
|
||||
|
||||
**验收标准**: 全站所有页面功能正常,无 Element UI 残留引用,`vite build` 成功。
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: 更新第三方依赖
|
||||
|
||||
以下 Vue 2 专属库需要更新为 Vue 3 兼容版本:
|
||||
|
||||
|
||||
| 当前依赖 | 操作 |
|
||||
| ------------------------- | ------------------------------------------------- |
|
||||
| `vue-meta` 2.x | 移除,改用 `@unhead/vue` 或 `document.title` |
|
||||
| `vuedraggable` 2.x | 升级到 `vuedraggable@next` (4.x) |
|
||||
| `vue-cropper` 0.5 | 升级到 `vue-cropper@next` |
|
||||
| `@riophae/vue-treeselect` | 替换为 `vue3-treeselect` 或 Element Plus 的 TreeSelect |
|
||||
| `vue-count-to` | 替换为 Vue 3 兼容版本或自行实现 |
|
||||
| `vue-plugin-hiprint` | 确认 Vue 3 兼容性,可能需要替换 |
|
||||
| `echarts` 4.9 | 升级到 5.x |
|
||||
| `@dhtmlx/trial-vue-gantt` | 确认 Vue 3 兼容版本 |
|
||||
| `quill` | 替换为 `@vueup/vue-quill` |
|
||||
| `axios` 0.24 | 升级到 1.x |
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: 清理和收尾
|
||||
|
||||
### 5.1 移除旧配置文件
|
||||
|
||||
- 删除 `vue.config.js`
|
||||
- 删除 `babel.config.js`
|
||||
- 删除 `.eslintrc.js`(后续可按需重新配置 ESLint flat config)
|
||||
- 删除 `build/` 目录(preview 脚本)
|
||||
|
||||
### 5.2 移除 @vue/compat
|
||||
|
||||
当所有组件和功能正常运行后:
|
||||
|
||||
- 在 `vite.config.js` 中移除 `'vue': '@vue/compat'` 别名
|
||||
- 移除 `compatConfig` 编译器选项
|
||||
- 卸载 `@vue/compat`
|
||||
- 修复剩余的 Vue 2 兼容性警告
|
||||
|
||||
### 5.3 环境变量迁移
|
||||
|
||||
- `VUE_APP_*` 环境变量需改为 `VITE_*` 前缀
|
||||
- `process.env.VUE_APP_*` 改为 `import.meta.env.VITE_*`
|
||||
- 创建 `.env.development` 和 `.env.production` 文件
|
||||
|
||||
---
|
||||
|
||||
## 执行建议
|
||||
|
||||
- **Phase 1-2** 是基础,已完成,项目可用 `vite` 启动和构建
|
||||
- **Phase 3a** 先做依赖切换 + 采购入库试点,验证迁移方案的完整流程和模式
|
||||
- **Phase 3b** 试点通过后,在仓库管理模块内推广,以模块为单位验证
|
||||
- **Phase 3c** 最后全面铺开,涵盖剩余 layout/components/views
|
||||
- **Phase 4** 可以与 Phase 3 并行,按需处理
|
||||
- **Phase 5** 在所有功能验证通过后进行
|
||||
- 整个过程中暂保留 JavaScript,不转 TypeScript,后续按需迁移
|
||||
- 每步完成后都应启动 `vite dev` 实际操作验证,确认无功能回退再进入下一步
|
||||
|
||||
129
.cursor/plans/optimize_production_plan_page_32a816e3.plan.md
Normal file
129
.cursor/plans/optimize_production_plan_page_32a816e3.plan.md
Normal file
@@ -0,0 +1,129 @@
|
||||
---
|
||||
name: Optimize Production Plan Page
|
||||
overview: Based on the PRD v1.5.0 gap analysis, fix a critical form-disabled bug that blocks MBOM editing in view mode, and implement missing features including view-page toolbar buttons, EBOM detail dialog, supply type ASSEMBLY option, list-page clickable columns, and several UX improvements.
|
||||
todos:
|
||||
- id: fix-form-disabled
|
||||
content: "P0: 修复 el-form disabled 阻断 MBOM 编辑 -- 将物料清单/补料清单 section 移出 el-form 包裹"
|
||||
status: completed
|
||||
- id: view-toolbar
|
||||
content: "P1: 查看页顶部工具栏添加「新增」「编辑」按钮"
|
||||
status: completed
|
||||
- id: ebom-view-dialog
|
||||
content: "P1: 表头订单BOM添加「查看」按钮 + EBOM详情弹窗"
|
||||
status: completed
|
||||
- id: supply-type-assembly
|
||||
content: "P1: 供应方式选项添加 ASSEMBLY(装配)"
|
||||
status: completed
|
||||
- id: list-material-dialog
|
||||
content: "P1: 列表页明细视图物料名称/物料清单列可点击弹窗"
|
||||
status: completed
|
||||
- id: edit-btn-behavior
|
||||
content: "P2: 单据视图已审核行编辑按钮改为跳转查看页"
|
||||
status: completed
|
||||
- id: view-switch-style
|
||||
content: "P2: 视图切换按钮添加 type=primary 样式"
|
||||
status: completed
|
||||
- id: import-dialog-enhance
|
||||
content: "P2: 引入订单弹窗优化 -- 层级展开表格、日期搜索、查询所有按钮"
|
||||
status: completed
|
||||
- id: record-navigation
|
||||
content: "P2: 查看/编辑页实现上一条/下一条记录导航"
|
||||
status: completed
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# 完善优化生产计划单页面
|
||||
|
||||
## 差距分析总览
|
||||
|
||||
对比 PRD v1.5.0 与当前代码,发现以下需要修复和完善的问题:
|
||||
|
||||
---
|
||||
|
||||
## P0 - 关键缺陷
|
||||
|
||||
### 1. 查看模式下 MBOM 编辑被 el-form disabled 阻断
|
||||
|
||||
**问题**: [form.vue](erp-frontend-vue/src/views/Production/PlanOrder/form.vue) 第 36 行 `<el-form :disabled="isView">` 包裹了整个页面内容(包括物料清单子表)。Element Plus 的 `el-form disabled` 会通过 provide/inject 传递给所有后代表单组件(el-switch、el-select、el-date-picker、el-button),导致即使 `canEditMbom` 为 `true`,查看模式下所有 MBOM 编辑控件仍然被禁用。
|
||||
|
||||
**修复**: 将物料清单子表和补料清单子表移出 `<el-form :disabled="isView">` 的包裹范围。具体做法:在 `</el-form>` (line 385) 之前关闭 form 标签,将物料清单和补料清单 section 移到 form 外面。表头和订单信息子表保留在 form 内(编辑时需要验证)。
|
||||
|
||||
---
|
||||
|
||||
## P1 - 功能缺失(PRD 明确要求)
|
||||
|
||||
### 2. 查看页顶部工具栏缺少按钮(PRD 6.3.13)
|
||||
|
||||
**现状**: 查看页仅显示 审核、反审核、收起 三个按钮。
|
||||
**PRD 要求**: 查看页应显示 新增、编辑、审核、反审核、收起。
|
||||
**修复**: 在 [form.vue](erp-frontend-vue/src/views/Production/PlanOrder/form.vue) 第 8-32 行的 `header-right` 区域,为 `isView` 模式添加「新增」和「编辑」按钮:
|
||||
|
||||
- 新增: 跳转 `/production/plan-order/new`
|
||||
- 编辑: 跳转 `/production/plan-order/edit/{planId}`(仅开立状态启用)
|
||||
|
||||
### 3. 订单BOM「查看」按钮 + EBOM 详情弹窗(PRD 6.3.9 / 7.6.5)
|
||||
|
||||
**现状**: 表头「订单BOM」仅有「选择」按钮(编辑模式)。查看模式或已选择 BOM 后无法查看 EBOM 详情。
|
||||
**PRD 要求**: 已选择 BOM 时(查看/编辑页),显示「查看」按钮打开 EBOM 详情弹窗。
|
||||
**修复**:
|
||||
|
||||
- 在表头「订单BOM」字段旁,当 `formData.bomId` 存在时显示「查看」链接按钮
|
||||
- 新增 EBOM 详情弹窗组件: 显示 EBOM 信息(EBOM单号、业务类型、物料编码、物料名称)、属性(母件基数、图纸号、版本号、版本说明)、BOM 组件表(序号、物料编码、物料名称、主计量、领料方式、分子、固定用量)
|
||||
- 复用已有的 `getEbom` API 和 `EbomLine` 类型
|
||||
|
||||
### 4. 供应方式选项缺少「装配」(PRD 4.4 / 附录A)
|
||||
|
||||
**现状**: `SUPPLY_TYPE_OPTIONS` (line 650-655) 只有 4 个选项: SELF_MADE(生产)、PROCESSING(加工)、PURCHASE(采购)、OUTSOURCE(委外)
|
||||
**PRD 要求**: 应有 5 个选项,包含 ASSEMBLY(装配)
|
||||
**修复**: 在 `SUPPLY_TYPE_OPTIONS` 中添加 `{ value: 'ASSEMBLY', label: '装配' }`
|
||||
|
||||
### 5. 列表页明细视图 - 物料名称/物料清单列可点击弹窗(PRD 7.2 #3 / 7.6.2)
|
||||
|
||||
**现状**: [index.vue](erp-frontend-vue/src/views/Production/PlanOrder/index.vue) 中「物料名称」(line 189) 和「物料清单」(line 197-201) 列为纯文本展示,不可点击。
|
||||
**PRD 要求**: 点击应弹出物料清单明细弹窗:标题「{计划编码} {物料编码} {物料名称} {数量} - 物料清单」,表格列:序号、物料编码、物料名称、主计量、需求量、可用量、领用量、供应方式。
|
||||
**修复**:
|
||||
|
||||
- 将这两列改为 `el-link` 可点击
|
||||
- 新增物料清单明细弹窗(`el-dialog`),调用 MBOM 相关 API 获取物料清单数据并展示
|
||||
- 需新增 API: 根据 planId + itemId 查询 MBOM lines (或复用 `getMbomLines`)
|
||||
|
||||
---
|
||||
|
||||
## P2 - 功能增强
|
||||
|
||||
### 6. 单据视图编辑按钮行为优化(PRD 3.2.4 注意)
|
||||
|
||||
**现状**: 已审核状态的编辑按钮 disabled。
|
||||
**PRD 说明**: "已审核状态的编辑实际以查看模式打开"。
|
||||
**修复**: [index.vue](erp-frontend-vue/src/views/Production/PlanOrder/index.vue) 第 253-260 行,已审核状态的编辑按钮不再 disabled,改为点击后跳转查看页 (`/view/`) 而非编辑页。
|
||||
|
||||
### 7. 视图切换按钮样式(PRD 6.1.1 / 6.2.1)
|
||||
|
||||
**现状**: 切换按钮无 type。
|
||||
**PRD 要求**: 「单据」「明细」切换按钮应为 `type="primary"`。
|
||||
**修复**: 给 [index.vue](erp-frontend-vue/src/views/Production/PlanOrder/index.vue) 第 108-119 行的切换按钮添加 `type="primary"`。
|
||||
|
||||
### 8. 引入订单弹窗优化(PRD 4.6 / 7.6.3)
|
||||
|
||||
**现状**: 弹窗是平铺的订单列表,无层级展开,无日期范围搜索,「重置」按钮而非「查询所有」。
|
||||
**PRD 要求**: 层级表格(父行=订单头可展开,子行=订单明细),搜索区含开始/结束日期,按钮名为「查询所有」。
|
||||
**修复**:
|
||||
|
||||
- 搜索区增加 开始日期、结束日期
|
||||
- 重置按钮改名为「查询所有」
|
||||
- 表格改为可展开行模式: 父行显示业务人员、业务单号、订单交期等,展开后显示订单明细行
|
||||
|
||||
### 9. 记录导航「上一条」「下一条」(PRD 6.3.12 / 7.6.8)
|
||||
|
||||
**现状**: 未实现。
|
||||
**PRD 要求**: 查看/编辑模式下,当存在多条计划记录时显示上一条/下一条导航按钮。
|
||||
**修复**: 在 form.vue 的 header-left 区域添加导航按钮,需要维护一个计划 ID 列表(可从列表页通过 route query 传入或调用 list API 获取相邻记录)。
|
||||
|
||||
---
|
||||
|
||||
## 涉及文件
|
||||
|
||||
- `erp-frontend-vue/src/views/Production/PlanOrder/form.vue` -- P0 #1, P1 #2/3/4, P2 #8/9
|
||||
- `erp-frontend-vue/src/views/Production/PlanOrder/index.vue` -- P1 #5, P2 #6/7
|
||||
- `erp-frontend-vue/src/api/productionPlan.ts` -- P1 #5 (可能需要新增 API)
|
||||
|
||||
265
.cursor/plans/production_issue_module_dbfe96a5.plan.md
Normal file
265
.cursor/plans/production_issue_module_dbfe96a5.plan.md
Normal file
@@ -0,0 +1,265 @@
|
||||
---
|
||||
name: Production Issue Module
|
||||
overview: Create the full production material requisition (生产领料单) module under Warehouse, including 3 API files, router configuration, list page, and a form page with header/line/detail three-level data management, following existing codebase patterns.
|
||||
todos:
|
||||
- id: api-layer
|
||||
content: "创建 3 个 API 文件: src/api/warehouse/issue.ts, issueLine.ts, issueDetail.ts,包含类型定义、状态常量和所有 CRUD + 业务接口"
|
||||
status: completed
|
||||
- id: router-config
|
||||
content: 在 router/index.ts 中追加 /warehouse 路由组,包含 issue 的 list/new/edit/view 四条路由
|
||||
status: completed
|
||||
- id: list-page
|
||||
content: 创建 src/views/Warehouse/Issue/index.vue 列表页:搜索区(7字段) + 工具栏(4按钮) + 表格(11列+操作列) + 分页 + 删除/出库校验逻辑
|
||||
status: completed
|
||||
- id: form-header
|
||||
content: 创建 src/views/Warehouse/Issue/form.vue 表头部分:页面框架 + el-collapse 表头表单(16字段, 4列布局) + 模式判断(isAdd/isEdit/isView) + 保存/取消/收起按钮
|
||||
status: completed
|
||||
- id: form-line-table
|
||||
content: form.vue 领料行子表:可编辑 el-table + 添加行 + 物料选择 + 领料数量输入 + 行CRUD
|
||||
status: completed
|
||||
- id: form-detail-table
|
||||
content: form.vue 出库明细子表:选中行后展示 + 仓库/库区/库位三级联动 el-select + 出库数量 + 明细CRUD
|
||||
status: completed
|
||||
- id: form-dialogs
|
||||
content: form.vue 4个选择弹窗:工单选择、物料选择、客户选择、工作站选择,搜索+表格+单选确认
|
||||
status: completed
|
||||
- id: form-business
|
||||
content: form.vue 业务逻辑:执行出库(checkQuantity + executeIssue)、数据加载(编辑/查看模式)、表单校验、状态控制
|
||||
status: completed
|
||||
- id: test-verify
|
||||
content: 整体联调验证:编译检查、页面路由跳转、列表加载、新增/编辑/查看模式切换
|
||||
status: completed
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# 生产领料单模块开发计划
|
||||
|
||||
## 背景
|
||||
|
||||
根据 [PRD 文档](prd/mom系统生产领料单-页面开发说明文档.md),开发仓储管理下的「生产领料」功能。该模块是项目中首个 Warehouse 模块,采用 **头(Header) -> 行(Line) -> 明细(Detail)** 三层数据结构,比现有的 WorkOrder(头+只读BOM子表)复杂度更高。
|
||||
|
||||
## 核心参考
|
||||
|
||||
- 现有最相似模块:[Production/WorkOrder](erp-frontend-vue/src/views/Production/WorkOrder/) (index.vue + form.vue)
|
||||
- API 模式:[workOrder.ts](erp-frontend-vue/src/api/workOrder.ts) (类型定义 + 状态常量 + API 函数)
|
||||
- 路由模式:[router/index.ts](erp-frontend-vue/src/router/index.ts) (Layout 子路由,list/new/edit/view 四条)
|
||||
|
||||
## 架构概览
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph pages [页面层]
|
||||
ListPage["index.vue 列表页"]
|
||||
FormPage["form.vue 新增/编辑/查看页"]
|
||||
end
|
||||
|
||||
subgraph api [API 层]
|
||||
IssueAPI["issue.ts 领料单头"]
|
||||
IssueLineAPI["issueLine.ts 领料行"]
|
||||
IssueDetailAPI["issueDetail.ts 出库明细"]
|
||||
end
|
||||
|
||||
subgraph backend [后端接口]
|
||||
HeaderAPI["/mes/wm/issueheader/*"]
|
||||
LineAPI["/mes/wm/issueline/*"]
|
||||
DetailAPI["/mes/wm/issuedetail/*"]
|
||||
WorkorderAPI["/mes/pro/workorder/list"]
|
||||
ItemAPI["/mes/md/mditem/list"]
|
||||
WarehouseAPI["/mes/wm/warehouse|location|area/list"]
|
||||
end
|
||||
|
||||
ListPage --> IssueAPI
|
||||
FormPage --> IssueAPI
|
||||
FormPage --> IssueLineAPI
|
||||
FormPage --> IssueDetailAPI
|
||||
IssueAPI --> HeaderAPI
|
||||
IssueLineAPI --> LineAPI
|
||||
IssueDetailAPI --> DetailAPI
|
||||
FormPage --> WorkorderAPI
|
||||
FormPage --> ItemAPI
|
||||
FormPage --> WarehouseAPI
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 文件清单
|
||||
|
||||
```
|
||||
erp-frontend-vue/src/
|
||||
├── api/
|
||||
│ └── warehouse/
|
||||
│ ├── issue.ts # 领料单头 API + 类型 + 状态常量
|
||||
│ ├── issueLine.ts # 领料行 CRUD API + 类型
|
||||
│ └── issueDetail.ts # 出库明细 CRUD API + 类型
|
||||
├── views/
|
||||
│ └── Warehouse/
|
||||
│ └── Issue/
|
||||
│ ├── index.vue # 列表页
|
||||
│ └── form.vue # 新增/编辑/查看页(含行表+明细表+弹窗)
|
||||
└── router/
|
||||
└── index.ts # 追加 /warehouse 路由组
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. API 层(3 个文件)
|
||||
|
||||
### 1.1 `src/api/warehouse/issue.ts`
|
||||
|
||||
- 类型:`IssueHeader`, `IssueHeaderQuery`, `IssueHeaderListResponse`
|
||||
- 状态常量:`STATUS_MAP` (PREPARE/CONFIRMED/APPROVED/FINISHED)
|
||||
- API 函数:
|
||||
- `getIssueHeaderList(params)` -> GET `/mes/wm/issueheader/list`
|
||||
- `getIssueHeaderDetail(issueId)` -> GET `/mes/wm/issueheader/{issueId}`
|
||||
- `createIssueHeader(data)` -> POST `/mes/wm/issueheader`
|
||||
- `updateIssueHeader(data)` -> PUT `/mes/wm/issueheader`
|
||||
- `deleteIssueHeader(ids)` -> DELETE `/mes/wm/issueheader/{ids}`
|
||||
- `executeIssue(issueId)` -> PUT `/mes/wm/issueheader/{issueId}` (执行出库)
|
||||
- `checkQuantity(issueId)` -> GET `/mes/wm/issueheader/checkQuantity/{issueId}`
|
||||
- `exportIssueHeader(params)` -> POST `/mes/wm/issueheader/export`
|
||||
- 辅助 API(弹窗选择):
|
||||
- `getWorkorderSelectList(params)` -> GET `/mes/pro/workorder/list`
|
||||
- `getItemSelectList(params)` -> GET `/mes/md/mditem/list`
|
||||
- `getClientSelectList(params)` -> 复用现有客户接口
|
||||
- `getWarehouseList()` -> GET `/mes/wm/warehouse/list`
|
||||
- `getLocationList(warehouseId)` -> GET `/mes/wm/location/list`
|
||||
- `getAreaList(locationId)` -> GET `/mes/wm/area/list`
|
||||
|
||||
### 1.2 `src/api/warehouse/issueLine.ts`
|
||||
|
||||
- 类型:`IssueLine`
|
||||
- API:`getIssueLineList(params)`, `createIssueLine(data)`, `updateIssueLine(data)`, `deleteIssueLine(ids)`
|
||||
|
||||
### 1.3 `src/api/warehouse/issueDetail.ts`
|
||||
|
||||
- 类型:`IssueDetail`
|
||||
- API:`getIssueDetailList(params)`, `createIssueDetail(data)`, `updateIssueDetail(data)`, `deleteIssueDetail(ids)`
|
||||
|
||||
---
|
||||
|
||||
## 2. 路由配置
|
||||
|
||||
在 [router/index.ts](erp-frontend-vue/src/router/index.ts) 最后的 `]` 前追加 `/warehouse` 路由组:
|
||||
|
||||
```typescript
|
||||
{
|
||||
path: '/warehouse',
|
||||
component: Layout,
|
||||
redirect: '/warehouse/issue',
|
||||
meta: { title: '仓储管理' },
|
||||
children: [
|
||||
{ path: 'issue', name: 'IssueList', component: () => import('@/views/Warehouse/Issue/index.vue'), meta: { title: '生产领料' } },
|
||||
{ path: 'issue/new', name: 'IssueNew', component: () => import('@/views/Warehouse/Issue/form.vue'), meta: { title: '新增领料单' } },
|
||||
{ path: 'issue/edit/:id', name: 'IssueEdit', component: () => import('@/views/Warehouse/Issue/form.vue'), meta: { title: '编辑领料单' } },
|
||||
{ path: 'issue/view/:id', name: 'IssueView', component: () => import('@/views/Warehouse/Issue/form.vue'), meta: { title: '查看领料单' } }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 列表页 `index.vue`
|
||||
|
||||
遵循 WorkOrder/index.vue 模式:
|
||||
|
||||
- **搜索区**:7 个字段 (issueCode, issueName, workorderCode, workstationName, status下拉, beginDate, endDate) + 搜索/重置按钮
|
||||
- **工具栏**:新增(success) / 修改(primary) / 删除(danger) / 导出(warning) 四个按钮
|
||||
- **表格**:复选框 + 11 列 (issueCode蓝色链接, issueName, workorderCode, taskCode, workstationName, clientName, issueDate, requiredTime, status标签, 操作列)
|
||||
- **操作列**:根据 status 动态显隐 — 草稿显示:查看/编辑/删除/执行出库;已完成仅显示:查看
|
||||
- **分页**:el-pagination,sizes=[10,20,50,100]
|
||||
- **删除校验**:仅 PREPARE 状态允许,非草稿提示 "只能删除草稿状态的单据!"
|
||||
- **执行出库**:调用 `checkQuantity` 校验 -> `executeIssue` -> 刷新列表
|
||||
|
||||
---
|
||||
|
||||
## 4. 表单页 `form.vue` (重点,三层数据)
|
||||
|
||||
这是本模块最复杂的部分,包含 **表头表单 + 领料行子表 + 出库明细子表 + 4个选择弹窗**。
|
||||
|
||||
### 4.1 页面顶部操作栏
|
||||
|
||||
- 新增/编辑模式:保存 + 取消 + 执行出库(编辑模式) + 收起/展开
|
||||
- 查看模式:新增 + 编辑(仅草稿) + 收起/展开
|
||||
|
||||
### 4.2 表头表单 (el-collapse + el-form)
|
||||
|
||||
- 4 列布局 (`el-col :span="6"`)
|
||||
- 字段:issueCode(必填), issueName(必填), 工单(选择弹窗), workorderCode(只读), 任务(选择), taskCode(只读), 工作站(选择), workstationCode/Name(只读), 客户(选择), clientCode/Name(只读), issueDate(日期), requiredTime(日期), status(标签), remark(textarea)
|
||||
- 选择按钮通过 `el-input` 的 `#append` 插槽实现,与 WorkOrder 一致
|
||||
|
||||
### 4.3 领料行子表 (el-table, 可编辑)
|
||||
|
||||
- 数据源:`lineList: IssueLine[]`
|
||||
- 列:序号, 物料编码(带选择按钮), 物料名称(只读), 规格型号(只读), 单位(只读), 领料数量(el-input-number), 批次号, 备注, 操作(编辑明细/删除)
|
||||
- 「添加行」按钮:push 空行到 lineList
|
||||
- 行点击/「编辑明细」:设置 `selectedLineIndex`,展示该行的出库明细
|
||||
- 保存流程:表头保存后,逐行调用 `createIssueLine` / `updateIssueLine`;删除行调用 `deleteIssueLine`
|
||||
|
||||
### 4.4 出库明细子表 (el-table, 可编辑)
|
||||
|
||||
- 仅当选中某领料行时显示
|
||||
- 数据源:`detailList: IssueDetail[]` (按 lineId 过滤)
|
||||
- 列:序号, 物料编码/名称(只读,从行带入), 仓库(el-select), 库区(el-select,联动), 库位(el-select,联动), 批次号, 出库数量(el-input-number), 备注, 操作(删除)
|
||||
- 仓库/库区/库位**三级联动**:选择仓库 -> 加载库区 -> 选择库区 -> 加载库位
|
||||
- 保存:调用 `createIssueDetail` / `updateIssueDetail` / `deleteIssueDetail`
|
||||
|
||||
### 4.5 选择弹窗(4 个)
|
||||
|
||||
|
||||
| 弹窗 | 数据来源 | 选择模式 | 回填字段 |
|
||||
| ----- | ------------------------- | ----- | -------------------------------------------------------- |
|
||||
| 选择工单 | `/mes/pro/workorder/list` | 单选 | workorderId, workorderCode |
|
||||
| 选择物料 | `/mes/md/mditem/list` | 单选/多选 | itemId, itemCode, itemName, specification, unitOfMeasure |
|
||||
| 选择客户 | `/mes/md/client/list` | 单选 | clientId, clientCode, clientName |
|
||||
| 选择工作站 | workstation接口 | 单选 | workstationId, workstationCode, workstationName |
|
||||
|
||||
|
||||
弹窗结构遵循 WorkOrder form.vue 的 `el-dialog` + 搜索区 + `el-table` + highlight-current-row + 确定/取消 模式。
|
||||
|
||||
### 4.6 数据加载流程(编辑/查看)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Page as form.vue
|
||||
participant API as API Layer
|
||||
participant BE as Backend
|
||||
|
||||
Page->>API: getIssueHeaderDetail(id)
|
||||
API->>BE: GET /mes/wm/issueheader/{id}
|
||||
BE-->>Page: 表头数据
|
||||
|
||||
Page->>API: getIssueLineList(issueId)
|
||||
API->>BE: GET /mes/wm/issueline/list?issueId=xx
|
||||
BE-->>Page: 领料行列表
|
||||
|
||||
Page->>API: getIssueDetailList(issueId)
|
||||
API->>BE: GET /mes/wm/issuedetail/list?issueId=xx
|
||||
BE-->>Page: 出库明细列表
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 4.7 保存流程
|
||||
|
||||
1. 表单校验 (issueCode必填, issueName必填)
|
||||
2. 新增:`createIssueHeader` -> 获取 issueId -> `router.replace` 到编辑页
|
||||
3. 编辑:`updateIssueHeader` -> 成功提示
|
||||
4. 领料行的增删改在保存表头后独立操作(行级 CRUD)
|
||||
5. 出库明细的增删改同样独立操作
|
||||
|
||||
### 4.8 执行出库流程
|
||||
|
||||
1. 前端校验:至少 1 条领料行,每行有明细数据
|
||||
2. 调用 `checkQuantity(issueId)` 校验数量匹配
|
||||
3. 调用 `executeIssue(issueId)` 执行出库
|
||||
4. 成功后刷新页面数据,status 变为 FINISHED
|
||||
|
||||
---
|
||||
|
||||
## 5. 关键实现要点
|
||||
|
||||
- **三级联动**:仓库 -> 库区 -> 库位,使用 watch 监听上级变化,清空下级选项并重新加载
|
||||
- **行级编辑**:领料行和出库明细均为表格内编辑(inline edit),非弹窗编辑
|
||||
- **状态控制**:所有编辑操作受 `isView` 和 `formData.status` 双重控制;FINISHED 状态只读
|
||||
- **样式复用**:直接复用 WorkOrder 的 `.form-container`, `.page-header`, `.main-card`, `.section-header`, `.dialog-search` 等 CSS 类
|
||||
|
||||
150
.cursor/plans/production_plan_mbom_features_a613ef11.plan.md
Normal file
150
.cursor/plans/production_plan_mbom_features_a613ef11.plan.md
Normal file
@@ -0,0 +1,150 @@
|
||||
---
|
||||
name: Production Plan MBOM Features
|
||||
overview: Complete the production plan page to support re-running BOM calculation, canceling workshop dispatch, conditionally editing workshop/date based on dispatch status, and modifying supply method -- all on an approved production plan in view mode.
|
||||
todos:
|
||||
- id: backend-revoke-issue
|
||||
content: Add PUT /erp/mp/mbom/revoke-issue/{mbomId} endpoint in MpMbomController, IMpMbomService, MpMbomServiceImpl
|
||||
status: completed
|
||||
- id: backend-bom-recalc
|
||||
content: Fix MpPlanServiceImpl.bomCalculate to delete non-issued MBOMs before re-creating, preventing duplicates
|
||||
status: completed
|
||||
- id: frontend-api-revoke
|
||||
content: Add revokeIssue(mbomId) function in erp-frontend-vue/src/api/mbom.ts
|
||||
status: completed
|
||||
- id: frontend-canEditMbom
|
||||
content: Change canEditMbom computed to allow editing in view mode (remove !isView.value check)
|
||||
status: completed
|
||||
- id: frontend-bom-confirm
|
||||
content: Add re-run confirmation dialog in handleBomCalculate when MBOMs already exist
|
||||
status: completed
|
||||
- id: frontend-revoke-confirm
|
||||
content: Add 撤销下发 confirmation dialog in handleMbomIssueToggle and call revokeIssue API
|
||||
status: completed
|
||||
- id: frontend-issued-guards
|
||||
content: Disable workshop/date editing when row is ISSUED with error messages
|
||||
status: completed
|
||||
- id: frontend-supply-success
|
||||
content: Show 修改成功 message on supply type change
|
||||
status: completed
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Complete Production Plan Page MBOM Features
|
||||
|
||||
## Current State
|
||||
|
||||
The production plan form (`form.vue`) already has partial support for BOM calculation, material list viewing, workshop dispatch, and supply method editing. However, several features are incomplete or have incorrect behavior:
|
||||
|
||||
- BOM calculation can be run but no confirmation when re-running (would create duplicates)
|
||||
- Workshop dispatch toggle lacks confirmation for revoke ("撤销下发")
|
||||
- No validation to prevent editing workshop/date when row is already issued
|
||||
- `canEditMbom` is gated by `!isView.value`, blocking edits on the "查看" (view) page
|
||||
- Backend has no dedicated revoke-issue endpoint
|
||||
- Backend `bomCalculate` creates duplicate MBOMs on re-run
|
||||
|
||||
## Changes Required
|
||||
|
||||
### 1. Backend: Add revoke-issue endpoint and fix BOM re-calculation
|
||||
|
||||
**[MpMbomController.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/mp/controller/MpMbomController.java)** -- Add `PUT /erp/mp/mbom/revoke-issue/{mbomId}`:
|
||||
|
||||
- Validate MBOM exists and is in ISSUED state
|
||||
- Call new `revokeIssue()` service method
|
||||
- Clear `issueStatus` (set to null), keep `workshopId`/`workshopName`/`issueDate` so user can adjust them
|
||||
|
||||
**[IMpMbomService.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/mp/service/IMpMbomService.java)** -- Add interface method:
|
||||
|
||||
```java
|
||||
public int revokeIssue(Long mbomId);
|
||||
```
|
||||
|
||||
**[MpMbomServiceImpl.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/mp/service/impl/MpMbomServiceImpl.java)** -- Implement `revokeIssue`:
|
||||
|
||||
- Set `issueStatus = null`
|
||||
- Update timestamp
|
||||
|
||||
**[MpPlanServiceImpl.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/mp/service/impl/MpPlanServiceImpl.java)** -- Fix `bomCalculate` for re-run:
|
||||
|
||||
- Before creating new MBOMs, find existing MBOMs for this plan
|
||||
- Delete non-issued MBOMs (and their lines) to avoid duplicates
|
||||
- Only create new MBOMs for plan lines that don't already have an issued MBOM
|
||||
|
||||
### 2. Frontend API: Add revoke-issue call
|
||||
|
||||
**[mbom.ts](erp-frontend-vue/src/api/mbom.ts)** -- Add:
|
||||
|
||||
```typescript
|
||||
export function revokeIssue(mbomId: number): Promise<void> {
|
||||
return request.put(`/erp/mp/mbom/revoke-issue/${mbomId}`)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Frontend: Update form.vue
|
||||
|
||||
**[form.vue](erp-frontend-vue/src/views/Production/PlanOrder/form.vue)** -- Main changes:
|
||||
|
||||
**(a) Allow MBOM editing in view mode** (line ~698):
|
||||
|
||||
- Change `canEditMbom` to remove `!isView.value` check:
|
||||
|
||||
```javascript
|
||||
const canEditMbom = computed(() => {
|
||||
const approved = formData.status === '审核' || formData.status === 'APPROVED'
|
||||
const hasMbom = (formData.mbomList?.length ?? 0) > 0
|
||||
return approved && hasMbom
|
||||
})
|
||||
```
|
||||
|
||||
**(b) BOM calculation with confirmation for re-run** (line ~714):
|
||||
|
||||
- In `handleBomCalculate()`, when `formData.mbomList` already has items, show `ElMessageBox.confirm('确认是否重新执行物料计算?', '警告', { type: 'warning' })` before proceeding
|
||||
|
||||
**(c) Issue toggle: add confirmation for revoke** (line ~802):
|
||||
|
||||
- In `handleMbomIssueToggle()`, when `checked === false` (turning OFF):
|
||||
- Show `ElMessageBox.confirm('撤销下发', '警告', { type: 'warning' })` confirmation
|
||||
- After confirmation, call `revokeIssue(id)` API instead of generic `saveMbomRow`
|
||||
- Reload plan data after success
|
||||
|
||||
**(d) Workshop selector: block when issued** (template line ~304):
|
||||
|
||||
- Add `:disabled="row.issueStatus === 'ISSUED'"` to the workshop `el-select`
|
||||
- In `handleMbomWorkshopChange()`, add early guard: if `row.issueStatus === 'ISSUED'`, show `ElMessage.error('下发状态下无法修改生产车间')` and return
|
||||
|
||||
**(e) Issue date picker: block when issued** (template line ~326):
|
||||
|
||||
- Add `:disabled="row.issueStatus === 'ISSUED'"` to the date `el-date-picker`
|
||||
- In `handleMbomIssueDateChange()`, add early guard: if `row.issueStatus === 'ISSUED'`, show `ElMessage.error('下发状态下无法修改生产日期')` and return
|
||||
|
||||
**(f) Supply method: always editable** (template line ~277):
|
||||
|
||||
- Supply method select and "转委外" button remain editable regardless of issue status (current behavior matches this, no change needed in the select itself)
|
||||
- But update `handleMbomSupplyTypeChange` to show success message "修改成功"
|
||||
|
||||
## Data Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Approved_Plan] -->|"Click BOM计算"| B{Has existing MBOMs?}
|
||||
B -->|No| C[Run BOM calculation]
|
||||
B -->|Yes| D["Confirm: 确认是否重新执行物料计算?"]
|
||||
D -->|OK| C
|
||||
C --> E[Refresh plan data]
|
||||
|
||||
F[MBOM_Row_Not_Issued] -->|"Toggle ON"| G{Workshop selected?}
|
||||
G -->|Yes| H[Call issueToWorkshop API]
|
||||
G -->|No| I["Warning: 请先选择下发车间"]
|
||||
|
||||
J[MBOM_Row_Issued] -->|"Toggle OFF"| K["Confirm: 撤销下发"]
|
||||
K -->|OK| L[Call revokeIssue API]
|
||||
L --> E
|
||||
|
||||
J -->|"Edit workshop"| M["Error: 下发状态下无法修改生产车间"]
|
||||
J -->|"Edit date"| N["Error: 下发状态下无法修改生产日期"]
|
||||
|
||||
F -->|"Edit workshop/date/supply"| O[Call updateMbom API]
|
||||
O --> P["Success: 修改成功"]
|
||||
```
|
||||
|
||||
|
||||
|
||||
124
.cursor/plans/purchase_order_pages_facedf14.plan.md
Normal file
124
.cursor/plans/purchase_order_pages_facedf14.plan.md
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
name: Purchase Order Pages
|
||||
overview: Implement the Purchase Order (采购订单) module per the PRD, upgrading the existing skeletal frontend pages and filling backend gaps (detail-view query, import dialog API, supplier integration).
|
||||
todos:
|
||||
- id: backend-detail-view
|
||||
content: Add selectPoOrderDetailList in PoOrderMapper.xml joining erp_po_order + erp_po_order_line for line-level detail view with filters (trackCode, itemCode, itemName, supplierName, date range). Add /list endpoint alias or param to return this.
|
||||
status: completed
|
||||
- id: backend-import-api
|
||||
content: Add GET /erp/po/order/leadIn endpoint in PoOrderController that queries erp_mp_purchase (APPROVED, unpurchased qty > 0) with search by trackCode/itemCode/itemName, returning 10-column data for import dialog.
|
||||
status: completed
|
||||
- id: backend-date-params
|
||||
content: Update PoOrderMapper.xml selectPoOrderList and selectPoOrderDocList to accept beginDate/endDate params (align with frontend naming).
|
||||
status: completed
|
||||
- id: frontend-supplier-api
|
||||
content: Add poSupplier API functions in purchaseOrder.ts (or new file) calling /erp/po/supplier/list. Map PoSupplier fields (supplierName, contact1, tel, contact1Tel, enableFlag).
|
||||
status: completed
|
||||
- id: frontend-index-fix
|
||||
content: "Fix index.vue detail view: replace row.lines?.[0]?.xxx with flat fields from the new detail-list query. Ensure date params align with backend."
|
||||
status: completed
|
||||
- id: frontend-form-header
|
||||
content: "Rework form.vue header: 4-row x 5-col layout per PRD 4.2. Add collapse toggle, audit fields, status tags using PREPARE/APPROVED codes, businessStatus select, contractNo, contractFile upload placeholder."
|
||||
status: completed
|
||||
- id: frontend-form-supplier
|
||||
content: "Rework supplier dialog in form.vue: use PoSupplier API, add 7 columns (序号/名称/电话/联系人/手机/状态/操作), search by name + contact, 快速添加 + 查询所有 buttons."
|
||||
status: completed
|
||||
- id: frontend-form-import
|
||||
content: "Implement real import dialog in form.vue: call /erp/po/order/leadIn API, 10-column table per PRD 4.5, search fields (跟单编号/料品大类/物料编码/物料名称), 全选 button, confirm adds lines with itemId."
|
||||
status: completed
|
||||
- id: frontend-form-table
|
||||
content: "Enhance material table: add show-summary for 合计 row (数量/金额/到货数量), auto-calc amount=qty*price, compute totalQuantity/totalAmount before save, add supplierCode to supplier selection."
|
||||
status: completed
|
||||
- id: frontend-form-buttons
|
||||
content: "Add all mode-specific buttons: view mode (新增/编辑/审核/反审核/打印/操作/收起), edit mode (保存/撤回/审核/反审核/操作/收起/引入/新增物料), 上一条/下一条 navigation."
|
||||
status: completed
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Purchase Order Page Development Plan
|
||||
|
||||
## Current State
|
||||
|
||||
The module has a working backend (CRUD, approve/unapprove, code generation, summary) and skeletal frontend pages. Key existing files:
|
||||
|
||||
- **Backend**: [PoOrderController.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/po/controller/PoOrderController.java), [PoOrderMapper.xml](mom-backend/ktg-mes/src/main/resources/mapper/po/PoOrderMapper.xml), [PoOrderLineMapper.xml](mom-backend/ktg-mes/src/main/resources/mapper/po/PoOrderLineMapper.xml), [PoSupplierController.java](mom-backend/ktg-mes/src/main/java/com/ktg/mes/po/controller/PoSupplierController.java)
|
||||
- **Frontend**: [index.vue](erp-frontend-vue/src/views/Purchasing/Order/index.vue), [form.vue](erp-frontend-vue/src/views/Purchasing/Order/form.vue), [purchaseOrder.ts](erp-frontend-vue/src/api/purchaseOrder.ts), [supplier.ts](erp-frontend-vue/src/api/supplier.ts)
|
||||
|
||||
## Gaps to Fill
|
||||
|
||||
### Backend
|
||||
|
||||
1. **Detail-view query**: The PRD detail view is line-level (83 rows for 44 orders). Current `selectPoOrderList` returns order-level rows. Need a new mapper query `selectPoOrderDetailList` that joins `erp_po_order` with `erp_po_order_line` and supports filters: `trackCode`, `orderCode`, `supplierName`, `itemCode`, `itemName`, `beginDate`, `endDate`.
|
||||
2. **Import dialog API (引入采购计划单明细)**: Need `GET /erp/po/order/leadIn` that queries `erp_mp_purchase` (status=APPROVED) with `purchaseQty - orderedQty > 0`, returning: planCode, salesOrderCode (trackCode), salesUserName, deliveryDate, itemId, itemCode, itemName, specification, unitName, needDate (demandDate), demandQty, orderedQty, unpurchasedQty. Support search by: trackCode, itemCode, itemName.
|
||||
3. **Date filter params**: `selectPoOrderList` uses `params.beginOrderDate`/`params.endOrderDate` but frontend sends `beginDate`/`endDate`. Need to add support for both or align naming.
|
||||
4. **Supplier list endpoint**: Backend already has `GET /erp/po/supplier/list` (at [PoSupplierController](mom-backend/ktg-mes/src/main/java/com/ktg/mes/po/controller/PoSupplierController.java)). Frontend currently calls `/mes/md/vendor` (MOM vendor table). For PO, should use `/erp/po/supplier`.
|
||||
|
||||
### Frontend
|
||||
|
||||
1. `**index.vue` detail view data model**: Currently accesses `row.lines?.[0]?.trackCode` but the list API returns flat orders without lines. After backend adds the line-level detail query, update the template to use flat fields directly (`row.trackCode`, `row.itemCode`, etc.).
|
||||
2. `**form.vue` major rework** (the biggest task):
|
||||
- **Status codes**: Use `PREPARE`/`APPROVED`/`CLOSED` instead of Chinese labels `开立`/`审核`
|
||||
- **Header collapse**: Add toggle button and `v-show` for header form (pattern from [PurchasePlan/form.vue](erp-frontend-vue/src/views/Production/PurchasePlan/form.vue))
|
||||
- **Full 4-row header layout** per PRD 4.2: add missing fields (审核员, 审核日期, 业务状态, 采购合同/上传, 用料需求 as read-only)
|
||||
- **Supplier dialog**: Switch from `/mes/md/vendor` to `/erp/po/supplier` API; add columns for 序号, 电话, 手机号, 状态, 操作(选择); add search by name + contact person + 快速添加 + 查询所有
|
||||
- **Import dialog**: Replace hardcoded data with real API call to `GET /erp/po/order/leadIn`; add 10-column table per PRD 4.5; add search fields (跟单编号, 料品大类, 物料编码, 物料名称); add 全选 button
|
||||
- **Material table summary row**: Add `show-summary` with sum of 数量, 金额, 到货数量
|
||||
- **Amount auto-calculation**: `amount = quantity * unitPrice` on change, update `totalQuantity` and `totalAmount` on header before save
|
||||
- **Buttons per mode**: view=[新增/编辑/审核/反审核/打印/操作/收起], edit=[保存/撤回/审核/反审核/操作/收起/引入/新增物料], add=[保存/取消/审核/反审核/收起/引入/新增物料]
|
||||
- **上一条/下一条** navigation (view/edit mode)
|
||||
- **撤回** button: reload saved data from server
|
||||
- **打印** button: `window.print()` or print dialog
|
||||
- **Compute totals** before save: `totalQuantity = sum(line.quantity)`, `totalAmount = sum(line.amount)`
|
||||
3. `**purchaseOrder.ts` API additions**: Add `getImportPlanDetails(params)`, `getPoSupplierList(params)` functions.
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph fe [Frontend]
|
||||
IndexVue["index.vue\n(list: detail + document views)"]
|
||||
FormVue["form.vue\n(add/edit/view)"]
|
||||
ApiTs["purchaseOrder.ts"]
|
||||
SupplierApi["supplier API"]
|
||||
end
|
||||
|
||||
subgraph be [Backend]
|
||||
Controller["PoOrderController"]
|
||||
SupplierCtrl["PoSupplierController"]
|
||||
OrderSvc["PoOrderService"]
|
||||
PurchaseSvc["MpPurchaseService"]
|
||||
OrderMapper["PoOrderMapper.xml"]
|
||||
LineMapper["PoOrderLineMapper.xml"]
|
||||
end
|
||||
|
||||
subgraph db [Database]
|
||||
PoOrder["erp_po_order"]
|
||||
PoLine["erp_po_order_line"]
|
||||
MpPurchase["erp_mp_purchase"]
|
||||
PoSupplier["erp_po_supplier"]
|
||||
end
|
||||
|
||||
IndexVue --> ApiTs
|
||||
FormVue --> ApiTs
|
||||
FormVue --> SupplierApi
|
||||
ApiTs --> Controller
|
||||
SupplierApi --> SupplierCtrl
|
||||
Controller --> OrderSvc
|
||||
Controller --> PurchaseSvc
|
||||
OrderSvc --> OrderMapper
|
||||
OrderSvc --> LineMapper
|
||||
OrderMapper --> PoOrder
|
||||
LineMapper --> PoLine
|
||||
PurchaseSvc --> MpPurchase
|
||||
SupplierCtrl --> PoSupplier
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Key Implementation Notes
|
||||
|
||||
- The `erp_po_order` + `erp_po_order_line` is a proper 1:N header/line model (unlike `erp_mp_purchase` which is flat). Backend already handles insert/update with lines in the controller.
|
||||
- Supplier selection dialog in the PRD references `erp_po_supplier` (not `md_vendor`). The controller at `/erp/po/supplier` is already implemented. Frontend needs a new API wrapper or reuse existing supplier.ts with path change.
|
||||
- For the import dialog, we query `erp_mp_purchase` (approved plans) and map fields to the import dialog's 10 columns.
|
||||
- Pattern reference: [PurchasePlan/form.vue](erp-frontend-vue/src/views/Production/PurchasePlan/form.vue) for header collapse, import dialog, material table patterns.
|
||||
|
||||
572
.cursor/plans/workorder_print_template_6cc2bcf4.plan.md
Normal file
572
.cursor/plans/workorder_print_template_6cc2bcf4.plan.md
Normal file
@@ -0,0 +1,572 @@
|
||||
---
|
||||
name: Universal Document Print
|
||||
overview: 设计并实现跨项目的通用单据打印框架,覆盖 erp-frontend-vue (Vue 3) 和 mom-backend-ui (Vue 2) 两个前端项目中所有单据类型的打印需求,采用配置驱动方式,一套设计思路适配全部单据。
|
||||
todos:
|
||||
- id: install-deps-vue3
|
||||
content: "erp-frontend-vue: 安装 qrcode + @types/qrcode"
|
||||
status: completed
|
||||
- id: install-deps-vue2
|
||||
content: "mom-backend-ui: 安装 qrcode(已有 vue-plugin-hiprint 用于标签,文档打印需另行处理)"
|
||||
status: pending
|
||||
- id: print-types
|
||||
content: 创建 PrintConfig 类型/接口定义(两项目各一份,结构一致)
|
||||
status: completed
|
||||
- id: qrcode-vue3
|
||||
content: "erp-frontend-vue: 创建 src/components/print/QrCode.vue"
|
||||
status: completed
|
||||
- id: print-dialog-vue3
|
||||
content: "erp-frontend-vue: 创建 src/components/print/PrintDialog.vue(含 @media print 样式)"
|
||||
status: completed
|
||||
- id: qrcode-vue2
|
||||
content: "mom-backend-ui: 创建 src/components/PrintDoc/QrCode.vue(Vue 2 版)"
|
||||
status: pending
|
||||
- id: print-dialog-vue2
|
||||
content: "mom-backend-ui: 创建 src/components/PrintDoc/PrintDialog.vue(Vue 2 版,含 @media print 样式)"
|
||||
status: pending
|
||||
- id: task-api
|
||||
content: "erp-frontend-vue: 在 workOrder.ts 中添加 ProTask 类型和 getTaskListByWorkorder API"
|
||||
status: completed
|
||||
- id: integrate-workorder-vue3
|
||||
content: "erp-frontend-vue: 生产工单 form.vue 集成打印"
|
||||
status: completed
|
||||
- id: integrate-sales-vue3
|
||||
content: "erp-frontend-vue: 销售订单 form.vue 集成打印"
|
||||
status: completed
|
||||
- id: integrate-purchase-vue3
|
||||
content: "erp-frontend-vue: 采购订单 form.vue 集成打印"
|
||||
status: completed
|
||||
- id: integrate-issue-vue3
|
||||
content: "erp-frontend-vue: 生产领料单 form.vue 集成打印"
|
||||
status: completed
|
||||
- id: integrate-arrival-vue2
|
||||
content: "mom-backend-ui: 到货通知单 index.vue 集成打印"
|
||||
status: pending
|
||||
- id: integrate-itemrecpt-vue2
|
||||
content: "mom-backend-ui: 物料入库单 index.vue 集成打印"
|
||||
status: pending
|
||||
- id: integrate-productsales-vue2
|
||||
content: "mom-backend-ui: 销售出库单 index.vue 集成打印"
|
||||
status: pending
|
||||
- id: integrate-remaining-vue2
|
||||
content: "mom-backend-ui: 其余仓库单据(退货/转移/杂项等)逐步集成打印"
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# 通用单据打印框架(跨项目)
|
||||
|
||||
## 现状分析
|
||||
|
||||
### erp-frontend-vue(Vue 3 + Element Plus)
|
||||
|
||||
- `handlePrint()` 要么仅调 `window.print()`(生产工单、采购订单),要么是占位符(销售订单等)
|
||||
- 无 `@media print` 样式、无 QR 码库、无打印组件
|
||||
- 包含单据:销售订单、采购订单、生产工单、生产领料单、采购到货单(表单未完成)
|
||||
|
||||
### mom-backend-ui(Vue 2 + Element UI)
|
||||
|
||||
- 已有 `vue-plugin-hiprint` 用于**条码标签**打印(物料/仓库/工位标签),但**无单据格式打印**
|
||||
- `handleHiPrint` 仅在 detail 页做标签打印,不是单据表单打印
|
||||
- 包含大量仓库单据模块:到货通知、入库单(4种)、领料单(3种)、出库单(2种)、退货单(3种)、转移单、装箱单、备料通知等
|
||||
|
||||
### 两项目共同点
|
||||
|
||||
所有单据结构高度一致:**表头字段** + **明细行列表**,适合用统一的配置驱动方案。
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 核心思路:配置驱动 + 双项目适配
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph config ["PrintConfig 配置接口(结构一致)"]
|
||||
fields["headerFields: 表头字段数组"]
|
||||
cols["columns: 明细列定义"]
|
||||
data["data: 明细行数据"]
|
||||
meta["title / qrCode / footer"]
|
||||
end
|
||||
|
||||
subgraph vue3 ["erp-frontend-vue (Vue 3)"]
|
||||
pd3["PrintDialog.vue"]
|
||||
qr3["QrCode.vue"]
|
||||
pages3["各单据 form.vue"]
|
||||
end
|
||||
|
||||
subgraph vue2 ["mom-backend-ui (Vue 2)"]
|
||||
pd2["PrintDialog.vue"]
|
||||
qr2["QrCode.vue"]
|
||||
pages2["各单据 index.vue"]
|
||||
end
|
||||
|
||||
pages3 -->|"构建 config"| pd3
|
||||
pages2 -->|"构建 config"| pd2
|
||||
pd3 --> qr3
|
||||
pd2 --> qr2
|
||||
config -.->|"同一结构"| pd3
|
||||
config -.->|"同一结构"| pd2
|
||||
```
|
||||
|
||||
|
||||
|
||||
### PrintConfig 接口定义
|
||||
|
||||
两个项目各自维护一份(Vue 3 用 TypeScript,Vue 2 用 JSDoc),结构完全一致:
|
||||
|
||||
```typescript
|
||||
/** 表头字段 */
|
||||
interface PrintHeaderField {
|
||||
label: string // "单据编码"
|
||||
value: string | number // "SCDD000001"
|
||||
span?: number // 占列数,默认 1(共 4 列一行)
|
||||
}
|
||||
|
||||
/** 明细表列 */
|
||||
interface PrintColumn {
|
||||
prop: string // 数据字段名
|
||||
label: string // 列标题
|
||||
width?: string // 列宽
|
||||
align?: 'left' | 'center' | 'right'
|
||||
type?: 'text' | 'index' | 'qrcode' | 'amount'
|
||||
qrCodeProp?: string // type=qrcode 时的编码内容字段
|
||||
formatter?: (row: any, index: number) => string
|
||||
}
|
||||
|
||||
/** 合计行 */
|
||||
interface PrintSummary {
|
||||
label: string
|
||||
value: string | number
|
||||
}
|
||||
|
||||
/** 完整打印配置 */
|
||||
interface PrintConfig {
|
||||
systemName?: string // 默认 "升阳云ERP"
|
||||
title: string // "销售订单" | "到货通知单" | ...
|
||||
subtitle?: string // "加工车间" 等
|
||||
qrCodeValue?: string // 右上角二维码内容
|
||||
headerFields: PrintHeaderField[] // 4 列网格,自动换行
|
||||
columns: PrintColumn[] // 明细表列
|
||||
data: any[] // 明细表数据
|
||||
summaries?: PrintSummary[] // 合计行(可选)
|
||||
footer: {
|
||||
creator?: string // 制单人
|
||||
approver?: string // 审核人
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 打印页面统一布局
|
||||
|
||||
```
|
||||
+------------------------------------------------------------------+
|
||||
| 升阳云ERP [QR 码] |
|
||||
| {title} - {subtitle} |
|
||||
| |
|
||||
| {label}: {value} {label}: {value} {label}: {value} {label}:|
|
||||
| {label}: {value} {label}: {value} {label}: {value} {label}:|
|
||||
| |
|
||||
| +----+----------+----------+------+------+----------+------+ |
|
||||
| | 序号| 列1 | 列2 | 列3 | 列4 | 列5 | 列6 | |
|
||||
| +----+----------+----------+------+------+----------+------+ |
|
||||
| | 1 | ... | ... | ... | ... | [QR码] | ... | |
|
||||
| +----+----------+----------+------+------+----------+------+ |
|
||||
| |
|
||||
| 制单人: xxx 审核人: xxx 打印日期: 2025-xx-xx |
|
||||
+------------------------------------------------------------------+
|
||||
```
|
||||
|
||||
## 实现步骤
|
||||
|
||||
### 第一步:依赖安装
|
||||
|
||||
**erp-frontend-vue:**
|
||||
|
||||
```bash
|
||||
cd erp-frontend-vue && npm install qrcode && npm install -D @types/qrcode
|
||||
```
|
||||
|
||||
**mom-backend-ui:**
|
||||
|
||||
```bash
|
||||
cd mom-backend-ui && npm install qrcode
|
||||
```
|
||||
|
||||
### 第二步:公共组件开发
|
||||
|
||||
#### Vue 3 版(erp-frontend-vue)
|
||||
|
||||
新建目录 `src/components/print/`,包含 3 个文件:
|
||||
|
||||
|
||||
| 文件 | 说明 |
|
||||
| --------------------------------------------------------------------------------------------- | -------------------------- |
|
||||
| [src/components/print/types.ts](erp-frontend-vue/src/components/print/types.ts) | PrintConfig 等类型定义 |
|
||||
| [src/components/print/QrCode.vue](erp-frontend-vue/src/components/print/QrCode.vue) | QR 码组件(Props: value, size) |
|
||||
| [src/components/print/PrintDialog.vue](erp-frontend-vue/src/components/print/PrintDialog.vue) | 通用打印对话框 |
|
||||
|
||||
|
||||
**QrCode.vue** — 使用 `qrcode.toDataURL()` 生成 base64 图片,渲染 `<img>` 标签。
|
||||
|
||||
**PrintDialog.vue** — 核心组件:
|
||||
|
||||
- Props: `v-model:visible`、`config: PrintConfig`
|
||||
- `el-dialog`(fullscreen)包裹打印预览
|
||||
- 对话框 header 有「打印」「关闭」按钮
|
||||
- 打印内容区使用纯 HTML table + CSS Grid(不依赖 Element Plus),确保打印输出干净
|
||||
- 组件内嵌 `@media print` 样式,隐藏对话框 header/footer,仅保留 `.print-content`
|
||||
|
||||
#### Vue 2 版(mom-backend-ui)
|
||||
|
||||
新建目录 `src/components/PrintDoc/`,包含 2 个文件:
|
||||
|
||||
|
||||
| 文件 | 说明 |
|
||||
| ------------------------------------------------------------------------------------------------- | --------------------------------------- |
|
||||
| [src/components/PrintDoc/QrCode.vue](mom-backend-ui/src/components/PrintDoc/QrCode.vue) | QR 码组件(Vue 2 语法) |
|
||||
| [src/components/PrintDoc/PrintDialog.vue](mom-backend-ui/src/components/PrintDoc/PrintDialog.vue) | 通用打印对话框(Vue 2 + Element UI `el-dialog`) |
|
||||
|
||||
|
||||
两个版本的**布局 HTML 和 CSS 完全一致**,仅框架语法不同:
|
||||
|
||||
- Vue 3: `<script setup>` + `defineProps` + `v-model:visible`
|
||||
- Vue 2: `export default` + `props` + `.sync` 修饰符
|
||||
|
||||
### 第三步:打印专用 CSS(两项目通用)
|
||||
|
||||
嵌入在 PrintDialog 组件内(或独立 CSS 文件),核心规则:
|
||||
|
||||
```css
|
||||
@media print {
|
||||
body > *:not(.el-overlay):not(.v-modal) { display: none !important; }
|
||||
.el-overlay, .v-modal { position: static !important; overflow: visible !important; }
|
||||
.el-dialog__wrapper { position: static !important; overflow: visible !important; }
|
||||
.el-dialog { box-shadow: none !important; border: none !important;
|
||||
margin: 0 !important; width: 100% !important; }
|
||||
.el-dialog__header, .el-dialog__footer,
|
||||
.print-dialog-actions { display: none !important; }
|
||||
.print-content { padding: 8mm 10mm; margin: 0; }
|
||||
.print-content table { page-break-inside: auto; }
|
||||
.print-content tr { page-break-inside: avoid; }
|
||||
}
|
||||
```
|
||||
|
||||
### 第四步:各单据集成
|
||||
|
||||
每个单据页面的 `handlePrint()` 只需:
|
||||
|
||||
1. 构建 `PrintConfig` 对象(映射该单据的字段)
|
||||
2. 设置 `showPrintDialog = true`
|
||||
|
||||
---
|
||||
|
||||
## 全部单据配置清单
|
||||
|
||||
### A. erp-frontend-vue 项目(Vue 3)
|
||||
|
||||
#### A1. 生产工单
|
||||
|
||||
**页面**: [src/views/Production/WorkOrder/form.vue](erp-frontend-vue/src/views/Production/WorkOrder/form.vue)
|
||||
**需新增 API**: `getTaskListByWorkorder(workorderId)` -> `GET /mes/pro/protask/list` (添加到 [src/api/workOrder.ts](erp-frontend-vue/src/api/workOrder.ts))
|
||||
|
||||
**表头字段(headerFields):**
|
||||
|
||||
- 单据编码 `workorderCode` / 跟单号 `salesOrderCode` / 物料编码 `productCode` / 工艺路线 `routeName`
|
||||
- 单据日期 `orderDate` / 操作员 `operatorName` / 物料名称 `productName + productSpc` / 生产线 `productionLine`
|
||||
- 单据状态 `status` / 订单交期 `deliveryDate` / 计量单位 `unitName` / 生产日期 `productionDate`
|
||||
- 业务状态 `businessStatus` / 需求日期 `requestDate` / 生产数量 `quantity` / 备注 `remark`
|
||||
|
||||
**明细列(工序,来自 ProTask):**
|
||||
|
||||
- 序号(index) / 工序编码 `processCode` / 工序名称 `processName` / 应报数量 `quantity` / 计件方式(固定"个人") / 扫码报工(qrcode) / 备注
|
||||
|
||||
**页脚**: 制单人 `createBy` / 审核人 `approverName`
|
||||
|
||||
---
|
||||
|
||||
#### A2. 销售订单
|
||||
|
||||
**页面**: [src/views/Sales/Order/form.vue](erp-frontend-vue/src/views/Sales/Order/form.vue)
|
||||
|
||||
**表头字段:**
|
||||
|
||||
- 单据编码 `orderCode` / 单据日期 `orderDate` / 单据状态 `orderStatus` / 业务类型 `bizType`
|
||||
- 客户名称 `clientName` / 销售人员 `salesmanName` / 销售部门 `deptName` / 合同号 `contractNo`
|
||||
- 交付日期 `deliveryDate` / 付款条件 `paymentTerms` / 收货人 `receiver` / 收货电话 `receiverPhone`
|
||||
- 收货地址 `receiverAddress`(span:2) / 备注 `remark`(span:2)
|
||||
|
||||
**明细列(物料行,来自 `lines`):**
|
||||
|
||||
- 序号 / 物料编码 `itemCode` / 物料名称 `itemName` / 型号规格 `specification` / 主计量 `unitOfMeasure` / 数量 `quantity` / 单价 `unitPrice` / 金额 `amount` / 质量要求 `qualityReq` / 备注 `remark`
|
||||
|
||||
**合计**: 总金额 `totalAmount`
|
||||
**页脚**: 制单人 `createBy` / 审核人 `auditorName`
|
||||
|
||||
---
|
||||
|
||||
#### A3. 采购订单
|
||||
|
||||
**页面**: [src/views/Purchasing/Order/form.vue](erp-frontend-vue/src/views/Purchasing/Order/form.vue)
|
||||
|
||||
**表头字段:**
|
||||
|
||||
- 单据编码 `orderCode` / 单据日期 `orderDate` / 单据状态 `status` / 业务类型 `businessType`
|
||||
- 业务状态 `businessStatus` / 供方 `supplierName` / 采购部门 `deptName` / 采购人员 `userName`
|
||||
- 到货日期 `deliveryDate` / 合同号 `contractNo` / 用料需求 `materialNeed` / 备注 `remark`
|
||||
|
||||
**明细列(采购行,来自 `lines`):**
|
||||
|
||||
- 序号 / 跟单编号 `trackCode` / 计划单号 `planCode` / 物料编码 `itemCode` / 物料名称 `itemName` / 型号规格 `specification` / 主计量 `unitName` / 数量 `quantity` / 单价 `unitPrice` / 金额 `amount` / 采购说明 `remark`
|
||||
|
||||
**合计**: 总数量 `totalQuantity` / 总金额 `totalAmount`
|
||||
**页脚**: 制单人 `operatorName` / 审核人 `approverName`
|
||||
|
||||
---
|
||||
|
||||
#### A4. 生产领料单
|
||||
|
||||
**页面**: [src/views/Warehouse/Issue/form.vue](erp-frontend-vue/src/views/Warehouse/Issue/form.vue)(需新增打印按钮)
|
||||
|
||||
**表头字段:**
|
||||
|
||||
- 单据编码 `issueCode` / 领料日期 `issueDate` / 单据状态 `status` / 工单编码 `workorderCode`
|
||||
- 工作站 `workstationName` / 客户名称 `clientName` / 需求时间 `requiredTime` / 备注 `remark`
|
||||
|
||||
**明细列(领料行):**
|
||||
|
||||
- 序号 / 物料编码 `itemCode` / 物料名称 `itemName` / 规格型号 `specification` / 计量单位 `unitName` / 领料数量 `quantityIssued` / 批次号 `batchCode` / 备注 `remark`
|
||||
|
||||
**页脚**: 制单人 `createBy`
|
||||
|
||||
---
|
||||
|
||||
### B. mom-backend-ui 项目(Vue 2)
|
||||
|
||||
以下单据在老项目中,均无单据打印功能(仅部分有标签打印)。统一使用 `PrintDialog` 组件集成。
|
||||
|
||||
#### B1. 到货通知单
|
||||
|
||||
**页面**: [src/views/mes/wm/arrivalnotice/index.vue](mom-backend-ui/src/views/mes/wm/arrivalnotice/index.vue) + [line.vue](mom-backend-ui/src/views/mes/wm/arrivalnotice/line.vue)
|
||||
|
||||
**表头字段:**
|
||||
|
||||
- 通知单编号 `noticeCode` / 通知单名称 `noticeName` / 采购订单号 `poCode` / 到货日期 `arrivalDate`
|
||||
- 供应商 `vendorName` / 联系人 `contact` / 联系方式 `tel` / 单据状态 `status`
|
||||
- 备注 `remark`(span:3)
|
||||
|
||||
**明细列(到货行):**
|
||||
|
||||
- 序号 / 物料编码 `itemCode` / 物料名称 `itemName` / 规格型号 `specification` / 单位 `unitName` / 到货数量 `quantityArrival` / 是否检验 `iqcCheck` / 合格数量 `quantityQuanlified` / 检验单号 `iqcCode` / 备注 `remark`
|
||||
|
||||
**页脚**: 制单人 `createBy`
|
||||
|
||||
---
|
||||
|
||||
#### B2. 物料入库单(采购入库)
|
||||
|
||||
**页面**: [src/views/mes/wm/itemrecpt/index.vue](mom-backend-ui/src/views/mes/wm/itemrecpt/index.vue) + [line.vue](mom-backend-ui/src/views/mes/wm/itemrecpt/line.vue)
|
||||
|
||||
**表头字段:**
|
||||
|
||||
- 入库单编号 `recptCode` / 入库单名称 `recptName` / 入库日期 `recptDate` / 单据状态 `status`
|
||||
- 到货通知单 `noticeCode` / 采购订单号 `poCode` / 供应商 `vendorName` / 备注 `remark`
|
||||
|
||||
**明细列(入库行):**
|
||||
|
||||
- 序号 / 物料编码 `itemCode` / 物料名称 `itemName` / 规格型号 `specification` / 单位 `unitName` / 入库数量 `quantityRecived` / 批次号 `batchCode`
|
||||
|
||||
**页脚**: 制单人 `createBy`
|
||||
|
||||
---
|
||||
|
||||
#### B3. 产品入库单
|
||||
|
||||
**页面**: [src/views/mes/wm/productrecpt/](mom-backend-ui/src/views/mes/wm/productrecpt/)
|
||||
|
||||
**表头字段**: 入库单编号、名称、工单编码、入库日期、状态、备注
|
||||
**明细列**: 产品编码、产品名称、规格、单位、入库数量、批次号
|
||||
|
||||
---
|
||||
|
||||
#### B4. 外协入库单
|
||||
|
||||
**页面**: [src/views/mes/wm/outsourcerecpt/](mom-backend-ui/src/views/mes/wm/outsourcerecpt/)
|
||||
|
||||
**表头**: 入库单编号、名称、外协工单号、入库日期、状态、备注
|
||||
**明细**: 物料编码、物料名称、规格、单位、入库数量、批次号
|
||||
|
||||
---
|
||||
|
||||
#### B5. 销售出库单
|
||||
|
||||
**页面**: [src/views/mes/wm/productsales/index.vue](mom-backend-ui/src/views/mes/wm/productsales/index.vue) + [line.vue](mom-backend-ui/src/views/mes/wm/productsales/line.vue)
|
||||
|
||||
**表头字段:**
|
||||
|
||||
- 出库单编号 `salesCode` / 出库单名称 `salesName` / 发货通知单 `noticeCode` / 销售订单 `soCode`
|
||||
- 客户编码 `clientCode` / 客户名称 `clientName` / 出库日期 `salesDate` / 单据状态 `status`
|
||||
- 收货人 `recipient` / 联系方式 `tel` / 承运商 `carrier` / 运输单号 `shippingNumber`
|
||||
- 收货地址 `address`(span:2) / 备注 `remark`(span:2)
|
||||
|
||||
**明细列(出库行):**
|
||||
|
||||
- 序号 / 产品编码 `itemCode` / 产品名称 `itemName` / 规格型号 `specification` / 单位 `unitName` / 出库数量 `quantitySales` / 批次号 `batchCode` / 是否检验 `oqcCheck` / 备注 `remark`
|
||||
|
||||
**页脚**: 制单人 `createBy`
|
||||
|
||||
---
|
||||
|
||||
#### B6. 发货通知单
|
||||
|
||||
**页面**: [src/views/mes/wm/salesnotice/](mom-backend-ui/src/views/mes/wm/salesnotice/)
|
||||
|
||||
**表头**: 通知单编号、销售订单号、客户名称、发货日期、收货人、联系方式、地址、承运商、状态
|
||||
**明细**: 产品编码、产品名称、规格、单位、发货数量、批次号
|
||||
|
||||
---
|
||||
|
||||
#### B7. 供应商退货单
|
||||
|
||||
**页面**: [src/views/mes/wm/rtvendor/index.vue](mom-backend-ui/src/views/mes/wm/rtvendor/index.vue) + [line.vue](mom-backend-ui/src/views/mes/wm/rtvendor/line.vue)
|
||||
|
||||
**表头字段:**
|
||||
|
||||
- 退货单编号 `rtCode` / 退货单名称 `rtName` / 采购订单 `poCode` / 退货日期 `rtDate`
|
||||
- 供应商 `vendorName` / 退货原因 `rtReason` / 运单号 `transportCode` / 单据状态 `status`
|
||||
- 备注 `remark`(span:3)
|
||||
|
||||
**明细列:**
|
||||
|
||||
- 序号 / 物料编码 `itemCode` / 物料名称 `itemName` / 规格型号 `specification` / 单位 `unitName` / 退货数量 `quantityRted` / 批次号 `batchCode` / 备注 `remark`
|
||||
|
||||
---
|
||||
|
||||
#### B8. 销售退货单
|
||||
|
||||
**页面**: [src/views/mes/wm/rtsales/](mom-backend-ui/src/views/mes/wm/rtsales/)
|
||||
|
||||
**表头**: 退货单编号、销售订单号、客户名称、退货日期、状态
|
||||
**明细**: 产品编码、产品名称、规格、单位、退货数量、批次号
|
||||
|
||||
---
|
||||
|
||||
#### B9. 生产退料单
|
||||
|
||||
**页面**: [src/views/mes/wm/rtissue/](mom-backend-ui/src/views/mes/wm/rtissue/)
|
||||
|
||||
**表头**: 退料单编号、工单编码、退料日期、状态
|
||||
**明细**: 物料编码、物料名称、规格、单位、退料数量、批次号
|
||||
|
||||
---
|
||||
|
||||
#### B10. 生产领料单
|
||||
|
||||
**页面**: [src/views/mes/wm/issue/index.vue](mom-backend-ui/src/views/mes/wm/issue/index.vue) + [line.vue](mom-backend-ui/src/views/mes/wm/issue/line.vue)
|
||||
|
||||
**表头**: 领料单编号、领料单名称、工单编码、工作站、领料日期、状态
|
||||
**明细**: 物料编码、物料名称、规格、单位、领料数量、备注
|
||||
|
||||
---
|
||||
|
||||
#### B11. 外协领料单
|
||||
|
||||
**页面**: [src/views/mes/wm/outsourceissue/](mom-backend-ui/src/views/mes/wm/outsourceissue/)
|
||||
|
||||
**表头**: 领料单编号、外协工单号、领料日期、状态
|
||||
**明细**: 物料编码、物料名称、规格、单位、领料数量
|
||||
|
||||
---
|
||||
|
||||
#### B12. 转移单
|
||||
|
||||
**页面**: [src/views/mes/wm/transfer/index.vue](mom-backend-ui/src/views/mes/wm/transfer/index.vue)
|
||||
|
||||
**表头字段:**
|
||||
|
||||
- 转移单编号 `transferCode` / 转移单名称 `transferName` / 转移类型 `transferType` / 转移日期 `transferDate`
|
||||
- 是否配送 `deliveryFlag` / 收货人 `recipient` / 联系方式 `tel` / 单据状态 `status`
|
||||
- 承运商 `carrier` / 运输单号 `shippingNumber` / 目的地 `destination` / 备注 `remark`
|
||||
|
||||
**明细**: 物料编码、物料名称、规格、单位、转移数量、批次号
|
||||
|
||||
---
|
||||
|
||||
#### B13. 杂项入库单 / 杂项出库单 / 备料通知单 / 装箱单
|
||||
|
||||
**页面**: 分别位于 `mes/wm/miscrecpt/`、`mes/wm/miscissue/`、`mes/wm/mrnotice/`、`mes/wm/package/`
|
||||
|
||||
结构与上述单据一致,表头字段略有不同,明细均为物料行。集成方式相同:构建 `PrintConfig` 即可。
|
||||
|
||||
---
|
||||
|
||||
## 实施优先级
|
||||
|
||||
### Phase 1 — 公共组件 + 核心单据(优先)
|
||||
|
||||
1. 安装依赖(两个项目)
|
||||
2. 创建公共打印组件(Vue 3 版 + Vue 2 版)
|
||||
3. erp-frontend-vue: 生产工单、销售订单、采购订单集成打印
|
||||
4. mom-backend-ui: 到货通知单、物料入库单集成打印
|
||||
|
||||
### Phase 2 — 仓库出入库单据
|
||||
|
||||
1. erp-frontend-vue: 生产领料单集成打印
|
||||
2. mom-backend-ui: 销售出库单、发货通知单、生产领料单集成打印
|
||||
|
||||
### Phase 3 — 退货/转移/其余单据
|
||||
|
||||
1. mom-backend-ui: 供应商退货单、销售退货单、生产退料单
|
||||
2. mom-backend-ui: 转移单、外协入库/领料、杂项入库/出库、备料通知、装箱单
|
||||
|
||||
---
|
||||
|
||||
## 文件变更总览
|
||||
|
||||
### erp-frontend-vue(新增 3 文件 + 修改 5 文件)
|
||||
|
||||
**新增:**
|
||||
|
||||
- `src/components/print/types.ts` — PrintConfig 类型定义
|
||||
- `src/components/print/QrCode.vue` — QR 码组件
|
||||
- `src/components/print/PrintDialog.vue` — 通用打印对话框
|
||||
|
||||
**修改:**
|
||||
|
||||
- `src/api/workOrder.ts` — 添加 ProTask 类型和 API
|
||||
- `src/views/Production/WorkOrder/form.vue` — 集成打印
|
||||
- `src/views/Sales/Order/form.vue` — 集成打印
|
||||
- `src/views/Purchasing/Order/form.vue` — 集成打印
|
||||
- `src/views/Warehouse/Issue/form.vue` — 添加打印按钮 + 集成打印
|
||||
|
||||
### mom-backend-ui(新增 2 文件 + 修改 N 个单据页面)
|
||||
|
||||
**新增:**
|
||||
|
||||
- `src/components/PrintDoc/QrCode.vue` — QR 码组件(Vue 2)
|
||||
- `src/components/PrintDoc/PrintDialog.vue` — 通用打印对话框(Vue 2)
|
||||
|
||||
**修改(Phase 1-3 逐步):**
|
||||
|
||||
- `src/views/mes/wm/arrivalnotice/index.vue` — 到货通知单
|
||||
- `src/views/mes/wm/itemrecpt/index.vue` — 物料入库单
|
||||
- `src/views/mes/wm/productsales/index.vue` — 销售出库单
|
||||
- `src/views/mes/wm/salesnotice/index.vue` — 发货通知单
|
||||
- `src/views/mes/wm/issue/index.vue` — 生产领料单
|
||||
- `src/views/mes/wm/rtvendor/index.vue` — 供应商退货单
|
||||
- `src/views/mes/wm/rtsales/index.vue` — 销售退货单
|
||||
- `src/views/mes/wm/rtissue/index.vue` — 生产退料单
|
||||
- `src/views/mes/wm/transfer/index.vue` — 转移单
|
||||
- 其余仓库单据页面...
|
||||
|
||||
**安装依赖:**
|
||||
|
||||
- erp-frontend-vue: `qrcode` + `@types/qrcode`
|
||||
- mom-backend-ui: `qrcode`
|
||||
|
||||
## 扩展性说明
|
||||
|
||||
新增任何单据的打印,不论在哪个项目中,只需:
|
||||
|
||||
1. 在该单据页面中引入 `PrintDialog` 组件
|
||||
2. 构建 `PrintConfig` 对象(映射表头字段 + 配置明细列 + 提供行数据)
|
||||
3. 设置 `showPrintDialog = true`
|
||||
|
||||
无需修改任何公共打印组件。
|
||||
341
.cursor/plans/修复layout菜单操作失效_99a7ebb5.plan.md
Normal file
341
.cursor/plans/修复layout菜单操作失效_99a7ebb5.plan.md
Normal file
@@ -0,0 +1,341 @@
|
||||
---
|
||||
name: 修复Layout菜单操作失效
|
||||
overview: 修复 Vue 2 到 Vue 3 迁移导致的 layout 菜单折叠/展开/关闭失效问题,根本原因是使用了 Vue 2 的 beforeDestroy 生命周期钩子,需要全部替换为 Vue 3 的 beforeUnmount
|
||||
todos:
|
||||
- id: fix-resize-handler
|
||||
content: "修复 ResizeHandler.js: beforeDestroy → beforeUnmount"
|
||||
status: completed
|
||||
- id: fix-topnav
|
||||
content: "修复 TopNav/index.vue: beforeDestroy → beforeUnmount"
|
||||
status: completed
|
||||
- id: fix-screenfull
|
||||
content: "修复 Screenfull/index.vue: beforeDestroy → beforeUnmount"
|
||||
status: completed
|
||||
- id: fix-rightpanel
|
||||
content: "修复 RightPanel/index.vue: beforeDestroy → beforeUnmount"
|
||||
status: completed
|
||||
- id: fix-editor-countto
|
||||
content: "修复 Editor 和 CountTo 组件: beforeDestroy → beforeUnmount"
|
||||
status: completed
|
||||
- id: fix-chart-components
|
||||
content: "修复所有图表组件和 mixins: beforeDestroy → beforeUnmount"
|
||||
status: completed
|
||||
- id: verify-layout
|
||||
content: 验证侧边栏、顶部菜单、全屏、右侧面板功能
|
||||
status: completed
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# 修复 Layout 菜单操作失效问题
|
||||
|
||||
## 问题根源
|
||||
|
||||
Vue 3 中,生命周期钩子名称发生了变化:
|
||||
|
||||
- `beforeDestroy` → `beforeUnmount`
|
||||
- `destroyed` → `unmounted`
|
||||
|
||||
当前项目使用了 `@vue/compat` (Vue 3 兼容模式),但这些组件仍在使用 Vue 2 的生命周期钩子。这导致组件销毁时的清理代码(移除事件监听器)没有执行,从而导致:
|
||||
|
||||
1. **侧边栏折叠/展开失效** - `[ResizeHandler.js](mom-backend-ui/src/layout/mixin/ResizeHandler.js)` 中的 resize 监听器没有正确清理
|
||||
2. **顶部菜单操作失效** - `[TopNav/index.vue](mom-backend-ui/src/components/TopNav/index.vue)` 中的 resize 监听器问题
|
||||
3. **右侧面板关闭失效** - `[RightPanel/index.vue](mom-backend-ui/src/components/RightPanel/index.vue)` 中的 click 监听器问题
|
||||
4. **全屏功能失效** - `[Screenfull/index.vue](mom-backend-ui/src/components/Screenfull/index.vue)` 中的监听器问题
|
||||
|
||||
## 影响范围
|
||||
|
||||
共 13 个文件使用了 `beforeDestroy`:
|
||||
|
||||
### 核心 Layout 相关(优先级 P0)
|
||||
|
||||
1. `[src/layout/mixin/ResizeHandler.js](mom-backend-ui/src/layout/mixin/ResizeHandler.js)` - 控制侧边栏响应式
|
||||
2. `[src/components/TopNav/index.vue](mom-backend-ui/src/components/TopNav/index.vue)` - 顶部菜单
|
||||
3. `[src/components/Screenfull/index.vue](mom-backend-ui/src/components/Screenfull/index.vue)` - 全屏功能
|
||||
4. `[src/components/RightPanel/index.vue](mom-backend-ui/src/components/RightPanel/index.vue)` - 右侧面板
|
||||
|
||||
### 其他组件(优先级 P1)
|
||||
|
||||
1. `[src/components/Editor/index.vue](mom-backend-ui/src/components/Editor/index.vue)` - 富文本编辑器
|
||||
2. `[src/components/CountTo/index.vue](mom-backend-ui/src/components/CountTo/index.vue)` - 数字动画
|
||||
|
||||
### 图表组件(优先级 P2)
|
||||
|
||||
1. `src/views/dashboard/BarChart.vue`
|
||||
2. `src/views/dashboard/LineChart.vue`
|
||||
3. `src/views/dashboard/PieChart.vue`
|
||||
4. `src/views/dashboard/RaddarChart.vue`
|
||||
5. `src/views/mes/report/chart/chart.vue`
|
||||
6. `src/views/mes/report/chart/mixins/resize.js`
|
||||
7. `src/views/dashboard/mixins/resize.js`
|
||||
|
||||
## 修复方案
|
||||
|
||||
### 方案:批量替换生命周期钩子
|
||||
|
||||
所有文件中的 `beforeDestroy` 直接替换为 `beforeUnmount`。
|
||||
|
||||
### 具体修改
|
||||
|
||||
#### 1. ResizeHandler Mixin
|
||||
|
||||
**文件**: `[src/layout/mixin/ResizeHandler.js](mom-backend-ui/src/layout/mixin/ResizeHandler.js)`
|
||||
|
||||
**第 17-19 行**:
|
||||
|
||||
```javascript
|
||||
// 修复前
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.$_resizeHandler)
|
||||
},
|
||||
|
||||
// 修复后
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('resize', this.$_resizeHandler)
|
||||
},
|
||||
```
|
||||
|
||||
**影响**: 修复侧边栏折叠/展开功能
|
||||
|
||||
---
|
||||
|
||||
#### 2. TopNav 组件
|
||||
|
||||
**文件**: `[src/components/TopNav/index.vue](mom-backend-ui/src/components/TopNav/index.vue)`
|
||||
|
||||
**第 107-109 行**:
|
||||
|
||||
```javascript
|
||||
// 修复前
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.setVisibleNumber)
|
||||
},
|
||||
|
||||
// 修复后
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('resize', this.setVisibleNumber)
|
||||
},
|
||||
```
|
||||
|
||||
**影响**: 修复顶部菜单响应式
|
||||
|
||||
---
|
||||
|
||||
#### 3. Screenfull 组件
|
||||
|
||||
**文件**: `[src/components/Screenfull/index.vue](mom-backend-ui/src/components/Screenfull/index.vue)`
|
||||
|
||||
**第 20-22 行**:
|
||||
|
||||
```javascript
|
||||
// 修复前
|
||||
beforeDestroy() {
|
||||
this.destroy()
|
||||
},
|
||||
|
||||
// 修复后
|
||||
beforeUnmount() {
|
||||
this.destroy()
|
||||
},
|
||||
```
|
||||
|
||||
**影响**: 修复全屏功能
|
||||
|
||||
---
|
||||
|
||||
#### 4. RightPanel 组件
|
||||
|
||||
**文件**: `[src/components/RightPanel/index.vue](mom-backend-ui/src/components/RightPanel/index.vue)`
|
||||
|
||||
**第 59-62 行**:
|
||||
|
||||
```javascript
|
||||
// 修复前
|
||||
beforeDestroy() {
|
||||
const elx = this.$refs.rightPanel
|
||||
elx.remove()
|
||||
},
|
||||
|
||||
// 修复后
|
||||
beforeUnmount() {
|
||||
const elx = this.$refs.rightPanel
|
||||
elx.remove()
|
||||
},
|
||||
```
|
||||
|
||||
**影响**: 修复右侧面板关闭功能
|
||||
|
||||
---
|
||||
|
||||
#### 5-6. Editor 和 CountTo 组件
|
||||
|
||||
**文件**:
|
||||
|
||||
- `src/components/Editor/index.vue`
|
||||
- `src/components/CountTo/index.vue`
|
||||
|
||||
**修改**: `beforeDestroy` → `beforeUnmount`
|
||||
|
||||
---
|
||||
|
||||
#### 7-13. 图表组件和 Mixins
|
||||
|
||||
**文件**:
|
||||
|
||||
- `src/views/dashboard/BarChart.vue`
|
||||
- `src/views/dashboard/LineChart.vue`
|
||||
- `src/views/dashboard/PieChart.vue`
|
||||
- `src/views/dashboard/RaddarChart.vue`
|
||||
- `src/views/mes/report/chart/chart.vue`
|
||||
- `src/views/mes/report/chart/mixins/resize.js`
|
||||
- `src/views/dashboard/mixins/resize.js`
|
||||
|
||||
**修改**: `beforeDestroy` → `beforeUnmount`
|
||||
|
||||
**影响**: 修复图表组件的内存泄漏问题
|
||||
|
||||
## 验证方法
|
||||
|
||||
### 测试 1: 侧边栏折叠/展开
|
||||
|
||||
1. 打开系统
|
||||
2. 点击左上角的 hamburger 图标(三条横线)
|
||||
3. 验证侧边栏正常折叠/展开
|
||||
4. 调整浏览器窗口大小
|
||||
5. 验证侧边栏在移动端自动收起
|
||||
|
||||
**预期结果**: 所有操作正常响应
|
||||
|
||||
---
|
||||
|
||||
### 测试 2: 顶部菜单
|
||||
|
||||
1. 启用顶部菜单模式(在布局设置中)
|
||||
2. 点击顶部菜单项
|
||||
3. 验证菜单切换正常
|
||||
4. 调整浏览器窗口大小
|
||||
5. 验证菜单项自动折叠到"更多菜单"
|
||||
|
||||
**预期结果**: 菜单操作正常
|
||||
|
||||
---
|
||||
|
||||
### 测试 3: 全屏功能
|
||||
|
||||
1. 点击顶部工具栏的全屏图标
|
||||
2. 验证进入全屏
|
||||
3. 再次点击退出全屏
|
||||
4. 验证图标状态正确切换
|
||||
|
||||
**预期结果**: 全屏功能正常
|
||||
|
||||
---
|
||||
|
||||
### 测试 4: 右侧面板
|
||||
|
||||
1. 点击顶部的"布局设置"
|
||||
2. 验证右侧面板打开
|
||||
3. 点击面板外部区域
|
||||
4. 验证面板自动关闭
|
||||
|
||||
**预期结果**: 面板开关正常
|
||||
|
||||
---
|
||||
|
||||
### 测试 5: 控制台检查
|
||||
|
||||
打开浏览器控制台,执行以下检查:
|
||||
|
||||
1. 切换不同页面
|
||||
2. 确认没有 "beforeDestroy is deprecated" 警告
|
||||
3. 确认没有内存泄漏警告
|
||||
4. 确认事件监听器正确添加和移除
|
||||
|
||||
## Vue 3 生命周期对照表
|
||||
|
||||
|
||||
| Vue 2 | Vue 3 | 说明 |
|
||||
| --------------- | --------------- | -------- |
|
||||
| `beforeCreate` | `beforeCreate` | 无变化 |
|
||||
| `created` | `created` | 无变化 |
|
||||
| `beforeMount` | `beforeMount` | 无变化 |
|
||||
| `mounted` | `mounted` | 无变化 |
|
||||
| `beforeUpdate` | `beforeUpdate` | 无变化 |
|
||||
| `updated` | `updated` | 无变化 |
|
||||
| `beforeDestroy` | `beforeUnmount` | **已重命名** |
|
||||
| `destroyed` | `unmounted` | **已重命名** |
|
||||
| `activated` | `activated` | 无变化 |
|
||||
| `deactivated` | `deactivated` | 无变化 |
|
||||
| `errorCaptured` | `errorCaptured` | 无变化 |
|
||||
|
||||
|
||||
## 技术要点
|
||||
|
||||
### 为什么需要修复
|
||||
|
||||
1. **事件监听器泄漏**: `beforeDestroy` 未执行导致 `removeEventListener` 没有调用
|
||||
2. **内存泄漏**: 未清理的监听器持续占用内存
|
||||
3. **功能失效**: 新的事件监听器无法正常工作
|
||||
4. **Vue 3 兼容性**: `@vue/compat` 不完全支持 Vue 2 语法
|
||||
|
||||
### 影响分析
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[组件挂载] --> B[添加事件监听器]
|
||||
B --> C[组件使用中]
|
||||
C --> D[组件卸载]
|
||||
D --> E{生命周期钩子}
|
||||
E -->|Vue 2: beforeDestroy| F[执行清理代码]
|
||||
E -->|Vue 3: beforeUnmount| F
|
||||
E -->|使用错误钩子| G[清理代码未执行]
|
||||
G --> H[监听器未移除]
|
||||
H --> I[功能失效]
|
||||
H --> J[内存泄漏]
|
||||
F --> K[监听器正确移除]
|
||||
K --> L[功能正常]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 修复优先级
|
||||
|
||||
### P0 - 立即修复(影响核心功能)
|
||||
|
||||
- ResizeHandler.js
|
||||
- TopNav/index.vue
|
||||
- Screenfull/index.vue
|
||||
- RightPanel/index.vue
|
||||
|
||||
### P1 - 高优先级(影响用户体验)
|
||||
|
||||
- Editor/index.vue
|
||||
- CountTo/index.vue
|
||||
|
||||
### P2 - 中优先级(影响特定页面)
|
||||
|
||||
- 所有图表组件和 mixins
|
||||
|
||||
## 预期效果
|
||||
|
||||
修复后:
|
||||
|
||||
- ✅ 侧边栏折叠/展开正常工作
|
||||
- ✅ 顶部菜单响应式正常
|
||||
- ✅ 全屏功能正常
|
||||
- ✅ 右侧面板开关正常
|
||||
- ✅ 无内存泄漏
|
||||
- ✅ 无控制台警告
|
||||
|
||||
## 后续建议
|
||||
|
||||
1. **全局搜索其他 Vue 2 语法**:
|
||||
```bash
|
||||
grep -r "beforeDestroy\|destroyed\|\$listeners\|\$on\|\$off" --include="*.vue" --include="*.js"
|
||||
```
|
||||
2. **考虑完全迁移到 Vue 3**:
|
||||
- 移除 `@vue/compat` 依赖
|
||||
- 使用纯 Vue 3 API
|
||||
- 更新所有组件库到最新版本
|
||||
3. **添加 ESLint 规则**:
|
||||
检测和阻止使用已弃用的 Vue 2 API
|
||||
|
||||
198
.cursor/plans/采购模块三页面开发计划_c58932f8.plan.md
Normal file
198
.cursor/plans/采购模块三页面开发计划_c58932f8.plan.md
Normal file
@@ -0,0 +1,198 @@
|
||||
---
|
||||
name: 采购模块三页面开发计划
|
||||
overview: 基于 PRD 文档和已有代码,完成采购计划单、采购订单、采购计划需求表三个页面的前后端开发与联调,按业务流程依赖关系分阶段推进。
|
||||
todos:
|
||||
- id: phase1-backend
|
||||
content: 阶段一后端:补全 MpPurchase 实体字段、Mapper 双视图查询、引入/审核/genCode 接口
|
||||
status: completed
|
||||
- id: phase1-frontend-list
|
||||
content: 阶段一前端列表:采购计划单 index.vue 明细/单据双视图 + 快捷标签 + 底部汇总
|
||||
status: completed
|
||||
- id: phase1-frontend-form
|
||||
content: 阶段一前端表单:采购计划单 form.vue 表头19字段 + 子表12列 + 引入弹窗(层级展开) + 按钮组
|
||||
status: completed
|
||||
- id: phase1-test
|
||||
content: 阶段一联调:新增→引入→保存→审核完整流程自测
|
||||
status: completed
|
||||
- id: phase2-backend
|
||||
content: 阶段二后端:确认 PoOrder 实体、引入采购计划明细接口、金额计算、到货回写
|
||||
status: completed
|
||||
- id: phase2-frontend-list
|
||||
content: 阶段二前端列表:采购订单 index.vue 明细/单据双视图 + 底部订单/到货数量汇总
|
||||
status: completed
|
||||
- id: phase2-frontend-form
|
||||
content: 阶段二前端表单:采购订单 form.vue 表头17字段 + 子表14列 + 供应商弹窗 + 引入弹窗 + 金额自动计算
|
||||
status: completed
|
||||
- id: phase2-test
|
||||
content: 阶段二联调:新增→选供应商→引入→单价金额→保存→审核完整流程自测
|
||||
status: completed
|
||||
- id: phase3-backend
|
||||
content: 阶段三后端:实现 /mp/plan/need/list 查询接口(物料汇总+库存可用量) + 导出接口
|
||||
status: completed
|
||||
- id: phase3-frontend
|
||||
content: 阶段三前端:新建 need.vue 单文件组件(搜索+4按钮+快捷标签+12列表格+3项底部汇总+负值高亮)
|
||||
status: completed
|
||||
- id: phase3-test
|
||||
content: 阶段三联调:报表查询+筛选+导出自测
|
||||
status: completed
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# 采购模块三页面开发计划
|
||||
|
||||
## 业务流程全景
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
MBOM["物料清单MBOM<br>供应方式=采购"] --> PurchasePlan["采购计划单<br>/mp/plan/purchase"]
|
||||
PurchasePlan -->|"引入计划明细"| PurchaseOrder["采购订单<br>/po/purchase/order"]
|
||||
PurchasePlan -->|"数据汇总"| NeedReport["采购计划需求表<br>/mp/plan/need"]
|
||||
PurchaseOrder -->|"到货引入"| Checkin["采购到货单"]
|
||||
Supplier["供应商档案"] -->|"选择供应商"| PurchaseOrder
|
||||
```
|
||||
|
||||
|
||||
|
||||
三个页面存在上下游依赖关系:**采购计划单 → 采购订单 → 采购计划需求表**,开发顺序应按此依赖链推进。
|
||||
|
||||
---
|
||||
|
||||
## 现有代码基础
|
||||
|
||||
已有可用的前后端骨架代码(来自 `erp-frontend-vue` 和 `mom-backend`):
|
||||
|
||||
- **采购计划单**: 前端 `erp-frontend-vue/src/views/Production/PurchasePlan/` (index.vue + form.vue),后端 `MpPurchaseController.java` + `MpPurchaseMapper.xml`,API `purchasePlan.ts`
|
||||
- **采购订单**: 前端 `erp-frontend-vue/src/views/Purchasing/Order/` (index.vue + form.vue),后端 `PoOrderController.java` + `PoOrderMapper.xml`,API `purchaseOrder.ts`
|
||||
- **采购计划需求表**: 前端无独立组件(Production/Reports 下有 DetailReport/TotalReport 可参考),后端接口 `GET /mp/plan/need/list` 已在前端开发规范中定义
|
||||
|
||||
开发重点是**对齐 PRD 文档中的字段、交互和业务逻辑**,而非从零开始。
|
||||
|
||||
---
|
||||
|
||||
## 阶段一:采购计划单(P0 - 核心上游)
|
||||
|
||||
> PRD: [mom系统采购计划单-页面开发说明文档.md](prd/mom系统采购计划单-页面开发说明文档.md)
|
||||
> 现有代码: `erp-frontend-vue/src/views/Production/PurchasePlan/` + `mom-backend/.../mp/`
|
||||
|
||||
### 后端任务
|
||||
|
||||
- **补全 MpPurchase 实体字段**: 对照 PRD 5.1 节 erp_mp_purchase 表,确认 `MpPurchase.java` 包含 businessType, businessStatus, deptId, deptName, operatorId, operatorName, approverId, approverName, approveDate, needType 等字段(部分已在 `alter_erp_mp_purchase_add_columns.sql` 中添加)
|
||||
- **补全 Mapper XML 查询**: `MpPurchaseMapper.xml` 需支持明细视图(物料维度 70 行)和单据视图(按 purchaseCode 聚合 31 行)两种查询模式;补充底部汇总 SQL(SUM purchaseQty, orderedQty)
|
||||
- **引入接口**: 确认 `/erp/mp/purchase/lead` 接口返回生产计划单列表(含展开的物料明细:需求数量/可用量/已采数量/未采数量),对齐 PRD 4.4 节引入弹窗的 8 列 + 展开 7 列
|
||||
- **审核/反审核**: 确认审核时填充 approverId/approverName/approveDate,反审核时校验无下游采购订单引用
|
||||
- **编码生成**: 确认 genCode 接口生成 CGJH + 6 位流水号
|
||||
|
||||
### 前端任务
|
||||
|
||||
- **列表页 index.vue — 双视图切换**: 对照 PRD 3.1/3.2 节,实现明细视图(11 列:序号/跟单编号/订单交期/单据编码/单据状态/物料名称/物料编码/采购数量/已订数量/单据日期/采购说明)和单据视图(9 列 + 操作列 查看/编辑/删除);工具栏按钮明细=[搜索/单据/查询所有/新增/导出],单据=[搜索/明细/查询所有/新增/删除/审核/反审核]
|
||||
- **列表页 — 快捷筛选标签**: 物料分类标签(成品/原材料/五金件等),来源动态加载
|
||||
- **列表页 — 底部汇总**: 采购数量 + 已订数量合计
|
||||
- **表单页 form.vue — 表头**: 对照 PRD 4.2 节 19 个字段(5 列布局),区分新增/编辑/查看模式的可编辑状态
|
||||
- **表单页 — 物料信息子表**: 12 列(序号/物料编码/物料名称/型号规格/主计量/需求日期/需求数量/可用量/采购数量/已订数量/采购说明/操作)
|
||||
- **表单页 — 引入弹窗**: 标题="选择生产计划单",搜索=[销售单号/物料编码/物料名称/日期范围],父行 8 列(销售员/销售单号/订单交期/计划单号/物料编码/物料名称/主计量/数量),展开子行 7 列(物料编码/物料名称/需求数量/可用量/已采数量/未采数量/备注)
|
||||
- **表单页 — 按钮组**: 新增=[保存/取消/审核/反审核/收起/引入],查看=[新增/编辑/审核/反审核/打印/操作/收起 + 上一条/下一条],编辑=[保存/撤回/审核/反审核/操作/收起/引入/新增物料]
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 明细视图 / 单据视图切换正常,数据行数一致
|
||||
- 新增 → 引入 → 保存 → 审核 完整流程跑通
|
||||
- 底部汇总数据正确
|
||||
|
||||
---
|
||||
|
||||
## 阶段二:采购订单(P0 - 核心执行单据)
|
||||
|
||||
> PRD: [mom系统采购订单-页面开发说明文档.md](prd/mom系统采购订单-页面开发说明文档.md)
|
||||
> 现有代码: `erp-frontend-vue/src/views/Purchasing/Order/` + `mom-backend/.../po/`
|
||||
|
||||
### 后端任务
|
||||
|
||||
- **确认 PoOrder / PoOrderLine 实体**: 对照 PRD 5.1/5.2 节 erp_po_order(22 字段)和 erp_po_order_line(18 字段),确认 `PoOrder.java` 和 `PoOrderLine.java` 字段完整
|
||||
- **引入接口(采购计划单明细)**: 确认 `/erp/po/order/lead` 或 `/leadInto` 接口返回采购计划单明细(10 列:计划单号/销售员/跟单编号/订单交期/物料编码/物料名称/需求日期/需求数量/已采数量/未采数量),支持按跟单编号/料品大类/物料编码/物料名称搜索
|
||||
- **供应商选择**: 确认 `/erp/po/supplier/list` 返回 7 列(序号/供应商名称/电话/业务联系人/手机号/状态/操作),注意 ERP 用 supplier_id/supplier_name vs MOM 用 vendor_id/vendor_name 的字段名差异
|
||||
- **金额计算**: 确认 line.amount = line.quantity * line.unitPrice,表头 totalQuantity / totalAmount 为明细行合计
|
||||
- **到货数量回写**: 确认到货单审核后回写 order_line.arrived_quantity
|
||||
- **Mapper XML**: `PoOrderMapper.xml` 需支持明细视图(83 行物料维度,含供应商列)和单据视图(44 行单据维度);底部汇总 SUM(quantity) 作为订单数量
|
||||
|
||||
### 前端任务
|
||||
|
||||
- **列表页 index.vue — 双视图**: 明细视图 12 列(序号/跟单编号/计划编号/单据编码/单据状态/供应商/物料名称/物料编码/需求日期/采购数量/到货数量/单据日期),单据视图 9 列 + 操作列
|
||||
- **表单页 form.vue — 表头**: 对照 PRD 4.2 节 17 字段(含供方选择弹窗、到货日期、采购合同上传、合同号),区分新增/编辑/查看模式
|
||||
- **表单页 — 物料子表**: 14 列(序号/跟单编号/计划单号/物料编码/物料名称/型号规格/主计量/需求日期/数量/单价/金额/到货数量/采购说明/操作),底部合计行
|
||||
- **供应商选择弹窗**: 标题="选择供应商",搜索=[供应商名称/业务联系人],按钮含"快速添加",7 列表格 79 行数据
|
||||
- **引入弹窗(采购计划单明细)**: 标题="采购计划单明细",10 列,按钮=[搜索/采购退货单/全选/确定/取消]
|
||||
- **按钮组差异**: 新增=[保存/取消/审核/反审核/收起/引入/新增物料],查看=[新增/编辑/审核/反审核/打印/操作/收起],编辑=[保存/撤回/审核/反审核/操作/收起/引入/新增物料],注意编辑页有"撤回"按钮而非"取消"
|
||||
- **金额自动计算**: 数量 x 单价 = 金额,合计行实时更新
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 新增 → 选择供应商 → 引入计划明细 → 修改单价 → 金额自动计算 → 保存 → 审核 完整流程
|
||||
- 供应商弹窗正确加载(注意 supplier vs vendor 字段映射)
|
||||
- 引入弹窗含全选和退货单切换按钮
|
||||
|
||||
---
|
||||
|
||||
## 阶段三:采购计划需求表(P1 - 只读报表)
|
||||
|
||||
> PRD: [mom系统采购计划需求表-页面开发说明文档.md](prd/mom系统采购计划需求表-页面开发说明文档.md)
|
||||
> 现有代码: 前端无独立组件(需新建 `need.vue`),后端接口 `GET /mp/plan/need/list` 待实现
|
||||
|
||||
### 后端任务
|
||||
|
||||
- **实现查询接口**: `GET /erp/mp/plan/need/list`,基于 erp_mp_purchase 按物料维度查询,关联库存计算可用量,返回 12 列(销售订单号/计划单号/物料编码/物料名称/需求数量/可用量/采购数量/已订数量/未订数量/单据日期/采购说明)
|
||||
- **实现导出接口**: `GET /erp/mp/plan/need/export`,参数同查询接口
|
||||
- **未订数量计算**: unorderedQty = purchaseQty - orderedQty
|
||||
- **可用量**: 查询库存可用量(可为负值,表示缺料)
|
||||
|
||||
### 前端任务
|
||||
|
||||
- **新建 need.vue**: 单文件组件,仅列表页无详情页
|
||||
- **搜索区**: 6 个搜索项(销售订单号/物料编码/物料名称/开始日期/结束日期/下拉选择)
|
||||
- **工具栏**: 4 按钮(搜索/查询所有/导出/打印)+ 快捷标签(原材料/零部件/五金)
|
||||
- **表格**: 12 列,底部汇总 3 项(采购数量/已订数量/未订数量)
|
||||
- **可用量负值高亮**: 可用量 < 0 时红色显示
|
||||
- **路由注册**: `/production/purchase-need` 或复用 `/mp/plan/need`
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 页面加载显示采购需求汇总数据
|
||||
- 快捷标签筛选正常
|
||||
- 导出 Excel 正常
|
||||
- 底部 3 项汇总数据正确
|
||||
|
||||
---
|
||||
|
||||
## 开发依赖与顺序
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title 采购模块开发甘特图
|
||||
dateFormat YYYY-MM-DD
|
||||
section 阶段一_采购计划单
|
||||
后端补全字段与接口 :a1, 2026-02-08, 2d
|
||||
前端列表页双视图 :a2, after a1, 2d
|
||||
前端表单页含引入弹窗 :a3, after a2, 3d
|
||||
联调与自测 :a4, after a3, 1d
|
||||
section 阶段二_采购订单
|
||||
后端引入与金额逻辑 :b1, after a1, 2d
|
||||
前端列表页双视图 :b2, after b1, 2d
|
||||
前端表单页含供应商弹窗 :b3, after b2, 3d
|
||||
联调与自测 :b4, after b3, 1d
|
||||
section 阶段三_需求报表
|
||||
后端查询汇总接口 :c1, after a4, 1d
|
||||
前端need_vue组件 :c2, after c1, 1d
|
||||
联调与自测 :c3, after c2, 1d
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 关键技术注意事项
|
||||
|
||||
- **供应商字段映射**: ERP 用 `supplier_id/supplier_name/supplier_code`,MOM 用 `vendor_id/vendor_name/vendor_code`(表名也不同:erp_po_supplier vs md_vendor),接口调用和数据同步时需做字段转换
|
||||
- **双视图模式**: 三个页面中采购计划单和采购订单都有明细/单据双视图,通过 `viewMode` 状态变量切换,共享搜索条件的公共字段
|
||||
- **引入弹窗嵌套表格**: 采购计划单的引入弹窗需支持父行展开子行(可用量/未采数量等),采购订单的引入弹窗为平铺 10 列
|
||||
- **金额计算**: 仅采购订单有单价/金额字段,采购计划单和需求表不涉及价格
|
||||
- **状态流转**: 采购计划单和采购订单共用 DRAFT→APPROVED 流转,反审核需校验下游引用
|
||||
|
||||
64
.cursor/plans/采购订单prd版本与手工新增物料补全_7593c8f2.plan.md
Normal file
64
.cursor/plans/采购订单prd版本与手工新增物料补全_7593c8f2.plan.md
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
name: 采购订单PRD版本与手工新增物料补全
|
||||
overview: 将采购订单开发说明文档版本升级至 2.3.0,在全文补全与「手动/手工新增物料」相关的引用、术语和业务规则,并统一截图数量说明。
|
||||
todos: []
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# 采购订单 PRD 版本更新与手工新增物料补全
|
||||
|
||||
## 现状
|
||||
|
||||
- 文档当前为 **2.2.0**(2026-02-13),已包含 **[4.3.1 手工新增物料](prd/mom系统采购订单-页面开发说明文档.md)** 的完整说明(操作流程、选择物料弹窗、与引入的区分)及两张截图引用。
|
||||
- 用户需求:**版本更新**、**补全新功能**,**特别是手动新增物料**。即在不改动 4.3.1 主体内容的前提下,做版本号与日期的升级,并在全文档中补全对手工/手动新增物料的引用与规则,使“手动新增物料”在文档中更易发现、前后一致。
|
||||
|
||||
## 修改范围(仅文档,无代码)
|
||||
|
||||
### 1. 版本与元信息
|
||||
|
||||
- **[prd/mom系统采购订单-页面开发说明文档.md](prd/mom系统采购订单-页面开发说明文档.md)** 头部:
|
||||
- 版本:`2.2.0` → `**2.3.0**`
|
||||
- 更新日期:保持或设为本次修订日期(如 `2026-02-13`)
|
||||
- **采集脚本** 行:将「共 17 张截图」改为「共 19 张截图」(2.2.0 已补充 2 张:可新增物料、点击添加物料)
|
||||
|
||||
### 2. 术语与可发现性(手动新增物料)
|
||||
|
||||
- **4.3.1 小节**:在首段前或标题后增加一句说明:**「本功能也称“手动新增物料”,与“手工新增物料”同义。」** 便于按“手动”检索。
|
||||
- **目录**:在「4. [新增/编辑页设计](#4-新增编辑页设计)」下增加一条四级目录:**「4.3.1 [手工(手动)新增物料](#431-手工新增物料)」**,便于从目录直接跳转到该功能。
|
||||
|
||||
### 3. 业务流程与按钮说明中的补全
|
||||
|
||||
- **0.3 采购订单内部业务流程表**:阶段 4「新增物料」一行,「结果」列由「子表末尾新增空行」扩展为:**「子表末尾新增空行;可通过「选择物料」选料并填数量/单价,见 4.3.1」**。
|
||||
- **6.3 新增/编辑页按钮**:「新增物料」行,「结果」列由「行数+1」扩展为:**「子表新增空行(行数+1);选料与完整流程见 4.3.1」**。
|
||||
|
||||
### 4. 业务规则补全
|
||||
|
||||
- **第 10 章 业务规则**:在 **10.2 引入规则** 之后新增 **10.2.1 手工(手动)新增物料规则**(或作为 10.2 的补充段落):
|
||||
- 说明与「引入」的区分:手工新增行无计划单/跟单来源,跟单编号/计划单号显示「手工单据」或「添加物料」;
|
||||
- 必选物料:须通过「选择物料」弹窗选择物料,回填编码/名称/规格/计量单位;
|
||||
- 数量、单价、需求日期、采购说明由用户填写,行金额 = 数量×单价 自动计算;
|
||||
- 引用:「操作流程与选择物料弹窗详见 [4.3.1 手工新增物料](#431-手工新增物料)」。
|
||||
|
||||
### 5. 修订历史
|
||||
|
||||
- 在 **修订历史** 表末尾新增一行 **2.3.0**:
|
||||
- **版本**:2.3.0
|
||||
- **日期**:2026-02-13(或实际修订日)
|
||||
- **修订内容**:版本更新至 2.3.0;补全新功能说明,重点补全**手动/手工新增物料**在业务流程(0.3)、按钮说明(6.3)、业务规则(10.2.1)中的引用与规则;目录增加 4.3.1 手工(手动)新增物料;4.3.1 增加“手动新增物料”同义说明;截图总数更新为 19 张。
|
||||
- **修订人**:System(或保留现有风格)
|
||||
|
||||
## 不改动部分
|
||||
|
||||
- 4.3.1 的现有正文(操作流程表、选择物料弹窗、与引入的区分表)保持不变。
|
||||
- 1.2 业务场景、1.4 截图表、4.3 子表列定义等已有对手工新增物料或截图的描述保持不变,仅在有需要时做最小化措辞微调(如与 10.2.1 一致)。
|
||||
|
||||
## 实施顺序建议
|
||||
|
||||
1. 头部版本、更新日期、截图数量
|
||||
2. 目录增加 4.3.1 条目
|
||||
3. 4.3.1 增加“手动新增物料”同义说明
|
||||
4. 0.3 表、6.3 表补全
|
||||
5. 第 10 章新增 10.2.1(或 10.2 补充段)
|
||||
6. 修订历史新增 2.3.0
|
||||
|
||||
按上述顺序修改后,文档版本为 2.3.0,且“手动新增物料”在概述、流程、按钮、业务规则和目录中均有明确补全与交叉引用。
|
||||
212
.cursor/plans/验证采购入库按钮修复_2bde3163.plan.md
Normal file
212
.cursor/plans/验证采购入库按钮修复_2bde3163.plan.md
Normal file
@@ -0,0 +1,212 @@
|
||||
---
|
||||
name: 验证采购入库按钮修复
|
||||
overview: 问题已解决!提供验证步骤和进一步诊断方法,确保采购入库页面的"新增"按钮正常工作。
|
||||
todos: []
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# 采购入库按钮修复 - 验证和测试计划
|
||||
|
||||
## 当前状态
|
||||
|
||||
问题**已经解决**!以下改进已经应用到代码中:
|
||||
|
||||
### 已完成的修复
|
||||
|
||||
#### 1. 移除了 `.prevent` 修饰符
|
||||
|
||||
**文件**: `[mom-backend-ui/src/views/mes/wm/itemrecpt/index.vue:57](mom-backend-ui/src/views/mes/wm/itemrecpt/index.vue)`
|
||||
|
||||
```vue
|
||||
<!-- 修复前 -->
|
||||
@click.prevent="handleAdd"
|
||||
|
||||
<!-- 修复后 -->
|
||||
@click="handleAdd"
|
||||
```
|
||||
|
||||
#### 2. 添加了完善的调试日志
|
||||
|
||||
在 `handleAdd` 方法中添加了详细的日志输出:
|
||||
|
||||
```javascript
|
||||
handleAdd() {
|
||||
console.log('[采购入库] handleAdd 方法被调用');
|
||||
console.log('[采购入库] 当前状态:', { open, title, optType });
|
||||
// ... 业务逻辑
|
||||
console.log('[采购入库] Dialog 状态已更新:', { open, title, optType });
|
||||
// DOM 检查
|
||||
this.$nextTick(() => {
|
||||
console.log('[采购入库] Dialog DOM 检查:', {
|
||||
dialogExists, overlayExists
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 增强了 Dialog 监控
|
||||
|
||||
添加了 Dialog 生命周期事件:
|
||||
|
||||
- `@open` - Dialog 开始打开
|
||||
- `@opened` - Dialog 完全打开
|
||||
- `@close` - Dialog 关闭
|
||||
|
||||
#### 4. 创建了诊断工具
|
||||
|
||||
- `[mom-backend-ui/DEBUGGING-ITEMRECPT.md](mom-backend-ui/DEBUGGING-ITEMRECPT.md)` - 完整诊断指南
|
||||
- `[mom-backend-ui/public/debug-itemrecpt.js](mom-backend-ui/public/debug-itemrecpt.js)` - 自动诊断脚本
|
||||
- `[CHANGES-ITEMRECPT-BUTTON-FIX.md](CHANGES-ITEMRECPT-BUTTON-FIX.md)` - 变更记录
|
||||
|
||||
## 验证步骤
|
||||
|
||||
### 步骤 1: 基本功能测试
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[打开采购入库页面] --> B[打开浏览器控制台F12]
|
||||
B --> C[点击新增按钮]
|
||||
C --> D{是否有日志输出?}
|
||||
D -->|有| E[检查日志内容]
|
||||
D -->|无| F[问题1:按钮未响应]
|
||||
E --> G{Dialog是否打开?}
|
||||
G -->|是| H[修复成功✓]
|
||||
G -->|否| I[问题2:Dialog未显示]
|
||||
|
||||
F --> F1[运行诊断脚本]
|
||||
I --> I1[查看DOM检查日志]
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 步骤 2: 控制台验证
|
||||
|
||||
1. 打开采购入库页面
|
||||
2. 按 F12 打开开发者工具
|
||||
3. 进入 Console 标签
|
||||
4. 在 Filter 输入框输入: `[采购入库]`
|
||||
5. 点击"新增"按钮
|
||||
|
||||
**预期输出**:
|
||||
|
||||
```
|
||||
[采购入库] handleAdd 方法被调用
|
||||
[采购入库] 当前状态: {open: false, title: "", optType: undefined}
|
||||
[采购入库] Dialog 状态已更新: {open: true, title: "添加物料入库单", optType: "add"}
|
||||
[采购入库] Dialog DOM 检查: {open: true, dialogExists: true, overlayExists: true}
|
||||
[采购入库] Dialog 开始打开动画
|
||||
[采购入库] Dialog 已完全打开
|
||||
```
|
||||
|
||||
### 步骤 3: 运行自动诊断脚本
|
||||
|
||||
在浏览器控制台执行:
|
||||
|
||||
```javascript
|
||||
fetch('/debug-itemrecpt.js').then(r => r.text()).then(eval)
|
||||
```
|
||||
|
||||
该脚本会自动检查:
|
||||
|
||||
- 按钮是否存在于 DOM
|
||||
- Vue 应用是否正常
|
||||
- 用户权限是否正确
|
||||
- Element Plus 是否加载
|
||||
- Plus 图标是否正常
|
||||
|
||||
## 问题排查矩阵
|
||||
|
||||
|
||||
| 现象 | 可能原因 | 解决方案 | 参考文档 |
|
||||
| ------------------- | ----------- | --------------------------------- | --------------------------- |
|
||||
| 按钮不存在于 DOM | 权限问题 | 检查用户是否有 `mes:wm:itemrecpt:add` 权限 | DEBUGGING-ITEMRECPT.md §问题1 |
|
||||
| 无任何日志输出 | 事件未绑定或按钮被禁用 | 检查按钮 disabled 属性和 z-index | DEBUGGING-ITEMRECPT.md §问题2 |
|
||||
| 有日志但 Dialog 未显示 | Dialog 渲染问题 | 检查 DOM 和 CSS,查看 DOM 检查日志 | DEBUGGING-ITEMRECPT.md §问题3 |
|
||||
| dialogExists: false | Vue 响应式问题 | 检查 open 变量,使用 Vue DevTools | DEBUGGING-ITEMRECPT.md §问题3 |
|
||||
| 有错误日志 | 代码异常 | 查看 errorCaptured 日志详情 | 控制台错误栈 |
|
||||
|
||||
|
||||
## 检查用户权限
|
||||
|
||||
在浏览器控制台执行:
|
||||
|
||||
```javascript
|
||||
// 检查当前用户权限
|
||||
window.$store?.getters?.permissions
|
||||
|
||||
// 或者检查是否包含特定权限
|
||||
window.$store?.getters?.permissions?.includes('mes:wm:itemrecpt:add')
|
||||
```
|
||||
|
||||
如果返回 `false` 或权限列表中不包含该权限,需要:
|
||||
|
||||
1. 联系管理员添加权限
|
||||
2. 或者在角色管理中配置权限
|
||||
|
||||
## 使用 Vue DevTools 调试
|
||||
|
||||
1. 安装 Vue DevTools 浏览器扩展
|
||||
2. 打开 Vue DevTools
|
||||
3. 在组件树中找到 `Itemrecpt` 组件
|
||||
4. 观察 `data` 中的变量:
|
||||
- `open` - Dialog 显示状态
|
||||
- `title` - Dialog 标题
|
||||
- `form` - 表单数据
|
||||
5. 点击按钮后实时查看变量变化
|
||||
|
||||
## 进一步诊断
|
||||
|
||||
如果按照上述步骤问题仍未解决,收集以下信息:
|
||||
|
||||
1. **浏览器信息**
|
||||
- 浏览器类型和版本
|
||||
- 操作系统版本
|
||||
2. **控制台输出**
|
||||
- 完整的日志输出(包含 [采购入库] 前缀的)
|
||||
- 任何错误信息和堆栈
|
||||
3. **权限信息**
|
||||
```javascript
|
||||
console.log('权限列表:', window.$store?.getters?.permissions)
|
||||
```
|
||||
4. **DOM 状态**
|
||||
```javascript
|
||||
console.log('按钮元素:', document.querySelector('button:contains("新增")'))
|
||||
console.log('Dialog:', document.querySelector('.el-dialog'))
|
||||
```
|
||||
5. **Vue DevTools 截图**
|
||||
- Itemrecpt 组件的 data 状态
|
||||
- open 变量的值
|
||||
|
||||
## 相关文档
|
||||
|
||||
- 详细诊断指南: `[DEBUGGING-ITEMRECPT.md](mom-backend-ui/DEBUGGING-ITEMRECPT.md)`
|
||||
- 完整变更记录: `[CHANGES-ITEMRECPT-BUTTON-FIX.md](CHANGES-ITEMRECPT-BUTTON-FIX.md)`
|
||||
- 诊断脚本: `[debug-itemrecpt.js](mom-backend-ui/public/debug-itemrecpt.js)`
|
||||
|
||||
## 后续行动
|
||||
|
||||
如果验证通过:
|
||||
|
||||
- 无需进一步操作,问题已解决
|
||||
|
||||
如果验证失败:
|
||||
|
||||
1. 按照问题排查矩阵定位具体问题
|
||||
2. 查阅 DEBUGGING-ITEMRECPT.md 获取详细解决方案
|
||||
3. 收集诊断信息寻求技术支持
|
||||
|
||||
## 总结
|
||||
|
||||
修复内容:
|
||||
|
||||
- 移除不必要的 `.prevent` 修饰符
|
||||
- 添加 18 个标准化调试日志
|
||||
- 增强 Dialog 事件监控
|
||||
- 创建完整的诊断工具集
|
||||
|
||||
验证要点:
|
||||
|
||||
- 点击按钮后应看到 `[采购入库]` 开头的日志
|
||||
- Dialog 应正常打开
|
||||
- 所有操作应有清晰的日志记录
|
||||
|
||||
Reference in New Issue
Block a user