Compare commits

...

224 Commits

Author SHA1 Message Date
0355f68bc6 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-05-07 17:32:35 +08:00
f21101e5e0 refactor(wms): 将钢卷异常报表导出功能从POI迁移到EasyExcel取消合并功能追求导出速度
- 移除 POI相关依赖和导入包
- 添加com.alibaba.excel.EasyExcel依赖
- 创建WmsCoilAbnormalExportVo导出DTO类,使用EasyExcel注解
- 重构导出方法,将原有的XSSFWorkbook方式替换为EasyExcel方式
- 优化导出性能,降低复杂度到O(n)
- 简化Excel样式设置和数据填充逻辑
- 保持原有导出数据结构和字段映射关系不变
2026-05-07 17:32:25 +08:00
16462daf7b fix(wms报表): 修复数据过滤和去重逻辑
确保在映射coilId和processedCoilIds前先过滤掉空值,避免潜在的错误
2026-05-07 17:17:46 +08:00
61385818d0 refactor(report): 重构拉矫线报表组件,使用统一模板
将拉矫线的各类报表(out/day/month/year/team/loss/comprehensive)重构为使用统一的ActionTemplate组件
增加axios请求超时时间至300000ms
简化导出按钮为单个按钮
2026-05-07 16:28:20 +08:00
6a01fb3576 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-05-07 16:23:23 +08:00
c39fc25a1a feat(bonus): 添加奖金分配、奖金池和岗位系数配置功能
- 新增 WmsBonusConfig 实体类用于奖金分配对象
- 新增 WmsBonusPool 实体类用于奖金池对象
- 新增 WmsPostCoeffConfig 实体类用于岗位系数配置对象
- 创建 IWmsBonusConfigService 接口及其实现类
- 创建 IWmsBonusPoolService 接口及其实现类
- 创建 IWmsPostCoeffConfigService 接口及其实现类
- 添加 WmsBonusConfigController 控制器实现 CRUD 操作
- 添加 WmsBonusPoolController 控制器实现 CRUD 操作
- 添加 WmsPostCoeffConfigController 控制器实现 CRUD 操作
- 创建对应的 Mapper 接口和 XML 映射文件
- 实现分页查询、导出 Excel 等功能
- 添加数据验证和业务逻辑处理
2026-05-07 16:23:11 +08:00
7da3e62ee5 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-05-07 11:35:48 +08:00
3511a85416 fix(wms报表): 修复仓库选项变化时未更新仓库ID的问题
取消watch中handleQuery的调用并添加immediate选项,确保仓库ID能正确同步
2026-05-07 11:35:38 +08:00
34418f14ca feat(导出功能): 添加导出全部数据功能并优化导出按钮样式
- 新增导出全部数据功能,包括当前页和所有数据
- 区分导出当前和导出全部按钮样式
- 重置查询时清空仓库ID参数
2026-05-07 11:24:31 +08:00
94b2a55d0a Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-05-07 11:20:02 +08:00
a5280923e1 双机架轧辊管理 2026-05-07 11:19:32 +08:00
b129dd8f13 refactor(CoilSelector): 重构多选模式界面并移除销售受限逻辑
重构多选模式界面,使用拖拽面板展示已选钢卷列表
移除销售视角受限逻辑及相关样式
调整默认分页大小为50条
2026-05-07 11:08:05 +08:00
89a079e49f feat(ems/dashboard): 重构能源管理仪表盘界面与功能
- 移除统计卡片,新增能源流向桑基图
- 优化能源类型二维表展示
- 添加产线能源时序分析图表
- 调整能源消耗趋势和能源产线占比图表
- 增加能源类型和产线筛选功能
2026-05-07 11:07:49 +08:00
d71b1c4959 perf(wms): 优化钢卷质量改判原因查询性能
- 在WmsCoilQualityRejudgeMapper中新增原生SQL查询方法selectMapsBySql
- 添加对应的XML映射配置执行动态SQL查询
- 将原有的Java端分组逻辑改为数据库端SQL聚合查询
- 使用内连接和子查询直接获取每个钢卷的最新改判原因
- 避免大量数据传输和客户端分组处理,提升查询效率
2026-05-06 18:05:15 +08:00
bb97d0d2a7 fix(wms): 修正异常钢卷导出接口路径和文件名
将导出接口从'materialCoil/export'改为'materialCoil/exportAbnormal',同时将导出文件名从'materialCoil'改为'abnormalCoil'以更准确反映功能
2026-05-06 17:45:22 +08:00
484d16017d Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-05-06 17:31:36 +08:00
2068c412b0 feat(wms): 添加钢卷异常报表导出功能
- 在IWmsMaterialCoilService中新增exportAbnormalReport方法
- 在WmsMaterialCoilController中新增/exportAbnormal接口
- 重构WmsMaterialCoilExportVo中的purpose字段为businessPurpose
- 在WmsMaterialCoilServiceImpl中实现异常报表导出逻辑
- 添加POI依赖支持Excel导出功能
- 新增WmsCoilAbnormalExportRow数据结构
- 实现钢卷信息与异常信息的关联查询和数据合并
- 支持按coilIds批量导出异常报表
- 实现Excel表格的样式设置和单元格合并功能
2026-05-06 17:29:42 +08:00
5950118c86 feat(wms): 添加excludeBound参数并调整表格列顺序
- 在delivery/canuse页面添加excludeBound参数
- 修复coil/panels/do页面颜色渐变语法错误
- 在report/receive页面透视表配置中添加规格字段
- 调整coil/panels/base页面表格列顺序
2026-05-06 16:21:32 +08:00
d26f98440f feat(warehouse): 增加支持拆分的列数
将 splitColumns 从 [1,2,3] 扩展为 [1,2,3,4,5],以支持更多列的拆分操作
2026-05-06 16:21:06 +08:00
268995e8e2 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-05-06 09:47:51 +08:00
abc7682e6f feat(erp): 添加采购订单实体字段扩展
- 在ErpPurchaseOrder实体类中新增单据类型、收发类别、部门、业务员等字段
- 在ErpPurchaseOrderBo业务对象中同步添加对应的查询条件字段
- 在ErpPurchaseOrderVo视图对象中添加Excel导出注解配置
- 在MyBatis映射文件中配置新增字段的数据库映射关系
- 在服务实现类中为新增字段添加查询条件构建逻辑
- 统一处理新增字段的JSON序列化和反序列化格式
2026-05-06 09:47:40 +08:00
bc2e42b110 feat(异常管理): 增强异常表格功能并优化显示
添加coil-info属性支持以显示异常挂载时机
新增创建人和创建时间列
调整主缺陷列位置
优化质量状态显示逻辑
2026-05-05 17:42:41 +08:00
2f5c799143 feat(contract): 添加合同置顶功能
在合同列表和表单中添加置顶功能,包括:
1. 表单中添加置顶开关
2. 列表项显示置顶标签和样式
3. 实现置顶状态切换操作
2026-05-05 17:42:14 +08:00
5605445c19 refactor(domain): 优化WmsCoilAbnormalVo类继承结构
- 添加BaseEntity父类继承以统一基础属性管理
- 移除冗余的基础字段定义
- 提升代码复用性和维护性
- 保持原有业务逻辑不变
2026-05-05 16:50:43 +08:00
54adbd532e feat(order): 添加订单置顶功能并优化排序规则
- 在CrmOrder实体类中新增isTop字段用于标识是否置顶
- 在CrmOrderBo业务对象中添加isTop属性支持查询过滤
- 在CrmOrderVo视图对象中添加isTop属性并配置Excel导出
- 更新MyBatis映射文件添加isTop字段的数据库映射关系
- 修改订单查询服务实现支持按置顶状态进行查询过滤
- 重构排序逻辑将原有的订单类型+创建时间排序改为置顶优先+状态+创建时间排序
- 新排序规则:置顶订单优先显示、已生效状态次之、最后按创建时间倒序排列
2026-05-05 16:48:13 +08:00
8c1ba2bf07 refactor(wms/report): 移除warehouseOptions的watch监听
立即执行watch可能导致不必要的初始查询,改为手动触发查询更合理
2026-05-05 15:19:34 +08:00
fa198181ee feat(wms): 新增报表透视表组件并优化操作状态显示
refactor: 替换select为tag显示操作状态
feat: 添加今天按钮到时间范围选择器
fix: 移除调试用的console.log
style: 调整按钮间距样式
feat: 新增厂家材质透视表和宽度厚度统计表
refactor: 优化导出功能去除orderBy参数
feat: 添加表面处理等查询条件
feat: 在coilTable中添加settings插槽
feat: 使用下拉菜单整合报表操作按钮
2026-05-05 14:52:24 +08:00
723ccc9e58 feat(wms): 添加炉计划钢卷重复性校验功能
- 实现 planId 和 coilId 组合的唯一性检查
- 在更新操作时排除当前记录的重复校验
- 查询数据库验证相同计划下的钢卷是否存在
- 抛出运行时异常阻止重复添加相同钢卷到计划
- 完善数据校验逻辑确保业务规则正确执行
2026-05-05 13:10:08 +08:00
28755f77c7 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-05-01 20:49:50 +08:00
b1c9bc5e81 feat(wms): 在双机架工序和报表配置中添加镀铬原料库选项 2026-05-01 20:49:45 +08:00
ea884b9096 fix(wms): 修复成品类型排序问题
- 将orderBy默认值从true修改为false以解决排序异常
2026-05-01 10:12:29 +08:00
68fc8c4261 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-30 15:22:32 +08:00
fa39c038de feat(crm): 在订单详情中添加表面质量字段
添加表面质量字段到订单详情表格和表单中,以满足业务需求
2026-04-30 15:22:29 +08:00
99b04de630 refactor(crm): 修改订单项目字段数据类型并新增表面质量属性
- 将宽度公差、厚度公差字段从 BigDecimal 类型改为 String 类型
- 将宽度、厚度字段从 BigDecimal 类型改为 String 类型
- 新增表面质量(surfaceQuality)字段及相应 getter/setter 方法
- 更新数据库映射文件添加表面质量字段映射
- 修改查询条件构建逻辑适配字符串类型字段判空
- 更新 Excel 导入导出配置适配新的数据类型
2026-04-30 15:21:39 +08:00
292e9df47d refactor(wms): 使用CoilInfoRender组件重构钢卷信息展示
将多个文件中重复的钢卷信息展示代码提取为CoilInfoRender组件,提高代码复用性和可维护性
2026-04-30 14:14:32 +08:00
945c3560eb feat: 增加"精包"选项并调整请求超时时间
- 在多个表单的包装要求选项中新增"精包"选项
- 将axios请求超时时间从20000毫秒调整为30000毫秒
- 在CRM订单详情中将包装要求输入框改为下拉选择框
2026-04-30 13:58:09 +08:00
12b3f0556d feat(wms/report): 新增修复报告页面和功能
feat(ems/assisted): 添加公辅消耗记录和类型管理功能

fix(eqp): 修改公辅消耗记录接口返回类型为Long

refactor(wms/report): 优化合并模板查询逻辑和统计信息展示

style(wms/report): 调整时间范围选择器组件逻辑

docs(wms/report): 更新配置文件中产线类型配置

feat(wms/report): 新增异常报告页面和功能
2026-04-30 13:57:42 +08:00
9967d8be46 feat(ems): 添加产线信息显示和视图切换功能
refactor(dashboard): 移除过时的趋势分析组件

- 在仪表盘表格中添加产线信息显示
- 在设备管理页面增加卡片/表格视图切换功能
- 删除不再使用的趋势分析组件
2026-04-30 13:06:14 +08:00
b1a997fde8 feat(调拨): 添加调拨记录查看功能并优化显示
- 在卷材信息页面添加调拨记录弹窗,展示批量调拨和技术部改判记录
- 为卷材选择器添加数据类型和状态过滤条件
- 调整仓库表格的flex布局比例
- 在卷材操作面板添加查看调拨记录按钮
2026-04-30 10:28:09 +08:00
89867e8d70 feat(wms): 添加更多列显示选项和样式优化
- 在delivery/canuse页面添加moreColumn属性控制额外列显示
- 在coil/panels/base页面添加moreColumn属性和相关列显示逻辑
- 优化表格容器样式防止内容溢出
- 为表格添加边框样式
2026-04-29 17:25:13 +08:00
634adccce8 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-29 16:13:30 +08:00
788f5d2b7c feat(eqp): 添加公辅消耗记录和公辅类型管理功能
- 创建公辅消耗记录实体类、业务对象和视图对象
- 实现公辅消耗记录的增删改查和导出功能
- 创建公辅类型实体类、业务对象和视图对象
- 实现公辅类型的增删改查和导出功能
- 添加对应的控制器、服务层和数据访问层实现
- 配置MyBatis映射文件和相关依赖
- 更新代码生成配置以适配新模块结构
2026-04-29 16:13:21 +08:00
6c1a15b952 feat(HRM): 为待办和申请页面添加删除驳回记录功能
为待办列表和外出/请假申请页面添加删除按钮,允许用户删除状态为"已驳回"的记录。同时为所有操作按钮添加loading状态防止重复点击。

- 在待办列表(index.vue)中添加删除按钮,处理驳回状态的记录
- 在外出申请(goout.vue)和请假申请(leave.vue)页面添加删除按钮
- 为所有操作按钮添加loading状态
- 新增删除API调用方法
2026-04-29 15:11:44 +08:00
7d4d2282fe Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-29 13:07:57 +08:00
bbe451cb23 feat(wms): 添加已删除数据查询功能
- 在WmsApprovalMapper中新增selectVoListWithDeleted方法用于查询未删除和已删除的审批数据
- 在WmsApprovalTaskMapper中新增selectVoListWithDeleted方法用于查询未删除和已删除的审批任务数据
- 更新WmsApprovalServiceImpl中审批任务查询逻辑,使用新的方法获取包含已删除数据的任务
- 更新WmsApprovalTaskServiceImpl中审批信息查询逻辑,使用新的方法获取包含已删除数据的审批
- 在XML映射文件中添加对应的SQL查询语句,支持按del_flag条件查询数据
2026-04-29 13:07:48 +08:00
73c461f0e4 feat: 新增酸轧系统实时跟踪和实绩功能
- 添加实时跟踪页面,支持查询Gauge和Shape数据
- 新增实绩页面,展示钢卷生产数据和工艺图表
- 优化钢卷追踪结果展示,增加创建步骤卷号显示
- 调整酸轧系统菜单结构,新增"实绩"和"实时"选项
- 扩展工艺图表展示,增加开卷机、温度等参数
- 修改计划列表分页大小为10
- 移除无用代码和注释
2026-04-29 10:40:16 +08:00
王文昊
5a56094e4f refactor(dict): 优化字典数据查询逻辑和接口
- 移除不必要的 ISysDictTypeService 依赖,简化 SysDictDataController
- 新增 selectDictDataByTypeRealtime 方法,支持实时查询字典数据,避免缓存问题
- 更新 SysDictDataController 中的字典数据查询逻辑,使用新方法
- 在 SysDictTypeController 中添加按字典类型编码精确查询的接口
- 更新前端组件以支持新的字典查询接口,优化字典选择器的加载逻辑
2026-04-28 19:12:50 +08:00
dde947516d Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-28 17:08:12 +08:00
0f0e0f3ae2 提交sql 2026-04-28 17:07:59 +08:00
b12d7679d8 feat(wms): 添加冷硬卷生产工艺数据图表展示
添加生产工艺数据图表展示功能,包括速度趋势、轧机出口速度和张力趋势图表
修复钢卷信息显示时的空值判断问题
2026-04-28 14:30:05 +08:00
419fcb6c62 feat(ems): 添加产线选择和总表功能,增强表格配置选项
- 在电表管理页面添加产线选择下拉框和总表开关
- 在能耗表格页面添加配置选项:显示求和行、分表求和、误差计算
- 实现表格汇总行计算功能
- 添加误差和误差率计算功能
2026-04-28 10:43:20 +08:00
674859504f fix(config): 更新生产环境SQL服务器API主机地址
- 将sql-server-api主机地址从192.168.0.219更改为140.143.206.120
- 保持端口配置为15000不变
- 确保基础URL构建逻辑正常工作
2026-04-28 09:02:24 +08:00
b7161e9541 数据贯通完成,规程重构 2026-04-27 20:37:59 +08:00
5b38ef734a feat(排产单): 新增排产单追踪页面和钢卷列表查询功能
- 添加排产单追踪页面,展示排产单详情和对应钢卷信息
- 新增listPlanCoils接口用于查询排产单对应的钢卷列表
- 在PlanSheetList组件中添加readonly属性控制操作按钮显示
- 优化CoilTable组件中钢卷号的列名显示
2026-04-27 18:36:23 +08:00
b85971d532 feat(crm): 添加销售员详情页数据加载功能
- 新增按销售员查询订单明细卷的API接口
- 为CoilTable和DeliveryTable组件添加高度属性
- 实现销售员详情页各标签页数据懒加载功能
- 优化销售员卡片点击和标签页切换时的数据加载逻辑
2026-04-27 18:14:54 +08:00
dc170c77d9 feat(delivery): 添加按负责人查询已绑定钢卷功能
- 在 IWmsDeliveryWaybillDetailService 中新增 getBoundCoilIdsByPrincipal 方法
- 在 WmsDeliveryWaybillDetailController 中添加 coilListByPrincipal 接口
- 实现 WmsDeliveryWaybillDetailServiceImpl 中的 getBoundCoilIdsByPrincipal 逻辑
- 使用 LambdaQueryWrapper 查询指定负责人的运单及关联钢卷信息
- 添加参数校验和空值处理机制
2026-04-27 17:28:19 +08:00
702de37397 feat(钢卷管理): 在操作列添加数字钢卷按钮并实现跳转功能
添加数字钢卷按钮到钢卷管理页面的操作列,并实现点击跳转到数字钢卷详情页面的功能。同时调整了操作列的宽度以适应新增按钮。
2026-04-27 16:42:43 +08:00
81252ccb2d feat(报表): 添加时间范围选择器组件并替换原有日期选择
重构报表页面中的日期选择功能,使用统一的 TimeRangePicker 组件替换原有的独立开始/结束时间选择器。
该组件提供快捷时间范围选择功能,并保持原有时间格式兼容性。同时优化了相关页面的数据结构,移除冗余的字典配置。
2026-04-27 16:42:32 +08:00
0c3382d6db feat(ems): 能源设备添加电表产线和总表标识字段
- 在 EmsMeter 实体类中新增 productionLine 和 isTotalMeter 字段
- 在 EmsMeterBo 业务对象中添加对应的产线和总表标识属性
- 更新 EmsMeterMapper.xml 映射文件以支持新字段的数据库映射
- 在查询条件中增加产线模糊匹配和总表标识精确匹配功能
- 在 EmsMeterVo 视图对象中添加 Excel 导出支持的新字段
2026-04-27 15:28:05 +08:00
3746175b24 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-27 14:38:26 +08:00
b3d33f4368 feat(退火模块): 新增退火报表页面并优化现有功能
新增退火报表页面,支持按时间、炉号等条件查询统计信息
优化退火计划和性能页面,增加当前钢卷号和逻辑库区筛选
改进KLPTable浮层组件,支持嵌套属性访问和更智能的定位
重构退火计划控制页面布局和交互,提升用户体验
2026-04-27 14:38:20 +08:00
3c5c71408b feat(钢卷类型异常): 添加原料类型缺失标签页并修复单位显示
- 新增原料类型缺失标签页及相关查询功能
- 将实测长度单位从mm修正为m
- 添加原料类型缺失列表的查询方法
2026-04-27 14:37:52 +08:00
bfb253ee1b refactor(aps): 排产计划报表导出报错解决
- 将ApsPlanDetailServiceImpl中的IApsPlanSheetService替换为ApsPlanSheetMapper
- 直接通过mapper进行数据查询操作,减少服务层依赖
- 修复计划表合并逻辑中的边界条件判断问题
- 确保数据起始行和结束行的有效性验证
2026-04-27 14:10:44 +08:00
74d0cfedf4 feat(aps): 添加根据排产单ID查询关联钢卷功能
- 在ApsPlanDetailController中新增/coils/{planSheetId}接口
- 实现queryCoilsByPlanSheetId方法查询指定排产单关联的钢卷
- 集成WmsCoilContractRel和WmsMaterialCoilService相关服务
- 根据排产日期筛选钢卷创建时间范围
- 添加日期范围计算工具方法支持天级别时间筛选
2026-04-27 13:50:41 +08:00
9e03dbe9de refactor(wms): 优化炉计划钢卷查询逻辑
- 移除 WmsFurnacePlanCoilVo 中的实际库位相关字段
- 添加 WmsMaterialCoilVo 类型的 coil 字段用于存储钢卷完整信息
- 将查询逻辑重构为分步骤处理:查询计划钢卷、批量获取钢卷信息、构建库区映射、填充数据
- 使用 WmsMaterialCoilVo 替代 WmsMaterialCoil 进行数据传输
- 新增 buildLogicWarehouseNameMap 和 fillCoilInfo 辅助方法提升代码可读性
- 通过批量查询减少数据库访问次数,提升查询性能
2026-04-27 13:23:49 +08:00
43ace2f91e feat(WmsAnnealPerformance): 添加当前钢卷号和逻辑库区ID筛选功能
- 在WmsAnnealPerformanceBo中新增currentCoilNo和warehouseId字段
- 在Mapper XML中添加currentCoilNo和warehouseId的查询条件
- 修改JOIN条件以支持多字段筛选
- 在服务实现中添加对新字段的筛选逻辑
- 更新注释内容以反映新的筛选条件
2026-04-27 13:00:33 +08:00
fe048ff91f feat(anneal-performance): 添加退火性能查询中的钢卷号筛选功能
- 在 WmsAnnealPerformanceMapper.xml 中添加钢卷号筛选的关联查询逻辑
- 在 WmsAnnealPerformanceServiceImpl 中实现钢卷号筛选的功能
- 添加筛选后统计数据重新计算的逻辑
- 实现过滤不匹配钢卷的跳过机制
- 添加过滤后无数据计划的移除处理
- 更新汇总统计信息以反映筛选后的实际数据
2026-04-27 11:31:22 +08:00
3e0859d4ce Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-27 11:03:18 +08:00
db18d4dc34 feat(WmsMaterialCoil): 修改原料材质的匹配功能
- 新增 onlyEmptyPackingStatus 字段用于查询打包状态为空的钢卷
- 修改数据库查询逻辑增加打包状态非空条件
- 更新查询条件实现打包状态匹配优化
- 添加服务层业务逻辑支持打包状态筛选功能
2026-04-27 11:03:04 +08:00
dd4ca3d380 fix: 统一长度单位显示为米并优化CoilInfo组件
将多处长度单位从毫米(mm)改为米(m),保持单位统一
重构CoilInfo组件为动态字段配置模式,提升可维护性
移除未使用的CoilInfoRender组件引用
2026-04-27 10:26:13 +08:00
8c0126d7f8 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-25 18:20:34 +08:00
73b65962f2 添加数据贯通代码未调试 2026-04-25 18:20:28 +08:00
ffc73689a1 添加数据贯通代码未调试 2026-04-25 18:19:29 +08:00
7fa0a7d38f style(wms/coil): 移除测量值显示中的冗余单位
统一移除组件中已包含在标签里的单位显示,避免重复
2026-04-25 17:08:25 +08:00
a1be1bf5ad Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-25 16:07:22 +08:00
bf44909686 feat(WmsDeliveryWaybillDetailController): 添加已发货钢卷统计数据接口
- 新增 statistics 接口用于统计已发货绑定钢卷的汇总数据
- 支持按时间范围查询已绑定钢卷ID列表
- 实现毛重、净重、数量等指标的数据统计功能
- 添加 startTime 和 endTime 参数支持时间段筛选
- 集成 WmsMaterialCoilService 的 getStatistics 方法
- 返回 Map 结构的统计数据结果
2026-04-25 16:07:13 +08:00
0cfffc3adb feat(wms): 添加leftWarehouseQuery属性并优化表格显示
优化线圈信息显示格式,移除单位后缀
调整移库记录表格列宽和显示内容
修改批量调拨和技术部改判的前后状态显示格式
2026-04-25 15:59:14 +08:00
5729f2ee1a Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-25 15:28:50 +08:00
511d5b7385 fix: 统一钢卷尺寸单位显示为毫米(mm)
修改多个组件中钢卷尺寸的单位显示,将"米(m)"统一改为"毫米(mm)",包括实测长度、宽度和厚度的标签及数值显示。同时调整了酸轧工序的标签名称从"酸轧工序"改为"酸连轧工序"以保持一致性。

