Compare commits

..

188 Commits

Author SHA1 Message Date
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
b4dc0ed9e4 Merge remote-tracking branch 'origin/0.8.X' into 0.8.X 2026-04-11 16:03:26 +08:00
5efdcf99dc feat(order): 添加订单物流运单信息查询功能
- 在CrmContractOrderFinanceVo中新增wmsDeliveryWaybills字段用于存储物流运单信息
- 添加WmsDeliveryWaybillVo依赖引入
- 在CrmOrderItemServiceImpl的两个查询方法中增加物流运单数据查询逻辑
- 使用LambdaQueryWrapper按订单ID批量查询关联的物流运单信息
- 将查询到的物流运单列表设置到返回结果中
2026-04-11 16:03:16 +08:00
砂糖
3020a4244d feat(wms): 新增报表导出文件管理功能
新增报表导出文件管理模块,包含后端接口和前端页面
在各类报表页面添加保存报表功能
优化CoilSelector和CoilCard组件显示
调整分页大小和表格高度
统一各产线报表配置
修复文件预览组件高度问题
2026-04-11 15:36:50 +08:00
391 changed files with 27911 additions and 2747 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

@@ -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
*/

View File

@@ -93,6 +93,30 @@ public class CrmOrderItem extends BaseEntity {
* 排产批次
*/
private String productionBatch;
/**
* 表面处理
*/
private String surfaceTreatment;
/**
* 切边要求
*/
private String edgeCuttingReq;
/**
* 包装要求
*/
private String packagingReq;
/**
* 宽度
*/
private BigDecimal width;
/**
* 厚度
*/
private BigDecimal 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
*/

View File

@@ -108,5 +108,34 @@ public class CrmOrderItemBo extends BaseEntity {
*/
private String productionBatch;
/**
* 表面处理
*/
private String surfaceTreatment;
/**
* 切边要求
*/
private String edgeCuttingReq;
/**
* 包装要求
*/
private String packagingReq;
/**
* 宽度
*/
private BigDecimal width;
/**
* 厚度
*/
private BigDecimal thickness;
/**
* 用途
*/
private String purpose;
}

View File

@@ -1,5 +1,6 @@
package com.klp.crm.domain.vo;
import com.klp.domain.vo.WmsDeliveryWaybillVo;
import com.klp.domain.vo.WmsReceivableVo;
import lombok.Data;
@@ -11,4 +12,7 @@ public class CrmContractOrderFinanceVo {
private List<CrmSalesObjectionVo> objectionList;
private List<WmsReceivableVo> receivableList;
// setWmsDeliveryWaybills
private List<WmsDeliveryWaybillVo> wmsDeliveryWaybills;
}

View File

@@ -131,5 +131,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 BigDecimal width;
/**
* 厚度
*/
@ExcelProperty(value = "厚度")
private BigDecimal 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
*/
@@ -142,4 +295,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

@@ -8,7 +8,9 @@ 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.CrmSalesObjection;
import com.klp.domain.WmsMaterialCoil;
import com.klp.domain.WmsReceivable;
import com.klp.domain.vo.WmsDeliveryWaybillVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.klp.crm.domain.bo.CrmOrderItemBo;
@@ -99,6 +101,12 @@ public class CrmOrderItemServiceImpl implements ICrmOrderItemService {
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.getEdgeCuttingReq()), CrmOrderItem::getEdgeCuttingReq, bo.getEdgeCuttingReq());
lqw.eq(StringUtils.isNotBlank(bo.getPackagingReq()), CrmOrderItem::getPackagingReq, bo.getPackagingReq());
lqw.eq(bo.getWidth() != null, CrmOrderItem::getWidth, bo.getWidth());
lqw.eq(bo.getThickness() != null, CrmOrderItem::getThickness, bo.getThickness());
lqw.eq(StringUtils.isNotBlank(bo.getPurpose()), CrmOrderItem::getPurpose, bo.getPurpose());
return lqw;
}
@@ -171,6 +179,12 @@ public class CrmOrderItemServiceImpl implements ICrmOrderItemService {
List<WmsReceivableVo> receivableList = wmsReceivableMapper.selectVoList(receivableWrapper);
result.setReceivableList(receivableList);
LambdaQueryWrapper<WmsDeliveryWaybill> waybillWrapper = new LambdaQueryWrapper<>();
waybillWrapper.in(WmsDeliveryWaybill::getOrderId, orderIds);
List<WmsDeliveryWaybillVo> wmsDeliveryWaybills = wmsDeliveryWaybillMapper.selectVoList(waybillWrapper);
result.setWmsDeliveryWaybills(wmsDeliveryWaybills);
return result;
}
@@ -276,6 +290,11 @@ public class CrmOrderItemServiceImpl implements ICrmOrderItemService {
List<WmsReceivableVo> receivableList = wmsReceivableMapper.selectVoList(receivableWrapper);
result.setReceivableList(receivableList);
LambdaQueryWrapper<WmsDeliveryWaybill> waybillWrapper = new LambdaQueryWrapper<>();
waybillWrapper.in(WmsDeliveryWaybill::getOrderId, orderIds);
List<WmsDeliveryWaybillVo> wmsDeliveryWaybills = wmsDeliveryWaybillMapper.selectVoList(waybillWrapper);
result.setWmsDeliveryWaybills(wmsDeliveryWaybills);
return result;
}

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,6 +181,31 @@ 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());
//逻辑删除
@@ -139,6 +241,31 @@ 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());
return lqw;

View File

@@ -23,6 +23,12 @@ 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="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 +56,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
customizer,
shipper,
production_batch,
surface_treatment,
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"/>
@@ -45,6 +70,31 @@ 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.create_by AS createBy,
@@ -79,6 +129,31 @@ 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.create_by AS createBy,

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

@@ -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<Void> add(@Validated(AddGroup.class) @RequestBody EqpAuxiliaryConsumeBo bo) {
return toAjax(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,49 @@
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;
/**
* 公辅消耗记录业务对象 eqp_auxiliary_consume
*
* @author klp
* @date 2026-04-29
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class EqpAuxiliaryConsumeBo extends BaseEntity {
/**
* 消耗记录ID
*/
private Long consumeId;
/**
* 记录日期
*/
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);
/**
* 新增公辅消耗记录
*/
Boolean 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 Boolean 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 flag;
}
/**
* 修改公辅消耗记录
*/
@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,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

@@ -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'
})
}

View File

