# 计划联动看板实现说明 ## 功能概述 计划联动看板用于展示销售订单的全流程联动信息,包括工单、排产、采购、投产、入库等关键节点的计划时间、实际时间及偏差对比。 ## 核心特性 1. **初始加载自动刷新**:页面首次加载时自动执行存储过程 `pr_Mes_LinkagePlan` 刷新数据 2. **查询按钮仅查询**:点击查询按钮时只执行SQL查询,不刷新数据 3. **重置按钮重新刷新**:点击重置按钮会重新执行存储过程 4. **背景色标记**:根据偏差情况自动标记单元格背景色(红色>7天,黄色>0天) 5. **交付跟踪**:点击行操作可查看销售订单详情(只读模式) ## 文件结构 ### 后端文件 ``` yudao-order-server/src/main/java/cn/iocoder/yudao/module/order/ ├── controller/admin/linkage/ │ ├── LinkagePlanController.java # 控制器 │ └── vo/ │ ├── LinkagePlanPageReqVO.java # 分页请求VO │ └── LinkagePlanRespVO.java # 响应VO ├── service/ │ ├── LinkagePlanService.java # 服务接口 │ └── impl/ │ └── LinkagePlanServiceImpl.java # 服务实现 └── dal/mysql/ └── LinkagePlanMapper.java # Mapper接口 yudao-order-server/src/main/resources/mapper/order/ └── LinkagePlanMapper.xml # MyBatis XML映射 ``` ### 前端文件 ``` yudao-ui/yudao-ui-admin-vue3/src/ ├── api/jiaohuo/ │ └── linkagePlan.ts # API接口定义 └── views/jiaohuo/ └── LinkagePlan.vue # 页面组件 ``` ## API接口 ### 获取计划联动看板列表 **接口地址**:`GET /admin-api/order/linkage-plan/list` **请求参数**: ```typescript { billNo?: string // 订单编号(模糊匹配) customNo?: string // 客户编码(模糊匹配) orderType?: string // 订单类型:计划/销售 itemNumber?: string // 物料代码 pageNo?: number // 页码 pageSize?: number // 每页数量 initialLoad?: boolean // 是否初始加载(内部使用) } ``` **响应数据**: ```typescript { code: 0, data: { list: LinkagePlanRespVO[], total: number }, msg: "success" } ``` ## 数据字段说明 | 字段 | 说明 | 类型 | 备注 | |------|------|------|------| | billNo | 订单编号 | String | | | customNo | 客户编码 | String | | | orderType | 类型 | String | | | itemNumber | 物料代码 | String | | | descr | 物料名称 | String | | | descr1 | 规格型号 | String | | | itemType | 产品类型 | String | | | qty | 数量 | Integer | | | updateTime | 生产通知 | String | 计划/实际:日期,偏差:天数 | | sysCapacityDate | 合同交期 | String | 计划/实际:日期,偏差:天数 | | type | 计划管控 | String | 计划/实际/偏差 | | bomstart | Bom设计开始 | String | 计划/实际:日期,偏差:天数 | | bomend | Bom设计结束 | String | 计划/实际:日期,偏差:天数 | | linestart | 工艺设计开始 | String | 计划/实际:日期,偏差:天数 | | lineend | 工艺设计结束 | String | 计划/实际:日期,偏差:天数 | | productstart | 生产开始 | String | 计划/实际:日期,偏差:天数 | | productend | 生产结束 | String | 计划/实际:日期,偏差:天数 | | needtime | 物料需求 | String | 计划/实际:日期,偏差:天数 | | sysMaterialDate | 物料满足 | String | 计划/实际:日期,偏差:天数 | | cgneedtime | 采购下单 | String | 计划/实际:日期,偏差:天数 | | cgend | 采购到货 | String | 计划/实际:日期,偏差:天数 | | blstart | 备料开始 | String | 计划/实际:日期,偏差:天数 | | blend | 备料结束 | String | 计划/实际:日期,偏差:天数 | | starttime | 报工开始 | String | 计划/实际:日期,偏差:天数 | | endtime | 报工结束 | String | 计划/实际:日期,偏差:天数 | | ipqcjystart | IQC检验开始 | String | 计划/实际:日期,偏差:天数 | | ipqcjyend | IQC检验结束 | String | 计划/实际:日期,偏差:天数 | | fqcjystart | FQC检验开始 | String | 计划/实际:日期,偏差:天数 | | fqcjyend | FQC检验结束 | String | 计划/实际:日期,偏差:天数 | | rkstart | 入库开始 | String | 计划/实际:日期,偏差:天数 | | rkend | 入库结束 | String | 计划/实际:日期,偏差:天数 | | fystarttime | 发运开始 | String | 计划/实际:日期,偏差:天数 | | fyendtime | 发运结束 | String | 计划/实际:日期,偏差:天数 | | levelnum | 排序 | Integer | | | background | 背景色标记 | String | 格式:字段名:颜色; | **重要说明**:所有日期字段统一使用String类型,因为: - "计划"和"实际"类型记录存储日期字符串(如"2024-01-15") - "偏差"类型记录存储天数字符串(如"0"、"7"、"-3") - 前端根据type字段判断如何格式化显示 ## 背景色规则 背景色字段格式:`字段名:颜色;字段名:颜色;...` 例如:`bomstart:red;bomend:yellow;linestart:red;` - **红色**:偏差 > 7天 - **黄色**:偏差 > 0天且 ≤ 7天 - **无色**:无偏差或未超期 ## 使用说明 ### 1. 配置权限 需要在系统菜单中配置权限标识:`order:linkage-plan:query` ### 2. 配置菜单 建议菜单路径:`S1产销协同 => 产销协同看板 => 计划联动看板` ### 3. 前端路由配置 在路由配置中添加: ```typescript { path: '/jiaohuo/linkage-plan', name: 'LinkagePlan', component: () => import('@/views/jiaohuo/LinkagePlan.vue'), meta: { title: '计划联动看板', permission: 'order:linkage-plan:query' } } ``` ### 4. 数据库准备 确保已执行存储过程创建脚本:`sql/mysql/pr_Mes_LinkagePlan_fixed.sql` ## 技术要点 ### 1. 初始加载控制 前端使用 `isInitialLoad` 标志控制是否执行存储过程: - 首次加载:`initialLoad=true`,执行存储过程 - 查询按钮:`initialLoad=false`,仅查询 - 重置按钮:`initialLoad=true`,重新执行存储过程 ### 2. 背景色渲染 使用 `cell-style` 属性动态设置单元格背景色: ```typescript const getCellStyle = ({ row, column }) => { const backgroundStr = row.background const columnProp = column.property // 解析background字符串 const styles = backgroundStr.split(';') for (const style of styles) { const [field, color] = style.split(':') if (field === columnProp) { return { backgroundColor: color === 'red' ? '#fef0f0' : '#fdf6ec' } } } return {} } ``` ### 3. 事务处理 Service层使用 `@Transactional` 确保存储过程执行和查询的原子性。 ## 注意事项 1. **存储过程执行时间**:首次加载可能需要较长时间,建议添加加载提示 2. **数据量控制**:建议使用分页,避免一次加载过多数据 3. **权限控制**:确保用户有相应的查询权限 4. **错误处理**:存储过程执行失败时会抛出异常,前端需要妥善处理 5. **数据类型**:所有日期字段使用String类型,因为"偏差"记录存储的是天数而非日期 6. **租户过滤**:LinkagePlan表无tenant_id字段,已使用`@InterceptorIgnore`禁用租户过滤 7. **字段映射**:数据库字段名包含大写字母(ItemType、Descr、Descr1),已使用`@TableField`注解映射 ## 已解决的问题 ### 问题1:表名错误 - **错误**:`Table 'dopdemo.linkage_plan_resp_v_o' doesn't exist` - **原因**:Mapper泛型使用了VO类而非DO类 - **解决**:创建LinkagePlanDO类,Mapper继承`BaseMapperX` ### 问题2:租户字段不存在 - **错误**:`Unknown column 'tenant_id' in 'where clause'` - **原因**:LinkagePlan表没有tenant_id字段,但MyBatis Plus自动添加了租户过滤 - **解决**:在Mapper方法上添加`@InterceptorIgnore(tenantLine = "true")`注解 ### 问题3:字段名大小写不匹配 - **错误**:`Unknown column 'item_type' in 'field list'` - **原因**:数据库字段名为ItemType(大写),MyBatis Plus默认转换为item_type - **解决**:在DO类中使用`@TableField("ItemType")`等注解指定实际字段名 ### 问题4:日期类型转换错误 - **错误**:`Cannot convert string '0' to java.time.LocalDateTime value` - **原因**:偏差记录中日期字段存储的是天数(如"0"、"7"),而非日期格式 - **解决**:将DO和VO中所有日期字段改为String类型,前端根据type字段判断如何显示 ## 扩展功能 可以考虑添加以下功能: 1. **导出Excel**:导出当前查询结果 2. **列显示控制**:允许用户自定义显示列 3. **数据刷新按钮**:手动触发存储过程刷新 4. **统计汇总**:添加各节点完成率统计 5. **预警提醒**:对超期项目进行预警提示