在表格、表单、描述组件等多个地方进行了单位统一修改,确保整个系统中钢卷尺寸单位显示一致。添加了钢卷状态的行样式显示功能,根据不同类型显示不同背景色。
2026-04-25 15:28:47 +08:00
01a06566ee Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-25 12:56:06 +08:00
865c00b5b4 fix(security): 更新安全配置并修正炉计划服务逻辑
- 在安全配置中添加 /wms/coilPendingAction/** 路径到忽略列表
- 从安全配置中移除测接口相关路径
- 移除 WmsFurnacePlanServiceImpl 中的 endTime 设置逻辑
- 简化炉计划实际开始时间设置流程
2026-04-25 12:55:56 +08:00
133817883d feat(钢卷信息): 添加暂存功能及暂存数据恢复功能
实现钢卷信息编辑的暂存功能,包括:
1. 添加暂存按钮及暂存逻辑
2. 添加暂存数据检测及恢复弹窗
3. 实现暂存数据的展示、使用和删除功能
2026-04-25 11:09:14 +08:00
668af2140a fix: 修复规格分割可能导致的undefined错误
处理多处规格(specification)分割时的空值情况,添加可选链操作符和默认值
修改wms报表合并查询参数,清空时间条件
调整acid页面容器样式
2026-04-25 09:40:12 +08:00
c5fa84df98 feat(router): 添加数字钢卷路由
feat(components): 为MutiSelect组件添加collapseTags属性

feat(views): 新增酸连轧系统页面及组件

feat(views): 添加数字钢卷信息展示组件

refactor(views): 重构基础面板组件,支持数字钢卷功能
2026-04-24 17:49:11 +08:00
594a921880 feat(wms): 新增综合报表模板及分条线报表组件
添加mands.vue模板组件用于综合报表展示,包含日期筛选、数据统计、图表展示等功能
新增and.vue分条线报表组件,继承综合报表模板功能
实现产出与消耗钢卷数据的对比统计及可视化展示
2026-04-24 17:49:01 +08:00
e4028effc7 feat(钢卷分条): 添加分条表单暂存功能
- 新增钢卷缓存API模块,提供暂存数据的增删改查功能
- 在分条表单中添加暂存按钮和恢复缓存数据功能
- 增加缓存数据展示弹窗,支持恢复或删除暂存数据
- 优化表格显示,添加序号列和高亮当前行
2026-04-24 16:32:41 +08:00
2aaa991516 fix(WmsCoilCacheMapper): 查询线圈缓存时过滤已删除记录
- 在 selectVoByCoilId 查询中添加 del_flag = 0 条件
- 确保只返回未被标记为删除的线圈缓存数据
2026-04-24 16:27:42 +08:00
c7cf377358 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-24 16:22:30 +08:00
f6c365d60e fix(data): 修复钢卷缓存查询返回类型和质量状态检查逻辑
- 修改 WmsCoilCacheMapper.xml 中 selectVoByCoilId 查询的返回类型
- 修复 WmsMaterialCoilServiceImpl 中质量状态检查的条件判断逻辑
- 确保非免检仓库的质量状态验证正常工作
2026-04-24 16:21:55 +08:00
a17969e5e2 refactor(wms): 替换钢卷卡片为表格展示并优化布局
将多个视图中的钢卷卡片组件替换为KLPTable表格组件,统一展示钢卷信息
添加浮动层配置显示详细字段,优化操作按钮布局
调整页面列宽比例,简化操作记录卡片样式
2026-04-24 14:39:16 +08:00
7803c38c27 fix(wayBill): 修改打印失败处理逻辑并显示错误提示
feat(CoilSelector): 添加镀层质量列并优化钢卷选择逻辑

1. 在wayBill组件中,当打印失败时不再尝试下载PDF,而是直接显示错误提示
2. 在CoilSelector组件中添加镀层质量列
3. 优化钢卷选择逻辑,增加对未判级钢卷的限制条件
2026-04-24 14:31:20 +08:00
a1b2a3b6bb feat(sql): 最新的klp表结构 2026-04-24 14:12:49 +08:00
9e32a34f62 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-24 14:07:22 +08:00
c84000059f feat(wms): 添加钢卷缓存功能模块
- 创建钢卷缓存实体类WmsCoilCache,包含缓存ID、钢卷ID、JSON数据等字段
- 定义钢卷缓存服务接口IWmsCoilCacheService,提供查询、新增、修改、删除等操作方法
- 实现钢卷缓存服务业务逻辑WmsCoilCacheServiceImpl,包含分页查询和批量操作功能
- 开发钢卷缓存控制器WmsCoilCacheController,提供RESTful API接口
- 创建钢卷缓存映射器WmsCoilCacheMapper及对应的XML映射文件
- 添加钢卷缓存业务对象WmsCoilCacheBo和视图对象WmsCoilCacheVo
- 实现按钢卷ID保存或更新缓存的功能,支持存在则覆盖、不存在则新增的逻辑
- 提供按钢卷ID查询缓存数据的专用接口
2026-04-24 14:05:58 +08:00
b7dade8ce1 添加甲骨文数据源 2026-04-24 14:03:43 +08:00
323d90db92 fix(wms): 修复钢卷发货时判级检查逻辑
- 移除原有的空白质检状态检查条件
- 添加特免逻辑库ID集合用于豁免未判级检查
- 实现针对特定仓库ID的判级检查绕过机制
- 保留对非特免仓库的未判级钢卷发货限制
- 修复历史数据检查的位置确保正确的执行顺序
2026-04-24 13:10:07 +08:00
b4bd96147f feat(wms): 添加钢卷待处理动作的加工后ID字段
- 在WmsCoilPendingActionIdCoilVo中新增processedCoilIds字段
- 更新WmsCoilPendingActionMapper.xml查询语句以包含processed_coil_ids
- 从WmsMaterialCoilAnnealExportVo中移除目标炉子ID的Excel导出映射
2026-04-24 10:46:18 +08:00
595d4839f3 fix(wms): 添加钢卷未判级状态检查
- 在发货前验证钢卷质量状态是否为空
- 对于未判级的钢卷阻止发货操作并抛出异常
- 确保只有经过质量判定的钢卷可以进行发货流程
2026-04-24 10:14:25 +08:00
cae3f0e14a fix(wms): 修正钢卷标签显示和添加参考长度字段
将标签中的"参考长度"改为"钢卷长度"并显示实际长度值
在表单中添加参考长度输入字段
2026-04-23 15:02:53 +08:00
2d1f4eb281 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-23 11:47:35 +08:00
84c26a2990 feat(contract): 启用产品内容组件并优化合同相关功能
- 在合同页面启用ProductContent组件替代注释代码
- 优化ProductContent组件数值计算和空值处理
- 修改ContractList组件从productContent字段获取数据
- 在OrderDetail组件添加"写入合同"功能
- 优化ReceiveTable组件未收款金额计算逻辑
2026-04-23 11:47:30 +08:00
b840574286 feat(wms): 添加根据钢卷ID查询发货关联信息功能
- 在 IWmsDeliveryWaybillDetailService 中新增 queryRelationByCoilId 方法
- 在 WmsDeliveryWaybillDetailController 中新增 /coilRelation/{coilId} 接口
- 在 WmsDeliveryWaybillDetailServiceImpl 中实现完整的关联查询逻辑
- 创建 WmsDeliveryCoilRelationVo 数据传输对象
- 支持查询发货单明细、发货单、发货计划和钢卷的完整关联信息
2026-04-23 09:54:22 +08:00
a553b8ddc4 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-22 17:47:17 +08:00
98eee1785f fix(database): 已知产品没有热轧卷板
- 移除了wms_product表的LEFT JOIN关联
- 简化了热轧卷板筛选条件,仅保留原材料类型的匹配
- 修正了包装状态检查中的产品表关联逻辑
- 删除了冗余的产品名称匹配条件
- 优化了子查询中的材料类型判断逻辑
2026-04-22 17:47:08 +08:00
8897a2ad9f feat(wms): 添加导出功能并增加导出时间参数
在coil基础面板中增加exportTimeBy参数用于导出时间控制
在退火性能页面添加导出按钮及导出功能
2026-04-22 17:14:47 +08:00
ce71fc937b Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-22 16:55:44 +08:00
18f5931b62 feat(WmsMaterialCoil): 添加按发货时间倒序排序功能
- 在WmsMaterialCoilBo中新增exportTimeBy字段用于控制排序方式
- 实现按发货时间倒序排序的逻辑分支
- 当exportTimeBy为true时按mc.export_time倒序排列
- 保持原有的异常排序和创建时间排序逻辑
2026-04-22 16:55:27 +08:00
1d4fbc6d3f feat(wms): 新增退火报表导出功能
- 在IWmsMaterialCoilService中添加queryAnnealExportList方法
- 在WmsMaterialCoilController中新增exportAnneal接口用于导出退火报表
- 在WmsMaterialCoilMapper中添加selectAnnealExportListByCoilIds查询方法
- 在WmsMaterialCoilMapper.xml中实现退火报表SQL查询,关联钢卷、退火计划、炉子等信息
- 在WmsMaterialCoilServiceImpl中实现退火报表数据查询逻辑
- 创建WmsMaterialCoilAnnealExportVo实体类用于退火报表数据导出
- 优化材质异常查询SQL逻辑,改进热轧卷板相关查询条件
2026-04-22 16:48:50 +08:00
1259a33664 feat(wms): 添加待办事项页面和导航入口
- 新增待办事项功能页面,包含标签待贴和其他待办选项卡
- 在导航栏添加待办事项快捷入口图标
- 更新仓库配置,添加罩式退火原料库选项
- 清理无用路由配置
2026-04-22 16:30:29 +08:00
19dad696a7 feat(排产单): 新增排产单列表组件和优化排产单详情页
refactor(线圈): 移除新增按钮并添加线圈ID格式校验

新增排产单列表组件PlanSheetList用于展示和选择排产单,重构排产单详情页布局和功能
优化线圈操作面板,移除无用新增按钮并添加线圈ID格式校验逻辑
2026-04-22 14:56:03 +08:00
fc203acd68 feat(CoilSelector): 添加创建时间列
feat(anneal/plan): 支持多目标炉选择并优化表单逻辑

- 在CoilSelector组件的数据配置中添加创建时间列
- 修改退火计划表单,支持选择多个目标炉
- 移除未使用的状态更新对话框
- 新增表单提交时对多目标炉的处理逻辑
2026-04-21 17:03:13 +08:00
c60ed8eb86 refactor(WmsFurnacePlanService): 移除炉计划插入操作中的实体验证
- 删除了插入前的实体验证调用 validEntityBeforeSave
- 简化了 insertByBo 方法的执行流程
- 提高了数据插入性能,减少了不必要的验证开销
2026-04-21 17:00:57 +08:00
7229b23fcd feat(标签渲染): 添加订货单位可编辑功能并优化标签数据加载
为标签渲染组件中的订货单位字段添加contenteditable属性,允许用户直接编辑
重构标签数据加载逻辑,当传入coilId时自动查询并填充合同号和订货单位
添加加载状态指示器,提升用户体验
2026-04-21 16:17:36 +08:00
54bdf600df Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-21 15:44:43 +08:00
a8e667a69b feat(wms): 新增原料材质与钢卷类型不匹配查询及修复功能
refactor(crm): 重构销售员管理界面为左右分栏布局

style(wms): 优化钢卷发货状态显示为单选按钮组

chore: 新增考勤请求工具类文件
2026-04-21 15:44:38 +08:00
ba613bb88d Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-21 15:38:21 +08:00
e44235abd8 feat(考勤管理): 新增考勤记录管理功能并移除配置编辑权限校验
新增考勤记录管理的前后端功能,包括查询、新增、修改、删除和同步考勤记录
移除系统配置编辑接口的权限校验注解
2026-04-21 15:38:11 +08:00
fecfb977e8 fix(database): 修复材料匹配查询中的遗漏筛选条件
- 在wms_raw_material表连接中添加了raw_material_name LIKE '%热轧卷板%'筛选条件
- 在wms_product表连接中添加了product_name LIKE '%热轧卷板%'筛选条件
- 确保只有名称包含'热轧卷板'的记录才会被匹配到查询结果中
2026-04-21 15:37:33 +08:00
bd9beb32eb feat(wms): 添加钢卷材质异常修复功能
- 在 IWmsMaterialCoilService 中新增 fixMaterialMismatchCoils 方法用于修复材质异常钢卷
- 在 WmsMaterialCoilController 中新增 /fixMaterialMismatch 接口提供修复功能
- 在 WmsMaterialCoilMapper.xml 中为材质异常查询添加按 coil_id 升序排序
- 在 WmsMaterialCoilServiceImpl 中实现材质异常修复逻辑,包括查询入场钢卷号、查找热轧卷板材质、批量更新 packing_status 等步骤
2026-04-21 13:41:07 +08:00
c571b12463 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-21 13:02:02 +08:00
a2067815a9 feat(wms): 添加考勤记录管理功能
- 新增 AttendanceRecords 实体类定义数据库表结构
- 创建 AttendanceRecordsBo 业务对象用于数据传输
- 实现 AttendanceRecordsController 提供 REST API 接口
- 开发 AttendanceRecordsMapper 数据访问层接口
- 实现 AttendanceRecordsServiceImpl 业务逻辑服务
- 定义 AttendanceRecordsVo 视图对象用于数据展示
- 集成 Excel 导出功能支持考勤数据批量导出
- 添加分页查询、条件筛选等数据检索功能
2026-04-21 13:01:53 +08:00
b160b86838 refactor(合同模板管理): 优化代码并修复潜在问题
- 将 deleteData 改为 delData 以保持 API 调用一致性
- 初始化 selectedTemplate 为空对象避免 null 引用
- 移除默认选择第一个模板的逻辑,由业务层控制
2026-04-21 09:57:30 +08:00
626aca5b85 feat(contract): 添加合同模板管理功能并优化导出逻辑
- 新增合同模板管理组件,支持模板的增删改查
- 优化合同导出功能,从订单项获取产品数据并添加金额大写转换
- 在合同编辑页面添加模板选择功能
- 为字典键值字段添加溢出提示
- 将数据键值输入框改为多行文本框
2026-04-21 09:38:42 +08:00
e22648bff0 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-21 09:28:19 +08:00
5adc316854 feat(xss): 更新XSS过滤排除路径配置
- 在XSS过滤排除列表中添加 /system/dict/data 路径
- 修正配置文件中的中文注释格式
- 保持原有的XSS过滤功能开关设置
- 维持其他系统监控和工具路径的过滤规则不变
2026-04-21 09:28:09 +08:00
王文昊
d61a2c795b feat(wms): 增强版本管理界面,添加方案参数功能
在版本管理页面中,新增方案参数的显示和编辑功能。用户可以通过操作按钮对方案点位和参数进行编辑和删除。后端服务也进行了相应的调整,以支持方案参数的增删改查操作。此更新提升了用户在管理方案时的灵活性和便捷性。
2026-04-20 19:34:01 +08:00
王文昊
f501994da6 feat(wms): 增加版本管理功能和操作按钮
在规程主表的操作列中新增“版本与方案”按钮,点击后可跳转至版本管理页面。更新了操作列的宽度以适应新按钮。同时,在后端服务中添加了对规程版本存在性的校验,确保在删除规程时不会影响相关版本数据。
2026-04-20 19:14:50 +08:00
王文昊
62b594026b feat(wms): 规程主表 wms_process_spec 全栈 CRUD(任务2)
新增规程档案后端(Entity/BO/VO/Mapper/Service/Controller),接口前缀 /wms/processSpec,
含分页查询、导出、详情、增删改;保存时校验规程编号唯一;逻辑删除与全局配置一致(0 未删 / 2 已删)。

新增 Flyway 脚本 V10 建表及唯一索引;前端增加 api/wms/processSpec.js 与 views/wms/processSpec/index.vue,
支持按编号/名称/类型/产线/产品类型/启用状态筛选,产线下拉关联现有产线接口。

说明:需在目标库执行迁移并在菜单中配置组件路径 wms/processSpec/index。
2026-04-20 18:20:29 +08:00
ee199388d5 feat(wms): 新增钢卷质量改判功能及记录
添加钢卷质量改判功能,包括改判原因输入框和改判记录API
在基础信息面板中新增改判原因字段,并调用新增的改判记录API保存改判历史
2026-04-20 16:55:54 +08:00
d69e445e82 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-20 15:23:20 +08:00
3d7fd09c60 feat(wms): 添加钢卷质量改判记录管理功能
- 创建 WmsCoilQualityRejudge 实体类定义数据库表结构
- 实现 IWmsCoilQualityRejudgeService 接口及其实现类
- 开发 WmsCoilQualityRejudgeController 控制器提供 REST API
- 添加 WmsCoilQualityRejudgeMapper 数据访问层接口
- 配置 MyBatis XML 映射文件实现数据库操作
- 定义 WmsCoilQualityRejudgeBo 业务对象和 Vo 视图对象
- 实现分页查询、新增、修改、删除等基础 CRUD 功能
- 集成 Excel 导出功能支持数据批量导出
- 添加数据验证和业务逻辑处理机制
2026-04-20 15:23:10 +08:00
5634964002 feat(ems): 新增能源记录管理功能并优化设备管理界面
- 添加能源记录API及相关功能
- 重构设备管理界面,简化表单字段
- 实现能源消耗表格视图,支持按月筛选和编辑
- 移除设备管理中的冗余字段和绑定库区显示
- 调整设备状态选择器为按钮样式
2026-04-20 15:15:37 +08:00
9f7870c63b fix(EmsEnergyRecordVo): 修正统计日期格式化注解
- 移除错误的ExcelDictFormat注解
- 添加DateTimeFormat注解以支持日期格式化
- 将日期格式统一为yyyy-MM-dd模式
2026-04-20 15:08:08 +08:00
29d0303247 fix(EmsEnergyRecordVo): 修正统计日期格式化注解
- 移除错误的ExcelDictFormat注解
- 添加DateTimeFormat注解以支持日期格式化
- 将日期格式统一为yyyy-MM-dd模式
2026-04-20 14:59:36 +08:00
c3bef9615e feat(energy-record): 为统计日期字段添加JSON和日期格式化注解
- 添加@JsonFormat注解以支持yyyy-MM-dd格式的JSON序列化
- 添加@DateTimeFormat注解以支持yyyy-MM-dd格式的日期解析
- 确保recordDate字段在API交互中的格式一致性
2026-04-20 14:47:57 +08:00
d398c2e4fc feat(energy-record): 修改新增能源消耗记录接口返回值类型
- 将控制器方法返回类型从 R<Void> 改为 R<Long>
- 将服务层实现方法返回类型从 Boolean 改为 Long
- 将服务接口方法返回类型从 Boolean 改为 Long
- 新增记录成功后返回记录ID而不是布尔值
- 保持原有的业务逻辑并在新增成功后设置能源记录ID
2026-04-20 14:39:51 +08:00
2dbf4a042e feat(wms): 新增材质异常钢卷查询功能
- 在IWmsMaterialCoilService中添加queryMaterialMismatchCoils方法定义
- 在WmsMaterialCoilController中新增查询材质异常钢卷的API接口
- 在WmsMaterialCoilMapper中添加selectMaterialMismatchCoilsPage分页查询方法
- 在WmsMaterialCoilMapper.xml中实现材质异常钢卷的SQL查询逻辑
- 在WmsMaterialCoilServiceImpl中实现材质异常钢卷查询的具体业务逻辑
- 通过关联查询优化性能,避免N+1问题并支持分页返回结果
2026-04-20 14:29:33 +08:00
be59e4cc79 feat(energy-record): 新增能源消耗记录的时间范围查询和设备信息关联功能
- 在 EmsEnergyRecordBo 中添加 recordStartDate、recordEndDate 用于时间范围筛选
- 添加 meterCode、energyName、model、manufacturer、meterStatus 等模糊查询字段
- 集成 DateTimeFormat 注解支持日期格式化
- 在 EmsEnergyRecordMapper 中新增 selectVoPagePlus 方法实现关联查询
- 通过 XML 配置实现能源记录与计量表、能源类型的左连接查询
- 在 EmsEnergyRecordServiceImpl 中重构查询逻辑支持多表关联和时间段筛选
- 在 EmsEnergyRecordVo 中扩展表计和能源相关展示字段
2026-04-20 13:54:39 +08:00
14e28a0169 feat(wms): 按入场钢卷号分组后按最新创建时间倒序排列
- 在钢卷查询中添加按入场钢卷号分组的功能
- 实现分组后按每组最新创建时间倒序排列
- 确保查询结果按时间顺序正确排序
2026-04-20 13:35:28 +08:00
a26089ce15 feat(WmsMaterialCoil): 添加按入场钢卷号分组功能
- 在 WmsMaterialCoilBo 中新增 groupByEnterCoilNo 字段
- 实现按 enter_coil_no 分组的查询逻辑
- 根据 bo 中的 groupByEnterCoilNo 参数动态添加分组条件
2026-04-20 13:32:51 +08:00
2d3caa65bc Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-20 13:08:44 +08:00
bd4d591934 feat(ems): 添加能源消耗记录管理功能
- 创建 EmsEnergyRecord 实体类,定义能耗记录主键、表计ID、能源ID、消耗量等字段
- 实现 EmsEnergyRecordBo 业务对象,用于接收前端参数并进行数据验证
- 开发 EmsEnergyRecordController 控制器,提供查询、新增、修改、删除和导出功能
- 配置 EmsEnergyRecordMapper 数据访问接口,继承 BaseMapperPlus 进行数据库操作
- 编写 EmsEnergyRecordMapper.xml 映射文件,定义结果集映射关系
- 实现 EmsEnergyRecordServiceImpl 服务类,封装业务逻辑和数据处理方法
- 定义 EmsEnergyRecordVo 视图对象,配置Excel导出注解和字典转换功能
- 提供 IEmsEnergyRecordService 接口,规范服务层方法契约
2026-04-20 13:08:33 +08:00
f7a8b3df22 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-20 11:04:18 +08:00
4fefc68bbc fix(wms): 修复合同ID为空时添加合同关系的错误
在合并、分条和批量分条操作中,当合同ID为空时不再尝试添加合同关系
同时优化批量分条时的合同关系添加逻辑,先过滤掉空合同ID
2026-04-20 11:04:14 +08:00
cdcf5e2428 加入规程管理sql 2026-04-19 14:29:57 +08:00
deb684ce27 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-19 14:28:02 +08:00
3f300e05e9 加入规程管理sql 2026-04-19 14:27:05 +08:00
af002b84d3 feat(合同管理): 新增钢卷与合同关联功能
- 添加钢卷与合同关联的API接口
- 在合卷、分条、打字等操作中增加合同选择组件
- 创建合同选择组件ContractSelect
- 在合同详情页新增生产成果展示页签
- 实现合同列表的本地存储功能
2026-04-18 16:18:22 +08:00
143764f7f8 feat(钢卷调拨): 新增调拨类型列和改判功能
添加调拨类型列显示和钢卷改判功能,包括改判弹窗和重贴标签操作
2026-04-18 15:56:28 +08:00
0822ca7cc8 refactor(wms): 修改钢卷合卷功能返回结果卷
- 将IWmsMaterialCoilService.mergeCoils方法返回值从Boolean改为Long
- 更新WmsMaterialCoilController.mergeCoils方法以返回合卷后的新钢卷ID
- 修改WmsMaterialCoilServiceImpl.mergeCoils实现以返回合并后的钢卷ID
- 移除原有的布尔返回值,改为返回实际的业务数据ID
- 保持事务处理和业务逻辑完整性
2026-04-18 14:53:42 +08:00
5b452bad31 fix(order): 修复订单详情中钢卷信息关联错误
- 将合同ID替换为订单ID进行钢卷信息映射
- 确保钢卷列表正确关联到对应的订单记录
- 修复了因键值不匹配导致的钢卷信息丢失问题
2026-04-18 14:48:58 +08:00
4f259c5aba Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-18 14:28:55 +08:00
34dd8004c4 fix(order): 解决计划日期时间设置问题
- 将日期设置为当天的开始时间 00:00:00
- 使用Calendar类精确设置小时、分钟、秒和毫秒为零值
- 确保计划日期查询使用正确的日期范围
- 避免因时间戳差异导致的数据查询不准确问题
2026-04-18 14:28:44 +08:00
254dada485 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-18 14:24:22 +08:00
ee2bb280b6 refactor(mapper): 更新 MyBatis 映射文件中的对应 SQL 查询 ID
- 将 ApsPlanSheetMapper 中的 selectList 方法重命名为 selectListByReq
- 更新 MyBatis 映射文件中的对应 SQL 查询 ID
- 修改服务实现类中的方法调用以匹配新方法名
2026-04-18 14:21:42 +08:00
96082b9124 feat(wms): 添加左侧逻辑库位查询功能并优化钢卷管理界面
在钢卷管理相关页面添加左侧逻辑库位树形查询功能,方便用户快速筛选库位
移除部分冗余代码和注释,优化页面布局和交互体验
添加钢卷统计数据显示功能,提升数据可视化
2026-04-18 13:36:24 +08:00
ddb1beb629 feat(wms): 添加钢卷物料订单关联信息查询功能
- 新增 queryPageListWithOrderRel 方法支持查询钢卷关联订单列表
- 实现批量查询避免 N+1 问题,提升查询性能
- 添加 listWithOrderRel 控制器接口供前端调用
- 集成 wms_coil_contract_rel 中间表与 crm_order 联查
- 优化查询逻辑,支持按需加载订单关联信息
- 完善异常处理和日志记录机制
2026-04-18 13:01:28 +08:00
67cf5aa7cb feat(wms): 添加钢卷关联订单信息查询功能
- 在WmsCoilContractRelMapper中新增selectOrdersByCoilId和selectOrdersByCoilIds方法
- 在WmsCoilContractRelMapper.xml中实现钢卷与订单关联查询的SQL映射
- 扩展WmsCoilContractRelVo类添加订单相关字段和@JsonFormat注解
- 在WmsMaterialCoilServiceImpl中注入coilContractRelMapper并实现填充订单信息逻辑
- 在WmsMaterialCoilVo中添加orderList字段存储关联订单列表
- 实现根据钢卷ID查询完整订单信息的JOIN查询功能
2026-04-18 11:49:10 +08:00
e1cc0fda34 feat(crm): 添加每日订单查询功能
- 在 ApsPlanDetailBo 中新增 planSheetIds 字段用于批量查询
- 实现 IApsPlanDetailService 的 queryListByPlanSheetIds 方法
- 添加 CrmOrderService 的 queryByIds 批量查询接口
- 在 CrmOrderController 中新增 /daily 接口查询当日订单
- 集成 APS 排产计划数据获取当日关联的 CRM 订单
- 添加 klp-aps 模块依赖支持跨模块数据查询
2026-04-18 11:11:14 +08:00
4e5e1bbca1 feat(crm): 订单查询功能新增关联钢卷信息展示
- 集成WMS钢卷合同关联查询服务
- 实现订单与钢卷批量关联查询逻辑
- 添加钢卷详细信息映射和组装功能
- 在CrmOrderVo中新增coilList字段存储钢卷列表
- 优化查询性能,避免N+1问题
- 支持按合同ID分组获取关联钢卷数据
2026-04-18 11:03:35 +08:00
2e363f9ad8 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-18 10:23:57 +08:00
f158830abf feat(wms): 添加钢卷与合同关联关系管理功能
- 创建 WmsCoilContractRel 实体类定义钢卷与合同关联关系数据结构
- 实现 IWmsCoilContractRelService 接口提供基础CRUD操作方法
- 开发 WmsCoilContractRelServiceImpl 业务逻辑实现类
- 添加 WmsCoilContractRelController 控制器支持RESTful API接口
- 设计 WmsCoilContractRelMapper 数据访问接口及XML映射文件
- 创建 WmsCoilContractRelBo 业务对象和 WmsCoilContractRelVo 视图对象
- 集成分页查询、新增、修改、删除和导出功能
- 添加数据验证和重复提交防护机制
2026-04-18 10:23:48 +08:00
843512ab7e Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-18 10:23:27 +08:00
dd27069b4c feat(KLPTable): 增强浮层组件功能并优化表格显示
- 为浮层组件添加列数配置和排除列功能
- 优化浮层位置计算逻辑,防止超出视窗边界
- 调整表格列显示,移除不必要列并添加净重列
- 更新浮层样式,支持网格布局和响应式显示
- 扩展浮层配置项,支持更多自定义选项
2026-04-18 10:23:24 +08:00
b95bd5b93d Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-18 10:18:02 +08:00
4d588985e8 feat(WmsMaterialCoil): 添加调拨类型非空筛选功能
- 在WmsMaterialCoilBo中新增hasTransferType字段用于标识是否查询调拨类型不为空的钢卷
- 在WmsMaterialCoilServiceImpl中实现调拨类型非空筛选逻辑
- 当hasTransferType为true时查询调拨类型不为空且不为字符串的钢卷记录
2026-04-18 10:17:22 +08:00
3ad3fd2fee feat(PlanDetailForm): 添加订单明细选择功能以快速录入成品信息
在成品信息组中添加选择订单明细按钮,点击可打开对话框选择订单明细并自动填充表单字段。移除未使用的订单类型列并优化附件查看按钮的样式。
2026-04-17 17:02:12 +08:00
79ee9d572d feat(contract): 替换产品内容组件为订单详情组件并优化表单字段
重构合同预览和订单详情展示,使用新的OrderDetail组件替代原有的ProductContent组件
调整订单详情表单字段,增加宽度、厚度等必要字段,移除不必要字段
优化表单验证规则和显示逻辑
2026-04-17 15:11:09 +08:00
c9742b08cf fix(wms): 修复规格分割可能导致的错误并增加分页大小
处理规格分割时可能出现的空值问题,使用可选链操作符和默认值
同时增加多个报表页面的分页大小限制
2026-04-17 15:10:21 +08:00
6bd5d2ded3 feat(CrmOrderItem): 添加订单项产品规格字段
- 在CrmOrderItem实体类中新增表面处理、切边要求、包装要求、宽度、厚度、用途字段
- 在CrmOrderItemBo业务对象中同步添加对应字段定义
- 在CrmOrderItemVo视图对象中添加Excel导出注解配置
- 更新MyBatis映射文件中的结果映射和插入字段列表
- 在查询条件构建器中添加新字段的查询支持
2026-04-17 14:16:46 +08:00
da1813e65a Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-17 09:54:43 +08:00
8dbb7d1113 feat(钢卷管理): 添加钢卷统计功能并优化仓库选择排序
新增钢卷统计接口和展示总净重功能
优化仓库选择组件,按使用频率排序选项
调整钢卷选择器布局和样式
2026-04-17 09:55:27 +08:00
ae77c529ae feat(wms): 添加物料卷统计总数功能
- 在WmsMaterialCoilServiceImpl中新增total_count字段统计
- 将统计结果添加到返回结果集中
- 处理空值情况并设置默认值为BigDecimal.ZERO
2026-04-17 09:54:34 +08:00
edcbf7a5f1 feat(退火操作): 新增退火操作事件记录功能
添加退火操作事件API及页面,实现退火炉操作记录功能
在计划管理页面增加操作事件记录,包括入炉、完成、添加和解绑操作
2026-04-16 17:12:08 +08:00
28622a2b16 refactor(wms): 优化钢卷计划和材料钢卷服务逻辑
- 在更新钢卷计划时设置创建时间和更新时间
- 添加登录用户信息到钢卷计划的创建者和更新者字段
- 初始化钢卷计划的状态和导出相关字段
- 移除占用仓库的冗余方法实现
- 在材料钢卷服务中同时更新数据类型和排他状态字段
2026-04-16 16:46:09 +08:00
44303cb1c7 fix(wms): 修复钢卷单个更新时的二维码步骤类型检查逻辑
- 修改了qrcodeStepType为空判断条件,从非空且不等于annealing改为直接判断是否为空
- 确保在qrcodeStepType为空时能够正确执行钢卷操作权限验证
- 修正了原有的逻辑错误,避免在特定条件下跳过必要的权限检查
2026-04-16 16:31:47 +08:00
c0f7c699a8 fix(wms): 修复钢卷更新时二维码步骤类型检查逻辑
- 在非退火步骤类型时才进行独占状态检查
- 添加对qrcodeStepType为空的边界情况处理
- 修复二维码内容更新中的空指针检查逻辑
2026-04-16 16:30:05 +08:00
e69dc5e76e fix(task): 关闭仓库使用次数定时任务
- 注释掉 cron 表达式以禁用定时执行
- 保留事务回滚配置以确保数据一致性
- 记录任务开始执行的日志信息功能仍然可用
2026-04-16 16:18:40 +08:00
ec0660acba refactor(vo): 让WmsAnnealOperateEventVo继承BaseEntity
- 添加com.klp.common.core.domain.BaseEntity导入
- 修改WmsAnnealOperateEventVo类继承BaseEntity
- 保持原有的Excel注解配置不变
2026-04-16 16:01:39 +08:00
110597657e Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-16 15:56:39 +08:00
50670b64d8 feat(material-coil): 添加退火操作的二维码步骤类型支持
- 修改IWmsMaterialCoilService接口中的updateByBo方法,增加qrcodeStepType参数
- 在WmsFurnacePlanServiceImpl中实现退火操作的库位分配功能
- 添加updateQrcodeContentForCustomStep方法支持自定义二维码步骤类型
- 更新controller调用传入null作为默认值
- 完善退火操作的二维码内容更新逻辑
2026-04-16 15:56:26 +08:00
砂糖
823afd7a00 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-16 15:50:58 +08:00
砂糖
344488f08e 临时修改 2026-04-16 15:50:54 +08:00
c2da7640c3 feat(wms): 添加退火操作事件管理功能
- 创建退火操作事件实体类 WmsAnnealOperateEvent
- 定义退火操作事件服务接口 IWmsAnnealOperateEventService
- 实现退火操作事件服务业务逻辑 WmsAnnealOperateEventServiceImpl
- 添加退火操作事件控制器 WmsAnnealOperateEventController
- 创建退火操作事件数据访问层 WmsAnnealOperateEventMapper
- 实现退火操作事件业务对象 WmsAnnealOperateEventBo 和视图对象 WmsAnnealOperateEventVo
- 集成 MyBatis Plus 分页查询和基础 CRUD 功能
- 添加 Excel 导出功能和操作日志记录
- 实现表单验证和重复提交防护机制
2026-04-16 14:55:43 +08:00
e99d7709d2 feat(warehouse): 添加仓库使用次数统计功能
- 在WmsMaterialCoilMapper中新增selectWarehouseIdCount方法用于统计仓库钢卷数量
- 在WmsWarehouseBo中新增orderByUseCount字段支持按使用次数排序
- 修改WmsWarehouseServiceImpl实现按使用次数或序号排序逻辑
- 创建WarehouseUseCountTask定时任务每晚1点更新仓库使用次数
- 实现定时计算各仓库中钢卷数量并更新到useCount字段功能
2026-04-16 14:25:54 +08:00
623e78629d feat(warehouse): 添加仓库使用次数字段支持
- 在WmsWarehouse实体类中新增useCount字段及注释
- 在WmsWarehouseBo业务对象中添加useCount属性
- 更新WmsWarehouseMapper.xml映射文件,增加useCount字段映射
- 在WmsWarehouseServiceImpl查询条件中加入useCount过滤逻辑
- 在WmsWarehouseVo视图对象中添加useCount字段并配置Excel导出
2026-04-16 14:03:26 +08:00
c1938e29a4 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-16 13:54:24 +08:00
54d426984b feat(wms): 添加钢卷物料统计数据接口
- 在 IWmsMaterialCoilService 中新增 getStatistics 方法用于汇总统计
- 在 WmsMaterialCoilController 中添加 /statisticsList 接口
- 在 WmsMaterialCoilMapper 中新增 selectStatistics 查询方法
- 在 WmsMaterialCoilMapper.xml 中实现统计 SQL 查询
- 在 WmsMaterialCoilServiceImpl 中实现统计业务逻辑
- 支持按筛选条件统计总毛重、总净重和总数
- 采用高性能查询方式只查询 sum/count 聚合数据
- 独立统计接口不影响原有分页查询功能
2026-04-16 13:54:12 +08:00
砂糖
440e70ee82 feat(组件): 为多选组件添加全选功能并移除板面校验
- 在多选组件中增加全选选项和功能
- 移除异常管理中的板面校验逻辑
- 修复保存按钮加载状态显示问题
2026-04-16 10:18:21 +08:00
砂糖
220a24da78 fix(wms): 修复参数名错误并移除无用导入
修复pendingAction接口中newCoilIds参数默认值问题
将createBy/updateBy统一改为createBys/updateBys
移除report模板中未使用的listCoilWithIds导入
2026-04-16 10:17:35 +08:00
c31dc4948e feat(WmsMaterialCoil): 添加按创建人筛选功能
- 在 WmsMaterialCoilBo 中新增 createBys 字段用于多创建人筛选
- 实现逗号分隔的创建人列表解析功能
- 添加非空验证和字符串清理逻辑
- 构建 in 查询条件支持多创建人匹配
- 集成到现有查询条件构建流程中
2026-04-16 09:42:37 +08:00
7b55f358b4 feat(WmsCoilPendingAction): 支持按多个创建人筛选待办操作
- 在WmsCoilPendingActionBo中新增createBys字段用于接收多个创建人参数
- 修改查询条件支持逗号分隔的多个创建人筛选功能
- 实现将createBys字符串拆分为列表并进行in查询的逻辑
- 添加空值过滤和字符串清理确保查询准确性
2026-04-16 09:15:09 +08:00
2fcc7b3279 fix(wms): 修复卷材待处理操作完成时的空值设置问题
- 添加对 newCoilIds 的空值和 "-" 值检查
- 避免在无效值情况下设置 processedCoilIds 字段
- 确保只有有效的新卷材 ID 才会被更新到操作记录中
2026-04-16 09:10:39 +08:00
砂糖
8e5ce5c119 feat(报表): 添加发货配卷时间列
在报表配置中添加发货配卷时间列,用于显示配卷事件的时间信息
2026-04-15 15:29:13 +08:00
砂糖
ee275d3ea5 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-15 15:28:35 +08:00
砂糖
5e80208d61 feat(wms): 在完成操作时传递新钢卷ID参数
修改completeAction接口以接收新钢卷ID参数,并在多个视图中调用时传递该参数
2026-04-15 15:28:28 +08:00
05f0933514 feat(wms): 添加配卷时间和实际发货时间字段支持
- 在WmsDeliveryWaybillDetailVo中新增exportTime字段用于实际发货时间
- 将deliveryTime字段的Excel导出标签从发货时间改为配卷时间
- 在数据库映射文件中添加exportTime字段的映射关系
- 在查询语句中加入export_time字段以支持实际发货时间数据获取
2026-04-15 15:21:17 +08:00
ec5da2a7ca fix(WmsMaterialCoilController): 修改编辑接口返回类型
- 将返回类型从 R<Void> 更改为 R<String>
- 修改返回方式从 toAjax() 改为 R.ok()
- 确保接口返回操作结果字符串而非空值
2026-04-15 14:33:09 +08:00
7d6957165d Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-15 14:31:36 +08:00
31648431c8 feat(wms): 完善钢卷操作完成接口功能
- 在completeAction方法中添加newCoilIds参数支持
- 修改updateByBo方法返回值为String类型,支持返回新钢卷ID
- 添加分卷时返回逗号分隔的ID字符串,合卷时返回单个ID的功能
- 在操作完成时记录processedCoilIds信息
- 优化异常处理和返回值验证逻辑
2026-04-15 14:31:27 +08:00
砂糖
36ff376c55 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-15 14:07:49 +08:00
砂糖
f68167b102 feat(报表): 添加月视图折线图并优化分条线显示逻辑
添加月视图日数据趋势折线图展示产出和消耗数据
优化分条信息统计组件仅在分条线时显示
在日视图中添加昨日数据对比显示
重构日期选择逻辑支持多种视图模式
2026-04-15 14:07:42 +08:00
671a7e129f Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-15 14:07:07 +08:00
84a0cb43ee fix(export): 修正配卷时间字段导出标题
- 将发货时间字段标题更正为配卷时间
2026-04-15 14:06:56 +08:00
砂糖
d15f57ae6d feat(wms): 添加修复工序的样式和分条选项
为酸轧、镀锌、脱脂、拉矫、双机架和镀铬修复工序添加渐变样式标识
在分条功能中增加修复工序的原料库和成品库选项
2026-04-15 10:54:26 +08:00
砂糖
b32f826488 Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X 2026-04-14 16:08:37 +08:00
砂糖
a99126a9a3 feat(CoilSelector): 添加物料类型选择并优化相关字段显示逻辑
添加物料类型选择下拉框,并根据选择的类型动态显示相关字段
将selectType默认值改为通过props传入的defaultType
优化查询逻辑,确保itemType与selectType保持一致
2026-04-14 16:08:33 +08:00
6e5b9fc962 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-14 15:45:26 +08:00
c9a93fe942 feat(crm): 添加订单定金相关字段支持
- 在CrmOrder实体类中新增unitPriceRemark、depositPayable、depositPaid、depositRatio字段
- 在CrmOrderBo业务对象中同步添加对应字段以支持查询条件
- 更新CrmOrderMapper.xml映射文件中的结果集和SQL查询语句
- 在CrmOrderServiceImpl服务实现中添加字段的查询条件处理逻辑
- 在CrmOrderVo视图对象中添加Excel导出注解配置
- 实现定金相关的业务查询功能包括应付定金、已付定金、定金比例等字段的检索
2026-04-14 15:45:15 +08:00
砂糖
5f5e5cacb4 feat(订单详情): 在钢卷选择器中添加订单详情显示功能
添加订单ID参数传递至钢卷选择器组件
在钢卷选择器中新增显示订单详情的复选框和面板
移除OrderDetail组件中未使用的API导入
2026-04-14 15:38:44 +08:00
砂糖
263c2b5f37 feat(报餐记录): 修改默认截止时间并支持动态配置
从系统配置获取报餐截止时间,默认值从12:00改为16:00
2026-04-14 11:13:56 +08:00
910ec2b22f fix(wms): 修复产品服务中更新时间字段设置问题
- 在WmsProductServiceImpl中添加了updateTime字段的正确设置
- 确保coils记录在更新时保持正确的更新时间戳
- 防止因时间字段未正确设置导致的数据同步问题
2026-04-14 10:14:52 +08:00
a62ef2d0b0 feat(wms): 添加物料卷数据过滤条件
- 添加数据类型过滤条件,只查询类型为1的数据
- 添加状态过滤条件,只查询状态为0的正常数据
- 优化物料卷查询逻辑,提高数据准确性
2026-04-14 10:10:54 +08:00
31d44c19ca Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-14 10:07:08 +08:00
fea3c78c4f feat(product): 添加批量更新钢卷itemId功能,由于只是一次性接口暂时不考虑速度
- 在IWmsProductService接口中添加batchUpdateCoilItemId方法定义
- 在WmsProductController中添加batchUpdateCoilItem REST端点
- 在WmsProductServiceImpl中实现批量更新逻辑
- 添加对WmsMaterialCoil和WmsRawMaterial实体的操作支持
- 实现根据逻辑库区ID查询并按itemType分类处理的功能
- 添加事务管理和异常回滚机制
- 返回产品和原料的数量统计结果
2026-04-14 10:06:59 +08:00
砂糖
8de4042bdf fix: 将库区显示改为规格显示并添加实际库区字段
在多个组件中将“库区”标签改为“规格”标签,并显示对应的规格数据
在CoilCard组件中添加实际库区字段的显示
2026-04-14 10:03:31 +08:00
砂糖
54bea01416 refactor(contract): 统一合同编号字段名从contractNo改为contractCode
修改多个组件中合同编号字段名以保持一致性,移除未使用的props和清理冗余代码
2026-04-14 10:03:16 +08:00
砂糖
9f3d402174 refactor(crm): 重构合同模块为订单模块并优化相关功能
重构合同模块为订单模块,包括以下主要变更:
1. 将合同编号字段从contractNo统一改为contractCode
2. 在CrmOrderBo中添加日期格式化注解
3. 重构ContractTabs组件为订单详情页
4. 添加销售员字段和相关选择器
5. 优化订单列表查询条件和展示
6. 调整订单附件管理功能
2026-04-13 17:48:19 +08:00
c3d6d7cece feat(crm): 添加订单合同详情字段映射和查询功能
- 在CrmOrderMapper.xml中新增合同名称、供应商、客户等相关字段映射
- 扩展SQL查询语句以支持合同详细信息的检索
- 在服务层实现中增加对新字段的搜索条件支持
- 添加合同签署时间、地点、内容等过滤条件的查询逻辑
- 实现供应商和客户联系信息的条件查询功能
- 集成技术附件、商务附件和生产进度的搜索过滤器
2026-04-13 16:50:18 +08:00
砂糖
37dc213605 feat(报表): 添加分条线统计组件并扩展合同字段
添加分条线专用的统计组件SplitSummary,用于展示分条处理的产出与消耗对比数据
在多个报表模板中集成该组件并添加钢卷高亮功能
扩展CrmOrder相关类的合同信息字段
2026-04-13 16:23:40 +08:00
砂糖
5ee730bffa feat(报表): 添加钢卷表格行高亮功能以标记共用卷
在分条线报表中,产出钢卷和投入钢卷可能存在共用卷的情况。添加高亮功能以便直观区分这些共用卷:
1. 在day.vue中计算共用卷ID列表
2. 在coilTable组件中实现行高亮逻辑和样式
2026-04-13 14:37:23 +08:00
砂糖
116d79e7c2 feat(wms): 新增调拨记录追溯功能并优化调拨表格
- 在调拨表格中添加生效状态列,显示已生效/未生效标签
- 新增调拨记录追溯页面,支持通过卷号查询调拨历史
- 实现常规筛选和特殊追溯两种查询方式
- 优化表格操作列显示逻辑,增加权限控制
2026-04-13 13:00:25 +08:00
砂糖
4c373e6af5 fix(wms): 修改标签中长度字段显示为钢卷长度并使用实际长度值
更新了两个标签渲染组件,将"参考长度"改为更准确的"钢卷长度"描述,并统一使用actualLength字段替代length字段显示实际长度值
2026-04-13 11:45:17 +08:00
砂糖
4beaf79fd6 feat(合同/客户): 添加发货单据展示功能
在合同和客户详情页新增发货单据标签页,展示wmsDeliveryWaybills数据
移除CustomerOrder中未使用的getSummary方法和相关代码
2026-04-11 16:24:04 +08:00
431 changed files with 35605 additions and 4861 deletions

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "interactive"
}

View File

@@ -0,0 +1,428 @@
package com.klp.framework.client;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.klp.framework.config.SqlServerApiProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* sql-server-api 统一调用客户端。
* <p>
* 对齐 {@code sql-server-api/app.py} 的接口规范:
* <ul>
* <li>GET /health</li>
* <li>GET /heartbeat</li>
* <li>POST /table-schema</li>
* <li>POST /execute-sql</li>
* </ul>
*/
@Component
public class SqlServerApiClient {
private final RestTemplate restTemplate;
private final SqlServerApiProperties properties;
public SqlServerApiClient(RestTemplate sqlServerApiRestTemplate, SqlServerApiProperties properties) {
this.restTemplate = sqlServerApiRestTemplate;
this.properties = properties;
}
public String getBaseUrl() {
return normalizeBaseUrl();
}
public Map<String, Object> health() {
return getForMap("/health");
}
public Map<String, Object> heartbeat() {
return getForMap("/heartbeat");
}
public TableSchemaResponse tableSchema(String tableType, String tableName) {
return postForObject("/table-schema", new TableSchemaRequest(tableType, tableName), TableSchemaResponse.class);
}
public ExecuteSqlResponse executeSql(String tableType, String sql, Map<String, Object> params) {
return postForObject("/execute-sql", new ExecuteSqlRequest(tableType, sql, params), ExecuteSqlResponse.class);
}
public <T> T get(String path, Class<T> responseType) {
return restTemplate.getForObject(buildUri(path), responseType);
}
public <T> T get(String path, Map<String, ?> queryParams, Class<T> responseType) {
URI uri = UriComponentsBuilder.fromHttpUrl(normalizeBaseUrl())
.path(normalizePath(path))
.queryParams(convertToQueryParams(queryParams))
.build(true)
.toUri();
return restTemplate.getForObject(uri, responseType);
}
public <T, R> T post(String path, R requestBody, Class<T> responseType) {
return restTemplate.postForObject(buildUri(path), requestBody, responseType);
}
public static class TableSchemaRequest {
@JsonProperty("table_type")
private String tableType;
@JsonProperty("table_name")
private String tableName;
public TableSchemaRequest() {
}
public TableSchemaRequest(String tableType, String tableName) {
this.tableType = tableType;
this.tableName = tableName;
}
public String getTableType() {
return tableType;
}
public void setTableType(String tableType) {
this.tableType = tableType;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
}
public static class ExecuteSqlRequest {
@JsonProperty("table_type")
private String tableType;
private String sql;
private Map<String, Object> params;
public ExecuteSqlRequest() {
}
public ExecuteSqlRequest(String tableType, String sql, Map<String, Object> params) {
this.tableType = tableType;
this.sql = sql;
this.params = params;
}
public String getTableType() {
return tableType;
}
public void setTableType(String tableType) {
this.tableType = tableType;
}
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public Map<String, Object> getParams() {
return params;
}
public void setParams(Map<String, Object> params) {
this.params = params;
}
}
public static class TableSchemaResponse {
private String tableType;
private String tableName;
private Schema schema;
public String getTableType() {
return tableType;
}
public void setTableType(String tableType) {
this.tableType = tableType;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public Schema getSchema() {
return schema;
}
public void setSchema(Schema schema) {
this.schema = schema;
}
public static class Schema {
private List<Column> columns = Collections.emptyList();
public List<Column> getColumns() {
return columns;
}
public void setColumns(List<Column> columns) {
this.columns = columns;
}
}
public static class Column {
private String name;
private String type;
private boolean nullable;
private Object defaultValue;
private boolean primaryKey;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isNullable() {
return nullable;
}
public void setNullable(boolean nullable) {
this.nullable = nullable;
}
public Object getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(Object defaultValue) {
this.defaultValue = defaultValue;
}
public boolean isPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(boolean primaryKey) {
this.primaryKey = primaryKey;
}
}
}
public static class ExecuteSqlResponse {
private String tableType;
private String resultType;
private Integer rowCount;
private Object result;
public String getTableType() {
return tableType;
}
public void setTableType(String tableType) {
this.tableType = tableType;
}
public String getResultType() {
return resultType;
}
public void setResultType(String resultType) {
this.resultType = resultType;
}
public Integer getRowCount() {
return rowCount;
}
public void setRowCount(Integer rowCount) {
this.rowCount = rowCount;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
private Map<String, Object> getForMap(String path) {
ResponseEntity<Map> responseEntity = restTemplate.exchange(buildUri(path), HttpMethod.GET, HttpEntity.EMPTY, Map.class);
Map<String, Object> body = responseEntity.getBody();
return body == null ? Collections.emptyMap() : body;
}
private <T> T postForObject(String path, Object requestBody, Class<T> responseType) {
return restTemplate.postForObject(buildUri(path), requestBody, responseType);
}
private URI buildUri(String path) {
return UriComponentsBuilder.fromHttpUrl(normalizeBaseUrl())
.path(normalizePath(path))
.build(true)
.toUri();
}
private String normalizeBaseUrl() {
if (properties.getBaseUrl() != null && properties.getBaseUrl().trim().length() > 0) {
return properties.getBaseUrl();
}
if (properties.getHost() == null || properties.getHost().trim().length() == 0 || properties.getPort() == null) {
throw new IllegalStateException("sql-server-api 配置缺失,请检查 host/port/base-url");
}
return "http://" + properties.getHost() + ":" + properties.getPort();
}
private String normalizePath(String path) {
if (path == null || path.trim().length() == 0) {
return "";
}
return path.startsWith("/") ? path : "/" + path;
}
public ExecuteSqlResponse queryPlanByCoilId(String coilId) {
return executeSql(
"oracle",
"select * from JXPLTCM.PLTCM_PDI_PLAN where COILID = :coilId",
singletonParam("coilId", coilId)
);
}
public ExecuteSqlResponse queryPlanList(int page, int pageSize) {
int endRow = page * pageSize;
int startRow = endRow - pageSize;
Map<String, Object> params = new java.util.HashMap<>();
params.put("startRow", startRow);
params.put("endRow", endRow);
return executeSql(
"oracle",
"select * from (select t.*, ROWNUM rn from (select * from JXPLTCM.PLTCM_PDI_PLAN order by INSDATE desc) t where ROWNUM <= :endRow) where rn > :startRow",
params
);
}
public ExecuteSqlResponse queryPlanCount() {
return executeSql(
"oracle",
"select count(*) as total from JXPLTCM.PLTCM_PDI_PLAN",
emptyParams()
);
}
public ExecuteSqlResponse queryPlanListByProcessCode(String processCode) {
return executeSql(
"oracle",
"select * from JXPLTCM.PLTCM_PDI_PLAN where PROCESS_CODE = :processCode order by INSDATE desc",
singletonParam("processCode", processCode)
);
}
public ExecuteSqlResponse queryPlanListByStatus(String status) {
return executeSql(
"oracle",
"select * from JXPLTCM.PLTCM_PDI_PLAN where STATUS = :status order by INSDATE desc",
singletonParam("status", status)
);
}
public ExecuteSqlResponse queryPlanByHotCoilId(String hotCoilId) {
return executeSql(
"oracle",
"select * from JXPLTCM.PLTCM_PDI_PLAN where HOT_COILID = :hotCoilId",
singletonParam("hotCoilId", hotCoilId)
);
}
public ExecuteSqlResponse queryProSegByEncoilId(String encoilId) {
return executeSql(
"oracle",
"select * from JXPLTCM.PLTCM_PRO_SEG where ENCOILID = :encoilId order by SEGNO",
singletonParam("encoilId", encoilId)
);
}
public ExecuteSqlResponse queryProSegByExcoilId(String excoilId) {
return executeSql(
"oracle",
"select * from JXPLTCM.PLTCM_PRO_SEG where EXCOILID = :excoilId order by SEGNO",
singletonParam("excoilId", excoilId)
);
}
public ExecuteSqlResponse queryQualityByExcoilId(String excoilId) {
return executeSql(
"oracle",
"select * from JXPLTCM.V_PLTCM_PDO_QUALITY where EXCOILID = :excoilId order by END_DATE desc",
singletonParam("excoilId", excoilId)
);
}
public ExecuteSqlResponse queryGaugeByMatId(String matId) {
return executeSql(
"oracle",
"select * from JXPLTCM.V_VBDA_GAUGE where MATID = :matId order by XTIME asc",
singletonParam("matId", matId)
);
}
public ExecuteSqlResponse queryShapeByMatId(String matId) {
return executeSql(
"oracle",
"select * from JXPLTCM.V_VBDA_SHAPE where MATID = :matId order by XTIME asc",
singletonParam("matId", matId)
);
}
private org.springframework.util.MultiValueMap<String, String> convertToQueryParams(Map<String, ?> queryParams) {
org.springframework.util.LinkedMultiValueMap<String, String> multiValueMap = new org.springframework.util.LinkedMultiValueMap<>();
if (queryParams == null || queryParams.isEmpty()) {
return multiValueMap;
}
for (Map.Entry<String, ?> entry : queryParams.entrySet()) {
Object value = entry.getValue();
if (value != null) {
multiValueMap.add(entry.getKey(), String.valueOf(value));
}
}
return multiValueMap;
}
private Map<String, Object> singletonParam(String key, Object value) {
java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>();
if (value != null) {
params.put(key, value);
}
return params;
}
private Map<String, Object> emptyParams() {
return new java.util.HashMap<String, Object>();
}
}

View File

@@ -0,0 +1,23 @@
package com.klp.framework.config;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import java.time.Duration;
/**
* sql-server-api HTTP 客户端配置
*/
@Configuration
public class SqlServerApiClientConfig {
@Bean
public RestTemplate sqlServerApiRestTemplate(RestTemplateBuilder builder) {
return builder
.setConnectTimeout(Duration.ofSeconds(5))
.setReadTimeout(Duration.ofSeconds(60))
.build();
}
}

View File

@@ -0,0 +1,51 @@
package com.klp.framework.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* sql-server-api 中间件配置
*/
@Component
@ConfigurationProperties(prefix = "sql-server-api")
public class SqlServerApiProperties {
/**
* 请求地址
*/
private String host;
/**
* 请求端口
*/
private Integer port;
/**
* 基础访问地址
*/
private String baseUrl;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
}

View File

@@ -0,0 +1,318 @@
package com.klp.framework.service;
import com.klp.framework.client.SqlServerApiClient;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 面向业务场景的 sql-server-api 查询服务。
* <p>
* 当前抽象为三个功能:
* <ol>
* <li>计划查询</li>
* <li>钢卷实际 / SEG 查询</li>
* <li>实时数据Gauge / Shape查询</li>
* </ol>
*/
@Service
public class SqlServerApiBusinessService {
private final SqlServerApiClient client;
public SqlServerApiBusinessService(SqlServerApiClient client) {
this.client = client;
}
/**
* 计划列表分页按时间倒序page 从 1 开始。
*/
public PlanListView getPlanList(int page, int pageSize) {
return PlanListView.fromExecuteSqlResponse(client.queryPlanList(page, pageSize));
}
/**
* 计划总数。
*/
public long getPlanCount() {
SqlServerApiClient.ExecuteSqlResponse resp = client.queryPlanCount();
List<Map<String, Object>> rows = asRowList(resp);
if (rows.isEmpty()) {
return 0L;
}
Object total = rows.get(0).get("total");
Number n = asNumber(total);
return n == null ? 0L : n.longValue();
}
/**
* 计划列表:按工艺流程编码筛选。
*/
public PlanListView getPlanListByProcessCode(String processCode) {
return PlanListView.fromExecuteSqlResponse(client.queryPlanListByProcessCode(processCode));
}
/**
* 计划列表:按状态筛选。
*/
public PlanListView getPlanListByStatus(String status) {
return PlanListView.fromExecuteSqlResponse(client.queryPlanListByStatus(status));
}
/**
* 计划详情:按成品卷号查询单条计划。
*/
public PlanDetailView getPlanByCoilId(String coilId) {
return PlanDetailView.fromExecuteSqlResponse(coilId, client.queryPlanByCoilId(coilId));
}
/**
* 计划详情:按热卷号查询。
*/
public PlanDetailView getPlanByHotCoilId(String hotCoilId) {
return PlanDetailView.fromExecuteSqlResponse(hotCoilId, client.queryPlanByHotCoilId(hotCoilId));
}
/**
* 钢卷实际 SEG 查询:按入口卷号查询。
* <p>
* 返回的是按 SEGNO 排序后的原始行数据。
*/
public SegSeriesView getSegByEncoilId(String encoilId) {
return SegSeriesView.fromExecuteSqlResponse(encoilId, client.queryProSegByEncoilId(encoilId));
}
/**
* 钢卷实际 SEG 查询:按出口卷号查询。
*/
public SegSeriesView getSegByExcoilId(String excoilId) {
return SegSeriesView.fromExecuteSqlResponse(excoilId, client.queryProSegByExcoilId(excoilId));
}
/**
* 钢卷 SEG 视图数据:把同一钢卷下按 SEGNO 排序的多行数据,整理成“一个钢卷 id + 一个属性对应一个列表”的结构。
* <p>
* 例如:厚度、张力、速度都会被整理成数组,方便前端直接画表或曲线。
*/
public SegSeriesView getSegSeriesViewByEncoilId(String encoilId) {
return getSegByEncoilId(encoilId);
}
/**
* 实时数据:厚度/仪表数据。
*/
public SqlServerApiClient.ExecuteSqlResponse getRealtimeGaugeByMatId(String matId) {
return client.queryGaugeByMatId(matId);
}
/**
* 实时数据:板形/形状数据。
*/
public SqlServerApiClient.ExecuteSqlResponse getRealtimeShapeByMatId(String matId) {
return client.queryShapeByMatId(matId);
}
/**
* 实时数据总入口:一次性返回厚度与板形两类数据。
*/
public RealtimeDataBundle getRealtimeData(String matId) {
return new RealtimeDataBundle(
getRealtimeGaugeByMatId(matId),
getRealtimeShapeByMatId(matId)
);
}
private static PlanListView toPlanListView(SqlServerApiClient.ExecuteSqlResponse response) {
return PlanListView.fromExecuteSqlResponse(response);
}
private static List<Map<String, Object>> asRowList(SqlServerApiClient.ExecuteSqlResponse response) {
if (response == null || response.getResult() == null) {
return Collections.emptyList();
}
Object result = response.getResult();
if (result instanceof List) {
List<?> list = (List<?>) result;
List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();
for (Object item : list) {
if (item instanceof Map) {
rows.add((Map<String, Object>) item);
}
}
return rows;
}
return Collections.emptyList();
}
private static Number asNumber(Object value) {
if (value instanceof Number) {
return (Number) value;
}
if (value == null) {
return null;
}
try {
return new BigDecimal(String.valueOf(value));
} catch (Exception ex) {
return null;
}
}
private static String asString(Object value) {
return value == null ? null : String.valueOf(value);
}
public static class PlanListView {
private final List<String> coilIds;
private final List<Map<String, Object>> rows;
public PlanListView(List<String> coilIds, List<Map<String, Object>> rows) {
this.coilIds = coilIds;
this.rows = rows;
}
public List<String> getCoilIds() {
return coilIds;
}
public List<Map<String, Object>> getRows() {
return rows;
}
public static PlanListView fromExecuteSqlResponse(SqlServerApiClient.ExecuteSqlResponse response) {
List<Map<String, Object>> rows = asRowList(response);
List<String> coilIds = rows.stream()
.map(row -> asString(row.get("COILID")))
.filter(value -> value != null && value.trim().length() > 0)
.distinct()
.collect(Collectors.toList());
return new PlanListView(coilIds, rows);
}
}
public static class PlanDetailView {
private final String coilId;
private final List<Map<String, Object>> rows;
private final Map<String, Object> firstRow;
public PlanDetailView(String coilId, List<Map<String, Object>> rows, Map<String, Object> firstRow) {
this.coilId = coilId;
this.rows = rows;
this.firstRow = firstRow;
}
public String getCoilId() {
return coilId;
}
public List<Map<String, Object>> getRows() {
return rows;
}
public Map<String, Object> getFirstRow() {
return firstRow;
}
public static PlanDetailView fromExecuteSqlResponse(String coilId, SqlServerApiClient.ExecuteSqlResponse response) {
List<Map<String, Object>> rows = asRowList(response);
Map<String, Object> firstRow = rows.isEmpty() ? Collections.<String, Object>emptyMap() : rows.get(0);
return new PlanDetailView(coilId, rows, firstRow);
}
}
public static class SegSeriesView {
private final String coilId;
private final List<Integer> segNo;
private final Map<String, List<Object>> series;
private final List<Map<String, Object>> rows;
public SegSeriesView(String coilId, List<Integer> segNo, Map<String, List<Object>> series, List<Map<String, Object>> rows) {
this.coilId = coilId;
this.segNo = segNo;
this.series = series;
this.rows = rows;
}
public String getCoilId() {
return coilId;
}
public List<Integer> getSegNo() {
return segNo;
}
public Map<String, List<Object>> getSeries() {
return series;
}
public List<Map<String, Object>> getRows() {
return rows;
}
@SuppressWarnings("unchecked")
public static SegSeriesView fromExecuteSqlResponse(String coilId, SqlServerApiClient.ExecuteSqlResponse response) {
List<Map<String, Object>> rows = asRowList(response);
Collections.sort(rows, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> left, Map<String, Object> right) {
Number leftSeg = asNumber(left.get("SEGNO"));
Number rightSeg = asNumber(right.get("SEGNO"));
int leftValue = leftSeg == null ? Integer.MAX_VALUE : leftSeg.intValue();
int rightValue = rightSeg == null ? Integer.MAX_VALUE : rightSeg.intValue();
if (leftValue > rightValue) {
return 1;
}
if (leftValue < rightValue) {
return -1;
}
return 0;
}
});
List<Integer> segNo = new ArrayList<Integer>();
for (Map<String, Object> row : rows) {
Number seg = asNumber(row.get("SEGNO"));
segNo.add(seg == null ? null : seg.intValue());
}
Map<String, List<Object>> series = new LinkedHashMap<String, List<Object>>();
for (Map<String, Object> row : rows) {
for (Map.Entry<String, Object> entry : row.entrySet()) {
String key = entry.getKey();
if ("SEGNO".equalsIgnoreCase(key)) {
continue;
}
series.computeIfAbsent(key, ignored -> new ArrayList<>()).add(entry.getValue());
}
}
return new SegSeriesView(coilId, segNo, series, rows);
}
}
public static class RealtimeDataBundle {
private final SqlServerApiClient.ExecuteSqlResponse gauge;
private final SqlServerApiClient.ExecuteSqlResponse shape;
public RealtimeDataBundle(SqlServerApiClient.ExecuteSqlResponse gauge,
SqlServerApiClient.ExecuteSqlResponse shape) {
this.gauge = gauge;
this.shape = shape;
}
public SqlServerApiClient.ExecuteSqlResponse getGauge() {
return gauge;
}
public SqlServerApiClient.ExecuteSqlResponse getShape() {
return shape;
}
}
}

View File

@@ -0,0 +1,79 @@
package com.klp.framework.sqlserver;
import com.klp.common.core.domain.R;
import com.klp.framework.service.SqlServerApiBusinessService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* sql-server-api 业务查询接口。
* <p>
* 提供计划、SEG、实时数据三个入口方便前端联动展示。
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/sql-server-api")
public class SqlServerApiController {
private final SqlServerApiBusinessService businessService;
/**
* 计划列表(分页)。
* page 从 1 开始,默认第 1 页,每页 20 条。
*/
@GetMapping("/plans")
public R<SqlServerApiBusinessService.PlanListView> planList(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int pageSize) {
return R.ok(businessService.getPlanList(page, pageSize));
}
/**
* 计划总数,用于前端分页器。
*/
@GetMapping("/plans/count")
public R<Map<String, Long>> planCount() {
Map<String, Long> result = new HashMap<>();
result.put("total", businessService.getPlanCount());
return R.ok(result);
}
/**
* 计划详情。
*/
@GetMapping("/plans/{coilId}")
public R<SqlServerApiBusinessService.PlanDetailView> planDetail(@PathVariable String coilId) {
return R.ok(businessService.getPlanByCoilId(coilId));
}
/**
* 钢卷实际 SEG按入口卷号查询。
*/
@GetMapping("/seg/{encoilId}")
public R<SqlServerApiBusinessService.SegSeriesView> segByEncoilId(@PathVariable String encoilId) {
return R.ok(businessService.getSegSeriesViewByEncoilId(encoilId));
}
/**
* 钢卷实际 SEG按出口卷号查询。
*/
@GetMapping("/seg-by-excoil/{excoilId}")
public R<SqlServerApiBusinessService.SegSeriesView> segByExcoilId(@PathVariable String excoilId) {
return R.ok(businessService.getSegByExcoilId(excoilId));
}
/**
* 实时数据:厚度、板形。
*/
@GetMapping("/realtime/{matId}")
public R<SqlServerApiBusinessService.RealtimeDataBundle> realtime(@PathVariable String matId) {
return R.ok(businessService.getRealtimeData(matId));
}
}

View File

@@ -102,7 +102,6 @@ public class SysConfigController extends BaseController {
/**
* 根据参数键名修改参数配置
*/
@SaCheckPermission("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping("/updateByKey")
public R<Void> updateByKey(@RequestBody SysConfig config) {

View File

@@ -11,7 +11,6 @@ import com.klp.common.core.page.TableDataInfo;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.system.service.ISysDictDataService;
import com.klp.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -32,7 +31,6 @@ import java.util.List;
public class SysDictDataController extends BaseController {
private final ISysDictDataService dictDataService;
private final ISysDictTypeService dictTypeService;
/**
* 查询字典数据列表
@@ -72,7 +70,7 @@ public class SysDictDataController extends BaseController {
*/
@GetMapping(value = "/type/{dictType}")
public R<List<SysDictData>> dictType(@PathVariable("dictType") String dictType) {
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
List<SysDictData> data = dictDataService.selectDictDataByTypeRealtime(dictType);
if (ObjectUtil.isNull(data)) {
data = new ArrayList<>();
}

View File

@@ -50,6 +50,14 @@ public class SysDictTypeController extends BaseController {
ExcelUtil.exportExcel(list, "字典类型", SysDictType.class, response);
}
/**
* 按字典类型编码精确查询(避免 /list 条件对 dict_type 使用 LIKE 时下划线通配问题;供页内齿轮等使用)
*/
@GetMapping("/byType/{dictType}")
public R<SysDictType> getByDictType(@PathVariable String dictType) {
return R.ok(dictTypeService.selectDictTypeByType(dictType));
}
/**
* 查询字典类型详细
*

View File

@@ -7,6 +7,12 @@ klp:
# 开发环境文件存储目录
directory-path: testDirectory
--- # sql-server-api 中间件配置(开发/测试环境)
sql-server-api:
host: 140.143.206.120
port: 15000
base-url: http://${sql-server-api.host}:${sql-server-api.port}
--- # OEE 聚合klp-da多服务地址配置
da:
oee:
@@ -92,14 +98,17 @@ spring:
url: jdbc:mysql://140.143.206.120:3306/cgldb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username: klp
password: KeLunPu123@
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# hikari:
# connectionTestQuery: SELECT 1 FROM DUAL
# Oracle 数据源
acid-l2:
lazy: true
type: ${spring.datasource.type}
driverClassName: oracle.jdbc.OracleDriver
# 示例jdbc:oracle:thin:@//localhost:1521/XE
url: jdbc:oracle:thin:@//localhost:1521/XE
username: ROOT
password: root
hikari:
connectionTestQuery: SELECT 1 FROM DUAL
# postgres:
# type: ${spring.datasource.type}
# driverClassName: org.postgresql.Driver

View File

@@ -7,6 +7,12 @@ klp:
# 生产环境文件存储目录
directory-path: /home/ubuntu/oa/folder
--- # sql-server-api 中间件配置(生产环境)
sql-server-api:
host: 140.143.206.120
port: 15000
base-url: http://${sql-server-api.host}:${sql-server-api.port}
--- # OEE 聚合klp-da多服务地址配置
da:
oee:
@@ -86,14 +92,17 @@ spring:
url: jdbc:mysql://140.143.206.120:3306/cgldb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username: klp
password: KeLunPu123@
# oracle:
# type: ${spring.datasource.type}
# driverClassName: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@//localhost:1521/XE
# username: ROOT
# password: root
# hikari:
# connectionTestQuery: SELECT 1 FROM DUAL
# Oracle 数据源
acid-l2:
lazy: true
type: ${spring.datasource.type}
driverClassName: oracle.jdbc.OracleDriver
# 示例jdbc:oracle:thin:@//localhost:1521/XE
url: jdbc:oracle:thin:@//localhost:1521/XE
username: ROOT
password: root
hikari:
connectionTestQuery: SELECT 1 FROM DUAL
# postgres:
# type: ${spring.datasource.type}
# driverClassName: org.postgresql.Driver

View File

@@ -53,7 +53,7 @@ server:
# 日志配置
logging:
level:
com.klp: @logging.level@
com.klp: warn
org.springframework: warn
config: classpath:logback-plus.xml
@@ -65,6 +65,7 @@ user:
# 密码锁定时间默认10分钟
lockTime: 10
# sql-server-api 中间件配置
# Spring配置
spring:
application:
@@ -154,7 +155,7 @@ security:
- /test/**
- /klp/generateRecord
- /klp/generateRecord/**
- /wms/coilPendingAction/**
# 测接口
# - /ems/energyConsumption
# - /ems/energyConsumption/**
@@ -260,8 +261,8 @@ springdoc:
xss:
# 过滤开关
enabled: true
# 排除链接多个用逗号分隔
excludes: /system/notice
# 排除链接(多个用逗号分隔)
excludes: /system/notice,/system/dict/data
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*

View File

@@ -0,0 +1,20 @@
-- 冷轧涂镀数智运营 - 规程主表
CREATE TABLE wms_process_spec (
spec_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
spec_code VARCHAR(64) NOT NULL COMMENT '规程编号',
spec_name VARCHAR(200) NOT NULL COMMENT '规程名称',
spec_type VARCHAR(32) NOT NULL DEFAULT 'PROCESS' COMMENT '类型(PROCESS=工艺规程,STANDARD=标准)',
line_id BIGINT NOT NULL COMMENT '产线ID',
product_type VARCHAR(100) NULL COMMENT '产品类型',
is_enabled TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用(0否1是)',
create_by VARCHAR(64) NULL COMMENT '创建人',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_by VARCHAR(64) NULL COMMENT '更新人',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常2删除与全局逻辑删除配置一致)',
remark VARCHAR(500) NULL COMMENT '备注',
PRIMARY KEY (spec_id),
UNIQUE KEY uk_wms_process_spec_code (spec_code),
KEY idx_wms_process_spec_line (line_id),
KEY idx_wms_process_spec_type (spec_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='规程主表';

View File

@@ -0,0 +1,39 @@
-- 规程版本表
CREATE TABLE wms_process_spec_version (
version_id BIGINT NOT NULL COMMENT '主键',
spec_id BIGINT NOT NULL COMMENT '规程主表ID',
version_code VARCHAR(64) NOT NULL COMMENT '版本号',
is_active TINYINT NOT NULL DEFAULT 0 COMMENT '是否当前生效(0否1是)',
status VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '状态(DRAFT草稿/PUBLISHED已发布/OBSOLETE作废等)',
create_by VARCHAR(64) NULL COMMENT '创建人',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_by VARCHAR(64) NULL COMMENT '更新人',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常2删除)',
remark VARCHAR(500) NULL COMMENT '备注',
PRIMARY KEY (version_id),
UNIQUE KEY uk_spec_version_code (spec_id, version_code),
KEY idx_spec_version_spec (spec_id),
KEY idx_spec_version_active (spec_id, is_active)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='规程版本表';
-- 方案点位表
CREATE TABLE wms_process_plan (
plan_id BIGINT NOT NULL COMMENT '主键',
version_id BIGINT NOT NULL COMMENT '规程版本ID',
segment_type VARCHAR(32) NOT NULL COMMENT '段类型(INLET/PROCESS/OUTLET)',
segment_name VARCHAR(100) NULL COMMENT '段名称',
point_name VARCHAR(200) NOT NULL COMMENT '点位名称',
point_code VARCHAR(64) NOT NULL COMMENT '点位编码',
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序',
create_by VARCHAR(64) NULL COMMENT '创建人',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_by VARCHAR(64) NULL COMMENT '更新人',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常2删除)',
remark VARCHAR(500) NULL COMMENT '备注',
PRIMARY KEY (plan_id),
UNIQUE KEY uk_plan_version_point_code (version_id, point_code),
KEY idx_plan_version (version_id),
KEY idx_plan_sort (version_id, sort_order)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='方案点位表';

View File

@@ -0,0 +1,20 @@
-- 方案参数表
CREATE TABLE wms_process_plan_param (
param_id BIGINT NOT NULL COMMENT '主键',
plan_id BIGINT NOT NULL COMMENT '方案点位ID',
param_code VARCHAR(64) NOT NULL COMMENT '参数编码',
param_name VARCHAR(200) NOT NULL COMMENT '参数名称',
target_value DECIMAL(24, 6) NULL COMMENT '设定值',
lower_limit DECIMAL(24, 6) NULL COMMENT '下限',
upper_limit DECIMAL(24, 6) NULL COMMENT '上限',
unit VARCHAR(32) NULL COMMENT '单位',
create_by VARCHAR(64) NULL COMMENT '创建人',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_by VARCHAR(64) NULL COMMENT '更新人',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常2删除)',
remark VARCHAR(500) NULL COMMENT '备注',
PRIMARY KEY (param_id),
UNIQUE KEY uk_plan_param_code (plan_id, param_code),
KEY idx_plan_param_plan (plan_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='方案参数表';

View File

@@ -21,6 +21,7 @@ import com.klp.aps.domain.vo.ApsPlanDetailVo;
import com.klp.aps.domain.bo.ApsPlanDetailBo;
import com.klp.aps.service.IApsPlanDetailService;
import com.klp.common.core.page.TableDataInfo;
import com.klp.domain.vo.WmsMaterialCoilVo;
/**
* 排产单明细
@@ -96,4 +97,11 @@ public class ApsPlanDetailController extends BaseController {
@PathVariable Long[] planDetailIds) {
return toAjax(iApsPlanDetailService.deleteWithValidByIds(Arrays.asList(planDetailIds), true));
}
// 根据排产单ID查询排产日期以及明细绑定的orderId,再根据这个orderId和排查时间查询返回钢卷
@GetMapping("/coils/{planSheetId}")
public R<List<WmsMaterialCoilVo>> getCoilsByPlanSheetId(@NotNull(message = "排产单ID不能为空")
@PathVariable Long planSheetId) {
return R.ok(iApsPlanDetailService.queryCoilsByPlanSheetId(planSheetId));
}
}

View File

@@ -7,6 +7,7 @@ import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
@@ -31,6 +32,11 @@ public class ApsPlanDetailBo extends BaseEntity {
*/
private Long planSheetId;
/**
* 关联排产单ID列表用于批量查询
*/
private List<Long> planSheetIds;
/**
* 内容序号
*/

View File

@@ -18,5 +18,5 @@ import java.util.List;
*/
public interface ApsPlanSheetMapper extends BaseMapperPlus<ApsPlanSheetMapper, ApsPlanSheet, ApsPlanSheetVo> {
List<ApsPlanSheetRowVo> selectList(ApsPlanSheetQueryReq req);
List<ApsPlanSheetRowVo> selectListByReq(ApsPlanSheetQueryReq req);
}

View File

@@ -8,6 +8,8 @@ import com.klp.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
import com.klp.domain.vo.WmsMaterialCoilVo;
/**
* 排产单明细Service接口
*
@@ -31,6 +33,11 @@ public interface IApsPlanDetailService {
*/
List<ApsPlanDetailVo> queryList(ApsPlanDetailBo bo);
/**
* 根据排产单ID列表查询明细
*/
List<ApsPlanDetailVo> queryListByPlanSheetIds(List<Long> planSheetIds);
/**
* 新增排产单明细
*/
@@ -50,4 +57,12 @@ public interface IApsPlanDetailService {
* 根据排产单ID删除明细
*/
int deleteByPlanSheetIds(Collection<Long> planSheetIds);
/**
* 根据排产单ID查询关联的钢卷列表根据计划日期筛选钢卷创建时间
*
* @param planSheetId 排产单ID
* @return 钢卷列表
*/
List<WmsMaterialCoilVo> queryCoilsByPlanSheetId(Long planSheetId);
}

View File

@@ -8,17 +8,24 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.utils.StringUtils;
import com.klp.domain.WmsCoilContractRel;
import com.klp.domain.vo.WmsMaterialCoilVo;
import com.klp.domain.vo.WmsCoilContractRelVo;
import com.klp.domain.bo.WmsMaterialCoilBo;
import com.klp.mapper.WmsCoilContractRelMapper;
import com.klp.service.IWmsMaterialCoilService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.klp.aps.domain.bo.ApsPlanDetailBo;
import com.klp.aps.domain.vo.ApsPlanDetailVo;
import com.klp.aps.domain.vo.ApsPlanSheetVo;
import com.klp.aps.domain.entity.ApsPlanDetail;
import com.klp.aps.mapper.ApsPlanDetailMapper;
import com.klp.aps.mapper.ApsPlanSheetMapper;
import com.klp.aps.service.IApsPlanDetailService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.*;
import java.util.stream.Collectors;
/**
* 排产单明细Service业务层处理
@@ -31,6 +38,9 @@ import java.util.Collection;
public class ApsPlanDetailServiceImpl implements IApsPlanDetailService {
private final ApsPlanDetailMapper baseMapper;
private final ApsPlanSheetMapper planSheetMapper;
private final WmsCoilContractRelMapper coilContractRelMapper;
private final IWmsMaterialCoilService materialCoilService;
/**
* 查询排产单明细
@@ -105,6 +115,19 @@ public class ApsPlanDetailServiceImpl implements IApsPlanDetailService {
return baseMapper.selectVoList(lqw);
}
/**
* 根据排产单ID列表查询明细
*/
@Override
public List<ApsPlanDetailVo> queryListByPlanSheetIds(List<Long> planSheetIds) {
if (planSheetIds == null || planSheetIds.isEmpty()) {
return new java.util.ArrayList<>();
}
LambdaQueryWrapper<ApsPlanDetail> lqw = Wrappers.lambdaQuery();
lqw.in(ApsPlanDetail::getPlanSheetId, planSheetIds);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ApsPlanDetail> buildQueryWrapper(ApsPlanDetailBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ApsPlanDetail> lqw = Wrappers.lambdaQuery();
@@ -194,4 +217,84 @@ public class ApsPlanDetailServiceImpl implements IApsPlanDetailService {
public int deleteByPlanSheetIds(Collection<Long> planSheetIds) {
return baseMapper.deleteByPlanSheetIds(planSheetIds);
}
@Override
public List<WmsMaterialCoilVo> queryCoilsByPlanSheetId(Long planSheetId) {
if (planSheetId == null) {
return Collections.emptyList();
}
ApsPlanSheetVo planSheet = planSheetMapper.selectVoById(planSheetId);
if (planSheet == null || planSheet.getPlanDate() == null) {
return Collections.emptyList();
}
Date planDate = planSheet.getPlanDate();
LambdaQueryWrapper<ApsPlanDetail> detailQw = Wrappers.lambdaQuery();
detailQw.eq(ApsPlanDetail::getPlanSheetId, planSheetId);
detailQw.eq(ApsPlanDetail::getDelFlag, 0);
List<ApsPlanDetailVo> details = baseMapper.selectVoList(detailQw);
List<Long> orderIds = details.stream()
.map(ApsPlanDetailVo::getOrderId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (orderIds.isEmpty()) {
return Collections.emptyList();
}
LambdaQueryWrapper<WmsCoilContractRel> relQw = Wrappers.lambdaQuery();
relQw.in(WmsCoilContractRel::getContractId, orderIds);
relQw.eq(WmsCoilContractRel::getDelFlag, 0);
List<WmsCoilContractRelVo> coilRels = coilContractRelMapper.selectVoList(relQw);
Map<Long, List<Long>> coilIdMap = coilRels.stream()
.filter(rel -> rel.getContractId() != null && rel.getCoilId() != null)
.collect(Collectors.groupingBy(
WmsCoilContractRelVo::getContractId,
Collectors.mapping(WmsCoilContractRelVo::getCoilId, Collectors.toList())
));
Set<Long> allCoilIds = coilIdMap.values().stream()
.flatMap(List::stream)
.collect(Collectors.toSet());
if (allCoilIds.isEmpty()) {
return Collections.emptyList();
}
WmsMaterialCoilBo coilBo = new WmsMaterialCoilBo();
coilBo.setCoilIds(allCoilIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
coilBo.setByCreateTimeStart(getStartOfDay(planDate));
coilBo.setByCreateTimeEnd(getEndOfDay(planDate));
return materialCoilService.queryList(coilBo);
}
private Date getStartOfDay(Date date) {
if (date == null) {
return null;
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
private Date getEndOfDay(Date date) {
if (date == null) {
return null;
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
return cal.getTime();
}
}

View File

@@ -283,7 +283,7 @@ public class ApsPlanSheetServiceImpl implements IApsPlanSheetService {
// ================== 【核心前7列自动合并】 ==================
int dataEndRow = r - 1;
if (dataStartRow <= dataEndRow) {
if (dataStartRow <= dataEndRow && dataEndRow > dataStartRow) {
for (int col = 0; col < 7; col++) { // 0~6 共7列
CellRangeAddress region = new CellRangeAddress(
dataStartRow,
@@ -318,7 +318,7 @@ public class ApsPlanSheetServiceImpl implements IApsPlanSheetService {
}
private List<ApsPlanSheetRowVo> queryListAll(ApsPlanSheetQueryReq req) {
return baseMapper.selectList(req);
return baseMapper.selectListByReq(req);
}
private String nvl(Object v, Object fallback) {

View File

@@ -19,7 +19,7 @@
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectList" parameterType="com.klp.aps.domain.dto.ApsPlanSheetQueryReq" resultType="com.klp.aps.domain.vo.ApsPlanSheetRowVo">
<select id="selectListByReq" parameterType="com.klp.aps.domain.dto.ApsPlanSheetQueryReq" resultType="com.klp.aps.domain.vo.ApsPlanSheetRowVo">
SELECT
d.plan_detail_id AS detailSheetId,
s.plan_date AS planDate,

View File

@@ -12,7 +12,7 @@
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
@@ -43,5 +43,9 @@
<groupId>com.klp</groupId>
<artifactId>klp-wms</artifactId>
</dependency>
<dependency>
<groupId>com.klp</groupId>
<artifactId>klp-aps</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,12 +1,17 @@
package com.klp.crm.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.Date;
import com.klp.aps.domain.bo.ApsPlanDetailBo;
import com.klp.aps.domain.bo.ApsPlanSheetBo;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.annotation.Log;
@@ -21,6 +26,10 @@ import com.klp.crm.domain.vo.CrmOrderVo;
import com.klp.crm.domain.bo.CrmOrderBo;
import com.klp.crm.service.ICrmOrderService;
import com.klp.common.core.page.TableDataInfo;
import com.klp.aps.domain.vo.ApsPlanSheetVo;
import com.klp.aps.domain.vo.ApsPlanDetailVo;
import com.klp.aps.service.IApsPlanSheetService;
import com.klp.aps.service.IApsPlanDetailService;
/**
* 正式订单主
@@ -35,6 +44,8 @@ import com.klp.common.core.page.TableDataInfo;
public class CrmOrderController extends BaseController {
private final ICrmOrderService iCrmOrderService;
private final IApsPlanSheetService iApsPlanSheetService;
private final IApsPlanDetailService iApsPlanDetailService;
/**
* 查询正式订单主列表
@@ -96,4 +107,54 @@ public class CrmOrderController extends BaseController {
@PathVariable String[] orderIds) {
return toAjax(iCrmOrderService.deleteWithValidByIds(Arrays.asList(orderIds), true));
}
/**
* 查询每日订单(根据排产计划获取今天的订单)
*
* @param planDate 排产日期,默认今天
*/
@GetMapping("/daily")
public R<List<CrmOrderVo>> getDailyOrders(
@RequestParam(value = "planDate", required = false)
@DateTimeFormat(pattern = "yyyy-MM-dd") Date planDate) {
if (planDate == null) {
planDate = new Date();
}
// 将日期设置为当天的开始时间 00:00:00
java.util.Calendar calendar = java.util.Calendar.getInstance();
calendar.setTime(planDate);
calendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
calendar.set(java.util.Calendar.MINUTE, 0);
calendar.set(java.util.Calendar.SECOND, 0);
calendar.set(java.util.Calendar.MILLISECOND, 0);
planDate = calendar.getTime();
ApsPlanSheetBo bo = new ApsPlanSheetBo();
bo.setPlanDate(planDate);
List<ApsPlanSheetVo> planSheetList = iApsPlanSheetService.queryList(bo);
if (planSheetList == null || planSheetList.isEmpty()) {
return R.ok(new ArrayList<>());
}
List<Long> planSheetIds = new ArrayList<>();
for (ApsPlanSheetVo sheet : planSheetList) {
planSheetIds.add(sheet.getPlanSheetId());
}
ApsPlanDetailBo detailBo = new ApsPlanDetailBo();
detailBo.setPlanSheetIds(planSheetIds);
List<ApsPlanDetailVo> detailList = iApsPlanDetailService.queryListByPlanSheetIds(planSheetIds);
if (detailList == null || detailList.isEmpty()) {
return R.ok(new ArrayList<>());
}
List<Long> orderIds = new ArrayList<>();
for (ApsPlanDetailVo detail : detailList) {
if (detail.getOrderId() != null) {
orderIds.add(detail.getOrderId());
}
}
if (orderIds.isEmpty()) {
return R.ok(new ArrayList<>());
}
List<CrmOrderVo> orders = iCrmOrderService.queryByIds(orderIds);
return R.ok(orders);
}
}

View File

@@ -85,6 +85,131 @@ public class CrmOrder extends BaseEntity {
*/
private String contractCode;
/**
* 合同名称
*/
private String contractName;
/**
* 供方
*/
private String supplier;
/**
* 需方
*/
private String customer;
/**
* 签订时间
*/
private Date signTime;
/**
* 签订地点
*/
private String signLocation;
/**
* 产品内容
*/
private String productContent;
/**
* 合同内容
*/
private String contractContent;
/**
* 供方地址
*/
private String supplierAddress;
/**
* 供方电话
*/
private String supplierPhone;
/**
* 供方开户行
*/
private String supplierBank;
/**
* 供方账号
*/
private String supplierAccount;
/**
* 供方税号
*/
private String supplierTaxNo;
/**
* 需方地址
*/
private String customerAddress;
/**
* 需方电话
*/
private String customerPhone;
/**
* 需方开户行
*/
private String customerBank;
/**
* 需方账号
*/
private String customerAccount;
/**
* 需方税号
*/
private String customerTaxNo;
/**
* 技术附件
*/
private String techAnnex;
/**
* 商务附件
*/
private String businessAnnex;
/**
* 排产函
*/
private String productionSchedule;
/**
* 算单价备注
*/
private String unitPriceRemark;
/**
* 应付定金(万元)
*/
private BigDecimal depositPayable;
/**
* 已付定金(万元)
*/
private BigDecimal depositPaid;
/**
* 定金比例(%
*/
private BigDecimal depositRatio;
/**
* 合同状态 0=草稿 1=生效 2=作废 3=已完成
*/
private Long status;
/**
* 关联合同IDwms_contract.contract_id
*/
@@ -101,4 +226,9 @@ public class CrmOrder extends BaseEntity {
@TableLogic
private Long delFlag;
/**
* 是否置顶 0-否 1-是
*/
private Integer isTop;
}

View File

@@ -72,11 +72,15 @@ public class CrmOrderItem extends BaseEntity {
/**
* 宽度公差
*/
private BigDecimal widthTolerance;
private String widthTolerance;
/**
* 厚度公差
*/
private BigDecimal thicknessTolerance;
private String thicknessTolerance;
/**
* 表面质量
*/
private String surfaceQuality;
/**
* 合同定价
*/
@@ -93,6 +97,30 @@ public class CrmOrderItem extends BaseEntity {
* 排产批次
*/
private String productionBatch;
/**
* 表面处理
*/
private String surfaceTreatment;
/**
* 切边要求
*/
private String edgeCuttingReq;
/**
* 包装要求
*/
private String packagingReq;
/**
* 宽度
*/
private String width;
/**
* 厚度
*/
private String thickness;
/**
* 用途
*/
private String purpose;
/**
* 删除标识 0正常 2删除
*/

View File

@@ -8,6 +8,7 @@ import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 正式订单主业务对象 crm_order
@@ -53,6 +54,8 @@ public class CrmOrderBo extends BaseEntity {
/**
* 交货日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date deliveryDate;
/**
@@ -95,6 +98,133 @@ public class CrmOrderBo extends BaseEntity {
*/
private String contractCode;
/**
* 合同名称
*/
private String contractName;
/**
* 供方
*/
private String supplier;
/**
* 需方
*/
private String customer;
/**
* 签订时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date signTime;
/**
* 签订地点
*/
private String signLocation;
/**
* 产品内容
*/
private String productContent;
/**
* 合同内容
*/
private String contractContent;
/**
* 供方地址
*/
private String supplierAddress;
/**
* 供方电话
*/
private String supplierPhone;
/**
* 供方开户行
*/
private String supplierBank;
/**
* 供方账号
*/
private String supplierAccount;
/**
* 供方税号
*/
private String supplierTaxNo;
/**
* 需方地址
*/
private String customerAddress;
/**
* 需方电话
*/
private String customerPhone;
/**
* 需方开户行
*/
private String customerBank;
/**
* 需方账号
*/
private String customerAccount;
/**
* 需方税号
*/
private String customerTaxNo;
/**
* 技术附件
*/
private String techAnnex;
/**
* 商务附件
*/
private String businessAnnex;
/**
* 排产函
*/
private String productionSchedule;
/**
* 算单价备注
*/
private String unitPriceRemark;
/**
* 应付定金(万元)
*/
private BigDecimal depositPayable;
/**
* 已付定金(万元)
*/
private BigDecimal depositPaid;
/**
* 定金比例(%
*/
private BigDecimal depositRatio;
/**
* 合同状态 0=草稿 1=生效 2=作废 3=已完成
*/
private Long status;
/**
* 关联合同IDwms_contract.contract_id
*/
@@ -105,6 +235,11 @@ public class CrmOrderBo extends BaseEntity {
*/
private String annexFiles;
/**
* 是否置顶 0-否 1-是
*/
private Integer isTop;
/**
* 关键字搜索
*/

View File

@@ -81,12 +81,17 @@ public class CrmOrderItemBo extends BaseEntity {
/**
* 宽度公差
*/
private BigDecimal widthTolerance;
private String widthTolerance;
/**
* 厚度公差
*/
private BigDecimal thicknessTolerance;
private String thicknessTolerance;
/**
* 表面质量
*/
private String surfaceQuality;
/**
* 合同定价
@@ -108,5 +113,34 @@ public class CrmOrderItemBo extends BaseEntity {
*/
private String productionBatch;
/**
* 表面处理
*/
private String surfaceTreatment;
/**
* 切边要求
*/
private String edgeCuttingReq;
/**
* 包装要求
*/
private String packagingReq;
/**
* 宽度
*/
private String width;
/**
* 厚度
*/
private String thickness;
/**
* 用途
*/
private String purpose;
}

View File

@@ -99,13 +99,19 @@ public class CrmOrderItemVo {
* 宽度公差
*/
@ExcelProperty(value = "宽度公差")
private BigDecimal widthTolerance;
private String widthTolerance;
/**
* 厚度公差
*/
@ExcelProperty(value = "厚度公差")
private BigDecimal thicknessTolerance;
private String thicknessTolerance;
/**
* 表面质量
*/
@ExcelProperty(value = "表面质量")
private String surfaceQuality;
/**
* 合同定价
@@ -131,5 +137,40 @@ public class CrmOrderItemVo {
@ExcelProperty(value = "排产批次")
private String productionBatch;
/**
* 表面处理
*/
@ExcelProperty(value = "表面处理")
private String surfaceTreatment;
/**
* 切边要求
*/
@ExcelProperty(value = "切边要求")
private String edgeCuttingReq;
/**
* 包装要求
*/
@ExcelProperty(value = "包装要求")
private String packagingReq;
/**
* 宽度
*/
@ExcelProperty(value = "宽度")
private String width;
/**
* 厚度
*/
@ExcelProperty(value = "厚度")
private String thickness;
/**
* 用途
*/
@ExcelProperty(value = "用途")
private String purpose;
}

View File

@@ -2,12 +2,15 @@ package com.klp.crm.domain.vo;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.klp.common.annotation.ExcelDictFormat;
import com.klp.common.convert.ExcelDictConvert;
import com.klp.common.core.domain.BaseEntity;
import com.klp.domain.vo.WmsMaterialCoilVo;
import lombok.Data;
@@ -114,6 +117,156 @@ public class CrmOrderVo extends BaseEntity {
@ExcelProperty(value = "合同号")
private String contractCode;
/**
* 合同名称
*/
@ExcelProperty(value = "合同名称")
private String contractName;
/**
* 供方
*/
@ExcelProperty(value = "供方")
private String supplier;
/**
* 需方
*/
@ExcelProperty(value = "需方")
private String customer;
/**
* 签订时间
*/
@ExcelProperty(value = "签订时间")
private Date signTime;
/**
* 签订地点
*/
@ExcelProperty(value = "签订地点")
private String signLocation;
/**
* 产品内容
*/
@ExcelProperty(value = "产品内容")
private String productContent;
/**
* 合同内容
*/
@ExcelProperty(value = "合同内容")
private String contractContent;
/**
* 供方地址
*/
@ExcelProperty(value = "供方地址")
private String supplierAddress;
/**
* 供方电话
*/
@ExcelProperty(value = "供方电话")
private String supplierPhone;
/**
* 供方开户行
*/
@ExcelProperty(value = "供方开户行")
private String supplierBank;
/**
* 供方账号
*/
@ExcelProperty(value = "供方账号")
private String supplierAccount;
/**
* 供方税号
*/
@ExcelProperty(value = "供方税号")
private String supplierTaxNo;
/**
* 需方地址
*/
@ExcelProperty(value = "需方地址")
private String customerAddress;
/**
* 需方电话
*/
@ExcelProperty(value = "需方电话")
private String customerPhone;
/**
* 需方开户行
*/
@ExcelProperty(value = "需方开户行")
private String customerBank;
/**
* 需方账号
*/
@ExcelProperty(value = "需方账号")
private String customerAccount;
/**
* 需方税号
*/
@ExcelProperty(value = "需方税号")
private String customerTaxNo;
/**
* 技术附件
*/
@ExcelProperty(value = "技术附件")
private String techAnnex;
/**
* 商务附件
*/
@ExcelProperty(value = "商务附件")
private String businessAnnex;
/**
* 排产函
*/
@ExcelProperty(value = "排产函")
private String productionSchedule;
/**
* 算单价备注
*/
@ExcelProperty(value = "算单价备注")
private String unitPriceRemark;
/**
* 应付定金(万元)
*/
@ExcelProperty(value = "应付定金(万元)")
private BigDecimal depositPayable;
/**
* 已付定金(万元)
*/
@ExcelProperty(value = "已付定金(万元)")
private BigDecimal depositPaid;
/**
* 定金比例(%
*/
@ExcelProperty(value = "定金比例(%")
private BigDecimal depositRatio;
/**
* 合同状态 0=草稿 1=生效 2=作废 3=已完成
*/
@ExcelProperty(value = "合同状态")
private Long status;
/**
* 关联合同IDwms_contract.contract_id
*/
@@ -126,6 +279,12 @@ public class CrmOrderVo extends BaseEntity {
@ExcelProperty(value = "附件")
private String annexFiles;
/**
* 是否置顶 0-否 1-是
*/
@ExcelProperty(value = "是否置顶")
private Integer isTop;
// @ExcelProperty(value = "客户编号")
private String customerCode;
@@ -142,4 +301,8 @@ public class CrmOrderVo extends BaseEntity {
private String createByName;
//更新人
private String updateByName;
/**
* 关联的钢卷列表
*/
private List<WmsMaterialCoilVo> coilList;
}

View File

@@ -22,6 +22,11 @@ public interface ICrmOrderService {
*/
CrmOrderVo queryById(String orderId);
/**
* 根据ID列表查询正式订单
*/
List<CrmOrderVo> queryByIds(List<Long> orderIds);
/**
* 查询正式订单主列表
*/

View File

@@ -95,12 +95,19 @@ public class CrmOrderItemServiceImpl implements ICrmOrderItemService {
lqw.eq(StringUtils.isNotBlank(bo.getMaterial()), CrmOrderItem::getMaterial, bo.getMaterial());
lqw.eq(StringUtils.isNotBlank(bo.getGrade()), CrmOrderItem::getGrade, bo.getGrade());
lqw.eq(bo.getWeight() != null, CrmOrderItem::getWeight, bo.getWeight());
lqw.eq(bo.getWidthTolerance() != null, CrmOrderItem::getWidthTolerance, bo.getWidthTolerance());
lqw.eq(bo.getThicknessTolerance() != null, CrmOrderItem::getThicknessTolerance, bo.getThicknessTolerance());
lqw.eq(StringUtils.isNotBlank(bo.getWidthTolerance()), CrmOrderItem::getWidthTolerance, bo.getWidthTolerance());
lqw.eq(StringUtils.isNotBlank(bo.getThicknessTolerance()), CrmOrderItem::getThicknessTolerance, bo.getThicknessTolerance());
lqw.eq(bo.getContractPrice() != null, CrmOrderItem::getContractPrice, bo.getContractPrice());
lqw.eq(StringUtils.isNotBlank(bo.getCustomizer()), CrmOrderItem::getCustomizer, bo.getCustomizer());
lqw.eq(StringUtils.isNotBlank(bo.getShipper()), CrmOrderItem::getShipper, bo.getShipper());
lqw.eq(StringUtils.isNotBlank(bo.getProductionBatch()), CrmOrderItem::getProductionBatch, bo.getProductionBatch());
lqw.eq(StringUtils.isNotBlank(bo.getSurfaceTreatment()), CrmOrderItem::getSurfaceTreatment, bo.getSurfaceTreatment());
lqw.eq(StringUtils.isNotBlank(bo.getSurfaceQuality()), CrmOrderItem::getSurfaceQuality, bo.getSurfaceQuality());
lqw.eq(StringUtils.isNotBlank(bo.getEdgeCuttingReq()), CrmOrderItem::getEdgeCuttingReq, bo.getEdgeCuttingReq());
lqw.eq(StringUtils.isNotBlank(bo.getPackagingReq()), CrmOrderItem::getPackagingReq, bo.getPackagingReq());
lqw.eq(StringUtils.isNotBlank(bo.getWidth()), CrmOrderItem::getWidth, bo.getWidth());
lqw.eq(StringUtils.isNotBlank(bo.getThickness()), CrmOrderItem::getThickness, bo.getThickness());
lqw.eq(StringUtils.isNotBlank(bo.getPurpose()), CrmOrderItem::getPurpose, bo.getPurpose());
return lqw;
}

View File

@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.utils.StringUtils;
import com.klp.crm.domain.vo.CrmOrderOperationTraceVo;
import com.klp.mapper.WmsCoilContractRelMapper;
import com.klp.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -17,6 +18,11 @@ import com.klp.crm.domain.vo.CrmOrderVo;
import com.klp.crm.domain.CrmOrder;
import com.klp.crm.mapper.CrmOrderMapper;
import com.klp.crm.service.ICrmOrderService;
import com.klp.domain.WmsCoilContractRel;
import com.klp.domain.bo.WmsMaterialCoilBo;
import com.klp.domain.vo.WmsMaterialCoilVo;
import com.klp.service.IWmsCoilContractRelService;
import com.klp.service.IWmsMaterialCoilService;
import java.util.*;
import java.util.stream.Collectors;
@@ -35,6 +41,10 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
private final ISysUserService userService;
private final WmsCoilContractRelMapper coilContractRelMapper;
private final IWmsMaterialCoilService materialCoilService;
/**
* 查询正式订单主
*/
@@ -43,6 +53,19 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
return baseMapper.selectVoById(orderId);
}
/**
* 根据ID列表查询正式订单
*/
@Override
public List<CrmOrderVo> queryByIds(List<Long> orderIds) {
if (orderIds == null || orderIds.isEmpty()) {
return new ArrayList<>();
}
LambdaQueryWrapper<CrmOrder> lqw = Wrappers.lambdaQuery();
lqw.in(CrmOrder::getOrderId, orderIds);
return baseMapper.selectVoList(lqw);
}
/**
* 查询正式订单主列表
*/
@@ -76,6 +99,57 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
}
}
}
// 查询订单关联的钢卷ID列表
List<Long> contractIds = records.stream()
.map(CrmOrderVo::getOrderId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (!contractIds.isEmpty()) {
// 批量查询钢卷与合同关联关系
LambdaQueryWrapper<WmsCoilContractRel> coilQw = Wrappers.lambdaQuery();
coilQw.in(WmsCoilContractRel::getContractId, contractIds);
coilQw.eq(WmsCoilContractRel::getDelFlag, 0);
List<WmsCoilContractRel> coilRels = coilContractRelMapper.selectList(coilQw);
// 按contractId分组,收集coilId列表
Map<Long, List<Long>> coilIdMap = coilRels.stream()
.filter(rel -> rel.getContractId() != null && rel.getCoilId() != null)
.collect(Collectors.groupingBy(
WmsCoilContractRel::getContractId,
Collectors.mapping(WmsCoilContractRel::getCoilId, Collectors.toList())
));
// 查询所有相关钢卷的详细信息
Set<Long> allCoilIds = coilIdMap.values().stream()
.flatMap(List::stream)
.collect(Collectors.toSet());
Map<Long, WmsMaterialCoilVo> coilVoMap = Collections.emptyMap();
if (!allCoilIds.isEmpty()) {
WmsMaterialCoilBo coilBo = new WmsMaterialCoilBo();
coilBo.setCoilIds(allCoilIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
List<WmsMaterialCoilVo> allCoils = materialCoilService.queryList(coilBo);
coilVoMap = allCoils.stream()
.collect(Collectors.toMap(WmsMaterialCoilVo::getCoilId, c -> c, (a, b) -> a));
}
// 设置到每个订单的coilIds和coilList字段
for (CrmOrderVo vo : records) {
if (vo.getOrderId() != null && coilIdMap.containsKey(vo.getOrderId())) {
List<Long> coilIdList = coilIdMap.get(vo.getOrderId());
// 设置coilList钢卷详细信息列表
List<WmsMaterialCoilVo> coilList = coilIdList.stream()
.map(coilVoMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
vo.setCoilList(coilList);
}
}
}
return TableDataInfo.build(result);
}
@@ -89,7 +163,10 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
.or().like("co.audit_user", bo.getKeyword())
.or().like("co.contract_code", bo.getKeyword())
.or().like("co.annex_files", bo.getKeyword())
.or().like("co.remark", bo.getKeyword()));
.or().like("co.remark", bo.getKeyword())
.or().like("co.contract_name", bo.getKeyword())
.or().like("co.supplier", bo.getKeyword())
.or().like("co.customer", bo.getKeyword()));
}
qw.eq(StringUtils.isNotBlank(bo.getOrderCode()), "co.order_code", bo.getOrderCode());
qw.eq(bo.getOrderType() != null, "co.order_type", bo.getOrderType());
@@ -104,13 +181,43 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
qw.eq(bo.getFinanceStatus() != null, "co.finance_status", bo.getFinanceStatus());
qw.eq(bo.getUnpaidAmount() != null, "co.unpaid_amount", bo.getUnpaidAmount());
qw.like(StringUtils.isNotBlank(bo.getContractCode()), "co.contract_code", bo.getContractCode());
qw.like(StringUtils.isNotBlank(bo.getContractName()), "co.contract_name", bo.getContractName());
qw.like(StringUtils.isNotBlank(bo.getSupplier()), "co.supplier", bo.getSupplier());
qw.like(StringUtils.isNotBlank(bo.getCustomer()), "co.customer", bo.getCustomer());
qw.eq(bo.getSignTime() != null, "co.sign_time", bo.getSignTime());
qw.like(StringUtils.isNotBlank(bo.getSignLocation()), "co.sign_location", bo.getSignLocation());
qw.eq(StringUtils.isNotBlank(bo.getProductContent()), "co.product_content", bo.getProductContent());
qw.eq(StringUtils.isNotBlank(bo.getContractContent()), "co.contract_content", bo.getContractContent());
qw.like(StringUtils.isNotBlank(bo.getSupplierAddress()), "co.supplier_address", bo.getSupplierAddress());
qw.like(StringUtils.isNotBlank(bo.getSupplierPhone()), "co.supplier_phone", bo.getSupplierPhone());
qw.like(StringUtils.isNotBlank(bo.getSupplierBank()), "co.supplier_bank", bo.getSupplierBank());
qw.like(StringUtils.isNotBlank(bo.getSupplierAccount()), "co.supplier_account", bo.getSupplierAccount());
qw.like(StringUtils.isNotBlank(bo.getSupplierTaxNo()), "co.supplier_tax_no", bo.getSupplierTaxNo());
qw.like(StringUtils.isNotBlank(bo.getCustomerAddress()), "co.customer_address", bo.getCustomerAddress());
qw.like(StringUtils.isNotBlank(bo.getCustomerPhone()), "co.customer_phone", bo.getCustomerPhone());
qw.like(StringUtils.isNotBlank(bo.getCustomerBank()), "co.customer_bank", bo.getCustomerBank());
qw.like(StringUtils.isNotBlank(bo.getCustomerAccount()), "co.customer_account", bo.getCustomerAccount());
qw.like(StringUtils.isNotBlank(bo.getCustomerTaxNo()), "co.customer_tax_no", bo.getCustomerTaxNo());
qw.like(StringUtils.isNotBlank(bo.getTechAnnex()), "co.tech_annex", bo.getTechAnnex());
qw.like(StringUtils.isNotBlank(bo.getBusinessAnnex()), "co.business_annex", bo.getBusinessAnnex());
qw.like(StringUtils.isNotBlank(bo.getProductionSchedule()), "co.production_schedule", bo.getProductionSchedule());
qw.like(StringUtils.isNotBlank(bo.getUnitPriceRemark()), "co.unit_price_remark", bo.getUnitPriceRemark());
qw.eq(bo.getDepositPayable() != null, "co.deposit_payable", bo.getDepositPayable());
qw.eq(bo.getDepositPaid() != null, "co.deposit_paid", bo.getDepositPaid());
qw.eq(bo.getDepositRatio() != null, "co.deposit_ratio", bo.getDepositRatio());
qw.eq(bo.getStatus() != null, "co.status", bo.getStatus());
qw.eq(bo.getContractId() != null, "co.contract_id", bo.getContractId());
qw.like(StringUtils.isNotBlank(bo.getAnnexFiles()), "co.annex_files", bo.getAnnexFiles());
qw.eq(bo.getIsTop() != null, "co.is_top", bo.getIsTop());
//逻辑删除
qw.eq("co.del_flag", 0);
//根据orderType排序预订单是0 正是订单是1 0排在前面 1排在后面 升序
qw.orderByAsc("co.order_type");
qw.orderByDesc("co.create_time");
//排序规则:
// 1. 置顶优先 (is_top=1 排在前面)
// 2. 状态为1(已生效)的排在前面
// 3. 创建时间倒序
qw.orderByDesc("co.is_top")
.orderByDesc("CASE WHEN co.status = 1 THEN 1 ELSE 0 END")
.orderByDesc("co.create_time");
return qw;
}
@@ -139,8 +246,41 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
lqw.eq(bo.getFinanceStatus() != null, CrmOrder::getFinanceStatus, bo.getFinanceStatus());
lqw.eq(bo.getUnpaidAmount() != null, CrmOrder::getUnpaidAmount, bo.getUnpaidAmount());
lqw.like(StringUtils.isNotBlank(bo.getContractCode()), CrmOrder::getContractCode, bo.getContractCode());
lqw.like(StringUtils.isNotBlank(bo.getContractName()), CrmOrder::getContractName, bo.getContractName());
lqw.like(StringUtils.isNotBlank(bo.getSupplier()), CrmOrder::getSupplier, bo.getSupplier());
lqw.like(StringUtils.isNotBlank(bo.getCustomer()), CrmOrder::getCustomer, bo.getCustomer());
lqw.eq(bo.getSignTime() != null, CrmOrder::getSignTime, bo.getSignTime());
lqw.like(StringUtils.isNotBlank(bo.getSignLocation()), CrmOrder::getSignLocation, bo.getSignLocation());
lqw.eq(StringUtils.isNotBlank(bo.getProductContent()), CrmOrder::getProductContent, bo.getProductContent());
lqw.eq(StringUtils.isNotBlank(bo.getContractContent()), CrmOrder::getContractContent, bo.getContractContent());
lqw.like(StringUtils.isNotBlank(bo.getSupplierAddress()), CrmOrder::getSupplierAddress, bo.getSupplierAddress());
lqw.like(StringUtils.isNotBlank(bo.getSupplierPhone()), CrmOrder::getSupplierPhone, bo.getSupplierPhone());
lqw.like(StringUtils.isNotBlank(bo.getSupplierBank()), CrmOrder::getSupplierBank, bo.getSupplierBank());
lqw.like(StringUtils.isNotBlank(bo.getSupplierAccount()), CrmOrder::getSupplierAccount, bo.getSupplierAccount());
lqw.like(StringUtils.isNotBlank(bo.getSupplierTaxNo()), CrmOrder::getSupplierTaxNo, bo.getSupplierTaxNo());
lqw.like(StringUtils.isNotBlank(bo.getCustomerAddress()), CrmOrder::getCustomerAddress, bo.getCustomerAddress());
lqw.like(StringUtils.isNotBlank(bo.getCustomerPhone()), CrmOrder::getCustomerPhone, bo.getCustomerPhone());
lqw.like(StringUtils.isNotBlank(bo.getCustomerBank()), CrmOrder::getCustomerBank, bo.getCustomerBank());
lqw.like(StringUtils.isNotBlank(bo.getCustomerAccount()), CrmOrder::getCustomerAccount, bo.getCustomerAccount());
lqw.like(StringUtils.isNotBlank(bo.getCustomerTaxNo()), CrmOrder::getCustomerTaxNo, bo.getCustomerTaxNo());
lqw.like(StringUtils.isNotBlank(bo.getTechAnnex()), CrmOrder::getTechAnnex, bo.getTechAnnex());
lqw.like(StringUtils.isNotBlank(bo.getBusinessAnnex()), CrmOrder::getBusinessAnnex, bo.getBusinessAnnex());
lqw.like(StringUtils.isNotBlank(bo.getProductionSchedule()), CrmOrder::getProductionSchedule, bo.getProductionSchedule());
lqw.like(StringUtils.isNotBlank(bo.getUnitPriceRemark()), CrmOrder::getUnitPriceRemark, bo.getUnitPriceRemark());
lqw.eq(bo.getDepositPayable() != null, CrmOrder::getDepositPayable, bo.getDepositPayable());
lqw.eq(bo.getDepositPaid() != null, CrmOrder::getDepositPaid, bo.getDepositPaid());
lqw.eq(bo.getDepositRatio() != null, CrmOrder::getDepositRatio, bo.getDepositRatio());
lqw.eq(bo.getStatus() != null, CrmOrder::getStatus, bo.getStatus());
lqw.eq(bo.getContractId() != null, CrmOrder::getContractId, bo.getContractId());
lqw.like(StringUtils.isNotBlank(bo.getAnnexFiles()), CrmOrder::getAnnexFiles, bo.getAnnexFiles());
lqw.eq(bo.getIsTop() != null, CrmOrder::getIsTop, bo.getIsTop());
//逻辑删除
lqw.eq(CrmOrder::getDelFlag, 0);
//排序规则:
// 1. 置顶优先 (is_top=1 排在前面)
// 2. 状态为1(已生效)的排在前面
// 3. 创建时间倒序
lqw.last("ORDER BY is_top DESC, CASE WHEN status = 1 THEN 1 ELSE 0 END DESC, create_time DESC");
return lqw;
}

View File

@@ -23,6 +23,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="customizer" column="customizer"/>
<result property="shipper" column="shipper"/>
<result property="productionBatch" column="production_batch"/>
<result property="surfaceTreatment" column="surface_treatment"/>
<result property="surfaceQuality" column="surface_quality"/>
<result property="edgeCuttingReq" column="edge_cutting_req"/>
<result property="packagingReq" column="packaging_req"/>
<result property="width" column="width"/>
<result property="thickness" column="thickness"/>
<result property="purpose" column="purpose"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
@@ -50,6 +57,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
customizer,
shipper,
production_batch,
surface_treatment,
surface_quality,
edge_cutting_req,
packaging_req,
width,
thickness,
purpose,
create_by,
create_time,
update_by,

View File

@@ -20,6 +20,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="unpaidAmount" column="unpaid_amount"/>
<result property="remark" column="remark"/>
<result property="contractCode" column="contract_code"/>
<result property="contractName" column="contract_name"/>
<result property="supplier" column="supplier"/>
<result property="customer" column="customer"/>
<result property="signTime" column="sign_time"/>
<result property="signLocation" column="sign_location"/>
<result property="productContent" column="product_content"/>
<result property="contractContent" column="contract_content"/>
<result property="supplierAddress" column="supplier_address"/>
<result property="supplierPhone" column="supplier_phone"/>
<result property="supplierBank" column="supplier_bank"/>
<result property="supplierAccount" column="supplier_account"/>
<result property="supplierTaxNo" column="supplier_tax_no"/>
<result property="customerAddress" column="customer_address"/>
<result property="customerPhone" column="customer_phone"/>
<result property="customerBank" column="customer_bank"/>
<result property="customerAccount" column="customer_account"/>
<result property="customerTaxNo" column="customer_tax_no"/>
<result property="techAnnex" column="tech_annex"/>
<result property="businessAnnex" column="business_annex"/>
<result property="productionSchedule" column="production_schedule"/>
<result property="unitPriceRemark" column="unit_price_remark"/>
<result property="depositPayable" column="deposit_payable"/>
<result property="depositPaid" column="deposit_paid"/>
<result property="depositRatio" column="deposit_ratio"/>
<result property="status" column="status"/>
<result property="contractId" column="contract_id"/>
<result property="annexFiles" column="annex_files"/>
<result property="createBy" column="create_by"/>
@@ -27,6 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="isTop" column="is_top"/>
</resultMap>
<select id="selectVoPagePlus" resultType="com.klp.crm.domain.vo.CrmOrderVo">
SELECT
@@ -45,8 +71,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
co.unpaid_amount AS unpaidAmount,
co.remark,
co.contract_code AS contractCode,
co.contract_name AS contractName,
co.supplier,
co.customer,
co.sign_time AS signTime,
co.sign_location AS signLocation,
co.product_content AS productContent,
co.contract_content AS contractContent,
co.supplier_address AS supplierAddress,
co.supplier_phone AS supplierPhone,
co.supplier_bank AS supplierBank,
co.supplier_account AS supplierAccount,
co.supplier_tax_no AS supplierTaxNo,
co.customer_address AS customerAddress,
co.customer_phone AS customerPhone,
co.customer_bank AS customerBank,
co.customer_account AS customerAccount,
co.customer_tax_no AS customerTaxNo,
co.tech_annex AS techAnnex,
co.business_annex AS businessAnnex,
co.production_schedule AS productionSchedule,
co.unit_price_remark AS unitPriceRemark,
co.deposit_payable AS depositPayable,
co.deposit_paid AS depositPaid,
co.deposit_ratio AS depositRatio,
co.status,
co.contract_id AS contractId,
co.annex_files AS annexFiles,
co.is_top AS isTop,
co.create_by AS createBy,
co.create_time AS createTime,
co.update_by AS updateBy,
@@ -79,8 +131,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
co.unpaid_amount AS unpaidAmount,
co.remark,
co.contract_code AS contractCode,
co.contract_name AS contractName,
co.supplier,
co.customer,
co.sign_time AS signTime,
co.sign_location AS signLocation,
co.product_content AS productContent,
co.contract_content AS contractContent,
co.supplier_address AS supplierAddress,
co.supplier_phone AS supplierPhone,
co.supplier_bank AS supplierBank,
co.supplier_account AS supplierAccount,
co.supplier_tax_no AS supplierTaxNo,
co.customer_address AS customerAddress,
co.customer_phone AS customerPhone,
co.customer_bank AS customerBank,
co.customer_account AS customerAccount,
co.customer_tax_no AS customerTaxNo,
co.tech_annex AS techAnnex,
co.business_annex AS businessAnnex,
co.production_schedule AS productionSchedule,
co.unit_price_remark AS unitPriceRemark,
co.deposit_payable AS depositPayable,
co.deposit_paid AS depositPaid,
co.deposit_ratio AS depositRatio,
co.status,
co.contract_id AS contractId,
co.annex_files AS annexFiles,
co.is_top AS isTop,
co.create_by AS createBy,
co.create_time AS createTime,
co.update_by AS updateBy,

View File

@@ -0,0 +1,99 @@
package com.klp.ems.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.annotation.Log;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.domain.R;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.ems.domain.vo.EmsEnergyRecordVo;
import com.klp.ems.domain.bo.EmsEnergyRecordBo;
import com.klp.ems.service.IEmsEnergyRecordService;
import com.klp.common.core.page.TableDataInfo;
/**
* 能源消耗记录
*
* @author klp
* @date 2026-04-20
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/ems/energyRecord")
public class EmsEnergyRecordController extends BaseController {
private final IEmsEnergyRecordService iEmsEnergyRecordService;
/**
* 查询能源消耗记录列表
*/
@GetMapping("/list")
public TableDataInfo<EmsEnergyRecordVo> list(EmsEnergyRecordBo bo, PageQuery pageQuery) {
return iEmsEnergyRecordService.queryPageList(bo, pageQuery);
}
/**
* 导出能源消耗记录列表
*/
@Log(title = "能源消耗记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(EmsEnergyRecordBo bo, HttpServletResponse response) {
List<EmsEnergyRecordVo> list = iEmsEnergyRecordService.queryList(bo);
ExcelUtil.exportExcel(list, "能源消耗记录", EmsEnergyRecordVo.class, response);
}
/**
* 获取能源消耗记录详细信息
*
* @param energyRecordId 主键
*/
@GetMapping("/{energyRecordId}")
public R<EmsEnergyRecordVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long energyRecordId) {
return R.ok(iEmsEnergyRecordService.queryById(energyRecordId));
}
/**
* 新增能源消耗记录
*/
@Log(title = "能源消耗记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Long> add(@Validated(AddGroup.class) @RequestBody EmsEnergyRecordBo bo) {
return R.ok(iEmsEnergyRecordService.insertByBo(bo));
}
/**
* 修改能源消耗记录
*/
@Log(title = "能源消耗记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody EmsEnergyRecordBo bo) {
return toAjax(iEmsEnergyRecordService.updateByBo(bo));
}
/**
* 删除能源消耗记录
*
* @param energyRecordIds 主键串
*/
@Log(title = "能源消耗记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{energyRecordIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] energyRecordIds) {
return toAjax(iEmsEnergyRecordService.deleteWithValidByIds(Arrays.asList(energyRecordIds), true));
}
}

View File

@@ -0,0 +1,60 @@
package com.klp.ems.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 能源消耗记录对象 ems_energy_record
*
* @author klp
* @date 2026-04-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("ems_energy_record")
public class EmsEnergyRecord extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 能耗记录主键ID
*/
@TableId(value = "energy_record_id")
private Long energyRecordId;
/**
* 表计ID关联计量设备表
*/
private Long meterId;
/**
* 能源ID关联能源类型表电/水/气/暖等)
*/
private Long energyId;
/**
* 消耗量
*/
private BigDecimal consumption;
/**
* 统计日期yyyy-MM-dd
*/
private Date recordDate;
/**
* 记录人ID
*/
private Long recordedBy;
/**
* 删除标志0=存在 2=删除)
*/
@TableLogic
private String delFlag;
/**
* 备注
*/
private String remark;
}

View File

@@ -72,5 +72,13 @@ public class EmsMeter extends BaseEntity {
* 备注
*/
private String remark;
/**
* 产线S1、S2、组装线、包装线等
*/
private String productionLine;
/**
* 是否总表0=否1=是
*/
private Integer isTotalMeter;
}

View File

@@ -0,0 +1,99 @@
package com.klp.ems.domain.bo;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 能源消耗记录业务对象 ems_energy_record
*
* @author klp
* @date 2026-04-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class EmsEnergyRecordBo extends BaseEntity {
/**
* 能耗记录主键ID
*/
private Long energyRecordId;
/**
* 表计ID关联计量设备表
*/
private Long meterId;
/**
* 能源ID关联能源类型表电/水/气/暖等)
*/
private Long energyId;
/**
* 消耗量
*/
private BigDecimal consumption;
/**
* 统计日期yyyy-MM-dd
*/
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date recordDate;
/**
* 统计日期开始时间yyyy-MM-dd不含时分秒
*/
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date recordStartDate;
/**
* 统计日期结束时间yyyy-MM-dd不含时分秒
*/
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date recordEndDate;
/**
* 记录人ID
*/
private Long recordedBy;
/**
* 备注
*/
private String remark;
/**
* 表计编号(模糊查询)
*/
private String meterCode;
/**
* 能源名称(模糊查询)
*/
private String energyName;
/**
* 设备型号(模糊查询)
*/
private String model;
/**
* 制造商(模糊查询)
*/
private String manufacturer;
/**
* 设备状态0=在用,1=停用,2=维护
*/
private Integer meterStatus;
}

View File

@@ -75,5 +75,15 @@ public class EmsMeterBo extends BaseEntity {
*/
private String remark;
/**
* 产线S1、S2、组装线、包装线等
*/
private String productionLine;
/**
* 是否总表0=否1=是
*/
private Integer isTotalMeter;
}

View File

@@ -0,0 +1,114 @@
package com.klp.ems.domain.vo;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.klp.common.annotation.ExcelDictFormat;
import com.klp.common.convert.ExcelDictConvert;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 能源消耗记录视图对象 ems_energy_record
*
* @author klp
* @date 2026-04-20
*/
@Data
@ExcelIgnoreUnannotated
public class EmsEnergyRecordVo {
private static final long serialVersionUID = 1L;
/**
* 能耗记录主键ID
*/
@ExcelProperty(value = "能耗记录主键ID")
private Long energyRecordId;
/**
* 表计ID关联计量设备表
*/
@ExcelProperty(value = "表计ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联计量设备表")
private Long meterId;
/**
* 能源ID关联能源类型表电/水/气/暖等)
*/
@ExcelProperty(value = "能源ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联能源类型表:电/水/气/暖等")
private Long energyId;
/**
* 消耗量
*/
@ExcelProperty(value = "消耗量")
private BigDecimal consumption;
/**
* 统计日期yyyy-MM-dd
*/
@ExcelProperty(value = "统计日期", converter = ExcelDictConvert.class)
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date recordDate;
/**
* 记录人ID
*/
@ExcelProperty(value = "记录人ID")
private Long recordedBy;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 表计编号
*/
private String meterCode;
/**
* 设备型号
*/
private String meterModel;
/**
* 制造商
*/
private String meterManufacturer;
/**
* 设备状态0=在用,1=停用,2=维护
*/
private Integer meterStatus;
/**
* 能源名称
*/
private String energyName;
/**
* 能源单位
*/
private String energyUnit;
/**
* 能源编号
*/
private String energyCode;
/**
* 能源描述
*/
private String energyDescription;
}

View File

@@ -89,6 +89,18 @@ public class EmsMeterVo {
@ExcelProperty(value = "备注")
private String remark;
/**
* 产线S1、S2、组装线、包装线等
*/
@ExcelProperty(value = "产线")
private String productionLine;
/**
* 是否总表0=否1=是
*/
@ExcelProperty(value = "是否总表")
private Integer isTotalMeter;
/**
* 库区ID
*/

View File

@@ -0,0 +1,19 @@
package com.klp.ems.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.ems.domain.EmsEnergyRecord;
import com.klp.ems.domain.vo.EmsEnergyRecordVo;
import com.klp.common.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Param;
/**
* 能源消耗记录Mapper接口
*
* @author klp
* @date 2026-04-20
*/
public interface EmsEnergyRecordMapper extends BaseMapperPlus<EmsEnergyRecordMapper, EmsEnergyRecord, EmsEnergyRecordVo> {
Page<EmsEnergyRecordVo> selectVoPagePlus(Page<Object> build,@Param("ew") QueryWrapper<EmsEnergyRecord> qw);
}

View File

@@ -0,0 +1,49 @@
package com.klp.ems.service;
import com.klp.ems.domain.EmsEnergyRecord;
import com.klp.ems.domain.vo.EmsEnergyRecordVo;
import com.klp.ems.domain.bo.EmsEnergyRecordBo;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 能源消耗记录Service接口
*
* @author klp
* @date 2026-04-20
*/
public interface IEmsEnergyRecordService {
/**
* 查询能源消耗记录
*/
EmsEnergyRecordVo queryById(Long energyRecordId);
/**
* 查询能源消耗记录列表
*/
TableDataInfo<EmsEnergyRecordVo> queryPageList(EmsEnergyRecordBo bo, PageQuery pageQuery);
/**
* 查询能源消耗记录列表
*/
List<EmsEnergyRecordVo> queryList(EmsEnergyRecordBo bo);
/**
* 新增能源消耗记录
*/
Long insertByBo(EmsEnergyRecordBo bo);
/**
* 修改能源消耗记录
*/
Boolean updateByBo(EmsEnergyRecordBo bo);
/**
* 校验并批量删除能源消耗记录信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,139 @@
package com.klp.ems.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.klp.ems.domain.bo.EmsEnergyRecordBo;
import com.klp.ems.domain.vo.EmsEnergyRecordVo;
import com.klp.ems.domain.EmsEnergyRecord;
import com.klp.ems.mapper.EmsEnergyRecordMapper;
import com.klp.ems.service.IEmsEnergyRecordService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 能源消耗记录Service业务层处理
*
* @author klp
* @date 2026-04-20
*/
@RequiredArgsConstructor
@Service
public class EmsEnergyRecordServiceImpl implements IEmsEnergyRecordService {
private final EmsEnergyRecordMapper baseMapper;
/**
* 查询能源消耗记录
*/
@Override
public EmsEnergyRecordVo queryById(Long energyRecordId){
return baseMapper.selectVoById(energyRecordId);
}
/**
* 查询能源消耗记录列表
*/
@Override
public TableDataInfo<EmsEnergyRecordVo> queryPageList(EmsEnergyRecordBo bo, PageQuery pageQuery) {
QueryWrapper<EmsEnergyRecord> qw = buildQueryWrapperPlus(bo);
Page<EmsEnergyRecordVo> result = baseMapper.selectVoPagePlus(pageQuery.build(), qw);
return TableDataInfo.build(result);
}
private QueryWrapper<EmsEnergyRecord> buildQueryWrapperPlus(EmsEnergyRecordBo bo) {
QueryWrapper<EmsEnergyRecord> qw = Wrappers.query();
// 主表字段查询(使用别名 er
qw.eq(bo.getMeterId() != null, "er.meter_id", bo.getMeterId());
qw.eq(bo.getEnergyId() != null, "er.energy_id", bo.getEnergyId());
qw.eq(bo.getConsumption() != null, "er.consumption", bo.getConsumption());
qw.eq(bo.getRecordDate() != null, "er.record_date", bo.getRecordDate());
qw.eq(bo.getRecordedBy() != null, "er.recorded_by", bo.getRecordedBy());
// 时间段筛选recordStartDate <= recordDate <= recordEndDate
qw.ge(bo.getRecordStartDate() != null, "er.record_date", bo.getRecordStartDate());
qw.le(bo.getRecordEndDate() != null, "er.record_date", bo.getRecordEndDate());
// 逻辑删除
qw.eq("er.del_flag", "0");
// 默认排序:按统计日期倒序
qw.orderByDesc("er.record_date");
return qw;
}
/**
* 查询能源消耗记录列表
*/
@Override
public List<EmsEnergyRecordVo> queryList(EmsEnergyRecordBo bo) {
LambdaQueryWrapper<EmsEnergyRecord> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<EmsEnergyRecord> buildQueryWrapper(EmsEnergyRecordBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<EmsEnergyRecord> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getMeterId() != null, EmsEnergyRecord::getMeterId, bo.getMeterId());
lqw.eq(bo.getEnergyId() != null, EmsEnergyRecord::getEnergyId, bo.getEnergyId());
lqw.eq(bo.getConsumption() != null, EmsEnergyRecord::getConsumption, bo.getConsumption());
lqw.eq(bo.getRecordDate() != null, EmsEnergyRecord::getRecordDate, bo.getRecordDate());
// 时间段筛选recordDateStart <= recordDate <= recordDateEnd
lqw.ge(bo.getRecordStartDate() != null, EmsEnergyRecord::getRecordDate, bo.getRecordStartDate());
lqw.le(bo.getRecordEndDate() != null, EmsEnergyRecord::getRecordDate, bo.getRecordEndDate());
lqw.eq(bo.getRecordedBy() != null, EmsEnergyRecord::getRecordedBy, bo.getRecordedBy());
return lqw;
}
/**
* 新增能源消耗记录
*/
@Override
public Long insertByBo(EmsEnergyRecordBo bo) {
EmsEnergyRecord add = BeanUtil.toBean(bo, EmsEnergyRecord.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setEnergyRecordId(add.getEnergyRecordId());
}
return add.getEnergyRecordId();
}
/**
* 修改能源消耗记录
*/
@Override
public Boolean updateByBo(EmsEnergyRecordBo bo) {
EmsEnergyRecord update = BeanUtil.toBean(bo, EmsEnergyRecord.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(EmsEnergyRecord entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除能源消耗记录
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -93,6 +93,8 @@ public class EmsMeterServiceImpl implements IEmsMeterService {
lqw.eq(bo.getStatus() != null, EmsMeter::getStatus, bo.getStatus());
lqw.eq(bo.getLastCalibrationDate() != null, EmsMeter::getLastCalibrationDate, bo.getLastCalibrationDate());
lqw.eq(bo.getThresholdValue() != null, EmsMeter::getThresholdValue, bo.getThresholdValue());
lqw.like(StringUtils.isNotBlank(bo.getProductionLine()), EmsMeter::getProductionLine, bo.getProductionLine());
lqw.eq(bo.getIsTotalMeter() != null, EmsMeter::getIsTotalMeter, bo.getIsTotalMeter());
return lqw;
}

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.klp.ems.mapper.EmsEnergyRecordMapper">
<resultMap type="com.klp.ems.domain.EmsEnergyRecord" id="EmsEnergyRecordResult">
<result property="energyRecordId" column="energy_record_id"/>
<result property="meterId" column="meter_id"/>
<result property="energyId" column="energy_id"/>
<result property="consumption" column="consumption"/>
<result property="recordDate" column="record_date"/>
<result property="recordedBy" column="recorded_by"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="remark" column="remark"/>
</resultMap>
<select id="selectVoPagePlus" resultType="com.klp.ems.domain.vo.EmsEnergyRecordVo">
SELECT
er.energy_record_id,
er.meter_id,
er.energy_id,
er.consumption,
er.record_date,
er.recorded_by,
er.remark,
m.meter_code AS meterCode,
m.model AS meterModel,
m.manufacturer AS meterManufacturer,
m.status AS meterStatus,
et.name AS energyName,
et.unit AS energyUnit,
et.code AS energyCode,
et.description AS energyDescription
FROM ems_energy_record er
LEFT JOIN ems_meter m ON er.meter_id = m.meter_id AND m.del_flag = '0'
LEFT JOIN ems_energy_type et ON er.energy_id = et.energy_type_id AND et.del_flag = '0'
${ew.customSqlSegment}
</select>
</mapper>

View File

@@ -21,6 +21,8 @@
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="remark" column="remark"/>
<result property="productionLine" column="production_line"/>
<result property="isTotalMeter" column="is_total_meter"/>
</resultMap>
<resultMap type="com.klp.ems.domain.vo.EmsMeterVo" id="EmsMeterVoResult">
@@ -35,6 +37,8 @@
<result property="lastCalibrationDate" column="last_calibration_date"/>
<result property="thresholdValue" column="threshold_value"/>
<result property="remark" column="remark"/>
<result property="productionLine" column="production_line"/>
<result property="isTotalMeter" column="is_total_meter"/>
<result property="warehouseId" column="warehouse_id"/>
<result property="warehouseName" column="warehouse_name"/>
</resultMap>
@@ -77,6 +81,8 @@
m.last_calibration_date,
m.threshold_value,
m.remark,
m.production_line,
m.is_total_meter,
COALESCE(w.warehouse_id, 0) as warehouse_id,
COALESCE(w.warehouse_name, '') as warehouse_name
FROM ems_meter m
@@ -95,6 +101,12 @@
<if test="status != null">
AND m.status = #{status}
</if>
<if test="productionLine != null and productionLine != ''">
AND m.production_line LIKE CONCAT('%', #{productionLine}, '%')
</if>
<if test="isTotalMeter != null">
AND m.is_total_meter = #{isTotalMeter}
</if>
</select>
<select id="selectMeterIds" parameterType="com.klp.ems.domain.bo.MeterFilterBo" resultType="java.lang.Long">

View File

@@ -76,4 +76,80 @@ public class ErpPurchaseOrder extends BaseEntity {
*/
private String remark;
/**
* 单据类型
*/
private String billType;
/**
* 收发类别
*/
private String receiveType;
/**
* 部门
*/
private String deptName;
/**
* 业务员
*/
private String salesman;
/**
* 供货单位ID
*/
private Long supplyUnitId;
/**
* 制单人
*/
private String maker;
/**
* 审核人
*/
private String auditor;
/**
* 记账人
*/
private String bookkeeper;
/**
* 审核日期
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date auditDate;
/**
* 存货编码
*/
private String stockCode;
/**
* 存货名称
*/
private String stockName;
/**
* 规格型号
*/
private String specModel;
/**
* 主计量单位
*/
private String mainUnit;
/**
* 入库数量
*/
private String stockQuantity;
/**
* 仓库ID
*/
private Long warehouseId;
}

View File

@@ -83,5 +83,80 @@ public class ErpPurchaseOrderBo extends BaseEntity {
*/
private String remark;
/**
* 单据类型
*/
private String billType;
/**
* 收发类别
*/
private String receiveType;
/**
* 部门
*/
private String deptName;
/**
* 业务员
*/
private String salesman;
/**
* 供货单位ID
*/
private Long supplyUnitId;
/**
* 制单人
*/
private String maker;
/**
* 审核人
*/
private String auditor;
/**
* 记账人
*/
private String bookkeeper;
/**
* 审核日期
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date auditDate;
/**
* 存货编码
*/
private String stockCode;
/**
* 存货名称
*/
private String stockName;
/**
* 规格型号
*/
private String specModel;
/**
* 主计量单位
*/
private String mainUnit;
/**
* 入库数量
*/
private String stockQuantity;
/**
* 仓库ID
*/
private Long warehouseId;
}

View File

@@ -90,5 +90,95 @@ public class ErpPurchaseOrderVo implements Serializable {
@ExcelProperty(value = "备注")
private String remark;
/**
* 单据类型
*/
@ExcelProperty(value = "单据类型")
private String billType;
/**
* 收发类别
*/
@ExcelProperty(value = "收发类别")
private String receiveType;
/**
* 部门
*/
@ExcelProperty(value = "部门")
private String deptName;
/**
* 业务员
*/
@ExcelProperty(value = "业务员")
private String salesman;
/**
* 供货单位ID
*/
@ExcelProperty(value = "供货单位ID")
private Long supplyUnitId;
/**
* 制单人
*/
@ExcelProperty(value = "制单人")
private String maker;
/**
* 审核人
*/
@ExcelProperty(value = "审核人")
private String auditor;
/**
* 记账人
*/
@ExcelProperty(value = "记账人")
private String bookkeeper;
/**
* 审核日期
*/
@JsonFormat(pattern = "yyyy-MM-dd")
@ExcelProperty(value = "审核日期")
private Date auditDate;
/**
* 存货编码
*/
@ExcelProperty(value = "存货编码")
private String stockCode;
/**
* 存货名称
*/
@ExcelProperty(value = "存货名称")
private String stockName;
/**
* 规格型号
*/
@ExcelProperty(value = "规格型号")
private String specModel;
/**
* 主计量单位
*/
@ExcelProperty(value = "主计量单位")
private String mainUnit;
/**
* 入库数量
*/
@ExcelProperty(value = "入库数量")
private String stockQuantity;
/**
* 仓库ID
*/
@ExcelProperty(value = "仓库ID")
private Long warehouseId;
}

View File

@@ -78,6 +78,21 @@ public class ErpPurchaseOrderServiceImpl implements IErpPurchaseOrderService {
lqw.eq(bo.getTotalAmount() != null, ErpPurchaseOrder::getTotalAmount, bo.getTotalAmount());
lqw.eq(bo.getOrderStatus() != null, ErpPurchaseOrder::getOrderStatus, bo.getOrderStatus());
lqw.like(StringUtils.isNotBlank(bo.getConfirmBy()), ErpPurchaseOrder::getConfirmBy, bo.getConfirmBy());
lqw.eq(StringUtils.isNotBlank(bo.getBillType()), ErpPurchaseOrder::getBillType, bo.getBillType());
lqw.eq(StringUtils.isNotBlank(bo.getReceiveType()), ErpPurchaseOrder::getReceiveType, bo.getReceiveType());
lqw.like(StringUtils.isNotBlank(bo.getDeptName()), ErpPurchaseOrder::getDeptName, bo.getDeptName());
lqw.like(StringUtils.isNotBlank(bo.getSalesman()), ErpPurchaseOrder::getSalesman, bo.getSalesman());
lqw.eq(bo.getSupplyUnitId() != null, ErpPurchaseOrder::getSupplyUnitId, bo.getSupplyUnitId());
lqw.like(StringUtils.isNotBlank(bo.getMaker()), ErpPurchaseOrder::getMaker, bo.getMaker());
lqw.like(StringUtils.isNotBlank(bo.getAuditor()), ErpPurchaseOrder::getAuditor, bo.getAuditor());
lqw.like(StringUtils.isNotBlank(bo.getBookkeeper()), ErpPurchaseOrder::getBookkeeper, bo.getBookkeeper());
lqw.eq(bo.getAuditDate() != null, ErpPurchaseOrder::getAuditDate, bo.getAuditDate());
lqw.like(StringUtils.isNotBlank(bo.getStockCode()), ErpPurchaseOrder::getStockCode, bo.getStockCode());
lqw.like(StringUtils.isNotBlank(bo.getStockName()), ErpPurchaseOrder::getStockName, bo.getStockName());
lqw.like(StringUtils.isNotBlank(bo.getSpecModel()), ErpPurchaseOrder::getSpecModel, bo.getSpecModel());
lqw.eq(StringUtils.isNotBlank(bo.getMainUnit()), ErpPurchaseOrder::getMainUnit, bo.getMainUnit());
lqw.eq(StringUtils.isNotBlank(bo.getStockQuantity()), ErpPurchaseOrder::getStockQuantity, bo.getStockQuantity());
lqw.eq(bo.getWarehouseId() != null, ErpPurchaseOrder::getWarehouseId, bo.getWarehouseId());
return lqw;
}

View File

@@ -21,6 +21,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="remark" column="remark"/>
<result property="billType" column="bill_type"/>
<result property="receiveType" column="receive_type"/>
<result property="deptName" column="dept_name"/>
<result property="salesman" column="salesman"/>
<result property="supplyUnitId" column="supply_unit_id"/>
<result property="maker" column="maker"/>
<result property="auditor" column="auditor"/>
<result property="bookkeeper" column="bookkeeper"/>
<result property="auditDate" column="audit_date"/>
<result property="stockCode" column="stock_code"/>
<result property="stockName" column="stock_name"/>
<result property="specModel" column="spec_model"/>
<result property="mainUnit" column="main_unit"/>
<result property="stockQuantity" column="stock_quantity"/>
<result property="warehouseId" column="warehouse_id"/>
</resultMap>

View File

@@ -3,7 +3,7 @@ gen:
# 作者
author: klp
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
packageName: com.klp.system
packageName: com.klp
# 自动去除表前缀默认是false
autoRemovePre: false
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)

View File

@@ -0,0 +1,99 @@
package com.klp.mes.eqp.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.annotation.Log;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.domain.R;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryConsumeVo;
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryConsumeBo;
import com.klp.mes.eqp.service.IEqpAuxiliaryConsumeService;
import com.klp.common.core.page.TableDataInfo;
/**
* 公辅消耗记录
*
* @author klp
* @date 2026-04-29
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/eqp/auxiliaryConsume")
public class EqpAuxiliaryConsumeController extends BaseController {
private final IEqpAuxiliaryConsumeService iEqpAuxiliaryConsumeService;
/**
* 查询公辅消耗记录列表
*/
@GetMapping("/list")
public TableDataInfo<EqpAuxiliaryConsumeVo> list(EqpAuxiliaryConsumeBo bo, PageQuery pageQuery) {
return iEqpAuxiliaryConsumeService.queryPageList(bo, pageQuery);
}
/**
* 导出公辅消耗记录列表
*/
@Log(title = "公辅消耗记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(EqpAuxiliaryConsumeBo bo, HttpServletResponse response) {
List<EqpAuxiliaryConsumeVo> list = iEqpAuxiliaryConsumeService.queryList(bo);
ExcelUtil.exportExcel(list, "公辅消耗记录", EqpAuxiliaryConsumeVo.class, response);
}
/**
* 获取公辅消耗记录详细信息
*
* @param consumeId 主键
*/
@GetMapping("/{consumeId}")
public R<EqpAuxiliaryConsumeVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long consumeId) {
return R.ok(iEqpAuxiliaryConsumeService.queryById(consumeId));
}
/**
* 新增公辅消耗记录
*/
@Log(title = "公辅消耗记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Long> add(@Validated(AddGroup.class) @RequestBody EqpAuxiliaryConsumeBo bo) {
return R.ok(iEqpAuxiliaryConsumeService.insertByBo(bo));
}
/**
* 修改公辅消耗记录
*/
@Log(title = "公辅消耗记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody EqpAuxiliaryConsumeBo bo) {
return toAjax(iEqpAuxiliaryConsumeService.updateByBo(bo));
}
/**
* 删除公辅消耗记录
*
* @param consumeIds 主键串
*/
@Log(title = "公辅消耗记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{consumeIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] consumeIds) {
return toAjax(iEqpAuxiliaryConsumeService.deleteWithValidByIds(Arrays.asList(consumeIds), true));
}
}

View File

@@ -0,0 +1,99 @@
package com.klp.mes.eqp.controller;
import java.util.List;
import java.util.Arrays;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.annotation.Log;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.domain.R;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryTypeVo;
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryTypeBo;
import com.klp.mes.eqp.service.IEqpAuxiliaryTypeService;
import com.klp.common.core.page.TableDataInfo;
/**
* 公辅类型
*
* @author klp
* @date 2026-04-29
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/eqp/auxiliaryType")
public class EqpAuxiliaryTypeController extends BaseController {
private final IEqpAuxiliaryTypeService iEqpAuxiliaryTypeService;
/**
* 查询公辅类型列表
*/
@GetMapping("/list")
public TableDataInfo<EqpAuxiliaryTypeVo> list(EqpAuxiliaryTypeBo bo, PageQuery pageQuery) {
return iEqpAuxiliaryTypeService.queryPageList(bo, pageQuery);
}
/**
* 导出公辅类型列表
*/
@Log(title = "公辅类型", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(EqpAuxiliaryTypeBo bo, HttpServletResponse response) {
List<EqpAuxiliaryTypeVo> list = iEqpAuxiliaryTypeService.queryList(bo);
ExcelUtil.exportExcel(list, "公辅类型", EqpAuxiliaryTypeVo.class, response);
}
/**
* 获取公辅类型详细信息
*
* @param typeId 主键
*/
@GetMapping("/{typeId}")
public R<EqpAuxiliaryTypeVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long typeId) {
return R.ok(iEqpAuxiliaryTypeService.queryById(typeId));
}
/**
* 新增公辅类型
*/
@Log(title = "公辅类型", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody EqpAuxiliaryTypeBo bo) {
return toAjax(iEqpAuxiliaryTypeService.insertByBo(bo));
}
/**
* 修改公辅类型
*/
@Log(title = "公辅类型", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody EqpAuxiliaryTypeBo bo) {
return toAjax(iEqpAuxiliaryTypeService.updateByBo(bo));
}
/**
* 删除公辅类型
*
* @param typeIds 主键串
*/
@Log(title = "公辅类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{typeIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] typeIds) {
return toAjax(iEqpAuxiliaryTypeService.deleteWithValidByIds(Arrays.asList(typeIds), true));
}
}

View File

@@ -0,0 +1,52 @@
package com.klp.mes.eqp.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 公辅消耗记录对象 eqp_auxiliary_consume
*
* @author klp
* @date 2026-04-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("eqp_auxiliary_consume")
public class EqpAuxiliaryConsume extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 消耗记录ID
*/
@TableId(value = "consume_id")
private Long consumeId;
/**
* 记录日期
*/
private Date recordDate;
/**
* 公辅类型ID关联ems_auxiliary_type
*/
private Long typeId;
/**
* 消耗量
*/
private BigDecimal consume;
/**
* 删除标志0=存在 2=删除)
*/
@TableLogic
private String delFlag;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,45 @@
package com.klp.mes.eqp.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 公辅类型对象 eqp_auxiliary_type
*
* @author klp
* @date 2026-04-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("eqp_auxiliary_type")
public class EqpAuxiliaryType extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 公辅类型ID
*/
@TableId(value = "type_id")
private Long typeId;
/**
* 公辅类型名称
*/
private String typeName;
/**
* 产线名称
*/
private String lineName;
/**
* 删除标志0=存在 2=删除)
*/
@TableLogic
private String delFlag;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,52 @@
package com.klp.mes.eqp.domain.bo;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 公辅消耗记录业务对象 eqp_auxiliary_consume
*
* @author klp
* @date 2026-04-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class EqpAuxiliaryConsumeBo extends BaseEntity {
/**
* 消耗记录ID
*/
private Long consumeId;
/**
* 记录日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date recordDate;
/**
* 公辅类型ID关联ems_auxiliary_type
*/
private Long typeId;
/**
* 消耗量
*/
private BigDecimal consume;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,41 @@
package com.klp.mes.eqp.domain.bo;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
/**
* 公辅类型业务对象 eqp_auxiliary_type
*
* @author klp
* @date 2026-04-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class EqpAuxiliaryTypeBo extends BaseEntity {
/**
* 公辅类型ID
*/
private Long typeId;
/**
* 公辅类型名称
*/
private String typeName;
/**
* 产线名称
*/
private String lineName;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,57 @@
package com.klp.mes.eqp.domain.vo;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.klp.common.annotation.ExcelDictFormat;
import com.klp.common.convert.ExcelDictConvert;
import lombok.Data;
/**
* 公辅消耗记录视图对象 eqp_auxiliary_consume
*
* @author klp
* @date 2026-04-29
*/
@Data
@ExcelIgnoreUnannotated
public class EqpAuxiliaryConsumeVo {
private static final long serialVersionUID = 1L;
/**
* 消耗记录ID
*/
@ExcelProperty(value = "消耗记录ID")
private Long consumeId;
/**
* 记录日期
*/
@ExcelProperty(value = "记录日期")
private Date recordDate;
/**
* 公辅类型ID关联ems_auxiliary_type
*/
@ExcelProperty(value = "公辅类型ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联ems_auxiliary_type")
private Long typeId;
/**
* 消耗量
*/
@ExcelProperty(value = "消耗量")
private BigDecimal consume;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,47 @@
package com.klp.mes.eqp.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.klp.common.annotation.ExcelDictFormat;
import com.klp.common.convert.ExcelDictConvert;
import lombok.Data;
/**
* 公辅类型视图对象 eqp_auxiliary_type
*
* @author klp
* @date 2026-04-29
*/
@Data
@ExcelIgnoreUnannotated
public class EqpAuxiliaryTypeVo {
private static final long serialVersionUID = 1L;
/**
* 公辅类型ID
*/
@ExcelProperty(value = "公辅类型ID")
private Long typeId;
/**
* 公辅类型名称
*/
@ExcelProperty(value = "公辅类型名称")
private String typeName;
/**
* 产线名称
*/
@ExcelProperty(value = "产线名称")
private String lineName;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,15 @@
package com.klp.mes.eqp.mapper;
import com.klp.mes.eqp.domain.EqpAuxiliaryConsume;
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryConsumeVo;
import com.klp.common.core.mapper.BaseMapperPlus;
/**
* 公辅消耗记录Mapper接口
*
* @author klp
* @date 2026-04-29
*/
public interface EqpAuxiliaryConsumeMapper extends BaseMapperPlus<EqpAuxiliaryConsumeMapper, EqpAuxiliaryConsume, EqpAuxiliaryConsumeVo> {
}

View File

@@ -0,0 +1,15 @@
package com.klp.mes.eqp.mapper;
import com.klp.mes.eqp.domain.EqpAuxiliaryType;
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryTypeVo;
import com.klp.common.core.mapper.BaseMapperPlus;
/**
* 公辅类型Mapper接口
*
* @author klp
* @date 2026-04-29
*/
public interface EqpAuxiliaryTypeMapper extends BaseMapperPlus<EqpAuxiliaryTypeMapper, EqpAuxiliaryType, EqpAuxiliaryTypeVo> {
}

View File

@@ -0,0 +1,49 @@
package com.klp.mes.eqp.service;
import com.klp.mes.eqp.domain.EqpAuxiliaryConsume;
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryConsumeVo;
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryConsumeBo;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 公辅消耗记录Service接口
*
* @author klp
* @date 2026-04-29
*/
public interface IEqpAuxiliaryConsumeService {
/**
* 查询公辅消耗记录
*/
EqpAuxiliaryConsumeVo queryById(Long consumeId);
/**
* 查询公辅消耗记录列表
*/
TableDataInfo<EqpAuxiliaryConsumeVo> queryPageList(EqpAuxiliaryConsumeBo bo, PageQuery pageQuery);
/**
* 查询公辅消耗记录列表
*/
List<EqpAuxiliaryConsumeVo> queryList(EqpAuxiliaryConsumeBo bo);
/**
* 新增公辅消耗记录
*/
Long insertByBo(EqpAuxiliaryConsumeBo bo);
/**
* 修改公辅消耗记录
*/
Boolean updateByBo(EqpAuxiliaryConsumeBo bo);
/**
* 校验并批量删除公辅消耗记录信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,49 @@
package com.klp.mes.eqp.service;
import com.klp.mes.eqp.domain.EqpAuxiliaryType;
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryTypeVo;
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryTypeBo;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 公辅类型Service接口
*
* @author klp
* @date 2026-04-29
*/
public interface IEqpAuxiliaryTypeService {
/**
* 查询公辅类型
*/
EqpAuxiliaryTypeVo queryById(Long typeId);
/**
* 查询公辅类型列表
*/
TableDataInfo<EqpAuxiliaryTypeVo> queryPageList(EqpAuxiliaryTypeBo bo, PageQuery pageQuery);
/**
* 查询公辅类型列表
*/
List<EqpAuxiliaryTypeVo> queryList(EqpAuxiliaryTypeBo bo);
/**
* 新增公辅类型
*/
Boolean insertByBo(EqpAuxiliaryTypeBo bo);
/**
* 修改公辅类型
*/
Boolean updateByBo(EqpAuxiliaryTypeBo bo);
/**
* 校验并批量删除公辅类型信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,110 @@
package com.klp.mes.eqp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryConsumeBo;
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryConsumeVo;
import com.klp.mes.eqp.domain.EqpAuxiliaryConsume;
import com.klp.mes.eqp.mapper.EqpAuxiliaryConsumeMapper;
import com.klp.mes.eqp.service.IEqpAuxiliaryConsumeService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 公辅消耗记录Service业务层处理
*
* @author klp
* @date 2026-04-29
*/
@RequiredArgsConstructor
@Service
public class EqpAuxiliaryConsumeServiceImpl implements IEqpAuxiliaryConsumeService {
private final EqpAuxiliaryConsumeMapper baseMapper;
/**
* 查询公辅消耗记录
*/
@Override
public EqpAuxiliaryConsumeVo queryById(Long consumeId){
return baseMapper.selectVoById(consumeId);
}
/**
* 查询公辅消耗记录列表
*/
@Override
public TableDataInfo<EqpAuxiliaryConsumeVo> queryPageList(EqpAuxiliaryConsumeBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<EqpAuxiliaryConsume> lqw = buildQueryWrapper(bo);
Page<EqpAuxiliaryConsumeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询公辅消耗记录列表
*/
@Override
public List<EqpAuxiliaryConsumeVo> queryList(EqpAuxiliaryConsumeBo bo) {
LambdaQueryWrapper<EqpAuxiliaryConsume> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<EqpAuxiliaryConsume> buildQueryWrapper(EqpAuxiliaryConsumeBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<EqpAuxiliaryConsume> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getRecordDate() != null, EqpAuxiliaryConsume::getRecordDate, bo.getRecordDate());
lqw.eq(bo.getTypeId() != null, EqpAuxiliaryConsume::getTypeId, bo.getTypeId());
lqw.eq(bo.getConsume() != null, EqpAuxiliaryConsume::getConsume, bo.getConsume());
return lqw;
}
/**
* 新增公辅消耗记录
*/
@Override
public Long insertByBo(EqpAuxiliaryConsumeBo bo) {
EqpAuxiliaryConsume add = BeanUtil.toBean(bo, EqpAuxiliaryConsume.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setConsumeId(add.getConsumeId());
}
return add.getConsumeId();
}
/**
* 修改公辅消耗记录
*/
@Override
public Boolean updateByBo(EqpAuxiliaryConsumeBo bo) {
EqpAuxiliaryConsume update = BeanUtil.toBean(bo, EqpAuxiliaryConsume.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(EqpAuxiliaryConsume entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除公辅消耗记录
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,110 @@
package com.klp.mes.eqp.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.klp.common.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryTypeBo;
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryTypeVo;
import com.klp.mes.eqp.domain.EqpAuxiliaryType;
import com.klp.mes.eqp.mapper.EqpAuxiliaryTypeMapper;
import com.klp.mes.eqp.service.IEqpAuxiliaryTypeService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 公辅类型Service业务层处理
*
* @author klp
* @date 2026-04-29
*/
@RequiredArgsConstructor
@Service
public class EqpAuxiliaryTypeServiceImpl implements IEqpAuxiliaryTypeService {
private final EqpAuxiliaryTypeMapper baseMapper;
/**
* 查询公辅类型
*/
@Override
public EqpAuxiliaryTypeVo queryById(Long typeId){
return baseMapper.selectVoById(typeId);
}
/**
* 查询公辅类型列表
*/
@Override
public TableDataInfo<EqpAuxiliaryTypeVo> queryPageList(EqpAuxiliaryTypeBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<EqpAuxiliaryType> lqw = buildQueryWrapper(bo);
Page<EqpAuxiliaryTypeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询公辅类型列表
*/
@Override
public List<EqpAuxiliaryTypeVo> queryList(EqpAuxiliaryTypeBo bo) {
LambdaQueryWrapper<EqpAuxiliaryType> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<EqpAuxiliaryType> buildQueryWrapper(EqpAuxiliaryTypeBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<EqpAuxiliaryType> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getTypeName()), EqpAuxiliaryType::getTypeName, bo.getTypeName());
lqw.like(StringUtils.isNotBlank(bo.getLineName()), EqpAuxiliaryType::getLineName, bo.getLineName());
return lqw;
}
/**
* 新增公辅类型
*/
@Override
public Boolean insertByBo(EqpAuxiliaryTypeBo bo) {
EqpAuxiliaryType add = BeanUtil.toBean(bo, EqpAuxiliaryType.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setTypeId(add.getTypeId());
}
return flag;
}
/**
* 修改公辅类型
*/
@Override
public Boolean updateByBo(EqpAuxiliaryTypeBo bo) {
EqpAuxiliaryType update = BeanUtil.toBean(bo, EqpAuxiliaryType.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(EqpAuxiliaryType entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除公辅类型
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,86 @@
package com.klp.mes.roll.controller;
import com.klp.common.annotation.Log;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.domain.R;
import com.klp.common.core.page.TableDataInfo;
import java.math.BigDecimal;
import com.klp.common.enums.BusinessType;
import com.klp.mes.roll.domain.bo.MesRollChangeBo;
import com.klp.mes.roll.domain.vo.MesRollChangeVo;
import com.klp.mes.roll.service.IMesRollChangeService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
/**
* 换辊记录
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/mes/rollChange")
public class MesRollChangeController extends BaseController {
private final IMesRollChangeService iMesRollChangeService;
/** 分页列表(支持按机架、换辊类型、时间筛选) */
@GetMapping("/list")
public TableDataInfo<MesRollChangeVo> list(MesRollChangeBo bo, PageQuery pageQuery) {
return iMesRollChangeService.queryPageList(bo, pageQuery);
}
/**
* 查询指定机架当前在机轧辊(最近一次换辊记录)
* GET /mes/rollChange/current?standNo=1%23
*/
@GetMapping("/current")
public R<MesRollChangeVo> current(@RequestParam String standNo) {
return R.ok(iMesRollChangeService.queryCurrentByStand(standNo));
}
/**
* 查询指定机架当前轧辊的实时工作长度m
* GET /mes/rollChange/workLength?standNo=1%23
*/
@GetMapping("/workLength")
public R<BigDecimal> workLength(@RequestParam String standNo) {
return R.ok(iMesRollChangeService.queryRealtimeWorkLength(standNo));
}
/** 详情 */
@GetMapping("/{changeId}")
public R<MesRollChangeVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long changeId) {
return R.ok(iMesRollChangeService.queryById(changeId));
}
/** 新增换辊记录 */
@Log(title = "换辊记录", businessType = BusinessType.INSERT)
@RepeatSubmit
@PostMapping
public R<Long> add(@Validated @RequestBody MesRollChangeBo bo) {
return R.ok(iMesRollChangeService.addChange(bo));
}
/** 修改换辊记录 */
@Log(title = "换辊记录", businessType = BusinessType.UPDATE)
@RepeatSubmit
@PutMapping
public R<Void> edit(@Validated @RequestBody MesRollChangeBo bo) {
return toAjax(iMesRollChangeService.updateByBo(bo));
}
/** 删除换辊记录 */
@Log(title = "换辊记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{changeIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] changeIds) {
return toAjax(iMesRollChangeService.deleteWithValidByIds(Arrays.asList(changeIds), true));
}
}

View File

@@ -0,0 +1,110 @@
package com.klp.mes.roll.controller;
import com.klp.common.annotation.Log;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.domain.R;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.mes.roll.domain.bo.MesRollInfoBo;
import com.klp.mes.roll.domain.vo.MesRollInfoVo;
import com.klp.mes.roll.service.IMesRollInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 轧辊库(轧辊总览页)
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/mes/rollInfo")
public class MesRollInfoController extends BaseController {
private final IMesRollInfoService iMesRollInfoService;
/** 分页列表 */
@GetMapping("/list")
public TableDataInfo<MesRollInfoVo> list(MesRollInfoBo bo, PageQuery pageQuery) {
return iMesRollInfoService.queryPageList(bo, pageQuery);
}
/** 状态统计卡片数据 */
@GetMapping("/stats")
public R<Map<String, Object>> stats() {
return R.ok(iMesRollInfoService.queryStatusStats());
}
/** 轧辊编号下拉列表(按辊型 + 状态过滤,均可为空) */
@GetMapping("/options")
public R<List<String>> options(String rollType, String status) {
return R.ok(iMesRollInfoService.queryRollNoList(rollType, status));
}
/** 详情 */
@GetMapping("/{rollId}")
public R<MesRollInfoVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long rollId) {
return R.ok(iMesRollInfoService.queryById(rollId));
}
/** 新增 */
@Log(title = "轧辊库", businessType = BusinessType.INSERT)
@RepeatSubmit
@PostMapping
public R<Long> add(@Validated(AddGroup.class) @RequestBody MesRollInfoBo bo) {
return R.ok(iMesRollInfoService.insertByBo(bo));
}
/** 修改 */
@Log(title = "轧辊库", businessType = BusinessType.UPDATE)
@RepeatSubmit
@PutMapping
public R<Void> edit(@Validated(EditGroup.class) @RequestBody MesRollInfoBo bo) {
return toAjax(iMesRollInfoService.updateByBo(bo));
}
/** 删除 */
@Log(title = "轧辊库", businessType = BusinessType.DELETE)
@DeleteMapping("/{rollIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] rollIds) {
return toAjax(iMesRollInfoService.deleteWithValidByIds(Arrays.asList(rollIds), true));
}
/** 封闭轧辊(状态改为 Scrapped / 报废) */
@Log(title = "轧辊库-封闭", businessType = BusinessType.UPDATE)
@PutMapping("/{rollId}/scrap")
public R<Void> scrap(@NotNull(message = "主键不能为空") @PathVariable Long rollId) {
return toAjax(iMesRollInfoService.scrapRoll(rollId));
}
/**
* 从换辊记录同步在线状态
* 将当前各机架在机轧辊的状态强制修正为 Online解决状态数据不一致问题
*/
@Log(title = "轧辊库-状态同步", businessType = BusinessType.UPDATE)
@PostMapping("/syncStatus")
public R<Void> syncStatus() {
iMesRollInfoService.syncStatusFromChange();
return R.ok();
}
/** 导出 */
@Log(title = "轧辊库", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(MesRollInfoBo bo, HttpServletResponse response) {
List<MesRollInfoVo> list = iMesRollInfoService.queryList(bo);
ExcelUtil.exportExcel(list, "轧辊数据", MesRollInfoVo.class, response);
}
}

View File

@@ -0,0 +1,77 @@
package com.klp.mes.roll.controller;
import com.klp.common.annotation.Log;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.R;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.enums.BusinessType;
import com.klp.mes.roll.domain.bo.MesRollStandbyBo;
import com.klp.mes.roll.domain.vo.MesRollStandbyVo;
import com.klp.mes.roll.service.IMesRollStandbyService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 下批轧辊(备用辊)
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/mes/rollStandby")
public class MesRollStandbyController extends BaseController {
private final IMesRollStandbyService iMesRollStandbyService;
/**
* 查询指定机架的下批轧辊列表
* GET /mes/rollStandby/list?standNo=1%23
*/
@GetMapping("/list")
public R<List<MesRollStandbyVo>> list(@RequestParam String standNo) {
return R.ok(iMesRollStandbyService.queryByStand(standNo));
}
/** 详情 */
@GetMapping("/{standbyId}")
public R<MesRollStandbyVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long standbyId) {
return R.ok(iMesRollStandbyService.queryById(standbyId));
}
/** 新增下批轧辊 */
@Log(title = "下批轧辊", businessType = BusinessType.INSERT)
@RepeatSubmit
@PostMapping
public R<Long> add(@Validated(AddGroup.class) @RequestBody MesRollStandbyBo bo) {
return R.ok(iMesRollStandbyService.addStandby(bo));
}
/** 修改下批轧辊 */
@Log(title = "下批轧辊", businessType = BusinessType.UPDATE)
@RepeatSubmit
@PutMapping
public R<Void> edit(@Validated @RequestBody MesRollStandbyBo bo) {
return toAjax(iMesRollStandbyService.updateByBo(bo));
}
/** 删除单条下批轧辊,同时将辊状态恢复为 Offline */
@Log(title = "下批轧辊", businessType = BusinessType.DELETE)
@DeleteMapping("/{standbyId}")
public R<Void> remove(@NotNull(message = "主键不能为空") @PathVariable Long standbyId) {
return toAjax(iMesRollStandbyService.deleteById(standbyId));
}
/**
* 清空指定机架的全部下批轧辊
* DELETE /mes/rollStandby/clear?standNo=1%23
*/
@Log(title = "下批轧辊", businessType = BusinessType.DELETE)
@DeleteMapping("/clear")
public R<Void> clear(@RequestParam String standNo) {
return toAjax(iMesRollStandbyService.clearByStand(standNo));
}
}

View File

@@ -0,0 +1,64 @@
package com.klp.mes.roll.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 换辊记录 mes_roll_change
* 四辊轧机双机架1# / 2#
* 每次换辊记录 4 支辊:上工作辊、下工作辊、上支撑辊、下支撑辊
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("mes_roll_change")
public class MesRollChange extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId(value = "change_id")
private Long changeId;
/** 换辊编号 */
private String changeNo;
/** 换辊时间 */
private Date changeTime;
/** 机架号1# / 2# */
private String standNo;
/** 换辊类型: 计划换辊 / 紧急换辊 */
private String changeType;
/** 换辊状态 */
private String changeStatus;
/** 操作人 */
private String operator;
/** 上工作辊 */
private String upperWrNo;
private BigDecimal upperWrDia;
/** 下工作辊 */
private String lowerWrNo;
private BigDecimal lowerWrDia;
/** 上支撑辊 */
private String upperBrNo;
private BigDecimal upperBrDia;
/** 下支撑辊 */
private String lowerBrNo;
private BigDecimal lowerBrDia;
@TableLogic
private Integer delFlag;
}

View File

@@ -0,0 +1,70 @@
package com.klp.mes.roll.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 轧辊库 mes_roll_info
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("mes_roll_info")
public class MesRollInfo extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId(value = "roll_id")
private Long rollId;
/** 轧辊编号 */
private String rollNo;
/** 辊型: WR=工作辊 / IR=中间辊 / BR=支撑辊 */
private String rollType;
/** 状态: Offline / Standby / Online / Scrapped */
private String status;
/** 初始辊径(mm) */
private BigDecimal initialDia;
/** 当前辊径(mm) */
private BigDecimal currentDia;
/** 最小可用辊径(mm) */
private BigDecimal minDia;
/** 粗糙度 Ra(μm) */
private BigDecimal roughness;
/** 凸度(mm) */
private BigDecimal crown;
/** 材质 */
private String material;
/** 磨削次数 */
private Integer grindCount;
/** 累计轧制重量(t) */
private BigDecimal totalRolledWeight;
/** 累计轧制长度(m) */
private BigDecimal totalRolledLength;
/** 累计轧制卷数 */
private Integer totalRolledCount;
/** 制造日期 */
private Date manufactureDate;
@TableLogic
private Integer delFlag;
}

View File

@@ -0,0 +1,59 @@
package com.klp.mes.roll.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 下批轧辊(备用辊,等待换上) mes_roll_standby
*
* 每条记录代表一个具体辊位的备用辊,例如:
* 机架 1#、上工作辊位、辊号 WR-020
*
* 辊型rollTypeWR = 工作辊BR = 支撑辊
* 辊位positionUP = 上DOWN = 下
* 机架standNo1# / 2#
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("mes_roll_standby")
public class MesRollStandby extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId(value = "standby_id")
private Long standbyId;
/** 机架号1# / 2# */
private String standNo;
/** 轧辊编号(关联 mes_roll_info.roll_no */
private String rollNo;
/** 辊型WR工作辊/ BR支撑辊 */
private String rollType;
/** 辊位UP/ DOWN */
private String position;
/** 当前直径 */
private BigDecimal diameter;
/** 粗糙度 */
private BigDecimal roughness;
/** 凸度 */
private BigDecimal crown;
/** 备用就绪时间 */
private Date readyTime;
@TableLogic
private Integer delFlag;
}

View File

@@ -0,0 +1,53 @@
package com.klp.mes.roll.domain.bo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.klp.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 换辊记录 业务对象
* 四辊轧机双机架1# / 2#
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MesRollChangeBo extends BaseEntity {
private Long changeId;
private String changeNo;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date changeTime;
/** 机架号1# / 2#,列表筛选用 */
private String standNo;
/** 换辊类型(列表筛选用) */
private String changeType;
private String changeStatus;
private String operator;
/** 上工作辊 */
private String upperWrNo;
private BigDecimal upperWrDia;
/** 下工作辊 */
private String lowerWrNo;
private BigDecimal lowerWrDia;
/** 上支撑辊 */
private String upperBrNo;
private BigDecimal upperBrDia;
/** 下支撑辊 */
private String lowerBrNo;
private BigDecimal lowerBrDia;
private String remark;
}

View File

@@ -0,0 +1,57 @@
package com.klp.mes.roll.domain.bo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.klp.common.core.domain.BaseEntity;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;
/**
* 轧辊库 业务对象
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MesRollInfoBo extends BaseEntity {
@NotNull(message = "轧辊ID不能为空", groups = EditGroup.class)
private Long rollId;
@NotBlank(message = "轧辊编号不能为空", groups = {AddGroup.class, EditGroup.class})
private String rollNo;
@NotBlank(message = "辊型不能为空", groups = {AddGroup.class, EditGroup.class})
private String rollType;
private String status;
private BigDecimal initialDia;
private BigDecimal currentDia;
private BigDecimal minDia;
private BigDecimal roughness;
private BigDecimal crown;
private String material;
private Integer grindCount;
private BigDecimal totalRolledWeight;
private BigDecimal totalRolledLength;
private Integer totalRolledCount;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date manufactureDate;
private String remark;
}

View File

@@ -0,0 +1,48 @@
package com.klp.mes.roll.domain.bo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.klp.common.core.domain.BaseEntity;
import com.klp.common.core.validate.AddGroup;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.util.Date;
/**
* 下批轧辊 业务对象
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class MesRollStandbyBo extends BaseEntity {
private Long standbyId;
/** 机架号1# / 2# */
@NotBlank(message = "机架号不能为空", groups = AddGroup.class)
private String standNo;
/** 轧辊编号 */
@NotBlank(message = "轧辊编号不能为空", groups = AddGroup.class)
private String rollNo;
/** 辊型WR / BR */
@NotBlank(message = "辊型不能为空", groups = AddGroup.class)
private String rollType;
/** 辊位UP / DOWN */
@NotBlank(message = "辊位不能为空", groups = AddGroup.class)
private String position;
private BigDecimal diameter;
private BigDecimal roughness;
private BigDecimal crown;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date readyTime;
private String remark;
}

View File

@@ -0,0 +1,57 @@
package com.klp.mes.roll.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 换辊记录 视图对象
* 四辊轧机双机架1# / 2#
*/
@Data
public class MesRollChangeVo {
private static final long serialVersionUID = 1L;
private Long changeId;
private String changeNo;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date changeTime;
/** 机架号1# / 2# */
private String standNo;
private String changeType;
private String changeStatus;
private String operator;
/** 上工作辊 */
private String upperWrNo;
private BigDecimal upperWrDia;
/** 下工作辊 */
private String lowerWrNo;
private BigDecimal lowerWrDia;
/** 上支撑辊 */
private String upperBrNo;
private BigDecimal upperBrDia;
/** 下支撑辊 */
private String lowerBrNo;
private BigDecimal lowerBrDia;
private String remark;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 本次换辊方案的累计工作长度m由 WMS 卷料数据计算得出 */
private BigDecimal workLength;
}

View File

@@ -0,0 +1,70 @@
package com.klp.mes.roll.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 轧辊库 视图对象
*/
@Data
@ExcelIgnoreUnannotated
public class MesRollInfoVo {
private static final long serialVersionUID = 1L;
@ExcelProperty("轧辊ID")
private Long rollId;
@ExcelProperty("轧辊编号")
private String rollNo;
@ExcelProperty("辊型")
private String rollType;
@ExcelProperty("状态")
private String status;
@ExcelProperty("初始辊径(mm)")
private BigDecimal initialDia;
@ExcelProperty("当前辊径(mm)")
private BigDecimal currentDia;
@ExcelProperty("最小辊径(mm)")
private BigDecimal minDia;
@ExcelProperty("粗糙度")
private BigDecimal roughness;
@ExcelProperty("凸度(mm)")
private BigDecimal crown;
@ExcelProperty("材质")
private String material;
@ExcelProperty("磨削次数")
private Integer grindCount;
@ExcelProperty("累计重量(t)")
private BigDecimal totalRolledWeight;
@ExcelProperty("累计长度(m)")
private BigDecimal totalRolledLength;
@ExcelProperty("累计卷数")
private Integer totalRolledCount;
@ExcelProperty("制造日期")
private Date manufactureDate;
@ExcelProperty("备注")
private String remark;
private Date createTime;
private Date updateTime;
}

View File

@@ -0,0 +1,47 @@
package com.klp.mes.roll.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 下批轧辊 视图对象
*/
@Data
public class MesRollStandbyVo {
private static final long serialVersionUID = 1L;
private Long standbyId;
/** 机架号1# / 2# */
private String standNo;
/** 轧辊编号 */
private String rollNo;
/** 辊型WR工作辊/ BR支撑辊 */
private String rollType;
/** 辊位UP/ DOWN */
private String position;
/** 辊位中文展示:上工作辊 / 下工作辊 / 上支撑辊 / 下支撑辊 */
private String positionLabel;
private BigDecimal diameter;
private BigDecimal roughness;
private BigDecimal crown;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date readyTime;
private String remark;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
}

View File

@@ -0,0 +1,30 @@
package com.klp.mes.roll.mapper;
import com.klp.common.core.mapper.BaseMapperPlus;
import com.klp.mes.roll.domain.MesRollChange;
import com.klp.mes.roll.domain.vo.MesRollChangeVo;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.Date;
/**
* 换辊记录 Mapper
*/
public interface MesRollChangeMapper extends BaseMapperPlus<MesRollChangeMapper, MesRollChange, MesRollChangeVo> {
/** 查询指定机架最新一次换辊记录(当前在机轧辊) */
MesRollChangeVo selectLatestByStand(@Param("standNo") String standNo);
/**
* 查询同机架下一次换辊时间(用于确定本次换辊的服务结束时刻)
* 返回 null 表示该辊仍在机
*/
Date selectNextChangeTime(@Param("standNo") String standNo, @Param("changeTime") Date changeTime);
/**
* 统计指定时间区间内的卷料实测长度之和mm→调用方除以1000转m
* endTime 为 null 时统计到当前时刻
*/
BigDecimal selectWorkLength(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
}

View File

@@ -0,0 +1,42 @@
package com.klp.mes.roll.mapper;
import com.klp.common.core.mapper.BaseMapperPlus;
import com.klp.mes.roll.domain.MesRollInfo;
import com.klp.mes.roll.domain.vo.MesRollInfoVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 轧辊库 Mapper
*/
public interface MesRollInfoMapper extends BaseMapperPlus<MesRollInfoMapper, MesRollInfo, MesRollInfoVo> {
/**
* 按状态统计数量(用于总览卡片)
*/
List<Map<String, Object>> selectStatusStats();
/**
* 查询轧辊编号列表(用于下拉选择,可按辊型和状态过滤)
*/
List<String> selectRollNoList(@Param("rollType") String rollType, @Param("status") String status);
/**
* 按轧辊编号查询(用于换辊时同步状态)
*/
MesRollInfo selectByRollNo(@Param("rollNo") String rollNo);
/**
* 更新轧辊状态
*/
int updateStatusByRollNo(@Param("rollNo") String rollNo, @Param("status") String status);
/**
* 条件更新:仅当辊当前状态等于 onlyIfStatus 时才更新(用于避免误覆盖已 Online 的辊)
*/
int updateStatusByRollNoIfStatus(@Param("rollNo") String rollNo,
@Param("status") String status,
@Param("onlyIfStatus") String onlyIfStatus);
}

View File

@@ -0,0 +1,20 @@
package com.klp.mes.roll.mapper;
import com.klp.common.core.mapper.BaseMapperPlus;
import com.klp.mes.roll.domain.MesRollStandby;
import com.klp.mes.roll.domain.vo.MesRollStandbyVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 下批轧辊 Mapper
*/
public interface MesRollStandbyMapper extends BaseMapperPlus<MesRollStandbyMapper, MesRollStandby, MesRollStandbyVo> {
/** 按机架查询下批轧辊列表 */
List<MesRollStandbyVo> selectByStand(@Param("standNo") String standNo);
/** 清空某机架的下批轧辊 */
int clearByStand(@Param("standNo") String standNo);
}

View File

@@ -0,0 +1,35 @@
package com.klp.mes.roll.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.mes.roll.domain.bo.MesRollChangeBo;
import com.klp.mes.roll.domain.vo.MesRollChangeVo;
import java.math.BigDecimal;
import java.util.Collection;
/**
* 换辊记录 Service 接口
*/
public interface IMesRollChangeService {
MesRollChangeVo queryById(Long changeId);
/** 查询指定机架当前在机轧辊(最新一次换辊记录) */
MesRollChangeVo queryCurrentByStand(String standNo);
TableDataInfo<MesRollChangeVo> queryPageList(MesRollChangeBo bo, PageQuery pageQuery);
/** 新增换辊记录,同步将涉及的轧辊状态更新为 Online */
Long addChange(MesRollChangeBo bo);
Boolean updateByBo(MesRollChangeBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 查询指定机架当前在机轧辊的实时工作长度m
* 从最近一次换辊时间到现在,统计 WMS 卷料实测长度之和
*/
BigDecimal queryRealtimeWorkLength(String standNo);
}

View File

@@ -0,0 +1,45 @@
package com.klp.mes.roll.service;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.mes.roll.domain.bo.MesRollInfoBo;
import com.klp.mes.roll.domain.vo.MesRollInfoVo;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 轧辊库 Service 接口
*/
public interface IMesRollInfoService {
MesRollInfoVo queryById(Long rollId);
TableDataInfo<MesRollInfoVo> queryPageList(MesRollInfoBo bo, PageQuery pageQuery);
List<MesRollInfoVo> queryList(MesRollInfoBo bo);
/** 按状态统计(总览卡片) */
Map<String, Object> queryStatusStats();
/** 轧辊编号下拉列表status 为 null 时不过滤状态) */
List<String> queryRollNoList(String rollType, String status);
Long insertByBo(MesRollInfoBo bo);
Boolean updateByBo(MesRollInfoBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/** 封闭轧辊:状态设为 Scrapped */
Boolean scrapRoll(Long rollId);
/**
* 从换辊记录同步在线状态:
* 每个机架最新一次换辊记录中的 4 支辊 → Online
* 下批辊列表中的辊 → Standby已由 addStandby 维护,此处不重复处理);
* 其余不变,仅修正当前在机辊的状态数据不一致问题。
*/
void syncStatusFromChange();
}

View File

@@ -0,0 +1,29 @@
package com.klp.mes.roll.service;
import com.klp.mes.roll.domain.bo.MesRollStandbyBo;
import com.klp.mes.roll.domain.vo.MesRollStandbyVo;
import java.util.List;
/**
* 下批轧辊 Service 接口
*/
public interface IMesRollStandbyService {
MesRollStandbyVo queryById(Long standbyId);
/** 查询指定机架的下批轧辊列表 */
List<MesRollStandbyVo> queryByStand(String standNo);
/** 新增下批轧辊,同步将该辊状态更新为 Standby */
Long addStandby(MesRollStandbyBo bo);
/** 修改下批轧辊 */
Boolean updateByBo(MesRollStandbyBo bo);
/** 删除某条下批轧辊,同步将该辊状态恢复为 Offline */
Boolean deleteById(Long standbyId);
/** 清空指定机架的全部下批轧辊,并将对应辊状态恢复为 Offline */
Boolean clearByStand(String standNo);
}

View File

@@ -0,0 +1,140 @@
package com.klp.mes.roll.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.helper.LoginHelper;
import com.klp.common.utils.StringUtils;
import com.klp.mes.roll.domain.MesRollChange;
import com.klp.mes.roll.domain.bo.MesRollChangeBo;
import com.klp.mes.roll.domain.vo.MesRollChangeVo;
import com.klp.mes.roll.mapper.MesRollChangeMapper;
import com.klp.mes.roll.mapper.MesRollInfoMapper;
import com.klp.mes.roll.service.IMesRollChangeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
/**
* 换辊记录 Service 实现
*/
@RequiredArgsConstructor
@Service
public class MesRollChangeServiceImpl implements IMesRollChangeService {
private final MesRollChangeMapper baseMapper;
private final MesRollInfoMapper rollInfoMapper;
@Override
public MesRollChangeVo queryById(Long changeId) {
return baseMapper.selectVoById(changeId);
}
@Override
public MesRollChangeVo queryCurrentByStand(String standNo) {
return baseMapper.selectLatestByStand(standNo);
}
@Override
public TableDataInfo<MesRollChangeVo> queryPageList(MesRollChangeBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<MesRollChange> lqw = buildQueryWrapper(bo);
Page<MesRollChangeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
// 为每条换辊记录计算工作长度(上辊时间 → 下辊时间,下辊时间为 null 时统计到 NOW()
for (MesRollChangeVo vo : result.getRecords()) {
Date endTime = baseMapper.selectNextChangeTime(vo.getStandNo(), vo.getChangeTime());
BigDecimal lengthMm = baseMapper.selectWorkLength(vo.getChangeTime(), endTime);
// mm 转 m保留 2 位小数
vo.setWorkLength(lengthMm == null ? BigDecimal.ZERO
: lengthMm.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP));
}
return TableDataInfo.build(result);
}
@Override
public BigDecimal queryRealtimeWorkLength(String standNo) {
MesRollChangeVo latest = baseMapper.selectLatestByStand(standNo);
if (latest == null || latest.getChangeTime() == null) {
return BigDecimal.ZERO;
}
BigDecimal lengthMm = baseMapper.selectWorkLength(latest.getChangeTime(), null);
return lengthMm == null ? BigDecimal.ZERO
: lengthMm.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP);
}
private LambdaQueryWrapper<MesRollChange> buildQueryWrapper(MesRollChangeBo bo) {
LambdaQueryWrapper<MesRollChange> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getStandNo()), MesRollChange::getStandNo, bo.getStandNo());
lqw.eq(StringUtils.isNotBlank(bo.getChangeType()), MesRollChange::getChangeType, bo.getChangeType());
lqw.eq(StringUtils.isNotBlank(bo.getChangeStatus()), MesRollChange::getChangeStatus, bo.getChangeStatus());
if (bo.getChangeTime() != null) {
lqw.ge(MesRollChange::getChangeTime, bo.getChangeTime());
}
lqw.orderByDesc(MesRollChange::getChangeTime, MesRollChange::getChangeId);
return lqw;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Long addChange(MesRollChangeBo bo) {
MesRollChange add = BeanUtil.toBean(bo, MesRollChange.class);
if (StringUtils.isBlank(add.getChangeNo())) {
add.setChangeNo("RC" + IdUtil.fastSimpleUUID().substring(0, 8).toUpperCase());
}
// 换辊时间强制使用服务器当前时间
add.setChangeTime(new Date());
// 操作人取当前登录用户昵称
add.setOperator(LoginHelper.getNickName());
// 换辊类型固定为"计划换辊"(通过页面触发)
if (StringUtils.isBlank(add.getChangeType())) {
add.setChangeType("三级换辊");
}
// 换辊前:将上一批在机轧辊状态改为 Offline
MesRollChangeVo prev = baseMapper.selectLatestByStand(add.getStandNo());
if (prev != null) {
for (String rollNo : Arrays.asList(
prev.getUpperWrNo(), prev.getLowerWrNo(),
prev.getUpperBrNo(), prev.getLowerBrNo())) {
if (StringUtils.isNotBlank(rollNo)) {
rollInfoMapper.updateStatusByRollNo(rollNo, "Offline");
}
}
}
baseMapper.insert(add);
// 将本次换上的 4 支辊状态同步为 Online
List<String> rollNos = Arrays.asList(
add.getUpperWrNo(), add.getLowerWrNo(),
add.getUpperBrNo(), add.getLowerBrNo()
);
for (String rollNo : rollNos) {
if (StringUtils.isNotBlank(rollNo)) {
rollInfoMapper.updateStatusByRollNo(rollNo, "Online");
}
}
return add.getChangeId();
}
@Override
public Boolean updateByBo(MesRollChangeBo bo) {
MesRollChange update = BeanUtil.toBean(bo, MesRollChange.class);
return baseMapper.updateById(update) > 0;
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,137 @@
package com.klp.mes.roll.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.utils.StringUtils;
import com.klp.mes.roll.domain.MesRollInfo;
import com.klp.mes.roll.domain.bo.MesRollInfoBo;
import com.klp.mes.roll.domain.vo.MesRollInfoVo;
import com.klp.mes.roll.domain.vo.MesRollChangeVo;
import com.klp.mes.roll.mapper.MesRollChangeMapper;
import com.klp.mes.roll.mapper.MesRollInfoMapper;
import com.klp.mes.roll.service.IMesRollInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 轧辊库 Service 实现
*/
@RequiredArgsConstructor
@Service
public class MesRollInfoServiceImpl implements IMesRollInfoService {
private final MesRollInfoMapper baseMapper;
private final MesRollChangeMapper rollChangeMapper;
@Override
public MesRollInfoVo queryById(Long rollId) {
return baseMapper.selectVoById(rollId);
}
@Override
public TableDataInfo<MesRollInfoVo> queryPageList(MesRollInfoBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<MesRollInfo> lqw = buildQueryWrapper(bo);
Page<MesRollInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<MesRollInfoVo> queryList(MesRollInfoBo bo) {
LambdaQueryWrapper<MesRollInfo> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
@Override
public Map<String, Object> queryStatusStats() {
List<Map<String, Object>> rows = baseMapper.selectStatusStats();
Map<String, Object> result = new HashMap<String, Object>(8);
int total = 0;
for (Map<String, Object> row : rows) {
String status = (String) row.get("status");
Number cnt = (Number) row.get("cnt");
result.put(status, cnt.intValue());
total += cnt.intValue();
}
result.put("total", total);
return result;
}
@Override
public List<String> queryRollNoList(String rollType, String status) {
return baseMapper.selectRollNoList(rollType, status);
}
private LambdaQueryWrapper<MesRollInfo> buildQueryWrapper(MesRollInfoBo bo) {
LambdaQueryWrapper<MesRollInfo> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getRollNo()), MesRollInfo::getRollNo, bo.getRollNo());
lqw.eq(StringUtils.isNotBlank(bo.getRollType()), MesRollInfo::getRollType, bo.getRollType());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), MesRollInfo::getStatus, bo.getStatus());
lqw.orderByAsc(MesRollInfo::getRollType, MesRollInfo::getRollId);
return lqw;
}
@Override
public Long insertByBo(MesRollInfoBo bo) {
MesRollInfo add = BeanUtil.toBean(bo, MesRollInfo.class);
if (StringUtils.isBlank(add.getStatus())) {
add.setStatus("Offline");
}
if (add.getGrindCount() == null) {
add.setGrindCount(0);
}
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setRollId(add.getRollId());
}
return add.getRollId();
}
@Override
public Boolean updateByBo(MesRollInfoBo bo) {
MesRollInfo update = BeanUtil.toBean(bo, MesRollInfo.class);
return baseMapper.updateById(update) > 0;
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
return baseMapper.deleteBatchIds(ids) > 0;
}
@Override
public Boolean scrapRoll(Long rollId) {
MesRollInfo current = baseMapper.selectById(rollId);
if (current == null || !"Offline".equals(current.getStatus())) {
throw new RuntimeException("只有离线状态的轧辊才可封闭");
}
MesRollInfo update = new MesRollInfo();
update.setRollId(rollId);
update.setStatus("Scrapped");
return baseMapper.updateById(update) > 0;
}
@Override
public void syncStatusFromChange() {
// 从每个机架最新换辊记录中取出在机辊号,更新为 Online
for (String standNo : Arrays.asList("1#", "2#")) {
MesRollChangeVo latest = rollChangeMapper.selectLatestByStand(standNo);
if (latest == null) continue;
for (String rollNo : Arrays.asList(
latest.getUpperWrNo(), latest.getLowerWrNo(),
latest.getUpperBrNo(), latest.getLowerBrNo())) {
if (StringUtils.isNotBlank(rollNo)) {
baseMapper.updateStatusByRollNo(rollNo, "Online");
}
}
}
}
}

View File

@@ -0,0 +1,85 @@
package com.klp.mes.roll.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.klp.common.utils.StringUtils;
import com.klp.mes.roll.domain.MesRollStandby;
import com.klp.mes.roll.domain.bo.MesRollStandbyBo;
import com.klp.mes.roll.domain.vo.MesRollStandbyVo;
import com.klp.mes.roll.mapper.MesRollInfoMapper;
import com.klp.mes.roll.mapper.MesRollStandbyMapper;
import com.klp.mes.roll.service.IMesRollStandbyService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
* 下批轧辊 Service 实现
*/
@RequiredArgsConstructor
@Service
public class MesRollStandbyServiceImpl implements IMesRollStandbyService {
private final MesRollStandbyMapper baseMapper;
private final MesRollInfoMapper rollInfoMapper;
@Override
public MesRollStandbyVo queryById(Long standbyId) {
return baseMapper.selectVoById(standbyId);
}
@Override
public List<MesRollStandbyVo> queryByStand(String standNo) {
return baseMapper.selectByStand(standNo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Long addStandby(MesRollStandbyBo bo) {
MesRollStandby add = BeanUtil.toBean(bo, MesRollStandby.class);
if (add.getReadyTime() == null) {
add.setReadyTime(new Date());
}
baseMapper.insert(add);
// 将该辊状态更新为 Standby下批待用
if (StringUtils.isNotBlank(add.getRollNo())) {
rollInfoMapper.updateStatusByRollNo(add.getRollNo(), "Standby");
}
return add.getStandbyId();
}
@Override
public Boolean updateByBo(MesRollStandbyBo bo) {
MesRollStandby update = BeanUtil.toBean(bo, MesRollStandby.class);
return baseMapper.updateById(update) > 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteById(Long standbyId) {
MesRollStandbyVo vo = baseMapper.selectVoById(standbyId);
boolean ok = baseMapper.deleteById(standbyId) > 0;
// 只有仍处于 Standby 状态时才回退为 Offline若已换上变 Online 则不干涉)
if (ok && vo != null && StringUtils.isNotBlank(vo.getRollNo())) {
rollInfoMapper.updateStatusByRollNoIfStatus(vo.getRollNo(), "Offline", "Standby");
}
return ok;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean clearByStand(String standNo) {
// 先查出所有辊号再清空
List<MesRollStandbyVo> list = baseMapper.selectByStand(standNo);
int rows = baseMapper.clearByStand(standNo);
for (MesRollStandbyVo vo : list) {
if (StringUtils.isNotBlank(vo.getRollNo())) {
// 只有仍处于 Standby 状态时才回退为 Offline换辊后已变 Online 的不动)
rollInfoMapper.updateStatusByRollNoIfStatus(vo.getRollNo(), "Offline", "Standby");
}
}
return rows > 0;
}
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.klp.mes.eqp.mapper.EqpAuxiliaryConsumeMapper">
<resultMap type="com.klp.mes.eqp.domain.EqpAuxiliaryConsume" id="EqpAuxiliaryConsumeResult">
<result property="consumeId" column="consume_id"/>
<result property="recordDate" column="record_date"/>
<result property="typeId" column="type_id"/>
<result property="consume" column="consume"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.klp.mes.eqp.mapper.EqpAuxiliaryTypeMapper">
<resultMap type="com.klp.mes.eqp.domain.EqpAuxiliaryType" id="EqpAuxiliaryTypeResult">
<result property="typeId" column="type_id"/>
<result property="typeName" column="type_name"/>
<result property="lineName" column="line_name"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="delFlag" column="del_flag"/>
<result property="remark" column="remark"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.klp.mes.roll.mapper.MesRollChangeMapper">
<!-- 查询指定机架最新一次换辊记录(即当前在机轧辊) -->
<select id="selectLatestByStand" resultType="com.klp.mes.roll.domain.vo.MesRollChangeVo">
SELECT change_id, change_no, change_time, stand_no, change_type, change_status, operator,
upper_wr_no, upper_wr_dia, lower_wr_no, lower_wr_dia,
upper_br_no, upper_br_dia, lower_br_no, lower_br_dia,
remark, create_time
FROM mes_roll_change
WHERE del_flag = 0
AND stand_no = #{standNo}
ORDER BY change_time DESC, change_id DESC
LIMIT 1
</select>
<!-- 查询同机架在本次换辊之后最近一次换辊的时间 -->
<select id="selectNextChangeTime" resultType="java.util.Date">
SELECT MIN(change_time)
FROM mes_roll_change
WHERE del_flag = 0
AND stand_no = #{standNo}
AND change_time > #{changeTime}
</select>
<!--
统计 [startTime, endTime) 时间段内,
符合条件的 wms_coil_pending_action 记录关联的卷料实测长度之和mm
endTime 为 null 时取 NOW() 作为上界。
processed_coil_ids 存储逗号分隔的 material_id 列表,使用 FIND_IN_SET 关联。
-->
<select id="selectWorkLength" resultType="java.math.BigDecimal">
SELECT IFNULL(SUM(mc.actual_length), 0)
FROM wms_coil_pending_action cpa
INNER JOIN wms_material_coil mc
ON FIND_IN_SET(mc.coil_id, cpa.processed_coil_ids) > 0
WHERE cpa.del_flag = 0
AND cpa.action_status = 2
AND cpa.action_type IN (205, 504, 524)
AND cpa.create_time &gt;= #{startTime}
AND cpa.create_time &lt; IFNULL(#{endTime}, NOW())
AND mc.create_time &gt;= #{startTime}
AND mc.create_time &lt; IFNULL(#{endTime}, NOW())
</select>
</mapper>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.klp.mes.roll.mapper.MesRollInfoMapper">
<select id="selectStatusStats" resultType="map">
SELECT status, COUNT(*) AS cnt
FROM mes_roll_info
WHERE del_flag = 0
GROUP BY status
</select>
<select id="selectRollNoList" resultType="string">
SELECT roll_no FROM mes_roll_info
WHERE del_flag = 0
AND status != 'Scrapped'
<if test="rollType != null and rollType != ''">
AND roll_type = #{rollType}
</if>
<if test="status != null and status != ''">
AND status = #{status}
</if>
ORDER BY roll_no ASC
</select>
<select id="selectByRollNo" resultType="com.klp.mes.roll.domain.MesRollInfo">
SELECT * FROM mes_roll_info
WHERE del_flag = 0 AND roll_no = #{rollNo}
LIMIT 1
</select>
<update id="updateStatusByRollNo">
UPDATE mes_roll_info
SET status = #{status}, update_time = NOW()
WHERE del_flag = 0 AND roll_no = #{rollNo}
</update>
<update id="updateStatusByRollNoIfStatus">
UPDATE mes_roll_info
SET status = #{status}, update_time = NOW()
WHERE del_flag = 0 AND roll_no = #{rollNo} AND status = #{onlyIfStatus}
</update>
</mapper>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.klp.mes.roll.mapper.MesRollStandbyMapper">
<!-- 按机架查询下批轧辊,附带辊位中文标签 -->
<select id="selectByStand" resultType="com.klp.mes.roll.domain.vo.MesRollStandbyVo">
SELECT
standby_id, stand_no, roll_no, roll_type, position,
CASE
WHEN roll_type = 'BR' AND position = 'UP' THEN '上支撑辊'
WHEN roll_type = 'WR' AND position = 'UP' THEN '上工作辊'
WHEN roll_type = 'WR' AND position = 'DOWN' THEN '下工作辊'
WHEN roll_type = 'BR' AND position = 'DOWN' THEN '下支撑辊'
ELSE CONCAT(position, roll_type)
END AS position_label,
diameter, roughness, crown, ready_time, remark, create_time
FROM mes_roll_standby
WHERE del_flag = 0
AND stand_no = #{standNo}
ORDER BY
FIELD(roll_type, 'BR', 'WR', 'WR', 'BR'),
FIELD(position, 'UP', 'UP', 'DOWN', 'DOWN')
</select>
<!-- 逻辑删除指定机架所有下批轧辊(清空) -->
<update id="clearByStand">
UPDATE mes_roll_standby
SET del_flag = 1
WHERE del_flag = 0
AND stand_no = #{standNo}
</update>
</mapper>

View File

@@ -41,6 +41,11 @@ public interface ISysDictDataService {
*/
SysDictData selectDictDataById(Long dictCode);
/**
* 按字典类型查询字典数据(直查库)。用于 HTTP `/dict/data/type/{type}`,避免 Spring Cache 在无界面操作灌数后仍返回空。
*/
List<SysDictData> selectDictDataByTypeRealtime(String dictType);
/**
* 批量删除字典数据信息
*

View File

@@ -15,6 +15,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
/**
@@ -81,6 +82,18 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
return baseMapper.selectById(dictCode);
}
/**
* 按类型查字典数据(直查数据库,不走 {@link com.klp.system.service.impl.SysDictTypeServiceImpl#selectDictDataByType} 的 Spring Cache
* SQL 脚本直插或外部改表后仍需立即在「按类型」HTTP 接口中可见,避免长期使用空缓存。
*/
@Override
public List<SysDictData> selectDictDataByTypeRealtime(String dictType) {
if (StringUtils.isBlank(dictType)) {
return Collections.emptyList();
}
return baseMapper.selectDictDataByType(dictType);
}
/**
* 批量删除字典数据信息
*

View File

@@ -119,7 +119,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
@Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
@Override
public SysDictType selectDictTypeByType(String dictType) {
return baseMapper.selectById(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
return baseMapper.selectOne(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
}
/**

View File

@@ -42,3 +42,11 @@ export function delPlanDetail(planDetailId) {
method: 'delete'
})
}
// 查询排产单对应的钢卷列表
export function listPlanCoils(planSheetId) {
return request({
url: '/aps/planDetail/coils/' + planSheetId,
method: 'get',
})
}

View File

@@ -52,3 +52,14 @@ export function listOrderPackaging(orderId) {
method: 'get',
})
}
/**
* 查询今日订单
*/
export function listTodayOrder(query) {
return request({
url: '/crm/order/daily',
method: 'get',
params: query
})
}

View File

@@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询能源消耗记录列表
export function listEnergyRecord(query) {
return request({
url: '/ems/energyRecord/list',
method: 'get',
params: query
})
}
// 查询能源消耗记录详细
export function getEnergyRecord(energyRecordId) {
return request({
url: '/ems/energyRecord/' + energyRecordId,
method: 'get'
})
}
// 新增能源消耗记录
export function addEnergyRecord(data) {
return request({
url: '/ems/energyRecord',
method: 'post',
data: data
})
}
// 修改能源消耗记录
export function updateEnergyRecord(data) {
return request({
url: '/ems/energyRecord',
method: 'put',
data: data
})
}
// 删除能源消耗记录
export function delEnergyRecord(energyRecordId) {
return request({
url: '/ems/energyRecord/' + energyRecordId,
method: 'delete'
})
}

Some files were not shown because too many files have changed in this diff Show More