@@ -0,0 +1,50 @@
import request from '@/utils/request'
// 计划列表(分页)
export function getTimingPlanList(page = 1, pageSize = 20) {
return request({
url: '/sql-server-api/plans',
method: 'get',
params: { page, pageSize }
})
}
// 计划总数
export function getTimingPlanCount() {
return request({
url: '/sql-server-api/plans/count',
method: 'get'
})
}
// 计划详情
export function getTimingPlanDetail(coilId) {
return request({
url: '/sql-server-api/plans/' + coilId,
method: 'get'
})
}
// 钢卷实际 SEG按入口卷号查询
export function getTimingSegByEncoilId(encoilId) {
return request({
url: '/sql-server-api/seg/' + encoilId,
method: 'get'
})
}
// 钢卷实际 SEG按出口卷号查询
export function getTimingSegByExcoilId(excoilId) {
return request({
url: '/sql-server-api/seg-by-excoil/' + excoilId,
method: 'get'
})
}
// 实时数据Gauge + Shape
export function getTimingRealtimeData(matId) {
return request({
url: '/sql-server-api/realtime/' + matId,
method: 'get'
})
}

View File

@@ -58,3 +58,11 @@ export function optionselect() {
method: 'get'
})
}
/** 按字典类型编码精确查询 sys_dict_type路径需编码 */
export function getDictTypeByCode(dictType) {
return request({
url: '/system/dict/type/byType/' + encodeURIComponent(dictType),
method: 'get'
})
}

View File

@@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询退火操作事件列表
export function listAnnealOperateEvent(query) {
return request({
url: '/wms/annealOperateEvent/list',
method: 'get',
params: query
})
}
// 查询退火操作事件详细
export function getAnnealOperateEvent(eventId) {
return request({
url: '/wms/annealOperateEvent/' + eventId,
method: 'get'
})
}
// 新增退火操作事件
export function addAnnealOperateEvent(data) {
return request({
url: '/wms/annealOperateEvent',
method: 'post',
data: data
})
}
// 修改退火操作事件
export function updateAnnealOperateEvent(data) {
return request({
url: '/wms/annealOperateEvent',
method: 'put',
data: data
})
}
// 删除退火操作事件
export function delAnnealOperateEvent(eventId) {
return request({
url: '/wms/annealOperateEvent/' + eventId,
method: 'delete'
})
}

View File

@@ -0,0 +1,56 @@
import request from '@/utils/request'
import attendanceRequest from '@/utils/attendanceRequest'
// 查询考勤记录列表
export function listRecords(query) {
return request({
url: '/wms/attendanceRecords/list',
method: 'get',
params: query
})
}
// 查询考勤记录详细
export function getRecords(id) {
return request({
url: '/wms/attendanceRecords/' + id,
method: 'get'
})
}
// 新增考勤记录
export function addRecords(data) {
return request({
url: '/wms/attendanceRecords',
method: 'post',
data: data
})
}
// 修改考勤记录
export function updateRecords(data) {
return request({
url: '/wms/attendanceRecords',
method: 'put',
data: data
})
}
// 删除考勤记录
export function delRecords(id) {
return request({
url: '/wms/attendanceRecords/' + id,
method: 'delete'
})
}
// 同步考勤记录
export function syncRecords(starttime) {
return attendanceRequest({
url: '/sync_attendance',
method: 'post',
data: {
starttime
}
})
}

View File

@@ -390,3 +390,37 @@ export function listTypeErrorCoil() {
timeout: 600000
})
}
export function getCoilStatisticsList(params) {
return request({
url: '/wms/materialCoil/statisticsList',
method: 'get',
params,
})
}
/**
* 查询原料材质与钢卷类型不匹配的钢卷
*/
export function listMismatchedItemCoil(params) {
return request({
url: '/wms/materialCoil/queryMaterialMismatchCoils',
method: 'get',
timeout: 600000,
params
})
}
/**
* 修复原料材质与钢卷类型不匹配的钢卷
*/
export function fixMismatchedItemCoil(coilId) {
return request({
url: '/wms/materialCoil/fixMaterialMismatch',
method: 'put',
timeout: 600000,
params: {
coilId
}
})
}

View File

@@ -0,0 +1,61 @@
import request from '@/utils/request'
// 查询钢卷缓存列表
export function listCoilCache(query) {
return request({
url: '/wms/coilCache/list',
method: 'get',
params: query
})
}
// 查询钢卷缓存详细
export function getCoilCache(cacheId) {
return request({
url: '/wms/coilCache/' + cacheId,
method: 'get'
})
}
// 新增钢卷缓存
export function addCoilCache(data) {
return request({
url: '/wms/coilCache',
method: 'post',
data: data
})
}
// 修改钢卷缓存
export function updateCoilCache(data) {
return request({
url: '/wms/coilCache',
method: 'put',
data: data
})
}
// 删除钢卷缓存
export function delCoilCache(cacheId) {
return request({
url: '/wms/coilCache/' + cacheId,
method: 'delete'
})
}
// 存储缓存
export function saveCoilCache(data) {
return request({
url: '/wms/coilCache/save',
method: 'post',
data: data
})
}
// 获取缓存
export function getCoilCacheByCoilId(coilId) {
return request({
url: '/wms/coilCache/getByCoilId/' + coilId,
method: 'get'
})
}

View File

@@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询钢卷与合同关联关系列表
export function listCoilContractRel(query) {
return request({
url: '/wms/coilContractRel/list',
method: 'get',
params: query
})
}
// 查询钢卷与合同关联关系详细
export function getCoilContractRel(relId) {
return request({
url: '/wms/coilContractRel/' + relId,
method: 'get'
})
}
// 新增钢卷与合同关联关系
export function addCoilContractRel(data) {
return request({
url: '/wms/coilContractRel',
method: 'post',
data: data
})
}
// 修改钢卷与合同关联关系
export function updateCoilContractRel(data) {
return request({
url: '/wms/coilContractRel',
method: 'put',
data: data
})
}
// 删除钢卷与合同关联关系
export function delCoilContractRel(relId) {
return request({
url: '/wms/coilContractRel/' + relId,
method: 'delete'
})
}

View File

@@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询钢卷质量改判记录列表
export function listCoilQualityRejudge(query) {
return request({
url: '/wms/coilQualityRejudge/list',
method: 'get',
params: query
})
}
// 查询钢卷质量改判记录详细
export function getCoilQualityRejudge(rejudgeId) {
return request({
url: '/wms/coilQualityRejudge/' + rejudgeId,
method: 'get'
})
}
// 新增钢卷质量改判记录
export function addCoilQualityRejudge(data) {
return request({
url: '/wms/coilQualityRejudge',
method: 'post',
data: data
})
}
// 修改钢卷质量改判记录
export function updateCoilQualityRejudge(data) {
return request({
url: '/wms/coilQualityRejudge',
method: 'put',
data: data
})
}
// 删除钢卷质量改判记录
export function delCoilQualityRejudge(rejudgeId) {
return request({
url: '/wms/coilQualityRejudge/' + rejudgeId,
method: 'delete'
})
}

View File

@@ -5,7 +5,8 @@ export function listCoilWarehouseOperationLog(query) {
return request({
url: '/wms/coilWarehouseOperationLog/list',
method: 'get',
params: query
params: query,
timeout: 100000,
})
}

View File

@@ -60,3 +60,14 @@ export function listBoundCoil(query) {
params: query
})
}
// 按销售员查询订单明细的卷
export function listDeliveryWaybillDetailBySaleman(principal) {
return request({
url: '/wms/deliveryWaybillDetail/coilListByPrincipal',
method: 'get',
params: {
principal: principal
}
})
}

View File

@@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询报导出文件列表
export function listExportFile(query) {
return request({
url: '/wms/exportFile/list',
method: 'get',
params: query
})
}
// 查询报导出文件详细
export function getExportFile(id) {
return request({
url: '/wms/exportFile/' + id,
method: 'get'
})
}
// 新增报导出文件
export function addExportFile(data) {
return request({
url: '/wms/exportFile',
method: 'post',
data: data
})
}
// 修改报导出文件
export function updateExportFile(data) {
return request({
url: '/wms/exportFile',
method: 'put',
data: data
})
}
// 删除报导出文件
export function delExportFile(id) {
return request({
url: '/wms/exportFile/' + id,
method: 'delete'
})
}

View File

@@ -122,10 +122,13 @@ export function startProcess(actionId) {
}
// 完成操作
export function completeAction(actionId) {
export function completeAction(actionId, newCoilIds) {
return request({
url: `/wms/coilPendingAction/complete/${actionId}`,
method: 'put'
method: 'put',
params: {
newCoilIds: newCoilIds || '-'
}
})
}

View File

@@ -0,0 +1,39 @@
import request from '@/utils/request'
export function listProcessPlan(query) {
return request({
url: '/wms/processPlan/list',
method: 'get',
params: query
})
}
export function getProcessPlan(planId) {
return request({
url: '/wms/processPlan/' + planId,
method: 'get'
})
}
export function addProcessPlan(data) {
return request({
url: '/wms/processPlan',
method: 'post',
data: data
})
}
export function updateProcessPlan(data) {
return request({
url: '/wms/processPlan',
method: 'put',
data: data
})
}
export function delProcessPlan(planId) {
return request({
url: '/wms/processPlan/' + planId,
method: 'delete'
})
}

View File

@@ -0,0 +1,39 @@
import request from '@/utils/request'
export function listProcessPlanParam(query) {
return request({
url: '/wms/processPlanParam/list',
method: 'get',
params: query
})
}
export function getProcessPlanParam(paramId) {
return request({
url: '/wms/processPlanParam/' + paramId,
method: 'get'
})
}
export function addProcessPlanParam(data) {
return request({
url: '/wms/processPlanParam',
method: 'post',
data: data
})
}
export function updateProcessPlanParam(data) {
return request({
url: '/wms/processPlanParam',
method: 'put',
data: data
})
}
export function delProcessPlanParam(paramId) {
return request({
url: '/wms/processPlanParam/' + paramId,
method: 'delete'
})
}

View File

@@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询规程主表列表
export function listProcessSpec(query) {
return request({
url: '/wms/processSpec/list',
method: 'get',
params: query
})
}
// 查询规程主表详细
export function getProcessSpec(specId) {
return request({
url: '/wms/processSpec/' + specId,
method: 'get'
})
}
// 新增规程主表
export function addProcessSpec(data) {
return request({
url: '/wms/processSpec',
method: 'post',
data: data
})
}
// 修改规程主表
export function updateProcessSpec(data) {
return request({
url: '/wms/processSpec',
method: 'put',
data: data
})
}
// 删除规程主表
export function delProcessSpec(specId) {
return request({
url: '/wms/processSpec/' + specId,
method: 'delete'
})
}

View File

@@ -0,0 +1,46 @@
import request from '@/utils/request'
export function listProcessSpecVersion(query) {
return request({
url: '/wms/processSpecVersion/list',
method: 'get',
params: query
})
}
export function getProcessSpecVersion(versionId) {
return request({
url: '/wms/processSpecVersion/' + versionId,
method: 'get'
})
}
export function addProcessSpecVersion(data) {
return request({
url: '/wms/processSpecVersion',
method: 'post',
data: data
})
}
export function updateProcessSpecVersion(data) {
return request({
url: '/wms/processSpecVersion',
method: 'put',
data: data
})
}
export function activateProcessSpecVersion(versionId) {
return request({
url: '/wms/processSpecVersion/activate/' + versionId,
method: 'put'
})
}
export function delProcessSpecVersion(versionId) {
return request({
url: '/wms/processSpecVersion/' + versionId,
method: 'delete'
})
}

View File

@@ -55,6 +55,13 @@ export const defaultColumns = [
width: '120',
showOverflowTooltip: true
},
{
label: '创建时间',
align: 'center',
prop: 'createTime',
width: '100',
showOverflowTooltip: true
},
{
label: '备注',
align: 'center',

View File

@@ -21,12 +21,6 @@
@close="handleClose" append-to-body :fullscreen="orderBy">
<!-- 搜索区域 -->
<el-form v-if="!rangeMode" inline :model="queryParams" class="search-form">
<!-- <el-form-item label="类型">
<el-select v-model="queryParams.selectType" placeholder="请选择类型" size="small">
<el-option label="成品" value="product" />
<el-option label="原料" value="raw_material" />
</el-select>
</el-form-item> -->
<el-form-item label="入场卷号">
<el-input v-model="queryParams.enterCoilNo" placeholder="请输入入场卷号" clearable size="small"
@keyup.enter.native="handleQuery" />
@@ -35,23 +29,29 @@
<el-input v-model="queryParams.currentCoilNo" placeholder="请输入当前卷号" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="物料">
<muti-select v-model="queryParams.itemName" :options="dict.type.coil_itemname" placeholder="请选择物料"
<el-form-item label="物料类型">
<el-select v-model="queryParams.itemType" placeholder="请选择物料类型" size="small" clearable>
<el-option label="成品" value="product" />
<el-option label="原料" value="raw_material" />
</el-select>
</el-form-item>
<el-form-item label="物料名称" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemName" :options="dict.type.coil_itemname" placeholder="请选择物料名称"
clearable />
</el-form-item>
<el-form-item label="规格">
<el-form-item label="规格" v-if="queryParams.itemType">
<memo-input storageKey="coilSpec" v-model="queryParams.itemSpecification" placeholder="请输入规格" clearable
size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="材质">
<el-form-item label="材质" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemMaterial" :options="dict.type.coil_material" placeholder="请选择材质"
clearable />
</el-form-item>
<el-form-item label="厂家">
<el-form-item label="厂家" v-if="queryParams.itemType">
<muti-select v-model="queryParams.itemManufacturer" :options="dict.type.coil_manufacturer" placeholder="请选择厂家"
clearable />
</el-form-item>
<el-form-item label="表面处理">
<el-form-item label="表面处理" v-if="queryParams.itemType">
<el-input v-model="queryParams.itemSurfaceTreatmentDesc" placeholder="请输入表面处理" clearable size="small" />
</el-form-item>
<el-form-item label="切边" prop="trimmingRequirement" v-if="orderBy">
@@ -68,8 +68,8 @@
</el-select>
</el-form-item>
<el-form-item label="品质">
<muti-select v-model="queryParams.qualityStatusCsv" :options="dict.type.coil_quality_status" placeholder="请选择品质"
clearable />
<muti-select v-model="queryParams.qualityStatusCsv" :options="dict.type.coil_quality_status"
placeholder="请选择品质" clearable />
</el-form-item>
<el-form-item label="实际库区" v-if="orderBy">
<actual-warehouse-select v-model="queryParams.actualWarehouseId" placeholder="请选择实际库区" canSelectLevel2
@@ -80,6 +80,8 @@
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
<el-checkbox v-if="orderBy" style="margin-left: 10px;" v-model="showCoilMap" size="small">显示钢卷地图</el-checkbox>
<el-checkbox v-if="orderBy && orderId" style="margin-left: 10px;" v-model="showOrderInfo"
size="small">显示订单详情</el-checkbox>
</el-form-item>
</el-form>
@@ -93,6 +95,7 @@
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
</el-table>
<div v-else>
@@ -111,12 +114,20 @@
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
</el-table>
</div>
<!-- 分页 -->
<div style="display: flex; justify-content: flex-end; align-items: flex-end; gap: 10px;">
<span>
总净重{{ coilTrimStatistics.total_net_weight || 0 }}t
</span>
<pagination v-if="!rangeMode" v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList" />
</div>
<div v-if="multiple && selectedCoils.length > 0" class="selected-stats">
<div class="stats-content">
@@ -138,6 +149,7 @@
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
<el-table-column label="操作" width="50">
<template slot-scope="scope">
@@ -163,12 +175,18 @@
:id="selectedNodeId" :canToggle="false" :canRelease="false" />
</div>
</DragResizeBox>
<DragResizeBox v-if="orderBy && orderId && showOrderInfo" storageKey="coil-order-info">
<div style="height: 100%; width: 100%; background-color: #fff;">
<order-detail v-if="orderBy && orderId && showOrderInfo" :orderId="orderId" :editable="false" />
</div>
</DragResizeBox>
</el-dialog>
</div>
</template>
<script>
import { listMaterialCoil } from '@/api/wms/coil';
import { listMaterialCoil, getCoilStatisticsList } from '@/api/wms/coil';
import { listActualWarehouse } from "@/api/wms/actualWarehouse";
import { treeActualWarehouseTwoLevel } from "@/api/wms/actualWarehouse";
import MemoInput from '@/components/MemoInput/index.vue';
@@ -177,6 +195,7 @@ import { defaultColumns } from './data';
import ActualWarehouseSelect from '@/components/KLPService/ActualWarehouseSelect/index.vue';
import WarehouseBirdMini from '@/views/wms/warehouse/components/WarehouseBirdMini.vue';
import DragResizeBox from '@/components/DragResizeBox/index.vue';
import OrderDetail from '@/views/crm/components/OrderDetail.vue';
export default {
name: 'CoilSelector',
@@ -185,7 +204,8 @@ export default {
MutiSelect,
ActualWarehouseSelect,
WarehouseBirdMini,
DragResizeBox
DragResizeBox,
OrderDetail
},
dicts: ['coil_itemname', 'coil_material', 'coil_manufacturer', 'coil_quality_status'],
props: {
@@ -254,6 +274,14 @@ export default {
type: Boolean,
default: false
},
orderId: {
type: String,
default: null
},
defaultType: {
type: String,
default: 'product'
}
},
data() {
return {
@@ -267,14 +295,15 @@ export default {
selectedCoil: null,
queryParams: {
pageNum: 1,
pageSize: 10,
pageSize: 50,
currentCoilNo: null,
grade: null,
itemSpecification: null,
itemMaterial: null,
itemManufacturer: null,
actualWarehouseId: null,
selectType: 'product',
itemType: this.defaultType,
selectType: this.defaultType,
status: 0, // 不包含已发货的钢卷
dataType: 1 // 只查询当前数据,不查询历史数据
},
@@ -287,6 +316,8 @@ export default {
warehouseTree: [],
treeProps: { label: "actualWarehouseName", children: "children" },
treeLoading: false,
showOrderInfo: false,
coilTrimStatistics: {},
};
},
computed: {
@@ -471,12 +502,18 @@ export default {
...this.queryParams,
...this.filters,
};
queryPayload.selectType = queryPayload.itemType;
// 处于销售视角且my视图时只查询当前用户的钢卷
console.log('this.salesRestricted', this.salesRestricted, this.currentTab, this.currentUserId);
if (this.salesRestricted && this.currentTab === 'my') {
queryPayload.saleId = this.currentUserId;
}
const response = await listMaterialCoil(queryPayload);
const { pageNum, pageSize, excludeBound, orderBy, ...noPager } = queryPayload;
getCoilStatisticsList(noPager).then((res) => {
console.log('钢卷统计数据:', res);
this.coilTrimStatistics = res.data || {};
});
if (response.code === 200) {
this.coilList = response.rows || [];
this.total = response.total || 0;
@@ -522,7 +559,8 @@ export default {
currentCoilNo: null,
grade: null,
dataType: 1,
selectType: 'raw_material',
itemType: this.defaultType,
selectType: this.defaultType,
};
this.getList();
},
@@ -534,11 +572,24 @@ export default {
this.$message.warning('您没有权限选择此钢卷');
return; // 终止后续逻辑
}
if (this.disableO) {
// 并且钢卷的warehouseId不是1988150210872930306
// 1988150380649967617
// 1988150800092950529
// 1988151027466170370其中之一才不能选择
const warehouseIds = ['1988150210872930306', '1988150380649967617', '1988150800092950529', '1988151027466170370'];
// 如果没有判级就不能选择,除非是那分剪四个库区
if (!row.qualityStatus && !warehouseIds.includes(row.warehouseId)) {
this.$message.warning('未判级的钢卷不能选择');
return;
}
const disabledOList = ['O', 'C+', 'C', 'C-', 'D+', 'D', 'D-']
if (this.disableO && disabledOList.includes(row.qualityStatus)) {
if (disabledOList.includes(row.qualityStatus)) {
this.$message.warning(`${row.qualityStatus}卷不能选择`);
return;
}
}
this.handleSelect(row);
},

View File

@@ -2,6 +2,7 @@
<div style="display: flex; align-items: center;" v-loading="loading">
<!-- 下拉选择器绑定计算属性做双向绑定保留原有样式+清空功能 -->
<el-select
v-if="!toolbarOnly"
v-model="innerValue"
:placeholder="placeholder"
clearable filterable
@@ -20,13 +21,13 @@
<div
v-if="editable"
@click="openDictDialog"
style="cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;"
:style="toolbarOnly ? 'cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; border-radius: 2px;' : 'cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;'"
>
<i class="el-icon-setting"></i>
</div>
<div
v-if="refresh"
v-if="refresh && !toolbarOnly"
@click="handleRefresh"
style="cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;"
>
@@ -37,7 +38,7 @@
<el-dialog
v-if="editable"
:visible.sync="open"
title="字典数据配置"
:title="panelTitle || '字典数据配置'"
width="600px"
append-to-body
>
@@ -145,14 +146,17 @@
</template>
<script>
import { addData, updateData, delData, listData } from '@/api/system/dict/data'
import { listType } from '@/api/system/dict/type'
import { addData, updateData, delData, getDicts } from '@/api/system/dict/data'
export default {
name: 'DictSelectEdit',
props: {
dictType: { type: String, default: '' },
editable: { type: Boolean, default: true },
/** 仅展示字典配置入口(齿轮)与弹窗,不渲染下拉框 — 用于列表页 Tab 旁内联维护字典 */
toolbarOnly: { type: Boolean, default: false },
/** 字典配置弹窗标题 */
panelTitle: { type: String, default: '' },
kisv: { type: Boolean, default: true },
value: { type: String, default: '' },
placeholder: { type: String, default: '请选择' },
@@ -163,18 +167,17 @@ export default {
data() {
return {
dictOptions: [],
dictId: '',
loading: false,
btnLoading: false,
delBtnLoading: '',
open: false,
editRowId: '', // 控制当前编辑行,为空则所有单元格都是文本状态
form: {
dictId: '',
dictLabel: '',
dictValue: '',
dictType: '',
sort: 0
dictSort: 0,
status: '0'
},
dictRules: {
dictLabel: [{ required: true, message: '请输入字典标签', trigger: 'blur' }],
@@ -214,17 +217,17 @@ export default {
watch: {
dictType: {
async handler(newVal) {
if (newVal) {
if (!newVal) return
// toolbarOnly仅打开弹窗时加载避免无谓请求下拉模式按 dict_type 加载选项
if (this.toolbarOnly) return
this.loading = true
try {
const dictId = await this.getDictId(newVal)
await this.getDictOptions(dictId)
await this.loadDictRows()
} catch (err) {
console.error('加载字典失败:', err)
} finally {
this.loading = false
}
}
},
immediate: true
},
@@ -236,14 +239,11 @@ export default {
}
},
methods: {
async getDictId(type) {
const res = await listType({ dictType: type })
if (res.rows?.length !== 1) {
this.$message.error('字典类型异常,未查询到对应配置')
return Promise.reject('字典类型异常')
}
this.dictId = res.rows[0].dictId
return this.dictId
/** 读字典数据行:优先 getDicts/dict/data/type/{type}),无权限点与系统字典页 list 不一致问题 */
async loadDictRows() {
const res = await getDicts(this.dictType)
this.dictOptions = res.data || []
return this.dictOptions
},
disabledFormat(item) {
if (this.disables) {
@@ -256,27 +256,36 @@ export default {
async handleRefresh() {
this.loading = true
try {
await this.getDictOptions(this.dictId)
await this.loadDictRows()
} catch (err) {
console.error('刷新字典失败:', err)
} finally {
this.loading = false
}
},
async getDictOptions(dictId) {
const res = await listData({ dictType: this.dictType, pageSize: 1000 })
this.dictOptions = res.rows || []
return this.dictOptions
},
openDictDialog() {
async openDictDialog() {
this.open = true
this.editRowId = ''
this.loading = true
try {
await this.loadDictRows()
this.resetDictForm()
this.form.dictId = this.dictId
this.form.dictType = this.dictType
this.editRowId = '' // 打开弹窗重置编辑状态
} catch (err) {
this.dictOptions = []
console.error('打开字典配置失败:', err)
this.$message.error('字典数据加载失败,请检查字典类型是否正确或稍后重试')
} finally {
this.loading = false
}
},
resetDictForm() {
this.form = { dictId: this.dictId, dictLabel: '', dictValue: '', dictType: this.dictType, sort: 0 }
this.form = {
dictLabel: '',
dictValue: '',
dictType: this.dictType,
dictSort: 0,
status: '0'
}
this.$refs.dictFormRef && this.$refs.dictFormRef.clearValidate()
},
handleKisvTableSync(row) {
@@ -290,7 +299,8 @@ export default {
try {
await addData(this.form)
this.$message.success('字典项新增成功!')
await this.getDictOptions(this.dictId)
await this.loadDictRows()
this.$emit('dict-updated')
this.resetDictForm()
} catch (err) {
this.$message.error('新增失败,请稍后重试')
@@ -309,18 +319,19 @@ export default {
async handleSaveRow(row) {
if (!row.dictLabel || !row.dictValue) {
this.$message.warning('字典标签和字典值不能为空!')
await this.getDictOptions(this.dictId)
await this.loadDictRows()
this.editRowId = '' // 校验失败,也必须还原单元格
return
}
row.sort = 0
if (row.dictSort == null) row.dictSort = 0
this.loading = true
try {
await updateData(row)
this.$message.success('字典项修改成功!')
this.$emit('dict-updated')
} catch (err) {
this.$message.error('修改失败,请稍后重试')
await this.getDictOptions(this.dictId)
await this.loadDictRows()
console.error(err)
} finally {
this.loading = false
@@ -339,7 +350,8 @@ export default {
try {
await delData(row.dictCode)
this.$message.success('删除成功!')
await this.getDictOptions(this.dictId)
await this.loadDictRows()
this.$emit('dict-updated')
} catch (err) {
this.$message.error('删除失败,请稍后重试')
console.error(err)

View File

@@ -1,5 +1,5 @@
<template>
<div class="xlsx-preview">
<div class="xlsx-preview" :style="{ height: height }">
<vue-office-excel :src="src" @render-error="handleExcelError" />
</div>
</template>
@@ -18,6 +18,11 @@ export default {
type: String,
required: true,
description: "Excel文件的URL或路径"
},
height: {
type: String,
default: "70vh",
description: "预览区域高度"
}
},
methods: {
@@ -32,7 +37,6 @@ export default {
<style scoped>
.xlsx-preview {
width: 100%;
height: 70vh;
overflow-y: auto;
}
</style>

View File

@@ -0,0 +1,269 @@
<template>
<div>
<div style="display: flex; align-items: center; margin-bottom: 12px;">
<el-select v-model="selectedValue" placeholder="请选择合同" style="width: 100%">
<el-option v-for="item in contractList" :key="item.orderId" :value="item.orderId"
:label="item.contractCode" />
</el-select>
<!-- 编辑按钮点击打开弹窗 -->
<el-button v-if="mode == 'today'" @click="openSelectDialog" type="primary" size="small" style="margin-left: 8px; padding: 0 12px;">
<i class="el-icon-setting"></i>
</el-button>
<!-- 刷新时不会移除手动添加的合同 -->
<el-button @click="handleRefresh" type="info" size="small" style="margin-left: 8px; padding: 0 12px;">
<i class="el-icon-refresh"></i>
</el-button>
</div>
<!-- 查询所有的合同和当前localstorage中的合同可以对localstorage中的合同进行新增和删除手动新增的合同带有手动添加的标记 -->
<el-dialog title="可选合同配置" :visible.sync="dialogVisible" width="80%" append-to-body>
<el-tabs v-model="activeTab">
<!-- 已配置合同tab -->
<el-tab-pane label="可选合同" name="configured">
<div v-if="contractList.length === 0" style="text-align: center; padding: 20px;">
暂无已配置合同
</div>
<el-table v-else :data="contractList" style="width: 100%" size="mini" height="600">
<el-table-column prop="contractCode" label="合同编号" width="160" />
<el-table-column prop="contractName" label="合同名称" width="180" />
<el-table-column prop="customer" label="客户" width="140" />
<el-table-column prop="salesman" label="销售人员" width="100" />
<el-table-column prop="deliveryDate" label="交付日期" width="110">
<template slot-scope="scope">
{{ scope.row.deliveryDate || '-' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
<el-table-column label="添加方式" width="90">
<template slot-scope="scope">
<el-tag v-if="scope.row.isManual" type="success" size="small">手动</el-tag>
<el-tag v-else type="info" size="small">接口</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="70">
<template slot-scope="scope">
<el-button type="danger" size="mini" @click="removeContract(scope.row.orderId)" plain>
移除
</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<!-- 所有合同tab -->
<el-tab-pane label="所有合同" name="all">
<div style="margin-bottom: 16px;">
<el-input v-model="searchKeyword" placeholder="搜索合同" @input="handleSearch" clearable size="small">
<el-button slot="append" icon="el-icon-search" size="small"></el-button>
</el-input>
</div>
<el-table :data="allContracts" style="width: 100%" size="mini" height="600">
<el-table-column prop="contractCode" label="合同编号" width="160" />
<el-table-column prop="contractName" label="合同名称" width="180" />
<el-table-column prop="customer" label="客户" width="140" />
<el-table-column prop="salesman" label="销售人员" width="100" />
<el-table-column prop="deliveryDate" label="交付日期" width="110">
<template slot-scope="scope">
{{ scope.row.deliveryDate || '-' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
<el-table-column label="状态" width="80">
<template slot-scope="scope">
<el-tag v-if="isContractInList(scope.row.orderId)" type="success" size="small">已添加</el-tag>
<el-tag v-else type="info" size="small">未添加</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button
v-if="!isContractInList(scope.row.orderId)"
type="primary"
size="mini"
@click="addContract(scope.row)"
plain
>
添加
</el-button>
<el-button
v-else
type="danger"
size="mini"
@click="removeContract(scope.row.orderId)"
plain
>
移除
</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="allContracts.length === 0" style="text-align: center; padding: 20px;">
暂无合同数据
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
</template>
<script>
import { listOrder, listTodayOrder } from '@/api/crm/order';
export default {
name: "ContractSelect",
props: {
value: {
type: String,
default: ""
},
mode: {
type: String,
default: "today" // today 或 all
}
},
data() {
return {
contractList: [],
dialogVisible: false,
searchKeyword: '',
allContracts: [],
activeTab: 'configured', // 默认显示已配置合同tab
}
},
computed: {
selectedValue: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
}
}
},
mounted() {
if (this.mode == "today") {
// 从localstorage中获取合同列表
this.loadFromLocalStorage();
} else {
this.loadContractList();
}
},
methods: {
// 从localStorage中加载合同列表
loadFromLocalStorage() {
try {
const storedContracts = localStorage.getItem('todayContracts');
if (storedContracts) {
this.contractList = JSON.parse(storedContracts);
} else {
// 如果localStorage中没有从接口获取
this.loadContractList();
}
} catch (error) {
console.error('Failed to load contracts from localStorage:', error);
this.loadContractList();
}
},
// 保存合同列表到localStorage
saveToLocalStorage() {
try {
localStorage.setItem('todayContracts', JSON.stringify(this.contractList));
} catch (error) {
console.error('Failed to save contracts to localStorage:', error);
}
},
// 加载合同列表
async loadContractList(keyword) {
if (this.mode == "all") {
const res = await listOrder({
pageNum: 1,
pageSize: 1000,
keyword: keyword || undefined,
});
this.contractList = res.rows || [];
}
else if (this.mode == "today") {
const res = await listTodayOrder();
// 获取现有手动添加的合同
const existingManualContracts = this.contractList.filter(item => item.isManual);
// 将接口返回的合同标记为非手动添加
const apiContracts = (res.data || []).map(item => ({
...item,
isManual: false
}));
// 合并合同列表,保留手动添加的合同
this.contractList = [...apiContracts, ...existingManualContracts];
// 去重,避免重复合同
this.contractList = this.contractList.filter((item, index, self) =>
index === self.findIndex(t => t.orderId === item.orderId)
);
// 保存到localStorage
this.saveToLocalStorage();
}
},
// 打开选择弹窗
async openSelectDialog() {
this.dialogVisible = true;
// 加载所有合同供选择
await this.loadAllContracts();
},
// 加载所有合同
async loadAllContracts() {
try {
const res = await listOrder({
pageNum: 1,
pageSize: 1000,
keyword: this.searchKeyword || undefined,
});
// 合并现有合同(包括手动添加的)
const existingContracts = this.contractList;
this.allContracts = [...res.rows || [], ...existingContracts].filter((item, index, self) =>
index === self.findIndex(t => t.orderId === item.orderId)
);
} catch (error) {
console.error('Failed to load all contracts:', error);
this.allContracts = [];
}
},
// 搜索合同
handleSearch() {
this.loadAllContracts();
},
// 检查合同是否在列表中
isContractInList(orderId) {
return this.contractList.some(item => item.orderId === orderId);
},
// 添加合同
addContract(contract) {
if (!this.isContractInList(contract.orderId)) {
this.contractList.push({
...contract,
isManual: true // 标记为手动添加
});
this.saveToLocalStorage();
}
},
// 移除合同
removeContract(orderId) {
this.contractList = this.contractList.filter(item => item.orderId !== orderId);
this.saveToLocalStorage();
},
// 刷新合同列表
handleRefresh() {
this.loadContractList();
},
}
}
</script>

View File

@@ -7,7 +7,7 @@
<el-popover placement="top" width="280" trigger="hover" popper-class="material-params-popover">
<div class="material-params-content">
<div class="params-title">
{{ coil.coilName || '—' }}
{{ coil.itemName || '—' }}
</div>
<div class="params-list">
<div class="param-coil">
@@ -35,6 +35,10 @@
</div>
<div class="param-divider"></div>
<div class="param-coil">
<div class="param-row" v-if="coil.actualWarehouseName">
<span class="param-label">实际库区</span>
<span class="param-value">{{ coil.actualWarehouseName }}</span>
</div>
<div class="param-row" v-if="coil.qualityStatus">
<span class="param-label">质量状态</span>
<span class="param-value">{{ coil.qualityStatus }}</span>
@@ -61,19 +65,19 @@
</div>
<div class="param-row" v-if="coil.length">
<span class="param-label">长度</span>
<span class="param-value">{{ coil.length }}</span>
<span class="param-value">{{ coil.length }}m</span>
</div>
<div class="param-row" v-if="coil.actualLength">
<span class="param-label">实测长度</span>
<span class="param-value">{{ coil.actualLength }}</span>
<span class="param-value">{{ coil.actualLength }}m</span>
</div>
<div class="param-row" v-if="coil.actualThickness">
<span class="param-label">实测厚度</span>
<span class="param-value">{{ coil.actualThickness }}</span>
<span class="param-value">{{ coil.actualThickness }}mm</span>
</div>
<div class="param-row" v-if="coil.actualWidth">
<span class="param-label">实测宽度</span>
<span class="param-value">{{ coil.actualWidth }}</span>
<span class="param-value">{{ coil.actualWidth }}mm</span>
</div>
<div class="param-row" v-if="coil.temperGrade">
<span class="param-label">调制度</span>
@@ -136,8 +140,8 @@
<span class="info-value" :title="coil.warehouseName">{{ coil.warehouseName || '—' }}</span>
</div>
<div class="info-coil">
<span class="info-label">库区</span>
<span class="info-value" :title="coil.actualWarehouseName">{{ coil.actualWarehouseName || '—'
<span class="info-label">规格</span>
<span class="info-value" :title="coil.specification">{{ coil.specification || '—'
}}</span>
</div>
<div class="info-coil">

View File

@@ -32,19 +32,19 @@
</div>
<div class="info-item" v-if="length">
<span class="label">长度</span>
<span class="value">{{ length }}</span>
<span class="value">{{ length }}m</span>
</div>
<div class="info-item" v-if="actualLength">
<span class="label">实测长度</span>
<span class="value">{{ actualLength }}</span>
<span class="value">{{ actualLength }}m</span>
</div>
<div class="info-item" v-if="actualLength">
<span class="label">实测厚度</span>
<span class="value">{{ actualThickness }}</span>
<span class="value">{{ actualThickness }}mm</span>
</div>
<div class="info-item" v-if="actualWidth">
<span class="label">实测宽度</span>
<span class="value">{{ actualWidth }}</span>
<span class="value">{{ actualWidth }}mm</span>
</div>
<div class="info-item">
<span class="label">厂家卷号</span>

View File

@@ -74,8 +74,10 @@ export default {
console.log('仓库API返回数据:', response);
const data = response.data || [];
console.log('处理后的数据:', data);
this.warehouseOptions = this.buildTreeOptions(data);
console.log('构建的树形选项:', this.warehouseOptions);
let options = this.buildTreeOptions(data);
options = this.sortOptionsByUsage(options);
this.warehouseOptions = options;
console.log('构建并排序后的树形选项:', this.warehouseOptions);
}).catch(error => {
console.error("加载仓库选项失败:", error);
this.warehouseOptions = [];
@@ -106,7 +108,36 @@ export default {
return options;
},
getWarehouseUsage() {
try {
const usage = localStorage.getItem('warehouseUsage');
return usage ? JSON.parse(usage) : {};
} catch (error) {
console.error('获取仓库使用记录失败:', error);
return {};
}
},
updateWarehouseUsage(warehouseId) {
try {
const usage = this.getWarehouseUsage();
usage[warehouseId] = (usage[warehouseId] || 0) + 1;
localStorage.setItem('warehouseUsage', JSON.stringify(usage));
} catch (error) {
console.error('更新仓库使用记录失败:', error);
}
},
sortOptionsByUsage(options) {
const usage = this.getWarehouseUsage();
return options.sort((a, b) => {
const usageA = usage[a.warehouseId] || 0;
const usageB = usage[b.warehouseId] || 0;
return usageB - usageA;
});
},
onChange(val) {
if (val) {
this.updateWarehouseUsage(val);
}
this.$emit('input', val);
this.$emit('change', val);
}

View File

@@ -7,7 +7,6 @@
<script>
import { listWarehouse } from '@/api/wms/warehouse';
// import { listActualWarehouse } from '@/api/wms/actualWarehouse';
import { treeActualWarehouseTwoLevel } from '@/api/wms/actualWarehouse';
export default {

View File

@@ -2,7 +2,7 @@
<transition name="el-fade-in-linear">
<div v-if="tooltipVisible && data" class="row-tooltip" :style="adjustedTooltipStyle" ref="rowTooltip">
<slot>
<div class="tooltip-list">
<div class="tooltip-list" :style="{ gridTemplateColumns: `repeat(${columnCount}, 1fr)` }">
<div class="tooltip-item" v-for="field in visibleColumns" :key="field.prop">
<span class="label">{{ field.label }}</span>
<span class="value">{{ formatTooltipValue(data, field) }}</span>
@@ -21,6 +21,10 @@ export default {
type: Array,
default: () => []
},
columnCount: {
type: Number,
default: 2
},
data: {
type: Object,
default: () => ({})
@@ -37,7 +41,20 @@ export default {
computed: {
// 一个列要同时有用 label 和 prop 才显示在浮层中, 并且prop有值时才显示
visibleColumns() {
return this.columns.filter(field => field.label && field.prop && this.data[field.prop])
// 辅助函数:递归/迭代获取多层嵌套的属性值
const getNestedValue = (obj, path) => {
if (!obj || !path) return undefined;
const pathArr = Array.isArray(path) ? path : path.split('.');
return pathArr.reduce((current, key) => {
return current === null || current === undefined ? undefined : current[key];
}, obj);
};
return this.columns.filter(field => {
if (!field.label || !field.prop) return false;
const value = getNestedValue(this.data, field.prop);
return value !== null && value !== undefined && value !== '';
})
},
// 修正后的tooltipStyle / 其实tooltipStyle只包含两个属性top, left 当在屏幕中无法完全展示时,需要根据实际情况调整位置
adjustedTooltipStyle() {
@@ -45,15 +62,47 @@ export default {
const tooltipRect = this.$refs.rowTooltip?.getBoundingClientRect();
if (!tooltipRect) return this.tooltipStyle;
// 检查是否超出底部边界
if (parseInt(top) + tooltipRect.height > window.innerHeight) {
return { ...this.tooltipStyle, top: `${window.innerHeight - tooltipRect.height - 12}px` };
let adjustedTop = parseInt(top);
let adjustedLeft = parseInt(left);
const offset = 20;
const scrollY = window.pageYOffset || document.documentElement.scrollTop;
// 考虑页面滚动的影响
adjustedTop += scrollY;
// 先尝试显示在右下方
let finalTop = adjustedTop;
let finalLeft = adjustedLeft;
// 检查是否超出右边界,如果超出则显示在左方
if (finalLeft + tooltipRect.width > window.innerWidth + (window.pageXOffset || 0)) {
finalLeft = adjustedLeft - tooltipRect.width - offset;
}
// 检查是否超出右侧边界
if (parseInt(left) + tooltipRect.width > window.innerWidth) {
return { ...this.tooltipStyle, left: `${window.innerWidth - tooltipRect.width - 16}px` };
// 检查是否超出下边界,如果超出则显示在上方
if (finalTop + tooltipRect.height > window.innerHeight + scrollY) {
finalTop = adjustedTop - tooltipRect.height - offset;
}
return this.tooltipStyle;
// 确保浮层不会超出上边界
if (finalTop < scrollY) {
finalTop = scrollY + offset;
}
// 确保浮层不会超出左边界
if (finalLeft < 0) {
finalLeft = offset;
}
// 再次检查并调整右边界
if (finalLeft + tooltipRect.width > window.innerWidth + (window.pageXOffset || 0)) {
finalLeft = Math.max(offset, (window.innerWidth - tooltipRect.width) / 2);
}
return {
top: `${finalTop}px`,
left: `${finalLeft}px`
};
}
},
methods: {
@@ -94,13 +143,39 @@ export default {
position: absolute;
background: #ffffff;
border: 1px solid #dcdcdc;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
padding: 12px 14px;
border-radius: 8px;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
padding: 16px 18px;
pointer-events: none;
z-index: 5;
/* max-height: 70%; */
z-index: 9999;
overflow: auto;
transition: all 0.3s ease-in-out;
transition: all 0.25s ease-out;
max-height: 75vh;
min-width: 420px;
}
.tooltip-list {
display: grid;
gap: 10px 16px;
grid-template-columns: repeat(2, 1fr);
}
.tooltip-item {
display: flex;
align-items: flex-start;
line-height: 1.5;
}
.tooltip-item .label {
flex-shrink: 0;
color: #909399;
font-weight: 500;
min-width: 90px;
}
.tooltip-item .value {
color: #303133;
word-break: break-word;
flex: 1;
}
</style>

View File

@@ -18,7 +18,7 @@
<slot name="append" v-bind="scope"></slot>
</template>
<!-- 3. 透传自定义列插槽直接接收<el-table-column> 嵌套的情况 -->
<!-- 3. 透传"自定义列"插槽直接接收<el-table-column> 嵌套的情况 -->
<slot v-bind:tableRef="tableRef"></slot>
<el-table-column v-if="selectionColumn" type="selection" width="55" align="center"></el-table-column>
@@ -27,7 +27,7 @@
</el-table>
<!-- 浮层组件 -->
<KLPTableFloatLayer v-if="floatLayer" :columns="floatLayerColumns" :data="hoveredRow" :tooltipVisible="tooltipVisible"
:tooltipStyle="tooltipStyle" />
:tooltipStyle="tooltipStyle" :columnCount="floatLayerColumnCount" />
</div>
<!-- 扩展层可后续统一添加分页如与 MyPagination 组件联动 -->
<slot name="pagination"></slot>
@@ -78,7 +78,9 @@ export default {
type: Object,
default: () => ({
columns: [],
title: '详细信息'
title: '详细信息',
columnCount: 2,
excludeColumns: ['action']
})
},
height: {
@@ -101,11 +103,16 @@ export default {
},
computed: {
floatLayerColumns() {
console.log(this.floatLayerConfig?.columns?.length > 1)
if (this.floatLayerConfig?.columns?.length > 1) {
return this.floatLayerConfig.columns
}
return this.columns;
},
floatLayerColumnCount() {
return this.floatLayerConfig?.columnCount || 2;
},
excludeColumns() {
return this.floatLayerConfig?.excludeColumns || ['action'];
}
},
methods: {
@@ -157,6 +164,15 @@ export default {
// 浮层相关
handleCellEnter(row, column, cell, event) {
if (!row || !event) return
// 检查是否是排除的列(操作列等)
const excludeColumns = this.excludeColumns
if (excludeColumns.includes(column.property)) {
this.tooltipVisible = false
this.hoveredRow = null
return
}
this.hoveredRow = row
this.tooltipVisible = true
this.updateTooltipPosition(event)

View File

@@ -1,8 +1,8 @@
<template>
<div class="muti-select">
<!-- 下拉选择模式 -->
<div v-if="type === 'select'" class="select-container">
<el-select
v-if="type === 'select'"
v-model="innerValue"
multiple
:placeholder="placeholder"
@@ -11,8 +11,17 @@
:allow-create="allowAdd"
:disabled="disabled"
:size="size"
:collapse-tags="collapseTags"
@change="handleChange"
>
<!-- 全选选项 -->
<!-- <el-option
v-if="showSelectAll && options.length > 0"
key="selectAll"
label="全选"
value="selectAll"
@click="toggleSelectAll"
/> -->
<el-option
v-for="item in options"
:key="item.value"
@@ -20,6 +29,7 @@
:value="item.value"
/>
</el-select>
</div>
<!-- 复选框模式 -->
<div v-else-if="type === 'checkbox'" class="checkbox-group">
@@ -33,14 +43,14 @@
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
<!-- <el-button
<el-button
v-if="showSelectAll && options.length > 0"
type="text"
size="small"
@click="toggleSelectAll"
>
{{ isAllSelected ? '取消全选' : '全选' }}
</el-button> -->
</el-button>
</div>
</div>
</template>
@@ -89,6 +99,10 @@
showSelectAll: {
type: Boolean,
default: true
},
collapseTags: {
type: Boolean,
default: true
}
},
// 计算属性捕获实现双向绑定
@@ -114,7 +128,9 @@
methods: {
// 处理选择变化
handleChange(val) {
this.$emit('change', val.join(','));
// 过滤掉 'selectAll' 选项
const filteredVal = val.filter(item => item !== 'selectAll');
this.$emit('change', filteredVal.join(','));
},
// 处理复选框变化
handleCheckboxChange(val) {

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