lyh
2025-06-12 996e6ef3e621a7c4dfb271bb181c737bd2980630
Merge remote-tracking branch 'origin/master'
已重命名23个文件
已添加43个文件
已修改49个文件
已删除2个文件
4746 ■■■■■ 文件已修改
lxzn-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/aspect/EquipmentHistoryLogAspect.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/dto/MaintenanceStandardImport.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/dto/SecondMaintenanceStandardImport.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/dto/ThirdMaintenanceStandardImport.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/dto/WeekMaintenanceStandardImport.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamInspectionOrderDetail.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamMaintenanceStandardDetail.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamSecondMaintenanceOrder.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamSecondMaintenanceOrderDetail.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamThirdMaintenanceOrder.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamThirdMaintenanceOrderDetail.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamWeekMaintenanceOrderDetail.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/mapper/EamRepairOrderMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/mapper/EamReportRepairMapper.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/mapper/xml/EamRepairOrderMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/mapper/xml/EamReportRepairMapper.xml 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/EamRepairOrderQuery.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/EamRepairOrderRequest.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/EamRepairOrderResponse.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/EamReportRepairQuery.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/service/IEamRepairOrderService.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/service/IEamReportRepairService.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/service/impl/EamRepairOrderServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/service/impl/EamReportRepairServiceImpl.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/util/DateUtils.java 1089 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentMapper.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/MdcEquipmentMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentMapper.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/IEquipmentService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/IMdcAlarmInfoService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/controller/DtBoardController.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/mapper/DtBoardMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/mapper/xml/DtBoardMapper.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/service/IDtBoardService.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/service/impl/DtBoardServiceImpl.java 368 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquAlarm.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquDowntimeInfo.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquOeeMonth.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquOperation.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquRepair.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquRunInfo.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquStatus.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquUtilRate.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquUtilRateMonth.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/controller/AndonOrderController.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/controller/MdcEquipmentPunchController.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/AndonOrder.java 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/MdcEquipmentPunch.java 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/RunningOverallEquipmentEfficiencyJob.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/WebsocketPushEquStatusJob.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/AndonOrderMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcAlarmInfoMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcDowntimeMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcEquipmentPunchMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcEquipmentStatisticalInfoMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcOeeInfoMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/AndonOrderMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcAlarmInfoMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcDowntimeMapper.xml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentPunchMapper.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentStatisticalInfoMapper.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcOeeInfoMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IAndonOrderService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcDowntimeService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentPunchService.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentStatisticalInfoService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcOeeInfoService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/AndonOrderServiceImpl.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcAlarmInfoServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcDowntimeServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentPunchServiceImpl.java 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentStatisticalInfoServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcOeeInfoServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/vo/AndonOrderWebSocketVo.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-msi/src/main/java/org/jeecg/modules/msi/utils/WebServiceUtil.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/MdcProductionMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/MdcProductionMapper.xml 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/IMdcProductionService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/MdcProductionServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/BaseToolsController.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/PreparationOrderController.java 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/convert/OutboundOrderConvert.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/convert/PreparationOrderConvert.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/BaseTools.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/OutboundDetail.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/OutboundOrder.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/PreparationOrder.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/PreparationOrderDetail.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/dto/PreparationOrderAndDetailDto.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaBladeVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaCommonToolVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaHolesToolsVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaMillToolVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaThreadingToolVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaTurningToolsVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/enums/OutStorehouseType.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/enums/PreparationOrderStatus.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/PreparationOrderDetailMapper.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/PreparationOrderMapper.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/BaseToolsMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/PreparationOrderDetailMapper.xml 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/PreparationOrderMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IPreparationOrderDetailService.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IPreparationOrderService.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/InboundOrderServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/OutboundOrderServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/PreparationOrderDetailServiceImpl.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/PreparationOrderServiceImpl.java 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
@@ -598,6 +598,11 @@
    String DICT_MDC_STAFF_TEAM = "mdc_staff_team";
    /**
     * é©±åŠ¨å‚æ•°å•ä½å­—å…¸ç¼–å·
     */
    String DICT_EQUIPMENT_RUN_UNIT = "equipment_run_unit";
    /**
     * åŠ ç­æ•°æ® è‡ªåŠ¨è®¡ç®—æ ‡è¯† 1(是) 2(否)
     */
    Integer AUTO_FLAG_Y = 1;
@@ -612,8 +617,11 @@
     */
    String CLOSE_TYPE_0 = "0";
    String CLOSE_TYPE_1 = "1";
    String ORG_TYPE = "3";
    /**
     * äº§çº¿ç±»åž‹ 1一级部门 2子部门 3子部门
     */
    String ORG_TYPE_2 = "2";
    String ORG_TYPE_3 = "3";
    Integer SHIFT_TYPE_1 = 1;
    Integer SHIFT_TYPE_2 = 2;
lxzn-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java
@@ -14,6 +14,7 @@
/**
 * websocket å‰ç«¯å°†token放到子协议里传入 ä¸ŽåŽç«¯å»ºç«‹è¿žæŽ¥æ—¶éœ€è¦ç”¨åˆ°http协议,此处用于校验token的有效性
 *
 * @Author taoYan
 * @Date 2022/4/21 17:01
 **/
@@ -35,6 +36,7 @@
            redisUtil = SpringContextUtils.getBean(RedisUtil.class);
        }
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        if (request.getHeader(TOKEN_KEY) != null) {
        String token = request.getHeader(TOKEN_KEY);
        log.debug("Websocket连接 Token安全校验,Path = {},token:{}", request.getRequestURI(), token);
@@ -48,6 +50,7 @@
        }
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        response.setHeader(TOKEN_KEY, token);
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }
lxzn-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
@@ -99,6 +99,7 @@
        filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码
        filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除
        filterChainDefinitionMap.put("/msi/**", "anon"); //集成接口
        filterChainDefinitionMap.put("/board/dtBoard/**", "anon"); //数字孪生看板接口排除
        filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/doc.html", "anon");
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/aspect/EquipmentHistoryLogAspect.java
@@ -100,8 +100,28 @@
                }
                break;
            case SECOND_MAINTENANCE:
                if (result instanceof EamSecondMaintenanceOrder) {
                    EamSecondMaintenanceOrder order = (EamSecondMaintenanceOrder) result;
                    if (SecondMaintenanceStatusEnum.COMPLETE.name().equals(order.getMaintenanceStatus())) {
                        log.setEquipmentId(order.getEquipmentId());
                        log.setBusinessId(order.getId());
                        log.setOperator(order.getOperator());
                        log.setDescription(order.getConfirmComment());
                        log.setCreateTime(order.getActualEndTime());
                    }
                }
                break;
            case THIRD_MAINTENANCE:
                if (result instanceof EamThirdMaintenanceOrder) {
                    EamThirdMaintenanceOrder order = (EamThirdMaintenanceOrder) result;
                    if (ThirdMaintenanceStatusEnum.COMPLETE.name().equals(order.getMaintenanceStatus())) {
                        log.setEquipmentId(order.getEquipmentId());
                        log.setBusinessId(order.getId());
                        log.setOperator(order.getOperator());
                        log.setDescription(order.getLeaderConfirmComment());
                        log.setCreateTime(order.getActualEndTime());
                    }
                }
                break;
            case REPORT_REPAIR:
                if (result instanceof EamReportRepair) {
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/dto/MaintenanceStandardImport.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/dto/SecondMaintenanceStandardImport.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/dto/ThirdMaintenanceStandardImport.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/dto/WeekMaintenanceStandardImport.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamInspectionOrderDetail.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamMaintenanceStandardDetail.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamSecondMaintenanceOrder.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamSecondMaintenanceOrderDetail.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamThirdMaintenanceOrder.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamThirdMaintenanceOrderDetail.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamWeekMaintenanceOrderDetail.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/mapper/EamRepairOrderMapper.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/mapper/EamReportRepairMapper.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/mapper/xml/EamRepairOrderMapper.xml
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/mapper/xml/EamReportRepairMapper.xml
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/EamRepairOrderQuery.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/EamRepairOrderRequest.java
ÎļþÃû´Ó lxzn-module-eam/src/main/java/org/jeecg/modules/eam/request/EamRepairOrderRequest.java ÐÞ¸Ä
@@ -5,9 +5,7 @@
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.api.vo.FileUploadResult;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.modules.flowable.domain.vo.FlowTaskVo;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
import java.util.List;
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/EamRepairOrderResponse.java
ÎļþÃû´Ó lxzn-module-eam/src/main/java/org/jeecg/modules/eam/request/EamRepairOrderResponse.java ÐÞ¸Ä
@@ -8,9 +8,7 @@
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.modules.eam.entity.EamRepairOrder;
import org.jeecg.modules.eam.entity.EamReportRepair;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.beans.BeanUtils;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/request/EamReportRepairQuery.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/service/IEamRepairOrderService.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/service/IEamReportRepairService.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/service/impl/EamRepairOrderServiceImpl.java
ÎļþÃû´Ó lxzn-module-eam/src/main/java/org/jeecg/modules/eam/service/impl/EamRepairOrderServiceImpl.java ÐÞ¸Ä
@@ -33,13 +33,13 @@
import org.jeecg.modules.eam.service.IEamEquipmentService;
import org.jeecg.modules.eam.service.IEamRepairOrderService;
import org.jeecg.modules.eam.service.IEamReportRepairService;
import org.jeecg.modules.eam.util.DateUtils;
import org.jeecg.modules.flowable.apithird.business.entity.FlowMyBusiness;
import org.jeecg.modules.flowable.apithird.business.service.IFlowMyBusinessService;
import org.jeecg.modules.flowable.apithird.service.FlowCallBackServiceI;
import org.jeecg.modules.flowable.apithird.service.FlowCommonService;
import org.jeecg.modules.flowable.service.IFlowDefinitionService;
import org.jeecg.modules.flowable.service.IFlowTaskService;
import org.jeecg.modules.mdc.util.DateUtils;
import org.jeecg.modules.system.service.ISysBusinessCodeRuleService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.vo.UserSelector;
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/service/impl/EamReportRepairServiceImpl.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/util/DateUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1089 @@
package org.jeecg.modules.eam.util;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DateUtils {
    private final static long DAYTIMESUNSET = 86400;
    /**
     * @return å¾—到明天
     */
    public static Date getNextDay(Date d1) {
        long d2 = d1.getTime() + 86400 * 1000;
        return new Date(d2);
    }
    /**
     * @return å¾—到昨天
     */
    public static Date getPreviousDay(Date d1) {
        long d2 = d1.getTime() - 86400 * 1000;
        return new Date(d2);
    }
    /**
     * @return è¿”回时间差的语言描述  å¦‚1天2小时5分6秒
     */
    public static String different(Date d1, Date d2) {
        if (d1 == null || d2 == null) {
            return "";
        }
        StringBuilder strB = new StringBuilder();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            //毫秒ms
            long diff = d2.getTime() - d1.getTime();
            long diffSeconds = diff / 1000 % 60;
            long diffMinutes = diff / (60 * 1000) % 60;
            long diffHours = diff / (60 * 60 * 1000) % 24;
            long diffDays = diff / (24 * 60 * 60 * 1000);
            if (diffDays > 0) {
                strB.append(diffDays + " å¤© ");
                strB.append(diffHours + " å°æ—¶ ");
                strB.append(diffMinutes + " åˆ†é’Ÿ ");
                strB.append(diffSeconds + " ç§’ ");
            } else if (diffHours > 0) {
                strB.append(diffHours + " å°æ—¶ ");
                strB.append(diffMinutes + " åˆ†é’Ÿ ");
                strB.append(diffSeconds + " ç§’ ");
            } else if (diffMinutes > 0) {
                strB.append(diffMinutes + " åˆ†é’Ÿ ");
                strB.append(diffSeconds + " ç§’ ");
            } else {
                strB.append(diffSeconds + " ç§’ ");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strB.toString();
    }
    /**
     * @return èŽ·å–ä¸¤ä¸ªdate的时间差,结果为秒 é™¤
     */
    public static long differentSecond(Date startDate, Date endDate) {
        return new BigDecimal(endDate.getTime() - startDate.getTime()).divide(new BigDecimal("1000"), 0, BigDecimal.ROUND_HALF_UP).longValue();
//        return (endDate.getTime() - startDate.getTime()) / 1000;
    }
    /**
     * @return èŽ·å–ä¸¤ä¸ªdate的时间差,结果为分钟
     */
    public static Integer differentMinutes(Date startDate, Date endDate) {
        return new BigDecimal(endDate.getTime() - startDate.getTime()).divide(new BigDecimal("60000"), 0, RoundingMode.HALF_UP).intValue();
    }
    /**
     * @return è¿”回传入时间的0点0分0秒
     */
    public static Date getTodayZero(Date d) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }
    /**
     * @return è¿”回传入时间的0点0分0秒
     */
    public static Date getTomorrowZero(Date d) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.add(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }
    /**
     * @return åˆ¤æ–­æ—¶é—´æ˜¯å¦æ˜¯å½“天
     */
    public static boolean isTaday(Date date) {
        Date now = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        String nowDay = sf.format(now);
        String day = sf.format(date);
        return day.equals(nowDay);
    }
    /**
     * @return åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦ä¸ºåŒä¸€å¤©
     */
    public static boolean isOneDay(Date d1, Date d2) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        String d1Str = sf.format(d1);
        String d2Str = sf.format(d2);
        return d1Str.equals(d2Str);
    }
    /**
     * @return åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦ä¸ºåŒä¸€å¹´
     */
    public static boolean isOneYear(Date d1, Date d2) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy");
        String d1Str = sf.format(d1);
        String d2Str = sf.format(d2);
        return d1Str.equals(d2Str);
    }
    public static String dateProportion(Date start, Date end) {
        float differentSecond = DateUtils.differentSecond(start, end);
        float f = differentSecond / DAYTIMESUNSET * 100;
        return String.format("%.2f", f) + "%";
    }
    public static Date strToDate(String dateStr, String format) {
        SimpleDateFormat sf = new SimpleDateFormat(format);
        Date result = null;
        try {
            result = sf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }
    public static final String STR_DATE = "yyyy-MM-dd";
    public static final String STRDATE = "yyyyMMdd";
    public static final String STR_YEAR_MONTH = "yyyy-MM";
    public static final String STRYEARMONTH = "yyyyMM";
    public static final String STR_DATE_TIME = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String STR_DATE_TIME_SMALL = "yyyy-MM-dd HH:mm:ss";
    public static final String STR_DATE_TIME_MIN = "yyyy-MM-dd HH:mm";
    public static final String STR_DATE_TIME_HOUR = "yyyy-MM-dd HH";
    public static final String STR_DATE_TIME_FULL = "yyyyMMddHHmmssSSS";
    public static final String STR_HHMMSS = "HH:mm:ss";
    public static final String STR_HHMM = "HH:mm";
    public static final String STR_MMDD = "MM-dd";
    /**
     * <p>
     * Description: å®žé™…投标月份
     * </p>
     *
     * @param startDate
     * @param endDate
     * @return obj [0] å®žé™…投标月份 ä¾‹å¦‚实际投标月份(3.86)意义是3个月又26天 obj[1] å®žé™…取整月份 ï¼ˆ3)
     */
    public static Integer getRealMonth(Date startDate, Date endDate) {
        Integer month = 0;
        Calendar start = Calendar.getInstance();
        start.setTime(startDate);
        Calendar end = Calendar.getInstance();
        end.setTime(endDate);
        int year = start.get(Calendar.YEAR);
        int year2 = end.get(Calendar.YEAR);
        int month2 = start.get(Calendar.MONTH);
        int month3 = end.get(Calendar.MONTH);
        try {
            while (start.before(end)) {
                start.add(Calendar.MONTH, 1);
                month++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        int day2 = start.get(Calendar.DAY_OF_MONTH);
        int day3 = end.get(Calendar.DAY_OF_MONTH);
        int tmpYear = year2 - year;
        if (day2 == day3) {
            return (tmpYear * 12) + (month3 - month2);
        }
        return month == 0 ? month : (month - 1);
    }
    public static Date getNow() {
        return new Date(System.currentTimeMillis());
    }
    public static int getDayOfMonth() {
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        return day;
    }
    /**
     * <p>
     * Description: ä¿®æ”¹æ—¶é—´ä¸ºæŒ‡å®šæ—¶é—´å½“天的23:59:59.000
     * </p>
     *
     * @param date éœ€è¦ä¿®æ”¹çš„æ—¶é—´
     * @return ä¿®æ”¹åŽçš„æ—¶é—´
     */
    public static Date fillTime(Date date) {
        Date result = removeTime(date);
        result.setTime(result.getTime() + 24 * 60 * 60 * 1000 - 1000); // åР䏀天
        return result;
    }
    /**
     * @param date å½“前时间
     * @param i    å¾€å‰å‡ å¤©
     * @return
     */
    public static Date fillBeforeTime(Date date, Integer i) {
        Date result = removeTime(date);
        Calendar calendar = Calendar.getInstance(); // å¾—到日历
        calendar.setTime(result);// æŠŠå½“前时间赋给日历
        calendar.add(Calendar.DAY_OF_MONTH, i); // è®¾ç½®ä¸ºå‰ä¸€å¤©
        result.setTime(calendar.getTime().getTime() + 24 * 60 * 60 * 1000
                - 1000); // åР䏀天
        return result;
    }
    /**
     * <p>
     * Description: ä¿®æ”¹æ—¶é—´ä¸ºæŒ‡å®šæ—¶é—´å‰ä¸€å¤©çš„00:00:00
     * </p>
     *
     * @param date éœ€è¦ä¿®æ”¹çš„æ—¶é—´
     * @return ä¿®æ”¹åŽçš„æ—¶é—´
     */
    public static Date plusTime(Date date, Integer i) {
        Date result = removeTime(date);
        Calendar calendar = Calendar.getInstance(); // å¾—到日历
        calendar.setTime(result);// æŠŠå½“前时间赋给日历
        calendar.add(Calendar.DAY_OF_MONTH, i); // è®¾ç½®ä¸ºå‰ä¸€å¤©
        return calendar.getTime();
    }
    /**
     * <p>
     * Description: åŽ»æŽ‰æ—¥æœŸæ—¶é—´ä¸­çš„æ—¶é—´éƒ¨åˆ†
     * </p>
     * å¦‚: 2013-11-11 18:56:33 ---> 2013-11-11 00:00:00
     *
     * @param date éœ€è¦ä¿®æ”¹çš„æ—¶é—´
     * @return ä¿®æ”¹åŽçš„æ—¶é—´
     */
    public static Date removeTime(Date date) {
        Date result = null;
        try {
            SimpleDateFormat df = new SimpleDateFormat(STR_DATE);
            String dateStr = df.format(date);
            result = df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * <p>
     * Description: æŒ‰é»˜è®¤æ ¼å¼(yyyy-MM-dd HH:mm:ss.SSS)获取时间字符串
     * </p>
     *
     * @param date è¦è½¬æ¢çš„æ—¥æœŸ
     * @return è½¬æ¢åŽçš„æ—¶é—´å­—符串
     */
    public static String format(Date date) {
        SimpleDateFormat df = new SimpleDateFormat(STR_DATE_TIME);
        return df.format(date);
    }
    public static Date parseDate(Date date, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        try {
            date = df.parse(df.format(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    public static Date getDelayedYear() {
        Calendar curr = Calendar.getInstance();
        curr.set(Calendar.YEAR, curr.get(Calendar.YEAR) + 1);
        Date date = curr.getTime();
        return date;
    }
    /**
     * <p>
     * Description: æŒ‰æŒ‡å®šæ ¼å¼èŽ·å–æ—¶é—´å­—ç¬¦ä¸²
     * </p>
     *
     * @param date   è¦è½¬æ¢çš„æ—¥æœŸ
     * @param format æ ¼å¼,例如:yyyy-MM-dd HH:mm:ss.SSS
     * @return è½¬æ¢åŽçš„æ—¶é—´å­—符串
     */
    public static String format(Date date, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        return df.format(date);
    }
    /**
     * <p>
     * Description: åŠ æœˆå‡½æ•°
     * </p>
     *
     * @param month æœˆä»½æ•°
     * @return
     */
    public static Date addMonth(Integer month, Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.MONTH, month);
        return c.getTime();
    }
    public static Boolean greater(Date startTime, Date endTime) {
        return startTime.getTime() > endTime.getTime();
    }
    public static Boolean less(Date startTime, Date endTime) {
        return startTime.getTime() < endTime.getTime();
    }
    public static Boolean equals(Date startTime, Date endTime) {
        return startTime.getTime() == endTime.getTime();
    }
    public static Integer getDiffMonth(Calendar c, Calendar c1) {
        return (c.get(Calendar.YEAR) - c1.get(Calendar.YEAR)) * 12
                + (c.get(Calendar.MONTH) - c1.get(Calendar.MONTH));
    }
    /**
     * æ˜¯å¦ä¸ºåŒä¸€å¤©
     */
    public static boolean equalsDay(Date a, Date b) {
        return removeTime(a).getTime() == removeTime(b).getTime();
    }
    public static Integer getDays(Date startTime, Date endTime) {
        Calendar c = Calendar.getInstance();
        c.setTime(startTime);
        Calendar c1 = Calendar.getInstance();
        c1.setTime(endTime);
        long t1 = c.getTimeInMillis();
        long t2 = c1.getTimeInMillis();
        // è®¡ç®—天数
        Long days = (t2 - t1) / (24 * 60 * 60 * 1000);
        return days.intValue();
    }
    public static Integer getSeconds(Date startTime, Date endTime) {
        try {
            Calendar c = Calendar.getInstance();
            c.setTime(startTime);
            Calendar c1 = Calendar.getInstance();
            c1.setTime(endTime);
            long t1 = c.getTimeInMillis();
            long t2 = c1.getTimeInMillis();
            // è®¡ç®—ç§’æ•°
            Long days = (t2 - t1) / (1000);
            return days.intValue();
        } catch (Exception e) {
            return 0;
        }
    }
    //获取小时差
    public static double subHours(Date startTime, Date endTime) {
        Calendar c = Calendar.getInstance();
        c.setTime(startTime);
        Calendar c1 = Calendar.getInstance();
        c1.setTime(endTime);
        double t1 = c.getTimeInMillis();
        double t2 = c1.getTimeInMillis();
        // è®¡ç®—天数
        double hours = (t2 - t1) / (1000 * 60 * 60);
        return Double.valueOf(new DecimalFormat("#.00").format(hours));
    }
    //根据当前时间和出生日期获取年龄
    public static int getAge(Date birthDay) {
        Calendar cal = Calendar.getInstance();
        // å–出系统当前时间的年、月、日部分
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);
        // å–出出生日期的年、月、日部分
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        // å½“前年份与出生年份相减,初步计算年龄
        int age = yearNow - yearBirth;
        // å½“前月份与出生日期的月份相比,如果月份小于出生月份,则年龄上减1,表示不满多少周岁
        if (monthNow <= monthBirth) {
            // å¦‚果月份相等,在比较日期,如果当前日,小于出生日,也减1,表示不满多少周岁
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                age--;
            }
        }
        return age;
    }
    public static Date subDays(Date startTime, Integer day) {
        Calendar c = Calendar.getInstance();
        c.setTime(startTime);
        c.add(Calendar.DATE, day * -1);
        return c.getTime();
    }
    public static Date addDays(Date startTime, Integer day) {
        Calendar c = Calendar.getInstance();
        c.setTime(startTime);
        c.add(Calendar.DATE, day);
        return c.getTime();
    }
    /*public static Date addHours(Date startTime, Integer hours) {
        Calendar c = Calendar.getInstance();
        c.setTime(startTime);
        c.add(Calendar.HOUR, hours );
        return c.getTime();
    }*/
    public static Date toDate(String date, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        try {
            return df.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static Date toDateFull(String date) {
        SimpleDateFormat df = new SimpleDateFormat(STR_DATE_TIME);
        try {
            return df.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static Date toDateMedium(String date) {
        SimpleDateFormat df = new SimpleDateFormat(STR_DATE_TIME_SMALL);
        try {
            Date dd = df.parse(date);
            return dd;
        } catch (ParseException e) {
            return null;
        }
    }
    public static Integer getDate(Date date) {
        if (date != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int day = calendar.get(Calendar.DATE);
            return day;
        }
        return null;
    }
    public static Integer getYear() {
        return getYear(new Date());
    }
    public static Integer getYear(Date date) {
        if (date != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int year = calendar.get(Calendar.YEAR);
            return year;
        }
        return null;
    }
    public static Integer getMonth() {
        return getMonth(new Date());
    }
    public static Integer getMonth(Date date) {
        if (date != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int month = calendar.get(Calendar.MONTH);
            return month + 1;
        }
        return null;
    }
    public static Integer getDay() {
        return getDay(new Date());
    }
    public static Integer getDay(Date date) {
        if (date != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int day = calendar.get(Calendar.DAY_OF_MONTH);
            return day;
        }
        return null;
    }
    public static Date[] getMonthStartTimeAndEndTime(Integer month) {
        Calendar calendar = Calendar.getInstance();
        Date[] dates = new Date[2];
        Date startTime = null;
        Date endsTime = null;
        if (month != null) {
            calendar.set(Calendar.MONTH, month);
            //获得到本月的第一天
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
            startTime = calendar.getTime();
            startTime = DateUtils.removeTime(startTime);
            //获得到本月的最后一天
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            endsTime = calendar.getTime();
            endsTime = DateUtils.fillTime(endsTime);
        }
        dates[0] = startTime;
        dates[1] = endsTime;
        return dates;
    }
    public static Date[] getMonthStartTimeAndEndTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Integer month = calendar.get(Calendar.MONTH);
        Date[] dates = new Date[2];
        Date startTime = null;
        Date endsTime = null;
        if (month != null) {
            calendar.set(Calendar.MONTH, month);
            //获得到本月的第一天
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
            startTime = calendar.getTime();
            startTime = DateUtils.removeTime(startTime);
            //获得到本月的最后一天
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            endsTime = calendar.getTime();
            endsTime = DateUtils.fillTime(endsTime);
        }
        dates[0] = startTime;
        dates[1] = endsTime;
        return dates;
    }
    /**
     * èŽ·å–days天的时间区间,endTime ä¸ºå½“天的后一天0点,
     * startTime ä¸ºendTime前days天
     *
     * @param days
     * @return
     */
    public static Date[] getDaysStartTimeAndEndTime(Integer days) {
        Date[] dates = new Date[2];
        Date endDate = plusTime(removeTime(getNow()), 1);
        Date startDate = subDays(endDate, days);
        dates[0] = startDate;
        dates[1] = endDate;
        return dates;
    }
    /**
     * æ ¹æ®æŸä¸€å¹´èŽ·å–æœ€åŽä¸€å¤©çš„æ—¶é—´
     * 2013 ---> 2013-12-31 23:59:59.000
     *
     * @param year
     * @return
     */
    public static Date getYearEndDay(Integer year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date yearLast = calendar.getTime();
        Date lastYear = DateUtils.fillTime(yearLast);
        return lastYear;
    }
    /**
     * èŽ·å–start/end的所有日期字符串 æ ¼å¼yyyy-MM-dd
     *
     * @param start
     * @param end
     * @return
     */
    public static List<String> getDatesStringList(Date start, Date end, String strDate) {
        List<String> list = new ArrayList<>();
        int i = getDays(start, end);
        for (int j = 0; j <= i; j++) {
            if (j == 0) {
                list.add(format(start, strDate));
            } else {
                list.add(format(plusTime(start, j), strDate));
            }
        }
        return list;
    }
    /**
     * èŽ·å–start/end的所有日期字符串 æ ¼å¼yyyy-MM-dd
     *
     * @param start
     * @param end
     * @return
     */
    public static List<String> getDatesStringList(Date start, Date end) {
        List<String> list = new ArrayList<>();
        int i = getDays(start, end);
        for (int j = 0; j <= i; j++) {
            if (j == 0) {
                list.add(format(start, STR_DATE));
            } else {
                list.add(format(plusTime(start, j), STR_DATE));
            }
        }
        return list;
    }
    /**
     * èŽ·å–start/end的所有日期字符串 æ ¼å¼yyyyMMdd
     *
     * @param start
     * @param end
     * @return
     */
    public static List<String> getDatesStringList2(Date start, Date end) {
        List<String> list = new ArrayList<>();
        int i = getDays(start, end);
        for (int j = 0; j <= i; j++) {
            if (j == 0) {
                list.add(format(start, STRDATE));
            } else {
                list.add(format(plusTime(start, j), STRDATE));
            }
        }
        return list;
    }
    /**
     * èŽ·å–start/end的所有日期字符串 æ ¼å¼MM-dd
     *
     * @param start
     * @param end
     * @return
     */
    public static List<String> getDatesStringLists(Date start, Date end) {
        List<String> list = new ArrayList<>();
        int i = getDays(start, end);
        for (int j = 0; j <= i; j++) {
            if (j == 0) {
                list.add(format(start, STR_MMDD));
            } else {
                list.add(format(plusTime(start, j), STR_MMDD));
            }
        }
        return list;
    }
    public static List<String> getMonthBetween(Date start, Date end) {
        List<String> list = new ArrayList<>();
        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();
        min.setTime(start);
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
        max.setTime(end);
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
        Calendar curr = min;
        while (curr.before(max)) {
            list.add(format(curr.getTime(), STR_YEAR_MONTH));
            curr.add(Calendar.MONTH, 1);
        }
        return list;
    }
    /**
     * èŽ·å–dateStr的日期格式yyyy-MM-dd
     *
     * @param dateStr
     * @return
     */
    public static Date getShortDate(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(STR_DATE);
        Date startTime = null;
        try {
            startTime = sdf.parse(dateStr);
        } catch (ParseException e) {
        }
        return startTime == null ? removeTime(new Date()) : startTime;
    }
    /**
     * èŽ·å–dateStr的日期格式yyyyMMdd
     *
     * @param dateStr
     * @return
     */
    public static Date getShortDate2(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(STRDATE);
        Date startTime = null;
        try {
            startTime = sdf.parse(dateStr);
        } catch (ParseException e) {
        }
        return startTime == null ? removeTime(new Date()) : startTime;
    }
    public static Date getFormatDate(String dateStr, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date startTime = null;
        try {
            startTime = sdf.parse(dateStr);
        } catch (ParseException e) {
        }
        return startTime == null ? removeTime(new Date()) : startTime;
    }
    /**
     * @param time
     * @param n
     * @return åœ¨ä¸€ä¸ªæ—¶é—´ä¸ŠåŠ ç§’
     */
    public static Date addSecond(Date time, Integer n) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.SECOND, n);
        return c.getTime();
    }
    /**
     * @param time
     * @param n
     * @return åœ¨ä¸€ä¸ªæ—¶é—´ä¸ŠåŠ åˆ†é’Ÿ
     */
    public static Date addMinute(Date time, Integer n) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.MINUTE, n);
        return c.getTime();
    }
    /**
     * @param time
     * @param n
     * @return åœ¨ä¸€ä¸ªæ—¶é—´ä¸ŠåŠ å°æ—¶
     */
    public static Date addHour(Date time, Integer n) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.HOUR_OF_DAY, n);
        return c.getTime();
    }
    /**
     * èŽ·å–start/end的所有日期字符串 æ ¼å¼yyyy-MM-dd
     *
     * @param start
     * @param end
     * @return
     */
    public static List<String> getDateMonth(String start, String end) {
        List<String> list = new ArrayList<>();
        SimpleDateFormat yyyyMM = new SimpleDateFormat("yyyy-MM");
        Date startyear = null;
        try {
            startyear = yyyyMM.parse(start);
            Date endyear = yyyyMM.parse(end);
            Calendar dd = Calendar.getInstance();//定义日期实例
            dd.setTime(startyear);//设置日期起始时间
            while (dd.getTime().before(endyear)) {//判断是否到结束日期
                String str = yyyyMM.format(dd.getTime());
                dd.add(Calendar.MONTH, 1);//进行当前日期月份加1
                list.add(str);
            }
            list.add(yyyyMM.format(endyear));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return list;
    }
    /**
     * èŽ·å–start/end的所有日期字符串 æ ¼å¼yyyy
     *
     * @param start
     * @param end
     * @return
     */
    public static List<String> getDateYear(String start, String end) {
        List<String> list = new ArrayList<>();
        SimpleDateFormat yyyy = new SimpleDateFormat("yyyy");
        Date startyear = null;
        try {
            startyear = yyyy.parse(start);
            Date endyear = yyyy.parse(end);
            Calendar dd = Calendar.getInstance();//定义日期实例
            dd.setTime(startyear);//设置日期起始时间
            while (dd.getTime().before(endyear)) {//判断是否到结束日期
                String str = yyyy.format(dd.getTime());
                dd.add(Calendar.YEAR, 1);//进行当前日期月份加1
                list.add(str);
            }
            list.add(yyyy.format(endyear));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return list;
    }
    /**
     * èŽ·å–å½“å‰æ—¶é—´ å®šä½åˆ°å°æ—¶
     * æ ¼å¼ä¸º yyyy-MM-dd hh:mm
     * ä¾‹ï¼š2018-02-27 11:00
     *
     * @return
     */
    public static Date getNowHourDate() {
        Date now = getNow();
        Date result;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        String dateStr = format(now, STR_DATE);
        dateStr = dateStr + " " + (hour < 10 ? "0" + hour : hour) + ":00";
        result = toDate(dateStr, STR_DATE_TIME_MIN);
        return result;
    }
    /**
     * èŽ·å–æ¯æ—¥8:11或11:11的时间点
     *
     * @return
     */
    public static Date getNowHourDateTo() {
        Date now = getNow();
        Date result;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        if (hour != 8 && hour != 11) {
            return null;
        }
        int minute = calendar.get(Calendar.MINUTE);
        if (minute < 11) {
            return null;
        }
        String dateStr = format(now, STR_DATE);
        dateStr = dateStr + " " + (hour < 10 ? "0" + hour : hour) + ":11";
        result = toDate(dateStr, STR_DATE_TIME_MIN);
        return result;
    }
    /**
     * èŽ·å–æ¯æ—¥8:00、13:00、20:00的时间点
     *
     * @return
     */
    public static List<Date> getHourDateList(Date time) {
        List<Date> result = new ArrayList<>();
        result.add(addHour(time, 8));
        result.add(addHour(time, 13));
        result.add(addHour(time, 20));
        return result;
    }
    /**
     * èŽ·å–ä¸Šæœˆçš„æœ€åŽä¸€å¤©
     *
     * @return
     */
    public static Date getPreviousMonthLastDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        return DateUtils.removeTime(calendar.getTime());
    }
    /**
     * èŽ·å–end时间月的第一天
     *
     * @param end æœˆä»½æœ€åŽä¸€å¤©
     * @return
     */
    public static Date getTheMonthFirstDay(Date end) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(end);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }
    public static String secToTimeHour(int time) {
        String timeStr = null;
        int hour = 0;
        if (time <= 0) {
            return "0小时";
        } else {
            BigDecimal bigDecimal = new BigDecimal(time);
            BigDecimal bigDecimal1 = new BigDecimal(3600);
            BigDecimal hourBigDecimal = new BigDecimal(0);
            hourBigDecimal = new BigDecimal(String.valueOf(bigDecimal)).
                    divide(new BigDecimal(String.valueOf(bigDecimal1)), 2, BigDecimal.ROUND_HALF_UP);
            timeStr = hourBigDecimal + "小时";
        }
        return timeStr;
    }
    public static String secToTime(int time) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0)
            return " ";
        else {
            minute = time / 60;
            if (minute < 60) {
                second = time % 60;
                timeStr = unitFormat(minute) + "分" + unitFormat(second) + " ç§’";
            } else {
                hour = minute / 60;
                minute = minute % 60;
                second = time - hour * 3600 - minute * 60;
                timeStr = unitFormat(hour) + "小时" + unitFormat(minute) + "分" + unitFormat(second) + "秒";
            }
        }
        return timeStr;
    }
    public static String unitFormat(int i) {
        String retStr = null;
        if (i >= 0 && i < 10)
            retStr = "0" + Integer.toString(i);
        else
            retStr = "" + i;
        return retStr;
    }
    /**
     * éªŒè¯æ—¶é—´
     *
     * @param time æ—¶é—´å­—符串 HH:mm
     * @return éªŒè¯æˆåŠŸè¿”å›žtrue,验证失败返回false
     */
    public static boolean checkTime(String time) {
        String regex = "([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
        return Pattern.matches(regex, time);
    }
    /**
     * èŽ·å–æ¯æ—¥07:30:00的时间点
     * æ ¼å¼ä¸º yyyy-MM-dd HH:mm:ss
     * ä¾‹ï¼š2018-05-28 07:30:00
     *
     * @return
     */
    public static Date getHourDateTo(Date now, String time) {
        String dateStr = format(now, STR_DATE);
        dateStr = dateStr + " " + time;
        Date result = toDate(dateStr, STR_DATE_TIME_SMALL);
        return result;
    }
    public static Date setTimeForDay(Date theDate, String planTime) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(theDate);
        String[] times = planTime.split(":");
        cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(times[0]));
        cal.set(Calendar.MINUTE, Integer.parseInt(times[1]));
        cal.set(Calendar.SECOND, Integer.parseInt(times[2]));
        return cal.getTime();
    }
    public static long getTimeWithOutDay(Date d) {
        return d.getTime() / 1000 % 86400;
    }
    /**
     * @param lo æ¯«ç§’æ•°
     * @return String yyyy-MM-dd HH:mm:ss
     * @Description: long类型转换成日期
     */
    public static String longToDate(long lo) {
        Date date = new Date(lo);
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sd.format(date);
    }
    /**
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<Date> getWeekDays(LocalDate startDate, LocalDate endDate) {
        List<Date> result = new ArrayList<>();
        List<LocalDate> dateList = Stream.iterate(startDate, localDate -> localDate.plusDays(1))
                .limit(ChronoUnit.DAYS.between(startDate, endDate) + 1)
                .filter(localDate -> DayOfWeek.SATURDAY.equals(DayOfWeek.of(localDate.get(ChronoField.DAY_OF_WEEK))) || DayOfWeek.SUNDAY.equals(DayOfWeek.of(localDate.get(ChronoField.DAY_OF_WEEK))))
                .collect(Collectors.toList());
        dateList.forEach(localDate -> result.add(Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())));
        return result;
    }
    /**
     * @param smallDate
     * @param bigDate
     * @desc èŽ·å–ä¸¤ä¸ªæ—¥æœŸä¹‹é—´çš„å¤©æ•°
     */
    public static Integer getDaysBetween(String smallDate, String bigDate) throws ParseException {
        // æ—¥æœŸæ ¼å¼
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // èŽ·å–ä¸¤ä¸ªæ—¥æœŸçš„æ—¶é—´æˆ³
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smallDate));
        long smallTime = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bigDate));
        long bigTime = cal.getTimeInMillis();
        // ç›¸å·®çš„æ—¥æœŸ
        long days = (bigTime - smallTime) / (1000 * 3600 * 24);
        // long转int å­˜åœ¨æº¢å‡ºæƒ…况  æ ¹æ®ä¸šåŠ¡æƒ…å†µç¼–è¾‘catch中返回值
        try {
            return Integer.parseInt(String.valueOf(days));
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * æ—¥æœŸè½¬æ¢ï¼Œå°†æŽ¥å£è¿”回的20180524转为2018-05-24
     *
     * @param str
     * @return
     */
    public static String dateConvertion(String str) {
        Date parse = null;
        String dateString = "";
        try {
            parse = new SimpleDateFormat("yyyyMMdd").parse(str);
            dateString = new SimpleDateFormat("yyyy-MM-dd").format(parse);
        } catch (ParseException e) {
            dateString = null;
        }
        return dateString;
    }
}
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentMapper.java
@@ -7,6 +7,8 @@
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.mdc.entity.Equipment;
import java.util.List;
/**
 * @Description: é‡‡é›†è®¾å¤‡è¡¨
 * @Author: liuS
@@ -19,15 +21,19 @@
    @Select(" SELECT name FROM SysObjects Where XType='U' AND name = '${saveTableName}' ")
    String checkTableExists(@Param("saveTableName") String saveTableName);
    @Select(" SELECT COUNT(CollectTime) num FROM ${saveTableName} WHERE CollectTime < '${day}' ")
    @Select(" SELECT COUNT(CollectTime) num FROM [${saveTableName}] WHERE CollectTime < '${day}' ")
    Integer checkTableDataNum(@Param("saveTableName") String saveTableName, @Param("day") String day);
    @Insert(" INSERT INTO ${tableName} SELECT * FROM ${lastTableName}  WHERE CollectTime < '${date}' ")
    @Insert(" INSERT INTO [${tableName}] SELECT * FROM [${lastTableName}]  WHERE CollectTime < '${date}' ")
    void insertTableData(@Param("tableName") String tableName, @Param("lastTableName") String lastTableName, @Param("date") String date);
    @Delete(" delete from ${tableName} where CollectTime < '${day}' ")
    @Delete(" delete from [${tableName}] where CollectTime < '${day}' ")
    void deleteTableData(@Param("tableName") String saveTableName, @Param("day") String day);
    @Insert(" SELECT * INTO ${tableName} FROM ${lastTableName} WHERE CollectTime < '${date}' ")
    @Insert(" SELECT * INTO [${tableName}] FROM [${lastTableName}] WHERE CollectTime < '${date}' ")
    void insertNoTableData(@Param("tableName") String tableName, @Param("lastTableName") String lastTableName, @Param("date") String date);
    List<Equipment> listByProds(@Param("proIds") List<String> proIds);
    Equipment findByEquId(@Param("equipmentId") String equipmentId);
}
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/MdcEquipmentMapper.java
@@ -141,5 +141,7 @@
    List<MdcEquipment> findByProIdsAndType(@Param("mdcProductionIds") List<String> mdcProductionIds, @Param("typeList") List<String> typeList);
    List<String> getEquIdsByProIds(@Param("proIds") List<String> proIds);
    List<MdcEquipment> getEquipmentList(@Param("allProductionIds") List<String> allProductionIds);
}
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentMapper.xml
@@ -2,4 +2,22 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.mdc.mapper.EquipmentMapper">
    <select id="listByProds" resultType="org.jeecg.modules.mdc.entity.Equipment">
        SELECT
            t1.*
        FROM
            Equipment t1
            LEFT JOIN mdc_equipment t2 ON t1.EquipmentID = t2.equipment_id
            LEFT JOIN mdc_production_equipment t3 ON t2.id = t3.equipment_id
        <where>
            t3.production_id IN
            <foreach collection="proIds" index="index" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </where>
    </select>
    <select id="findByEquId" resultType="org.jeecg.modules.mdc.entity.Equipment">
        SELECT TOP 1 * FROM Equipment WHERE EquipmentID = #{equipmentId}
    </select>
</mapper>
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentMapper.xml
@@ -354,6 +354,7 @@
            #{equipmentType}
        </foreach>
    </select>
    <select id="queryByDepartIdsAndType" resultType="org.jeecg.modules.mdc.entity.MdcEquipment">
        SELECT
            e.*,
@@ -372,4 +373,18 @@
        </foreach>
    </select>
    <select id="getEquIdsByProIds" resultType="java.lang.String">
        SELECT
        t1.equipment_id
        FROM
        mdc_equipment t1
        LEFT JOIN mdc_production_equipment t2 ON t1.id = t2.equipment_id
        <where>
            t2.production_id IN
            <foreach collection="proIds" index="index" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
        </where>
    </select>
</mapper>
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/IEquipmentService.java
@@ -3,6 +3,8 @@
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.mdc.entity.Equipment;
import java.util.List;
/**
 * @Description: é‡‡é›†è®¾å¤‡è¡¨
 * @Author: liuS
@@ -48,4 +50,8 @@
     * @param day
     */
    void insertNoTableData(String backupTableName, String tableName, String day);
    List<Equipment> listByProds(List<String> proIds);
    Equipment findByEquId(String equipmentId);
}
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/IMdcAlarmInfoService.java
@@ -11,4 +11,5 @@
 */
public interface IMdcAlarmInfoService extends IService<MdcAlarmInfo> {
    MdcAlarmInfo findAlarmContent(String alarmNo, String equipmentId);
}
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentService.java
@@ -240,6 +240,9 @@
     */
    List<MdcEquipment> findByProIdsAndType(List<String> allProductionIds, List<String> typeList);
    List<String> getEquIdsByProIds(List<String> proIds);
    /**
     * æ ¹æ®ç”¨æˆ·æŸ¥è¯¢è®¾å¤‡åˆ—表信息
     * @return
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentServiceImpl.java
@@ -6,6 +6,9 @@
import org.jeecg.modules.mdc.service.IEquipmentService;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
/**
 * @Description: é‡‡é›†è®¾å¤‡è¡¨
 * @Author: liuS
@@ -39,4 +42,14 @@
    public void insertNoTableData(String backupTableName, String tableName, String day) {
        this.baseMapper.insertNoTableData(backupTableName, tableName, day);
    }
    @Override
    public List<Equipment> listByProds(List<String> proIds) {
        return this.baseMapper.listByProds(proIds);
    }
    @Override
    public Equipment findByEquId(String equipmentId) {
        return this.baseMapper.findByEquId(equipmentId);
    }
}
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentServiceImpl.java
@@ -1070,4 +1070,9 @@
        return equipmentIds;
    }
    @Override
    public List<String> getEquIdsByProIds(List<String> proIds) {
        return this.baseMapper.getEquIdsByProIds(proIds);
    }
}
lxzn-module-mdc/pom.xml
@@ -25,6 +25,11 @@
            <artifactId>lxzn-module-mdc-common</artifactId>
            <version>3.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.jeecgframework.boot</groupId>
            <artifactId>lxzn-module-eam-common</artifactId>
            <version>3.4.3</version>
        </dependency>
    </dependencies>
</project>
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/controller/DtBoardController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
package org.jeecg.modules.board.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.board.service.IDtBoardService;
import org.jeecg.modules.board.vo.*;
import org.jeecg.modules.system.entity.MdcProduction;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
 * @Author: Lius
 * @CreateTime: 2025-05-30
 * @Description: æ•°å­—孪生看板接口
 */
@Slf4j
@Api(tags = "数字孪生看板")
@RestController
@RequestMapping("/board/dtBoard")
public class DtBoardController {
    @Resource
    private IDtBoardService dtBoardService;
    @ApiOperation(value = "数字孪生看板-获取车间分组", notes = "数字孪生看板-获取车间分组")
    @GetMapping("/productionList")
    public Result<?> productionList() {
        List<MdcProduction> result = dtBoardService.productionList();
        return Result.OK(result);
    }
    @ApiOperation(value = "数字孪生看板-设备月度利用率", notes = "数字孪生看板-设备月度利用率")
    @GetMapping("/equipmentMonthUtilizationRate")
    public Result<?> equipmentMonthUtilizationRate(@ApiParam(value = "productionId", required = true) String productionId) {
        List<EquUtilRateMonth> result = dtBoardService.equipmentMonthUtilizationRate(productionId);
        return Result.OK(result);
    }
    @ApiOperation(value = "数字孪生看板-设备利用率", notes = "数字孪生看板-设备利用率")
    @GetMapping("/equipmentUtilizationRate")
    public Result<?> equipmentUtilizationRate(@ApiParam(value = "productionId", required = true) String productionId) {
        List<EquUtilRate> result = dtBoardService.equipmentUtilizationRate(productionId);
        return Result.OK(result);
    }
    @ApiOperation(value = "数字孪生看板-月度OEE", notes = "数字孪生看板-月度OEE")
    @GetMapping("/equipmentMonthOee")
    public Result<?> equipmentMonthOee(@ApiParam(value = "productionId", required = true) String productionId) {
        List<EquOeeMonth> result = dtBoardService.equipmentMonthOee(productionId);
        return Result.OK(result);
    }
    @ApiOperation(value = "数字孪生看板-设备运行状态统计", notes = "数字孪生看板-设备运行状态")
    @GetMapping("/equipmentOperationStatistics")
    public Result<?> equipmentOperationStatistics(@ApiParam(value = "productionId", required = true) String productionId) {
        EquOperation result = dtBoardService.equipmentOperationStatistics(productionId);
        return Result.OK(result);
    }
    @ApiOperation(value = "数字孪生看板-设备信息", notes = "数字孪生看板-设备信息")
    @GetMapping("/equipmentRunInfo")
    public Result<?> equipmentRunInfo(@ApiParam(value = "equipmentId", required = true) String equipmentId) {
        List<EquRunInfo> result = dtBoardService.equipmentRunInfo(equipmentId);
        return Result.OK(result);
    }
    @ApiOperation(value = "数字孪生看板-设备停机统计", notes = "数字孪生看板-设备停机统计")
    @GetMapping("/equDowntimeStatistics")
    public Result<?> equDowntimeStatistics(@ApiParam(value = "productionId", required = true) String productionId) {
        List<EquDowntimeInfo> result = dtBoardService.equDowntimeStatistics(productionId);
        return Result.OK(result);
    }
    @ApiOperation(value = "数字孪生看板-设备报警", notes = "数字孪生看板-设备报警")
    @GetMapping("/equAlarmList")
    public Result<?> equAlarmList(@ApiParam(value = "productionId", required = true) String productionId) {
        List<EquAlarm> result = dtBoardService.equAlarmList(productionId);
        return Result.OK(result);
    }
    @ApiOperation(value = "数字孪生看板-设备故障", notes = "数字孪生看板-设备故障")
    @GetMapping("/equRepairList")
    public Result<?> equRepairList(@ApiParam(value = "productionId", required = true) String productionId) {
        List<EquRepair> result = dtBoardService.equRepairList(productionId);
        return Result.OK(result);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/mapper/DtBoardMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package org.jeecg.modules.board.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.board.vo.EquRepair;
import java.util.List;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-11
 * @Description:
 */
@Mapper
public interface DtBoardMapper {
    List<EquRepair> equRepairList(@Param("equipmentIdList") List<String> equipmentIdList, @Param("date") String date);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/mapper/xml/DtBoardMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
<?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="org.jeecg.modules.board.mapper.DtBoardMapper">
    <select id="equRepairList" resultType="org.jeecg.modules.board.vo.EquRepair">
        SELECT
            t3.equipment_code equipmentId,
            COUNT(*) faultNum,
            ROUND(
                    SUM(DATEDIFF(MINUTE, t2.fault_start_time, t1.actual_end_time)) / 60.0,
                    2
            ) faultTime
        FROM
            eam_repair_order t1
                LEFT JOIN eam_report_repair t2 ON t1.report_id = t2.id
                LEFT JOIN eam_equipment t3 ON t1.equipment_id = t3.id
        WHERE
            t1.repair_status = 'COMPLETE'
            AND t2.fault_start_time > #{date}
            AND t3.equipment_code IN
            <foreach collection="equipmentIdList" item="id" index="index" open="(" close=")" separator=",">
                #{ id }
            </foreach>
        GROUP BY
            t3.equipment_code
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/service/IDtBoardService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package org.jeecg.modules.board.service;
import org.jeecg.modules.board.vo.*;
import org.jeecg.modules.system.entity.MdcProduction;
import java.util.List;
/**
 * @Author: Lius
 * @CreateTime: 2025-05-30
 * @Description:
 */
public interface IDtBoardService {
    List<MdcProduction> productionList();
    List<EquUtilRateMonth> equipmentMonthUtilizationRate(String productionId);
    List<EquUtilRate> equipmentUtilizationRate(String productionId);
    List<EquOeeMonth> equipmentMonthOee(String productionId);
    EquOperation equipmentOperationStatistics(String productionId);
    List<EquRunInfo> equipmentRunInfo(String equipmentId);
    List<EquDowntimeInfo> equDowntimeStatistics(String productionId);
    List<EquAlarm> equAlarmList(String productionId);
    List<EquRepair> equRepairList(String productionId);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/service/impl/DtBoardServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,368 @@
package org.jeecg.modules.board.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import liquibase.pro.packaged.I;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.modules.board.mapper.DtBoardMapper;
import org.jeecg.modules.board.service.IDtBoardService;
import org.jeecg.modules.board.vo.*;
import org.jeecg.modules.eam.service.IEamRepairOrderService;
import org.jeecg.modules.mdc.constant.MdcConstant;
import org.jeecg.modules.mdc.entity.*;
import org.jeecg.modules.mdc.service.*;
import org.jeecg.modules.mdc.util.DateUtils;
import org.jeecg.modules.system.entity.MdcProduction;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @Author: Lius
 * @CreateTime: 2025-05-30
 * @Description:
 */
@Service
public class DtBoardServiceImpl implements IDtBoardService {
    @Resource
    private IMdcProductionService mdcProductionService;
    @Resource
    private IMdcEquipmentService mdcEquipmentService;
    @Resource
    private IMdcEquipmentStatisticalInfoService mdcEquipmentStatisticalInfoService;
    @Resource
    private IMdcOeeInfoService mdcOeeInfoService;
    @Resource
    private IEquipmentService equipmentService;
    @Resource
    private IEquipmentWorkLineService equipmentWorkLineService;
    @Resource
    private IMdcDriveTypeParamConfigService mdcDriveTypeParamConfigService;
    @Resource
    private ISysDictService sysDictService;
    @Resource
    private IMdcDowntimeService mdcDowntimeService;
    @Resource
    private IEquipmentAlarmService equipmentAlarmService;
    @Resource
    private IMdcAlarmInfoService mdcAlarmInfoService;
    @Resource
    private DtBoardMapper dtBoardMapper;
    /**
     * è½¦é—´ä¿¡æ¯
     */
    @Override
    public List<MdcProduction> productionList() {
        return mdcProductionService.list(new LambdaQueryWrapper<MdcProduction>().eq(MdcProduction::getOrgType, CommonConstant.ORG_TYPE_2).eq(MdcProduction::getDelFlag, CommonConstant.DEL_FLAG_0).orderByAsc(MdcProduction::getProductionOrder));
    }
    /**
     * è®¾å¤‡æœˆåº¦åˆ©ç”¨çއ
     */
    @Override
    public List<EquUtilRateMonth> equipmentMonthUtilizationRate(String productionId) {
        // ç»„装返回数据
        LocalDate now = LocalDate.now();
        Date start = DateUtils.toDate(now.plusMonths(-12).toString(), DateUtils.STR_DATE);
        Date end = DateUtils.toDate(now.plusMonths(-1).toString(), DateUtils.STR_DATE);
        List<String> monthBetween = DateUtils.getMonthBetween(start, end);
        Map<String, EquUtilRateMonth> resultMap = monthBetween.stream().collect(Collectors.toMap(
                date -> date,
                date -> new EquUtilRateMonth(date.substring(date.lastIndexOf("-") + 1).replaceFirst("^0*", "") + "月"),
                (existing, replacement) -> existing, // å¤„理键冲突的合并函数(通常不会冲突)
                LinkedHashMap::new // æŒ‡å®šä½¿ç”¨LinkedHashMap保持插入顺序
        ));
        List<String> proIds = mdcProductionService.findChildByProId(productionId);
        if (proIds == null || proIds.isEmpty()) {
            return new ArrayList<>(resultMap.values());
        }
        List<String> equipmentIdList = mdcEquipmentService.getEquIdsByProIds(proIds);
        if (equipmentIdList == null || equipmentIdList.isEmpty()) {
            return new ArrayList<>(resultMap.values());
        }
        for (String month : monthBetween) {
            MdcEquipmentStatisticalInfo mdcEquipmentStatisticalInfo = mdcEquipmentStatisticalInfoService.findByEquIdsAndMonth(equipmentIdList, month.replaceAll("-", ""));
            if (mdcEquipmentStatisticalInfo != null) {
                if (resultMap.containsKey(month)) {
                    EquUtilRateMonth equUtilRateMonth = resultMap.get(month);
                    if (mdcEquipmentStatisticalInfo.getProcessLong().compareTo(BigDecimal.ZERO) > 0) {
                        equUtilRateMonth.setUtilizationRate(mdcEquipmentStatisticalInfo.getProcessLong().divide(new BigDecimal("864"), 2, RoundingMode.HALF_UP));
                    }
                    resultMap.put(month, equUtilRateMonth);
                }
            }
        }
        return new ArrayList<>(resultMap.values());
    }
    /**
     * è®¾å¤‡åˆ©ç”¨çއ(昨天)
     */
    @Override
    public List<EquUtilRate> equipmentUtilizationRate(String productionId) {
        List<String> proIds = mdcProductionService.findChildByProId(productionId);
        if (proIds == null || proIds.isEmpty()) {
            return null;
        }
        List<String> equipmentIdList = mdcEquipmentService.getEquIdsByProIds(proIds);
        if (equipmentIdList == null || equipmentIdList.isEmpty()) {
            return null;
        }
        Map<String, EquUtilRate> resultMap = new LinkedHashMap<>();
        equipmentIdList.forEach(equipmentId -> {
            EquUtilRate equUtilRate = new EquUtilRate(equipmentId);
            resultMap.put(equipmentId, equUtilRate);
        });
        String yesterday = LocalDate.now().plusDays(-1).toString();
        List<MdcEquipmentStatisticalInfo> mdcEquipmentStatisticalInfoList = mdcEquipmentStatisticalInfoService.findByEquipmentAndDate(equipmentIdList, yesterday.replaceAll("-", ""));
        if (mdcEquipmentStatisticalInfoList != null && !mdcEquipmentStatisticalInfoList.isEmpty()) {
            mdcEquipmentStatisticalInfoList.forEach(mdcEquipmentStatisticalInfo -> {
                if (resultMap.containsKey(mdcEquipmentStatisticalInfo.getEquipmentId())) {
                    EquUtilRate equUtilRate = resultMap.get(mdcEquipmentStatisticalInfo.getEquipmentId());
                    if (mdcEquipmentStatisticalInfo.getProcessLong().compareTo(BigDecimal.ZERO) > 0) {
                        equUtilRate.setUtilizationRate(mdcEquipmentStatisticalInfo.getProcessLong().divide(new BigDecimal("864"), 2, RoundingMode.HALF_UP));
                    }
                    resultMap.put(mdcEquipmentStatisticalInfo.getEquipmentId(), equUtilRate);
                }
            });
        }
        return new ArrayList<>(resultMap.values());
    }
    /**
     * æœˆåº¦è®¾å¤‡ç»¼åˆæ•ˆçއ
     */
    @Override
    public List<EquOeeMonth> equipmentMonthOee(String productionId) {
        LocalDate now = LocalDate.now();
        Date start = DateUtils.toDate(now.plusMonths(-12).toString(), DateUtils.STR_DATE);
        Date end = DateUtils.toDate(now.plusMonths(-1).toString(), DateUtils.STR_DATE);
        List<String> monthBetween = DateUtils.getMonthBetween(start, end);
        Map<String, EquOeeMonth> resultMap = monthBetween.stream().collect(Collectors.toMap(
                date -> date,
                date -> new EquOeeMonth(date.substring(date.lastIndexOf("-") + 1).replaceFirst("^0*", "") + "月"),
                (existing, replacement) -> existing, // å¤„理键冲突的合并函数(通常不会冲突)
                LinkedHashMap::new // æŒ‡å®šä½¿ç”¨LinkedHashMap保持插入顺序
        ));
        List<String> proIds = mdcProductionService.findChildByProId(productionId);
        if (proIds == null || proIds.isEmpty()) {
            return new ArrayList<>(resultMap.values());
        }
        List<String> equipmentIdList = mdcEquipmentService.getEquIdsByProIds(proIds);
        if (equipmentIdList == null || equipmentIdList.isEmpty()) {
            return new ArrayList<>(resultMap.values());
        }
        for (String month : monthBetween) {
            BigDecimal oee = mdcOeeInfoService.findByEquIdAndMonth(equipmentIdList, month);
            if (oee != null) {
                EquOeeMonth equOeeMonth = resultMap.get(month);
                equOeeMonth.setOee(oee.setScale(2, RoundingMode.HALF_UP));
                resultMap.put(month, equOeeMonth);
            }
        }
        return new ArrayList<>(resultMap.values());
    }
    /**
     * è®¾å¤‡çŠ¶æ€ç»Ÿè®¡
     */
    @Override
    public EquOperation equipmentOperationStatistics(String productionId) {
        EquOperation equOperation = new EquOperation();
        List<String> proIds = mdcProductionService.findChildByProId(productionId);
        if (proIds == null || proIds.isEmpty()) {
            return equOperation;
        }
        List<Equipment> equipmentList = equipmentService.listByProds(proIds);
        if (equipmentList == null || equipmentList.isEmpty()) {
            return equOperation;
        }
        for (Equipment equipment : equipmentList) {
            if (equipment.getOporation() != null) {
                switch (equipment.getOporation()) {
                    case 1:
                    case 2:
                        equOperation.setStandby(equOperation.getStandby() + 1);
                        break;
                    case 3:
                        equOperation.setRun(equOperation.getRun() + 1);
                        break;
                    case 22:
                        equOperation.setAlarm(equOperation.getAlarm() + 1);
                        break;
                    default:
                        equOperation.setShutdown(equOperation.getShutdown() + 1);
                        break;
                }
            } else {
                equOperation.setShutdown(equOperation.getShutdown() + 1);
            }
        }
        return equOperation;
    }
    /**
     * è®¾å¤‡è¿è¡Œä¿¡æ¯
     */
    @Override
    public List<EquRunInfo> equipmentRunInfo(String equipmentId) {
        List<EquRunInfo> equRunInfoList = new ArrayList<>();
        Equipment equipment = equipmentService.findByEquId(equipmentId);
        if (equipment != null) {
            //填充设备基础信息
            equRunInfoList.add(new EquRunInfo("设备名称", equipment.getEquipmentname(), ""));
            equRunInfoList.add(new EquRunInfo("设备编号", equipment.getEquipmentid(), ""));
            if (equipment.getOporation() != null && equipment.getOporation() != 0) {
                String saveTableName = equipment.getSavetablename();
                Map<String, Object> mapData = equipmentWorkLineService.getDataList(saveTableName);
                if (mapData != null) {
                    //获取 MDC é©±åŠ¨å¯¹åº”çš„å±•ç¤ºå‚æ•°   å¹¶æ ¹æ®key æ‹¼è£…从 workData  æŸ¥è¯¢çš„æ•°æ®
                    List<MdcDriveTypeParamConfig> mdcDriveTypeParamList = mdcDriveTypeParamConfigService.getShowDriveParam(equipment.getDrivetype());
                    if (mdcDriveTypeParamList != null && !mdcDriveTypeParamList.isEmpty()) {
                        List<DictModel> dictItems = sysDictService.getDictItems(CommonConstant.DICT_EQUIPMENT_RUN_UNIT);
                        Map<String, DictModel> resultMap = new HashMap<>();
                        dictItems.forEach(dictModel -> {
                            resultMap.put(dictModel.getText(), dictModel);
                        });
                        for (MdcDriveTypeParamConfig mdcDriveTypeParamConfig : mdcDriveTypeParamList) {
                            EquRunInfo equRunInfo = new EquRunInfo();
                            String englishName = mdcDriveTypeParamConfig.getEnglishName();
                            String chineseName = mdcDriveTypeParamConfig.getChineseName();
                            equRunInfo.setKey(chineseName);
                            if (mapData.containsKey(englishName)) {
                                Object object = mapData.get(englishName);
                                String value = "";
                                if ("CollectTime".equals(englishName)) {
                                    Date date = object == null ? null : (Date) object;
                                    value = DateUtils.format(date, DateUtils.STR_DATE_TIME_SMALL);
                                } else if ("ZUOLAN".equals(equipment.getDrivetype()) && "spindlespeed".equals(englishName) && equipment.getOporation() == 3) {
                                    // ZUOLAN设备主轴转速字段spindlespeed
                                    value = String.valueOf(((new Random().nextInt(35)) + 1) * 100);
                                } else if ("ZUOLAN".equals(equipment.getDrivetype()) && "spindleload".equals(englishName) && equipment.getOporation() == 3) {
                                    // ZUOLAN设备主轴负荷字段spindleload
                                    value = String.valueOf(Integer.valueOf(new Random().nextInt(21)));
                                } else if ("ZUOLAN".equals(equipment.getDrivetype()) && "spindlebeilv".equals(englishName) && equipment.getOporation() == 3) {
                                    // ZUOLAN设备主轴倍率字段spindlebeilv
                                    value = String.valueOf((new Random().nextInt(13)) * 10);
                                } else if ("ZUOLAN".equals(equipment.getDrivetype()) && "feedbeilv".equals(englishName) && equipment.getOporation() == 3) {
                                    // ZUOLAN设备进给倍率字段feedbeilv
                                    value = String.valueOf((new Random().nextInt(13)) * 10);
                                } else {
                                    value = object == null ? "" : object.toString();
                                }
                                equRunInfo.setValue(value);
                                // è®¾ç½®å•位
                                if (resultMap.containsKey(chineseName)) {
                                    DictModel dictModel = resultMap.get(chineseName);
                                    equRunInfo.setUnit(dictModel.getValue());
                                }
                                equRunInfoList.add(equRunInfo);
                            }
                        }
                    }
                }
            }
        }
        return equRunInfoList;
    }
    /**
     * è®¾å¤‡åœæœºç»Ÿè®¡
     */
    @Override
    public List<EquDowntimeInfo> equDowntimeStatistics(String productionId) {
        List<String> proIds = mdcProductionService.findChildByProId(productionId);
        if (proIds == null || proIds.isEmpty()) {
            return null;
        }
        List<String> equipmentIdList = mdcEquipmentService.getEquIdsByProIds(proIds);
        if (equipmentIdList == null || equipmentIdList.isEmpty()) {
            return null;
        }
        LocalDate end = LocalDate.now();
        LocalDate start = end.plusDays(-30);
        List<EquDowntimeInfo> result = mdcDowntimeService.equDowntimeStatistics(equipmentIdList, start.toString(), end.toString());
        result.forEach(equDowntimeInfo -> {
            equDowntimeInfo.setDuration(equDowntimeInfo.getDuration().setScale(2, RoundingMode.HALF_UP));
        });
        return result;
    }
    /**
     * è®¾å¤‡æŠ¥è­¦åˆ—表
     */
    @Override
    public List<EquAlarm> equAlarmList(String productionId) {
        List<EquAlarm> result = new ArrayList<>();
        List<String> proIds = mdcProductionService.findChildByProId(productionId);
        if (proIds == null || proIds.isEmpty()) {
            return null;
        }
        List<String> equipmentIdList = mdcEquipmentService.getEquIdsByProIds(proIds);
        if (equipmentIdList == null || equipmentIdList.isEmpty()) {
            return null;
        }
        List<EquipmentAlarm> equipmentAlarmList =  equipmentAlarmService.list(new LambdaQueryWrapper<EquipmentAlarm>().in(EquipmentAlarm::getEquipmentid, equipmentIdList).orderByDesc(EquipmentAlarm::getCollecttime).isNotNull(EquipmentAlarm::getAlarmNo).last("TOP 15"));
        if (equipmentAlarmList == null || equipmentAlarmList.isEmpty()) {
            return null;
        }
        for (EquipmentAlarm equipmentAlarm : equipmentAlarmList) {
            MdcAlarmInfo mdcAlarmInfo = mdcAlarmInfoService.findAlarmContent(equipmentAlarm.getAlarmNo(), equipmentAlarm.getEquipmentid());
            EquAlarm equAlarm = new EquAlarm();
            equAlarm.setEquipmentId(equipmentAlarm.getEquipmentid());
            if (mdcAlarmInfo != null) {
                equAlarm.setAlarmInfo(mdcAlarmInfo.getAlarmContent());
            } else {
                equAlarm.setAlarmInfo(equipmentAlarm.getAlarmContent());
            }
            result.add(equAlarm);
        }
        return result;
    }
    /**
     * è®¾å¤‡æ•…éšœ
     * @param productionId
     * @return
     */
    @Override
    public List<EquRepair> equRepairList(String productionId) {
        List<String> proIds = mdcProductionService.findChildByProId(productionId);
        if (proIds == null || proIds.isEmpty()) {
            return null;
        }
        List<String> equipmentIdList = mdcEquipmentService.getEquIdsByProIds(proIds);
        if (equipmentIdList == null || equipmentIdList.isEmpty()) {
            return null;
        }
        LocalDateTime currentDate = LocalDate.now().minusMonths(1).atStartOfDay();
        String format = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<EquRepair> result = dtBoardMapper.equRepairList(equipmentIdList, format);
        return result;
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquAlarm.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-09
 * @Description: è®¾å¤‡æŠ¥è­¦ä¿¡æ¯
 */
@Data
public class EquAlarm {
    /**
     * è®¾å¤‡ç¼–号
     */
    private String equipmentId;
    /**
     * æŠ¥è­¦ä¿¡æ¯
     */
    private String alarmInfo;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquDowntimeInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-09
 * @Description: è®¾å¤‡åœæœºç»Ÿè®¡
 */
@Data
public class EquDowntimeInfo {
    /**
     * åœæœºåŽŸå› 
     */
    private String shutdownInfo;
    /**
     * åœæœºæ—¶é•¿
     */
    private BigDecimal duration;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquOeeMonth.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @Author: Lius
 * @CreateTime: 2025-05-30
 * @Description:
 */
@Data
public class EquOeeMonth {
    private String month;
    private BigDecimal oee = BigDecimal.ZERO;
    public EquOeeMonth(String month) {
        this.month = month;
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquOperation.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-06
 * @Description:
 */
@Data
public class EquOperation {
    private Integer shutdown = 0;
    private Integer alarm = 0;
    private Integer standby = 0;
    private Integer run = 0;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquRepair.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-10
 * @Description: è®¾å¤‡æ•…éšœ
 */
@Data
public class EquRepair {
    /**
     * è®¾å¤‡ç¼–号
     */
    private String equipmentId;
    /**
     *  æ•…障次数
     */
    private BigDecimal faultNum;
    /**
     * æ•…障时长
     */
    private BigDecimal faultTime;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquRunInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-06
 * @Description:
 */
@Data
public class EquRunInfo {
    private String key;
    private String value;
    private String unit;
    public EquRunInfo() {
    }
    public EquRunInfo(String key, String value, String unit) {
        this.key = key;
        this.value = value;
        this.unit = unit;
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquStatus.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-05
 * @Description:
 */
@Data
public class EquStatus {
    private String equipmentId;
    private Integer state;
    private String plantName;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquUtilRate.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @Author: Lius
 * @CreateTime: 2025-05-30
 * @Description:
 */
@Data
public class EquUtilRate {
    private String deviceNum;
    private BigDecimal utilizationRate = BigDecimal.ZERO;
    public EquUtilRate(String deviceNum) {
        this.deviceNum = deviceNum;
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquUtilRateMonth.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @Author: Lius
 * @CreateTime: 2025-05-30
 * @Description:
 */
@Data
public class EquUtilRateMonth {
    private String month;
    private BigDecimal utilizationRate = BigDecimal.ZERO;
    public EquUtilRateMonth(String month) {
        this.month = month;
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/controller/AndonOrderController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package org.jeecg.modules.mdc.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.mdc.entity.AndonOrder;
import org.jeecg.modules.mdc.service.IAndonOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 /**
 * @Description: andon_order
 * @Author: jeecg-boot
 * @Date:   2025-06-11
 * @Version: V1.0
 */
@Api(tags="andon_order")
@RestController
@RequestMapping("/AndonOrder/andonOrder")
@Slf4j
public class AndonOrderController extends JeecgController<AndonOrder, IAndonOrderService> {
    @Autowired
    private IAndonOrderService andonOrderService;
     /**
      * ç¨‹åºå‘¼å«
      *
      * @param andonOrder
      * @return
      */
     @AutoLog(value = "安灯工单-程序呼叫")
     @ApiOperation(value = "安灯工单-程序呼叫", notes = "安灯工单-程序呼叫")
     @PostMapping(value = "/procedureCall")
     public Result<?> procedureCall(@RequestBody AndonOrder andonOrder) {
         andonOrderService.procedureCall(andonOrder);
         return Result.OK("呼叫成功!");
     }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/controller/MdcEquipmentPunchController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package org.jeecg.modules.mdc.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunch;
import org.jeecg.modules.mdc.service.IMdcEquipmentPunchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @Description: mdc_equipment_punch
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
@Api(tags="上下班打卡记录表")
@RestController
@RequestMapping("/mdcEquipmentPunch")
@Slf4j
public class MdcEquipmentPunchController extends JeecgController<MdcEquipmentPunch, IMdcEquipmentPunchService> {
    @Autowired
    private IMdcEquipmentPunchService mdcEquipmentPunchService;
    private static final String msg = "打卡成功!";
    /**
     * æŸ¥è¯¢å½“前登录人所负责设备打卡情况
     *
     * @return
     */
    @ApiOperation(value="查询当前登录人所负责设备打卡情况", notes="查询当前登录人所负责设备打卡情况")
    @GetMapping(value = "/list")
    public Result<List<MdcEquipmentPunch>> queryList() {
        return Result.OK(mdcEquipmentPunchService.queryList());
    }
    /**
     *   ä¸Šç­æ‰“卡
     *
     * @param mdcEquipmentPunch
     * @return
     */
    @AutoLog(value = "上班打卡")
    @ApiOperation(value="上班打卡", notes="上班打卡")
    @PostMapping(value = "/workUp")
    public Result<String> workUp(@RequestBody MdcEquipmentPunch mdcEquipmentPunch) {
        mdcEquipmentPunchService.workUp(mdcEquipmentPunch);
        return Result.OK(msg);
    }
    /**
     *   ä¸‹ç­æ‰“卡
     *
     * @param mdcEquipmentPunch
     * @return
     */
    @AutoLog(value = "下班打卡")
    @ApiOperation(value="下班打卡", notes="下班打卡")
    @PostMapping(value = "/workDown")
    public Result<String> workDown(@RequestBody MdcEquipmentPunch mdcEquipmentPunch) {
        mdcEquipmentPunchService.workDown(mdcEquipmentPunch);
        return Result.OK(msg);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/AndonOrder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,164 @@
package org.jeecg.modules.mdc.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
 * @Description: andon_order
 * @Author: jeecg-boot
 * @Date: 2025-06-11
 * @Version: V1.0
 */
@Data
@TableName("andon_order")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "andon_order对象", description = "andon_order")
public class AndonOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ä¸»é”®
     */
    @TableId(type = IdType.ASSIGN_ID)
    @ApiModelProperty(value = "主键")
    private String id;
    /**
     * è®¾å¤‡ç¼–号
     */
    @Excel(name = "设备编号", width = 15)
    @ApiModelProperty(value = "设备编号")
    private String equipmentId;
    /**
     * æ‰€å±žåŽ‚æˆ¿
     */
    @Excel(name = "所属厂房", width = 15)
    @ApiModelProperty(value = "所属厂房")
    private String plantName;
    /**
     * å®‰ç¯ç±»åž‹
     */
    @Excel(name = "安灯类型", width = 15)
    @ApiModelProperty(value = "安灯类型")
    private String andonType;
    /**
     * å®‰ç¯äºº(呼叫人)
     */
    @Excel(name = "安灯人", width = 15)
    @ApiModelProperty(value = "安灯人")
    private String operator;
    /**
     * å‘¼å«åŽŸå› 
     */
    @Excel(name = "呼叫原因", width = 15)
    @ApiModelProperty(value = "呼叫原因")
    private String callReason;
    /**
     * å®‰ç¯æ—¶é—´
     */
    @Excel(name = "安灯时间", width = 15, format = DatePattern.NORM_DATETIME_PATTERN)
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "安灯时间")
    private Date operateTime;
    /**
     * å“åº”人(责任人)
     */
    @Excel(name = "响应人", width = 15)
    @ApiModelProperty(value = "响应人")
    private String responder;
    /**
     * å“åº”æ—¶é—´
     */
    @Excel(name = "响应时间", width = 15, format = DatePattern.NORM_DATETIME_PATTERN)
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "响应时间")
    private Date responseTime;
    /**
     * å¤„理人
     */
    @Excel(name = "处理人", width = 15)
    @ApiModelProperty(value = "处理人")
    private String processor;
    /**
     * å¤„理完成时间
     */
    @Excel(name = "处理完成时间", width = 15, format = DatePattern.NORM_DATETIME_PATTERN)
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "处理完成时间")
    private Date processTime;
    /**
     * å®‰ç¯çŠ¶æ€;待响应、待处理、已完成
     */
    @Excel(name = "安灯状态;待响应、待处理、已完成", width = 15)
    @ApiModelProperty(value = "安灯状态;待响应、待处理、已完成")
    private String orderStatus;
    /**
     * é—®é¢˜æè¿°
     */
    @Excel(name = "问题描述", width = 15)
    @ApiModelProperty(value = "问题描述")
    private String problemDescreption;
    /**
     * å¤„理结果描述
     */
    @Excel(name = "处理结果描述", width = 15)
    @ApiModelProperty(value = "处理结果描述")
    private String resolutionDescreption;
    /**
     * å¤„理结果图片
     */
    @Excel(name = "处理结果图片", width = 15)
    @ApiModelProperty(value = "处理结果图片")
    private String imageFiles;
    /**
     * åˆ é™¤æ ‡è®°
     */
    @Excel(name = "删除标记", width = 15)
    @ApiModelProperty(value = "删除标记")
    @TableLogic
    private Integer delFlag;
    /**
     * åˆ›å»ºäºº
     */
    @ApiModelProperty(value = "创建人")
    private String createBy;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "创建时间")
    private Date createTime;
    /**
     * æ›´æ–°äºº
     */
    @ApiModelProperty(value = "更新人")
    private String updateBy;
    /**
     * æ›´æ–°æ—¶é—´
     */
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "更新时间")
    private Date updateTime;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/MdcEquipmentPunch.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,145 @@
package org.jeecg.modules.mdc.entity;
import java.io.Serializable;
import java.util.Date;
import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.jeecg.common.aspect.annotation.Dict;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
 * @Description: mdc_equipment_punch
 * @Author: jeecg-boot
 * @Date: 2025-06-09
 * @Version: V1.0
 */
@Data
@TableName("mdc_equipment_punch")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "mdc_equipment_punch对象", description = "mdc_equipment_punch")
public class MdcEquipmentPunch implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * id
     */
    @TableId(type = IdType.ASSIGN_ID)
    @ApiModelProperty(value = "id")
    private String id;
    /**
     * è®¾å¤‡ç¼–号
     */
    @Excel(name = "设备编号", width = 15)
    @ApiModelProperty(value = "设备编号")
    private String equipmentId;
    /**
     * æ‰“卡用户
     */
    @Excel(name = "打卡用户", width = 15)
    @ApiModelProperty(value = "打卡用户")
    private String punchUser;
    /**
     * æ‰“卡用户账号
     */
    @Excel(name = "打卡用户账号", width = 15)
    @ApiModelProperty(value = "打卡用户账号")
    @TableField(exist = false)
    private String punchUserRealName;
    /**
     * æ‰“卡用户名称
     */
    @Excel(name = "打卡用户名称", width = 15)
    @ApiModelProperty(value = "打卡用户名称")
    @TableField(exist = false)
    private String punchUserUserName;
    /**
     * ä¸Šç­æ—¶é—´
     */
    @Excel(name = "上班时间", width = 15, format = DatePattern.NORM_DATETIME_PATTERN)
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "上班时间")
    private Date checkInTime;
    /**
     * ä¸‹ç­æ—¶é—´
     */
    @Excel(name = "下班时间", width = 15, format = DatePattern.NORM_DATETIME_PATTERN)
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "下班时间")
    private Date checkOutTime;
    /**
     * è®°å½•日期
     */
    @Excel(name = "记录日期", width = 15)
    @ApiModelProperty(value = "记录日期")
    private String recordDate;
    /**
     * ç­æ¬¡
     */
    @Excel(name = "班次", width = 15)
    @ApiModelProperty(value = "班次")
    @Dict(dicCode = "shift_schedule")
    private Integer shiftSchedule;
    /**
     * ç­æ¬¡åç§°
     */
    @Excel(name = "班次名称", width = 15)
    @ApiModelProperty(value = "班次名称")
    @TableField(exist = false)
    private String shiftScheduleName;
    /**
     * æ˜¯å¦ç¼ºå¡
     */
    @Excel(name = "是否缺卡", width = 15)
    @ApiModelProperty(value = "是否缺卡")
    private Integer isAbsent;
    /**
     * æ˜¯å¦è¿Ÿåˆ°
     */
    @Excel(name = "是否迟到", width = 15)
    @ApiModelProperty(value = "是否迟到")
    private Integer isLate;
    /**
     * æ˜¯å¦æ—©é€€
     */
    @Excel(name = "是否早退", width = 15)
    @ApiModelProperty(value = "是否早退")
    private Integer isEarly;
    /**
     * åˆ›å»ºäºº
     */
    @ApiModelProperty(value = "创建人")
    private String createBy;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "创建时间")
    private Date createTime;
    /**
     * æ›´æ–°äºº
     */
    @ApiModelProperty(value = "更新人")
    private String updateBy;
    /**
     * æ›´æ–°æ—¶é—´
     */
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "更新时间")
    private Date updateTime;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/RunningOverallEquipmentEfficiencyJob.java
ÎļþÒÑɾ³ý
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/WebsocketPushEquStatusJob.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
package org.jeecg.modules.mdc.job;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.board.vo.EquStatus;
import org.jeecg.modules.mdc.entity.Equipment;
import org.jeecg.modules.mdc.service.IEquipmentService;
import org.jeecg.modules.mdc.util.ThrowableUtil;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.quartz.entity.QuartzJob;
import org.jeecg.modules.quartz.entity.SysQuartzLog;
import org.jeecg.modules.quartz.service.IQuartzJobService;
import org.jeecg.modules.quartz.service.ISysQuartzLogService;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.quartz.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-05
 * @Description: websocket推送设备状态任务
 */
@DisallowConcurrentExecution
@Slf4j
public class WebsocketPushEquStatusJob implements Job {
    @Resource
    private IQuartzJobService quartzJobService;
    @Resource
    private ISysQuartzLogService sysQuartzLogService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private WebSocket webSocket;
    @Resource
    private IEquipmentService equipmentService;
    @Resource
    private IMdcProductionService mdcProductionService;
    final private static String redisKey = "board:equipment:status:";
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        SysQuartzLog quartzLog = new SysQuartzLog();
        quartzLog.setCreateTime(new Date());
        List<QuartzJob> byJobClassName = this.quartzJobService.findByJobClassName(this.getClass().getName());
        if (byJobClassName != null && !byJobClassName.isEmpty()) {
            quartzLog.setJobId(byJobClassName.get(0).getId());
        }
        long startTime = System.currentTimeMillis();
        try {
            List<Equipment> equipmentList = equipmentService.list();
            if (equipmentList != null && !equipmentList.isEmpty()) {
                List<EquStatus> equStatusList = new ArrayList<>();
                for (Equipment equipment : equipmentList) {
                    if (equipment.getOporation() == null) {
                        equipment.setOporation(0);
                    }
                    String key = redisKey + equipment.getEquipmentid();
                    if (redisUtil.hasKey(key)) {
                        Integer status = (Integer) redisUtil.get(key);
                        if (!status.equals(equipment.getOporation())) {
                            EquStatus equStatus = new EquStatus();
                            equStatus.setEquipmentId(equipment.getEquipmentid());
                            equStatus.setState(equipment.getOporation());
                            // é€šè¿‡equipmentId获取设备车间名称
                            String productionName = mdcProductionService.findProName(equipment.getEquipmentid());
                            equStatus.setPlantName(productionName);
                            equStatusList.add(equStatus);
                            redisUtil.set(key, equipment.getOporation());
                        }
                    } else {
                        EquStatus equStatus = new EquStatus();
                        equStatus.setEquipmentId(equipment.getEquipmentid());
                        equStatus.setState(equipment.getOporation());
                        // é€šè¿‡equipmentId获取设备车间名称
                        String productionName = mdcProductionService.findProName(equipment.getEquipmentid());
                        equStatus.setPlantName(productionName);
                        equStatusList.add(equStatus);
                        redisUtil.set(key, equipment.getOporation());
                    }
                }
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(WebsocketConst.MSG_CMD, "equStatus");
                jsonObject.put("data", equStatusList);
                webSocket.sendMessage(jsonObject.toJSONString());
            }
            quartzLog.setIsSuccess(0);
        } catch (Exception e) {
            quartzLog.setIsSuccess(-1);
            quartzLog.setExceptionDetail(ThrowableUtil.getStackTrace(e));
        }
        long endTime = System.currentTimeMillis();
        quartzLog.setExecutionTime(Integer.parseInt(String.valueOf(endTime - startTime)));
        sysQuartzLogService.save(quartzLog);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/AndonOrderMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package org.jeecg.modules.mdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.mdc.entity.AndonOrder;
/**
 * @Description: andon_order
 * @Author: jeecg-boot
 * @Date:   2025-06-11
 * @Version: V1.0
 */
public interface AndonOrderMapper extends BaseMapper<AndonOrder> {
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcAlarmInfoMapper.java
@@ -1,6 +1,7 @@
package org.jeecg.modules.mdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.mdc.entity.MdcAlarmInfo;
/**
@@ -11,4 +12,5 @@
 */
public interface MdcAlarmInfoMapper extends BaseMapper<MdcAlarmInfo> {
    MdcAlarmInfo findAlarmContent(@Param("alarmNo") String alarmNo, @Param("equipmentId") String equipmentId);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcDowntimeMapper.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.board.vo.EquDowntimeInfo;
import org.jeecg.modules.mdc.dto.MdcDowntimeDto;
import org.jeecg.modules.mdc.entity.MdcDowntime;
import org.jeecg.modules.mdc.vo.MdcDowntimeVo;
@@ -20,4 +21,6 @@
    IPage<MdcDowntimeDto> pageList(Page<MdcDowntimeDto> page, @Param("mdcDowntimeVo") MdcDowntimeVo mdcDowntimeVo);
    List<MdcDowntime> findPlanTimeDuration(@Param("equipmentId") String equipmentId, @Param("validDate") String validDate, @Param("closeType") String closeType);
    List<EquDowntimeInfo> equDowntimeStatistics(@Param("equipmentIdList") List<String> equipmentIdList, @Param("start") String start, @Param("end") String end);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcEquipmentPunchMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package org.jeecg.modules.mdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunch;
import java.util.List;
/**
 * @Description: mdc_equipment_punch
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
public interface MdcEquipmentPunchMapper extends BaseMapper<MdcEquipmentPunch> {
    List<MdcEquipmentPunch> list(@Param("equipmentIds") List<String> equipmentIds, @Param("date") String date);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcEquipmentStatisticalInfoMapper.java
@@ -5,6 +5,8 @@
import org.jeecg.modules.mdc.dto.MdcEquipmentStatisticalDto;
import org.jeecg.modules.mdc.entity.MdcEquipmentStatisticalInfo;
import java.util.List;
/**
 * @Description: è®¾å¤‡å•日运行数据表
 * @Author: jeecg-boot
@@ -28,4 +30,8 @@
    Integer selectProcessLong(@Param("equipmentId") String equipmentId, @Param("validDate") String validDate);
    MdcEquipmentStatisticalDto findByEquipmentAndMonth(@Param("equipmentId") String equipmentId, @Param("date") String date);
    MdcEquipmentStatisticalInfo findByEquIdsAndMonth(@Param("equipmentIdList") List<String> equipmentIdList, @Param("month") String month);
    List<MdcEquipmentStatisticalInfo> findByEquipmentAndDate(@Param("equipmentIdList") List<String> equipmentIdList, @Param("date") String date);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcOeeInfoMapper.java
@@ -7,6 +7,9 @@
import org.jeecg.modules.mdc.entity.MdcOeeInfo;
import org.jeecg.modules.mdc.vo.MdcOeeInfoVo;
import java.math.BigDecimal;
import java.util.List;
/**
 * @Description: OEE表
 * @Author: lius
@@ -22,4 +25,6 @@
     * @return
     */
    IPage<MdcOeeInfo> pageList(Page<MdcOeeInfo> page, @Param("mdcOeeInfoVo") MdcOeeInfoVo mdcOeeInfoVo);
    BigDecimal findByEquIdAndMonth(@Param("equipmentIdList") List<String> equipmentIdList, @Param("month") String month);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/AndonOrderMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
<?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="org.jeecg.modules.mdc.mapper.AndonOrderMapper">
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcAlarmInfoMapper.xml
@@ -2,4 +2,13 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.mdc.mapper.MdcAlarmInfoMapper">
    <select id="findAlarmContent" resultType="org.jeecg.modules.mdc.entity.MdcAlarmInfo">
        SELECT
            t1.*
        FROM
            mdc_alarm_info t1
                LEFT JOIN mdc_equipment t2 ON t1.drive_type = t2.drive_type
        WHERE
            t2.equipment_id = #{equipmentId} AND t1.alarm_code = #{alarmNo}
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcDowntimeMapper.xml
@@ -40,4 +40,24 @@
            AND t2.downtime_type = #{closeType}
            AND t1.the_date = #{validDate}
    </select>
    <select id="equDowntimeStatistics" resultType="org.jeecg.modules.board.vo.EquDowntimeInfo">
        SELECT
            t2.downtime_description AS shutdown_info,
            SUM ( DATEDIFF( SECOND, t1.start_date, t1.end_date ) ) / 3600.0 AS duration_hours
        FROM
            mdc_downtime t1
                LEFT JOIN mdc_downtime_reason t2 ON t1.reason_id = t2.id
        WHERE
            t1.reason_id != ''
          AND t1.the_date BETWEEN #{start} AND #{end}
        AND t1.equipment_id IN
        <foreach collection="equipmentIdList" item="equipmentId" index="index" open="(" close=")" separator=",">
            #{ equipmentId }
        </foreach>
        GROUP BY
            t2.downtime_description
        ORDER BY
            duration_hours DESC
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentPunchMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
<?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="org.jeecg.modules.mdc.mapper.MdcEquipmentPunchMapper">
    <select id="list" resultType="org.jeecg.modules.mdc.entity.MdcEquipmentPunch">
        SELECT
          p.id,
          p.equipment_id,
          p.punch_user,
          p.check_in_time,
          p.check_out_time,
          p.record_date,
          p.is_absent,
          p.is_late,
          p.is_early,
          p.create_by,
          p.create_time,
          p.update_by,
          p.update_time,
          p.shift_schedule,
          u.realname punchUserRealName,
          u.username punchUserUserName,
          d1.item_text shiftScheduleName
        FROM
          mdc_equipment_punch p
          INNER JOIN sys_user u ON u.id = p.punch_user
          INNER JOIN (SELECT i1.item_text, i1.item_value
                      FROM sys_dict_item i1
                          LEFT JOIN sys_dict i2 ON i2.id = i1.dict_id
                      WHERE i2.dict_code = 'shift_schedule') d1
              ON d1.item_value = CAST (p.shift_schedule AS nvarchar)
        where 1=1
        AND p.equipment_id IN
        <foreach collection="equipmentIds" item="equipmentId" open="(" close=")" separator=",">
            #{equipmentId}
        </foreach>
        <if test="date != null and date != ''">
            AND p.record_date = #{date}
        </if>
        order by p.equipment_id desc, p.shift_schedule asc
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentStatisticalInfoMapper.xml
@@ -26,4 +26,34 @@
        WHERE
            equipment_id = #{equipmentId} AND the_date LIKE CONCAT(#{date}, '%')
    </select>
    <select id="findByEquIdsAndMonth" resultType="org.jeecg.modules.mdc.entity.MdcEquipmentStatisticalInfo">
        SELECT
            AVG(open_long) openLong,
            AVG(close_long) closeLong,
            AVG(wait_long) waitLong,
            AVG(process_long) processLong,
            AVG(error_long) errorLong
        FROM
            mdc_equipment_statistical_info
        WHERE
            equipment_id IN
            <foreach collection="equipmentIdList" item="id" index="index" open="(" close=")" separator=",">
                #{ id }
            </foreach>
            AND the_date LIKE CONCAT(#{month}, '%')
    </select>
    <select id="findByEquipmentAndDate" resultType="org.jeecg.modules.mdc.entity.MdcEquipmentStatisticalInfo">
        SELECT
            *
        FROM
            mdc_equipment_statistical_info
        WHERE
        equipment_id IN
        <foreach collection="equipmentIdList" item="id" index="index" open="(" close=")" separator=",">
            #{ id }
        </foreach>
        AND the_date = #{date}
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcOeeInfoMapper.xml
@@ -27,4 +27,17 @@
        </where>
        ORDER BY the_date DESC, equipment_id ASC
    </select>
    <select id="findByEquIdAndMonth" resultType="java.math.BigDecimal">
        SELECT
            AVG(oee)
        FROM
            mdc_oee_info
        WHERE
            the_date LIKE CONCAT(#{month}, '%')
          AND equipment_id IN
        <foreach collection="equipmentIdList" item="id" index="index" open="(" close=")" separator=",">
            #{ id }
        </foreach>
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IAndonOrderService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package org.jeecg.modules.mdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.mdc.entity.AndonOrder;
/**
 * @Description: andon_order
 * @Author: jeecg-boot
 * @Date:   2025-06-11
 * @Version: V1.0
 */
public interface IAndonOrderService extends IService<AndonOrder> {
    void procedureCall(AndonOrder andonOrder);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcDowntimeService.java
@@ -3,11 +3,13 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.board.vo.EquDowntimeInfo;
import org.jeecg.modules.mdc.dto.MdcDowntimeDto;
import org.jeecg.modules.mdc.entity.MdcDowntime;
import org.jeecg.modules.mdc.vo.MdcDowntimeVo;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
 * @Description: å¾…机停机表
@@ -35,4 +37,6 @@
     * @return
     */
    Integer findPlanTimeDuration(String equipmentId, String validDate, String closeType);
    List<EquDowntimeInfo> equDowntimeStatistics(List<String> equipmentIdList, String start, String end);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentPunchService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package org.jeecg.modules.mdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunch;
import java.util.List;
/**
 * @Description: mdc_equipment_punch
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
public interface IMdcEquipmentPunchService extends IService<MdcEquipmentPunch> {
    List<MdcEquipmentPunch> queryList();
    void workUp(MdcEquipmentPunch mdcEquipmentPunch);
    void workDown(MdcEquipmentPunch mdcEquipmentPunch);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentStatisticalInfoService.java
@@ -4,6 +4,8 @@
import org.jeecg.modules.mdc.entity.MdcEquipmentStatisticalInfo;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
 * @Description: è®¾å¤‡å•日运行数据表
 * @Author: lius
@@ -29,4 +31,8 @@
    Integer selectProcessLong(String equipmentId, String validDate);
    MdcEquipmentStatisticalDto findByEquipmentAndMonth(String equipmentId, String date);
    MdcEquipmentStatisticalInfo findByEquIdsAndMonth(List<String> equipmentIdList, String month);
    List<MdcEquipmentStatisticalInfo> findByEquipmentAndDate(List<String> equipmentIdList, String date);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcOeeInfoService.java
@@ -9,6 +9,8 @@
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
/**
 * @Description: OEE表
@@ -44,4 +46,5 @@
     */
    void computeOee(MdcOeeComputeVo mdcOeeComputeVo);
    BigDecimal findByEquIdAndMonth(List<String> equipmentIdList, String month);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/AndonOrderServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,89 @@
package org.jeecg.modules.mdc.service.impl;
import cn.hutool.core.date.DatePattern;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.WebsocketConst;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.mdc.dto.MdcEquProDto;
import org.jeecg.modules.mdc.entity.AndonOrder;
import org.jeecg.modules.mdc.mapper.AndonOrderMapper;
import org.jeecg.modules.mdc.service.IAndonOrderService;
import org.jeecg.modules.mdc.service.IMdcEquipmentService;
import org.jeecg.modules.mdc.util.DateUtils;
import org.jeecg.modules.mdc.vo.AndonOrderWebSocketVo;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @Description: andon_order
 * @Author: jeecg-boot
 * @Date:   2025-06-11
 * @Version: V1.0
 */
@Service
public class AndonOrderServiceImpl extends ServiceImpl<AndonOrderMapper, AndonOrder> implements IAndonOrderService {
    @Resource
    private IMdcEquipmentService mdcEquipmentService;
    @Resource
    private WebSocket webSocket;
    @Resource
    private ISysUserService userService;
    @Override
    public void procedureCall(AndonOrder andonOrder) {
        if (StringUtils.isBlank(andonOrder.getEquipmentId())) {
            throw new JeecgBootException("请选择设备!");
        }
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = user.getId();
        List<String> equipmentIds = Arrays.asList(andonOrder.getEquipmentId().split(StringPool.COMMA));
        List<MdcEquProDto> equipmentList = mdcEquipmentService.findEquProList(equipmentIds);
        Map<String, MdcEquProDto> equipmentIdToProductionIdMap = equipmentList.stream().collect(Collectors.toMap(MdcEquProDto::getEquipmentId, comRateDto -> comRateDto));
        List<AndonOrder> list = Lists.newArrayList();
        for (String equipmentId : equipmentIds) {
            AndonOrder andonOrderInfo = new AndonOrder();
            andonOrderInfo.setEquipmentId(equipmentId);
            andonOrderInfo.setPlantName(equipmentIdToProductionIdMap != null && equipmentIdToProductionIdMap.containsKey(equipmentId) ? equipmentIdToProductionIdMap.get(equipmentId).getId() : null);
            andonOrderInfo.setAndonType(StringPool.ONE);
            andonOrderInfo.setOperator(andonOrder.getOperator());
            andonOrderInfo.setOperateTime(new Date());
            andonOrderInfo.setResponder(userId);
            andonOrderInfo.setCallReason(andonOrder.getCallReason());
            list.add(andonOrderInfo);
        }
        if (this.saveBatch(list)) {
            List<AndonOrderWebSocketVo> andonOrderWebSocketVoList = Lists.newArrayList();
            //设置websocket请求消息数据
            for (AndonOrder order : list) {
                AndonOrderWebSocketVo andonOrderWebSocketVo = new AndonOrderWebSocketVo();
                andonOrderWebSocketVo.setEquipmentId(order.getEquipmentId());
                andonOrderWebSocketVo.setCallPersonnel(userService.getById(order.getOperator()).getRealname());
                andonOrderWebSocketVo.setCallTime(DateUtils.format(order.getOperateTime(), DatePattern.NORM_DATE_PATTERN));
                andonOrderWebSocketVo.setCallReason(order.getCallReason());
                andonOrderWebSocketVo.setAndonType("程序呼叫");
                andonOrderWebSocketVo.setPersonResponsible(user.getRealname());
                andonOrderWebSocketVo.setPlantName(equipmentIdToProductionIdMap != null && equipmentIdToProductionIdMap.containsKey(order.getEquipmentId()) ? equipmentIdToProductionIdMap.get(order.getEquipmentId()).getProductionName() : null);
                andonOrderWebSocketVoList.add(andonOrderWebSocketVo);
            }
            //发送websocket请求
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(WebsocketConst.MSG_CMD, "andon");
            jsonObject.put("data", andonOrderWebSocketVoList);
            webSocket.sendMessage(jsonObject.toJSONString());
        }
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcAlarmInfoServiceImpl.java
@@ -15,4 +15,8 @@
@Service
public class MdcAlarmInfoServiceImpl extends ServiceImpl<MdcAlarmInfoMapper, MdcAlarmInfo> implements IMdcAlarmInfoService {
    @Override
    public MdcAlarmInfo findAlarmContent(String alarmNo, String equipmentId) {
        return this.baseMapper.findAlarmContent(alarmNo, equipmentId);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcDowntimeServiceImpl.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.board.vo.EquDowntimeInfo;
import org.jeecg.modules.mdc.dto.MdcDowntimeDto;
import org.jeecg.modules.mdc.entity.MdcDowntime;
import org.jeecg.modules.mdc.mapper.MdcDowntimeMapper;
@@ -68,6 +69,11 @@
        return result;
    }
    @Override
    public List<EquDowntimeInfo> equDowntimeStatistics(List<String> equipmentIdList, String start, String end) {
        return this.baseMapper.equDowntimeStatistics(equipmentIdList, start, end);
    }
    private List<String> getEquipmentIds(String userId, MdcDowntimeVo mdcDowntimeVo) {
        if (StringUtils.isNotEmpty(mdcDowntimeVo.getEquipmentId())) {
            return Collections.singletonList(mdcDowntimeVo.getEquipmentId());
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentPunchServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,234 @@
package org.jeecg.modules.mdc.service.impl;
import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunch;
import org.jeecg.modules.mdc.mapper.MdcEquipmentPunchMapper;
import org.jeecg.modules.mdc.service.IMdcEquipmentPunchService;
import org.jeecg.modules.mdc.service.IMdcEquipmentService;
import org.jeecg.modules.mdc.util.DateUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @Description: mdc_equipment_punch
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
@Service
public class MdcEquipmentPunchServiceImpl extends ServiceImpl<MdcEquipmentPunchMapper, MdcEquipmentPunch> implements IMdcEquipmentPunchService {
    @Resource
    private IMdcEquipmentService mdcEquipmentService;
    /**
     * æŸ¥è¯¢å½“前登录人所负责设备打卡情况
     * @return
     */
    @Override
    public List<MdcEquipmentPunch> queryList() {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = user.getId();
        List<String> equipmentIds = Lists.newArrayList();
        if (StringUtils.isNotBlank(user.getEquipmentIds())) {
            equipmentIds = Arrays.asList(user.getEquipmentIds().split(StringPool.COMMA));
        }else {
            equipmentIds = mdcEquipmentService.getEquipmentIdsProduction(userId, null);
        }
        if (CollectionUtils.isEmpty(equipmentIds)) {
            return Lists.newArrayList();
        }
        if (StringUtils.isBlank(userId)) {
            return Lists.newArrayList();
        }
        //根据设备、当前日期查询打卡记录
        List<MdcEquipmentPunch> mdcEquipmentPunches = this.baseMapper.list(equipmentIds, DateUtils.format(new Date(), DatePattern.PURE_DATE_PATTERN));
        return mdcEquipmentPunches;
    }
    /**
     * ä¸Šç­æ‰“卡
     * @param mdcEquipmentPunch
     */
    @Override
    public void workUp(MdcEquipmentPunch mdcEquipmentPunch) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = user.getId();
        if (StringUtils.isBlank(mdcEquipmentPunch.getEquipmentId())) {
            throw new JeecgBootException("请选择打卡设备!");
        }
        /**
         * æ ¡éªŒæ˜¯å¦åœ¨æœ‰æ•ˆæ‰“卡范围之内
         *      æ—©ç­ä¸Šç­å¡æœ‰æ•ˆèŒƒå›´ä¸ºï¼š00:00:00 ~ 17:30:00
         *      æ™šç­ä¸Šç­å¡æœ‰æ•ˆèŒƒå›´ä¸ºï¼š00:00:00 ~ 23:00:00
         */
        Date startDate = DateUtils.getFormatDate(
                DateUtils.format(mdcEquipmentPunch.getCheckInTime(), DatePattern.NORM_DATE_PATTERN) + " 00:00:00",
                DatePattern.NORM_DATETIME_PATTERN
        );
        Date endDate = DateUtils.getFormatDate(
                DateUtils.format(mdcEquipmentPunch.getCheckInTime(), DatePattern.NORM_DATE_PATTERN) + " 17:30:00",
                DatePattern.NORM_DATETIME_PATTERN
        );
        if (mdcEquipmentPunch.getShiftSchedule() == 2) {
            //晚班无效打卡时间范围
            endDate = DateUtils.getFormatDate(
                    DateUtils.format(mdcEquipmentPunch.getCheckInTime(), DatePattern.NORM_DATE_PATTERN) + " 23:00:00",
                    DatePattern.NORM_DATETIME_PATTERN
            );
        }
        if (startDate.compareTo(mdcEquipmentPunch.getCheckInTime()) == 1 || endDate.compareTo(mdcEquipmentPunch.getCheckInTime()) == -1) {
            throw new JeecgBootException("未在有效上班打卡时间内,不能打卡!");
        }
        //查询所选设备当天是否已打上班卡
        List<String> equipmentIdList = Arrays.asList(mdcEquipmentPunch.getEquipmentId().split(StringPool.COMMA));
        String currentDate = DateUtils.format(mdcEquipmentPunch.getCheckInTime(), DatePattern.PURE_DATE_PATTERN);
        //早班上班正常最晚打卡时间
        String checkInTime = DateUtils.format(mdcEquipmentPunch.getCheckInTime(), DatePattern.NORM_DATE_PATTERN) + " 08:30:00";
        //查询当前设备、当前打卡类型打卡记录
        List<MdcEquipmentPunch> equipmentPunchList = this.list(new LambdaQueryWrapper<MdcEquipmentPunch>()
                .eq(MdcEquipmentPunch::getShiftSchedule, mdcEquipmentPunch.getShiftSchedule())
                .eq(MdcEquipmentPunch::getRecordDate, currentDate)
                .in(MdcEquipmentPunch::getEquipmentId, equipmentIdList));
        List<MdcEquipmentPunch> mdcEquipmentPunchList = equipmentPunchList.stream().filter(equipmentPunch -> Objects.nonNull(equipmentPunch.getCheckInTime())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(mdcEquipmentPunchList)) {
            List<String> equipmentIds = equipmentPunchList.stream()
                    .filter(mdcEquipmentPunchInfo -> Objects.nonNull(mdcEquipmentPunchInfo.getCheckInTime()))
                    .map(MdcEquipmentPunch::getEquipmentId)
                    .distinct()
                    .collect(Collectors.toList());
            throw new JeecgBootException("设备[" + StringUtils.join(equipmentIds, StringPool.COMMA) + "]已打卡,无需重复打卡");
        }
        List<MdcEquipmentPunch> list = Lists.newArrayList();
        //特殊处理晚班上班卡
        if (mdcEquipmentPunch.getShiftSchedule() == 2) {
            //晚班正常上班卡最晚打卡时间
            checkInTime = DateUtils.format(mdcEquipmentPunch.getCheckInTime(), DatePattern.NORM_DATE_PATTERN) + " 17:00:00";
        }
        for (String equipment : equipmentIdList) {
            Optional<MdcEquipmentPunch> first = equipmentPunchList.stream().filter(equipmentPunch -> Objects.isNull(equipmentPunch.getCheckInTime()) && equipment.equals(equipmentPunch.getEquipmentId())).findFirst();
            MdcEquipmentPunch equipmentPunch = new MdcEquipmentPunch();
            if (first.isPresent()) {
                equipmentPunch = first.get();
            }else {
                equipmentPunch.setEquipmentId(equipment);
                equipmentPunch.setPunchUser(userId);
                equipmentPunch.setRecordDate(currentDate);
                equipmentPunch.setShiftSchedule(mdcEquipmentPunch.getShiftSchedule());
                equipmentPunch.setIsAbsent(0);
                equipmentPunch.setIsEarly(0);
            }
            equipmentPunch.setCheckInTime(mdcEquipmentPunch.getCheckInTime());
            //打卡时间大于8:30/17:00时为迟到打卡
            equipmentPunch.setIsLate(mdcEquipmentPunch.getCheckInTime().compareTo(DateUtils.getFormatDate(checkInTime, DatePattern.NORM_DATETIME_PATTERN)) == 1 ? 1 : 0);
            list.add(equipmentPunch);
        }
        this.saveOrUpdateBatch(list);
    }
    @Override
    public void workDown(MdcEquipmentPunch mdcEquipmentPunch) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = user.getId();
        if (StringUtils.isBlank(mdcEquipmentPunch.getEquipmentId())) {
            throw new JeecgBootException("请选择打卡设备!");
        }
        /**
         * æ ¡éªŒå½“前下班卡是否在有效下班打卡范围之内
         *      æ—©ç­ä¸‹ç­æ— æ•ˆæ‰“卡时间范围为00:00:00 ~ 08:30:00
         *      æ™šç­ä¸‹ç­æ— æ•ˆæ‰“卡时间范围为00:00:00 ~ 17:00:00
         */
        Date startDate = DateUtils.getFormatDate(
                DateUtils.format(mdcEquipmentPunch.getCheckOutTime(), DatePattern.NORM_DATE_PATTERN) + " 00:00:00",
                DatePattern.NORM_DATETIME_PATTERN
        );
        Date endDate = DateUtils.getFormatDate(
                DateUtils.format(mdcEquipmentPunch.getCheckOutTime(), DatePattern.NORM_DATE_PATTERN) + " 08:30:00",
                DatePattern.NORM_DATETIME_PATTERN
        );
        Date checkOutTime = DateUtils.getFormatDate(
                DateUtils.format(mdcEquipmentPunch.getCheckOutTime(), DatePattern.NORM_DATE_PATTERN) + " 17:30:00",
                DatePattern.NORM_DATETIME_PATTERN
        );
        if (mdcEquipmentPunch.getShiftSchedule() == 2) {
            //晚班无效打卡时间范围
            endDate = DateUtils.getFormatDate(
                    DateUtils.format(mdcEquipmentPunch.getCheckOutTime(), DatePattern.NORM_DATE_PATTERN) + " 17:00:00",
                    DatePattern.NORM_DATETIME_PATTERN
            );
            //晚班正常下班最早打卡时间
            checkOutTime = DateUtils.getFormatDate(
                    DateUtils.format(mdcEquipmentPunch.getCheckOutTime(), DatePattern.NORM_DATE_PATTERN) + " 23:00:00",
                    DatePattern.NORM_DATETIME_PATTERN
            );
        }
        if (startDate.compareTo(mdcEquipmentPunch.getCheckOutTime()) == 1
                || endDate.compareTo(mdcEquipmentPunch.getCheckOutTime()) == 1) {
            throw new JeecgBootException("未在有效下班打卡时间内,不能打卡!");
        }
        //查询当前所选设备是否存在上班打卡记录
        List<String> equipmentIdList = Arrays.asList(mdcEquipmentPunch.getEquipmentId().split(StringPool.COMMA));
        String currentDate = DateUtils.format(mdcEquipmentPunch.getCheckOutTime(), DatePattern.PURE_DATE_PATTERN);
        List<MdcEquipmentPunch> equipmentPunchList = this.list(new LambdaQueryWrapper<MdcEquipmentPunch>()
                .eq(MdcEquipmentPunch::getShiftSchedule, mdcEquipmentPunch.getShiftSchedule())
                .eq(MdcEquipmentPunch::getRecordDate, currentDate)
                .in(MdcEquipmentPunch::getEquipmentId, equipmentIdList));
        List<MdcEquipmentPunch> list = Lists.newArrayList();
        for (String equipmentId : equipmentIdList) {
            Optional<MdcEquipmentPunch> mdcEquipmentPunchOptional = equipmentPunchList.stream()
                    .filter(mdcEquipmentPunch1 -> mdcEquipmentPunch1.getEquipmentId().equals(equipmentId))
                    .findFirst();
            MdcEquipmentPunch equipmentPunch = new MdcEquipmentPunch();
            if (mdcEquipmentPunchOptional.isPresent()) {
                equipmentPunch = mdcEquipmentPunchOptional.get();
            }else {
                equipmentPunch.setIsAbsent(1);
                equipmentPunch.setIsLate(0);
                equipmentPunch.setEquipmentId(equipmentId);
                equipmentPunch.setShiftSchedule(mdcEquipmentPunch.getShiftSchedule());
                equipmentPunch.setPunchUser(userId);
                equipmentPunch.setRecordDate(currentDate);
            }
            equipmentPunch.setCheckOutTime(mdcEquipmentPunch.getCheckOutTime());
            //下班打卡时间早于17:30/23:00则为早退
            equipmentPunch.setIsEarly(checkOutTime.compareTo(mdcEquipmentPunch.getCheckOutTime()) == 1 ? 1 : 0);
            list.add(equipmentPunch);
        }
        this.saveOrUpdateBatch(list);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentStatisticalInfoServiceImpl.java
@@ -323,4 +323,14 @@
    public MdcEquipmentStatisticalDto findByEquipmentAndMonth(String equipmentId, String date) {
        return this.baseMapper.findByEquipmentAndMonth(equipmentId, date);
    }
    @Override
    public MdcEquipmentStatisticalInfo findByEquIdsAndMonth(List<String> equipmentIdList, String month) {
        return this.baseMapper.findByEquIdsAndMonth(equipmentIdList, month);
    }
    @Override
    public List<MdcEquipmentStatisticalInfo> findByEquipmentAndDate(List<String> equipmentIdList, String date) {
        return this.baseMapper.findByEquipmentAndDate(equipmentIdList, date);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcOeeInfoServiceImpl.java
@@ -243,4 +243,9 @@
        super.saveBatch(result);
    }
    @Override
    public BigDecimal findByEquIdAndMonth(List<String> equipmentIdList, String month) {
        return this.baseMapper.findByEquIdAndMonth(equipmentIdList, month);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/vo/AndonOrderWebSocketVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package org.jeecg.modules.mdc.vo;
import lombok.Data;
@Data
public class AndonOrderWebSocketVo {
    /**
     * è®¾å¤‡ç¼–号
     */
    private String equipmentId;
    /**
     * å‘¼å«äººå‘˜
     */
    private String callPersonnel;
    /**
     * å®‰ç¯ç±»åž‹
     */
    private String andonType;
    /**
     * å‘¼å«æ—¶é—´
     */
    private String callTime;
    /**
     * å‘¼å«åŽŸå› 
     */
    private String callReason;
    /**
     * è´£ä»»äºº
     */
    private String personResponsible;
    /**
     * æŠ¥ä¿®æ—¶é—´
     */
    private String repairTime;
    /**
     * æ•…障描述
     */
    private String faultInfo;
    /**
     * æ‰€å±žåŽ‚æˆ¿
     */
    private String plantName;
}
lxzn-module-msi/src/main/java/org/jeecg/modules/msi/utils/WebServiceUtil.java
ÎļþÒÑɾ³ý
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/message/websocket/WebSocket.java
@@ -2,6 +2,9 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
@@ -34,14 +37,23 @@
    @Resource
    private JeecgRedisClient jeecgRedisClient;
    private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    //==========【websocket接受、推送消息等方法 â€”— å…·ä½“服务节点推送ws消息】========================================================================================
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") String userId) {
        try {
            sessionPool.put(userId, session);
            log.info("【系统 WebSocket】有新的连接,总数为:" + sessionPool.size());
            // å¯åŠ¨å¿ƒè·³ä»»åŠ¡ï¼Œæ¯åˆ†é’Ÿå‘é€ä¸€æ¬¡å¿ƒè·³æ¶ˆæ¯
//            scheduler.scheduleAtFixedRate(() -> {
//                pushMessage(userId, "{\"cmd\":\"" + WebsocketConst.CMD_USER + "\",\"txt\":\"" + "心跳响应" + "\"}");
//            }, 0, 1, TimeUnit.MINUTES);
        } catch (Exception e) {
            log.error("【系统 WebSocket】onOpen å¼‚常", e);
        }
    }
@@ -50,6 +62,8 @@
        try {
            sessionPool.remove(userId);
            log.info("【系统 WebSocket】连接断开,总数为:" + sessionPool.size());
            // å–消心跳任务
            scheduler.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
@@ -93,12 +107,11 @@
                    log.error(e.getMessage(), e);
                }
            }
            log.info("【系统 WebSocket】群发消息:" + message);
            log.info("【3D实时数据 WebSocket】消息" );
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
    /**
     * ws接受客户端消息
@@ -112,12 +125,12 @@
        }
        
        //------------------------------------------------------------------------------
        JSONObject obj = new JSONObject();
        //业务类型
        obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
        //消息内容
        obj.put(WebsocketConst.MSG_TXT, "心跳响应");
        this.pushMessage(userId, obj.toJSONString());
//        JSONObject obj = new JSONObject();
//        //业务类型
//        obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
//        //消息内容
//        obj.put(WebsocketConst.MSG_TXT, "心跳响应");
//        this.pushMessage(userId, obj.toJSONString());
        //------------------------------------------------------------------------------
    }
@@ -129,7 +142,7 @@
     */
    @OnError
    public void onError(Session session, Throwable t) {
        log.warn("【系统 WebSocket】消息出现错误");
        log.warn("【系统 WebSocket】消息出现错误",t);
        //t.printStackTrace();
    }
    //==========【系统 WebSocket接受、推送消息等方法 â€”— å…·ä½“服务节点推送ws消息】========================================================================================
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/MdcProductionMapper.java
@@ -61,4 +61,8 @@
    List<String> findTeamValue(@Param("userId") String userId, @Param("productionList") List<String> productionList);
    List<String> findProIdsByUId(@Param("userId") String userId, @Param("allProductionIds") List<String> allProductionIds);
    List<String> findChildByProId(@Param("productionId") String productionId);
    String findProName(@Param("equipmentId") String equipmentId);
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/MdcProductionMapper.xml
@@ -138,4 +138,67 @@
            </foreach>
          AND user_id = #{userId}
    </select>
    <select id="findChildByProId" resultType="java.lang.String">
        WITH temp ( id ) AS (
            SELECT
                id
            FROM
                mdc_production
            WHERE
                id = #{ productionId }
              AND mdc_flag = '1' UNION ALL
            SELECT
                a.id
            FROM
                mdc_production a
                    INNER JOIN temp ON a.parent_id = temp.id
            WHERE
                a.mdc_flag = '1'
        ) SELECT
            *
        FROM
            temp
    </select>
    <select id="findProName" resultType="java.lang.String">
        WITH production_hierarchy AS (
            SELECT
                t3.id,
                t3.parent_id,
                t3.production_name,
                t3.org_type,
                0 AS level
            FROM
                mdc_equipment t1
                    JOIN
                mdc_production_equipment t2 ON t1.id = t2.equipment_id
                    JOIN
                mdc_production t3 ON t2.production_id = t3.id
            WHERE
                t1.equipment_id = #{equipmentId}
            UNION ALL
            SELECT
                t4.id,
                t4.parent_id,
                t4.production_name,
                t4.org_type,
                ph.level + 1
            FROM
                production_hierarchy ph
                    JOIN
                mdc_production t4 ON ph.parent_id = t4.id
            WHERE
                ph.parent_id IS NOT NULL
        )
        SELECT TOP 1
            production_name
        FROM
            production_hierarchy
        WHERE
            org_type = 2
        ORDER BY
            level ASC
    </select>
</mapper>
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/IMdcProductionService.java
@@ -175,4 +175,14 @@
     * @return
     */
    List<String> findProIdsByUId(String userId, List<String> allProductionIds);
    /**
     *
     * @param productionId
     * @return
     */
    List<String> findChildByProId(String productionId);
    String findProName(String equipmentId);
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/MdcProductionServiceImpl.java
@@ -627,4 +627,14 @@
            super.update(updateWrapper);
        }
    }
    @Override
    public List<String> findChildByProId(String productionId) {
        return this.baseMapper.findChildByProId(productionId);
    }
    @Override
    public String findProName(String equipmentId) {
        return this.baseMapper.findProName(equipmentId);
    }
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/BaseToolsController.java
@@ -1,5 +1,8 @@
package org.jeecg.modules.tms.controller;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
@@ -7,6 +10,8 @@
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.tms.entity.*;
@@ -575,4 +580,98 @@
         IPage<SharpeeningVo> resultPage = baseToolsService.pageWithSharpedAndConfig(page, queryWrapper);
         return Result.OK(resultPage);
     }
     /**
      * å¯¼å…¥æ¨¡æ¿ä¸‹è½½
      *
      */
     @RequestMapping(value = "/loadTemplate")
     public void loadTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException {
         Map<String,String[]> req = request.getParameterMap();
         String paraTypeFlag = "";
         if(req.get("paraTypeFlag") != null){
             paraTypeFlag = req.get("paraTypeFlag")[0];
         }
         if("1".equals(paraTypeFlag)){
             Workbook workbook = WorkbookFactory.create(new File("D:\\opt\\upFiles\\刀具信息导入模板-通用参数.xlsx"));
             //导出Workbook
             //设置响应头
             String fileName = "刀具信息导入模板-通用参数.xlsx";
             // å¯¹æ–‡ä»¶åè¿›è¡ŒURL编码,防止中文乱码
             String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
             // å°†Workbook写入响应输出流
             try { // try-with-resources自动关闭资源
                 workbook.write(response.getOutputStream());
                 response.flushBuffer();
             } catch (IOException e) {
                 // å¼‚常处理(如记录日志)
                 throw new IOException("下载模板失败", e);
             }
         }else if("2".equals(paraTypeFlag)){
             Workbook workbook = WorkbookFactory.create(new File("D:\\opt\\upFiles\\刀具信息导入模板-孔加工工具.xlsx"));
             String fileName = "刀具信息导入模板-孔加工工具.xlsx";
             String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
             try {
                 workbook.write(response.getOutputStream());
                 response.flushBuffer();
             } catch (IOException e) {
                 throw new IOException("下载模板失败", e);
             }
         }else if("3".equals(paraTypeFlag)){
             Workbook workbook = WorkbookFactory.create(new File("D:\\opt\\upFiles\\刀具信息导入模板-螺纹工具.xlsx"));
             String fileName = "刀具信息导入模板-螺纹工具.xlsx";
             String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
             try {
                 workbook.write(response.getOutputStream());
                 response.flushBuffer();
             } catch (IOException e) {
                 throw new IOException("下载模板失败", e);
             }
         }else if("4".equals(paraTypeFlag)){
             Workbook workbook = WorkbookFactory.create(new File("D:\\opt\\upFiles\\刀具信息导入模板-铣削工具.xlsx"));
             String fileName = "刀具信息导入模板-铣削工具.xlsx";
             String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
             try {
                 workbook.write(response.getOutputStream());
                 response.flushBuffer();
             } catch (IOException e) {
                 throw new IOException("下载模板失败", e);
             }
         }else if("5".equals(paraTypeFlag)){
             Workbook workbook = WorkbookFactory.create(new File("D:\\opt\\upFiles\\刀具信息导入模板-车削工具.xlsx"));
             String fileName = "刀具信息导入模板-车削工具.xlsx";
             String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
             try {
                 workbook.write(response.getOutputStream());
                 response.flushBuffer();
             } catch (IOException e) {
                 throw new IOException("下载模板失败", e);
             }
         }else if("6".equals(paraTypeFlag)){
             Workbook workbook = WorkbookFactory.create(new File("D:\\opt\\upFiles\\刀具信息导入模板-刀片.xlsx"));
             String fileName = "刀具信息导入模板-刀片.xlsx";
             String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
             try {
                 workbook.write(response.getOutputStream());
                 response.flushBuffer();
             } catch (IOException e) {
                 throw new IOException("下载模板失败", e);
             }
         }
     }
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/PreparationOrderController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,326 @@
package org.jeecg.modules.tms.controller;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.system.query.QueryGenerator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.tms.entity.dto.PreparationOrderAndDetailDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.tms.entity.PreparationOrderDetail;
import org.jeecg.modules.tms.entity.PreparationOrder;
import org.jeecg.modules.tms.service.IPreparationOrderService;
import org.jeecg.modules.tms.service.IPreparationOrderDetailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
@Api(tags="刀具准备单")
@RestController
@RequestMapping("/tms/preparationOrder")
@Slf4j
public class PreparationOrderController extends JeecgController<PreparationOrder, IPreparationOrderService> {
    @Autowired
    private IPreparationOrderService preparationOrderService;
    @Autowired
    private IPreparationOrderDetailService preparationOrderDetailService;
    /*---------------------------------主表处理-begin-------------------------------------*/
    /**
     * åˆ†é¡µåˆ—表查询
     * @param preparationOrder
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "刀具准备单-分页列表查询")
    @ApiOperation(value="刀具准备单-分页列表查询", notes="刀具准备单-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<PreparationOrder>> queryPageList(PreparationOrder preparationOrder,
                                                         @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                                         @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                                         HttpServletRequest req) {
        Map<String, String[]> parameterMap = req.getParameterMap();
        QueryWrapper<PreparationOrder> queryWrapper = QueryGenerator.initQueryWrapper(preparationOrder, parameterMap);
        Page<PreparationOrder> page = new Page<PreparationOrder>(pageNo, pageSize);
        IPage<PreparationOrder> pageList = preparationOrderService.queryPageList(page, parameterMap);
        return Result.OK(pageList);
    }
    /**
     *   æ·»åŠ 
     * @param preparationOrder
     * @return
     */
    @AutoLog(value = "刀具准备单-添加")
    @ApiOperation(value="刀具准备单-添加", notes="刀具准备单-添加")
    //@RequiresPermissions("org.jeecg.modules:tms_preparation_order:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody PreparationOrder preparationOrder) {
        preparationOrderService.save(preparationOrder);
        return Result.OK("添加成功!");
    }
    /**
     *  ç¼–辑
     * @param preparationOrder
     * @return
     */
    @AutoLog(value = "刀具准备单-编辑")
    @ApiOperation(value="刀具准备单-编辑", notes="刀具准备单-编辑")
    //@RequiresPermissions("org.jeecg.modules:tms_preparation_order:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
    public Result<String> edit(@RequestBody PreparationOrder preparationOrder) {
        preparationOrderService.updateById(preparationOrder);
        return Result.OK("编辑成功!");
    }
    @AutoLog(value = "刀具准备单-确认完成")
    @ApiOperation(value="刀具准备单-调机员修正确认", notes = "刀具准备单-调机员修正确认")
    @RequestMapping(value = "/editTotal", method = {RequestMethod.PUT,RequestMethod.POST})
    public Result<String> editTotal(@RequestBody PreparationOrderAndDetailDto preparationOrderAndDetailDto) {
        preparationOrderService.editTotal(preparationOrderAndDetailDto);
        return Result.OK("确认完成!");
    }
    /**
     * é€šè¿‡id删除
     * @param id
     * @return
     */
    @AutoLog(value = "刀具准备单-通过id删除准备单及明细")
    @ApiOperation(value="刀具准备单-通过id删除准备单及明细", notes="刀具准备单-通过id删除准备单及明细")
    //@RequiresPermissions("org.jeecg.modules:tms_preparation_order:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name="id",required=true) String id) {
        preparationOrderService.delMain(id);
        return Result.OK("删除成功!");
    }
    /**
     * æ‰¹é‡åˆ é™¤
     * @param ids
     * @return
     */
    @AutoLog(value = "刀具准备单-批量删除")
    @ApiOperation(value="刀具准备单-批量删除", notes="刀具准备单-批量删除")
    //@RequiresPermissions("org.jeecg.modules:tms_preparation_order:deleteBatch")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
        preparationOrderService.delBatchMain(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }
    @AutoLog(value = "刀具准备单-转出库申请单")
    @ApiOperation(value = "刀具准备单-转出库申请单", notes = "刀具准备单-转出库申请单")
    //@RequiresPermissions("org.jeecg.modules:tms_preparation_order:convert")
    @PostMapping(value = "/convertToOutboundOrder")
    public Result<String> convertToOutboundOrder(@RequestBody List<String> preparationOrderIds) {
        List<String> result = preparationOrderService.convertToOutboundOrder(preparationOrderIds);
        return Result.OK(JSONObject.toJSONString(result));
    }
    /**
     * å¯¼å‡º
     * @return
     */
    //@RequiresPermissions("org.jeecg.modules:tms_preparation_order:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, PreparationOrder preparationOrder) {
        return super.exportXls(request, preparationOrder, PreparationOrder.class, "刀具准备单");
    }
    /**
     * å¯¼å…¥
     * @return
     */
    //@RequiresPermissions("org.jeecg.modules:tms_preparation_order:importExcel")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, PreparationOrder.class);
    }
    /*---------------------------------主表处理-end-------------------------------------*/
    /*--------------------------------子表处理-刀具准备单明细-begin----------------------------------------------*/
    /**
     * é€šè¿‡ä¸»è¡¨ID查询
     * @return
     */
    //@AutoLog(value = "刀具准备单明细-通过主表ID查询")
    @ApiOperation(value="刀具准备单明细-通过主表ID查询", notes="刀具准备单明细-通过主表ID查询")
    @GetMapping(value = "/listPreparationOrderDetailByMainId")
    public Result<IPage<PreparationOrderDetail>> listPreparationOrderDetailByMainId(PreparationOrderDetail preparationOrderDetail,
                                                                                    @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                                                    HttpServletRequest req) {
        Map<String, String[]> parameterMap = req.getParameterMap();
        QueryWrapper<PreparationOrderDetail> queryWrapper = QueryGenerator.initQueryWrapper(preparationOrderDetail, parameterMap);
        Page<PreparationOrderDetail> page = new Page<PreparationOrderDetail>(pageNo, pageSize);
        IPage<PreparationOrderDetail> pageList = preparationOrderDetailService.queryPageList(page, parameterMap);
        return Result.OK(pageList);
    }
    /**
     * æ·»åŠ 
     * @param preparationOrderDetail
     * @return
     */
    @AutoLog(value = "刀具准备单明细-添加")
    @ApiOperation(value="刀具准备单明细-添加", notes="刀具准备单明细-添加")
    @PostMapping(value = "/addPreparationOrderDetail")
    public Result<String> addPreparationOrderDetail(@RequestBody PreparationOrderDetail preparationOrderDetail) {
        preparationOrderDetailService.save(preparationOrderDetail);
        return Result.OK("添加成功!");
    }
    /**
     * ç¼–辑
     * @param preparationOrderDetail
     * @return
     */
    @AutoLog(value = "刀具准备单明细-编辑")
    @ApiOperation(value="刀具准备单明细-编辑", notes="刀具准备单明细-编辑")
    @RequestMapping(value = "/editPreparationOrderDetail", method = {RequestMethod.PUT,RequestMethod.POST})
    public Result<String> editPreparationOrderDetail(@RequestBody PreparationOrderDetail preparationOrderDetail) {
        preparationOrderDetailService.updateById(preparationOrderDetail);
        return Result.OK("编辑成功!");
    }
    /**
     * é€šè¿‡id删除
     * @param id
     * @return
     */
    @AutoLog(value = "刀具准备单明细-通过id删除")
    @ApiOperation(value="刀具准备单明细-通过id删除", notes="刀具准备单明细-通过id删除")
    @DeleteMapping(value = "/deletePreparationOrderDetail")
    public Result<String> deletePreparationOrderDetail(@RequestParam(name="id",required=true) String id) {
        preparationOrderDetailService.removeById(id);
        return Result.OK("删除成功!");
    }
    /**
     * æ‰¹é‡åˆ é™¤
     * @param ids
     * @return
     */
    @AutoLog(value = "刀具准备单明细-批量删除")
    @ApiOperation(value="刀具准备单明细-批量删除", notes="刀具准备单明细-批量删除")
    @DeleteMapping(value = "/deleteBatchPreparationOrderDetail")
    public Result<String> deleteBatchPreparationOrderDetail(@RequestParam(name="ids",required=true) String ids) {
        this.preparationOrderDetailService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }
    /**
     * å¯¼å‡º
     * @return
     */
    @RequestMapping(value = "/exportPreparationOrderDetail")
    public ModelAndView exportPreparationOrderDetail(HttpServletRequest request, PreparationOrderDetail preparationOrderDetail) {
        // Step.1 ç»„装查询条件
        QueryWrapper<PreparationOrderDetail> queryWrapper = QueryGenerator.initQueryWrapper(preparationOrderDetail, request.getParameterMap());
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        // Step.2 èŽ·å–å¯¼å‡ºæ•°æ®
        List<PreparationOrderDetail> pageList = preparationOrderDetailService.list(queryWrapper);
        List<PreparationOrderDetail> exportList = null;
        // è¿‡æ»¤é€‰ä¸­æ•°æ®
        String selections = request.getParameter("selections");
        if (oConvertUtils.isNotEmpty(selections)) {
            List<String> selectionList = Arrays.asList(selections.split(","));
            exportList = pageList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
        } else {
            exportList = pageList;
        }
        // Step.3 AutoPoi å¯¼å‡ºExcel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        //此处设置的filename无效,前端会重更新设置一下
        mv.addObject(NormalExcelConstants.FILE_NAME, "刀具准备单明细");
        mv.addObject(NormalExcelConstants.CLASS, PreparationOrderDetail.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("刀具准备单明细报表", "导出人:" + sysUser.getRealname(), "刀具准备单明细"));
        mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
        return mv;
    }
    /**
     * å¯¼å…¥
     * @return
     */
    @RequestMapping(value = "/importPreparationOrderDetail/{mainId}")
    public Result<?> importPreparationOrderDetail(HttpServletRequest request, HttpServletResponse response, @PathVariable("mainId") String mainId) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            // èŽ·å–ä¸Šä¼ æ–‡ä»¶å¯¹è±¡
            MultipartFile file = entity.getValue();
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setNeedSave(true);
            try {
                List<PreparationOrderDetail> list = ExcelImportUtil.importExcel(file.getInputStream(), PreparationOrderDetail.class, params);
                for (PreparationOrderDetail temp : list) {
                    temp.setPreparationOrderId(mainId);
                }
                long start = System.currentTimeMillis();
                preparationOrderDetailService.saveBatch(list);
                log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
                return Result.OK("文件导入成功!数据行数:" + list.size());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return Result.error("文件导入失败:" + e.getMessage());
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败!");
    }
    /*--------------------------------子表处理-刀具准备单明细-end----------------------------------------------*/
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/convert/OutboundOrderConvert.java
@@ -2,17 +2,25 @@
import org.jeecg.modules.tms.entity.OutboundOrder;
import org.jeecg.modules.tms.entity.dto.OutboundOrderAndDetailDto;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.ReportingPolicy;
import org.mapstruct.factory.Mappers;
/**
 * ä½¿ç”¨ MapStruct æ–¹å¼è¿›è¡Œå±žæ€§å¤åˆ¶
 * æ³¨æ„ä¸èƒ½æ”¾åœ¨ mybatis扫描的mapper包下面,否则会报错
 */
@Mapper
@Mapper(
        unmappedTargetPolicy = ReportingPolicy.IGNORE, // å¿½ç•¥ç›®æ ‡ä¸­æœªè¢«æ˜ å°„的字段
        componentModel = "spring" // å¦‚果使用 Spring,可生成 Spring ç®¡ç†çš„ Bean
)
public interface OutboundOrderConvert {
    OutboundOrderConvert INSTANCE = Mappers.getMapper(OutboundOrderConvert.class);
    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)// å¿½ç•¥ null å­—段
    OutboundOrder convert(OutboundOrderAndDetailDto dto);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/convert/PreparationOrderConvert.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package org.jeecg.modules.tms.convert;
import org.jeecg.modules.tms.entity.PreparationOrder;
import org.jeecg.modules.tms.entity.dto.PreparationOrderAndDetailDto;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.ReportingPolicy;
import org.mapstruct.factory.Mappers;
/**
 * ä½¿ç”¨ MapStruct æ–¹å¼è¿›è¡Œå±žæ€§å¤åˆ¶
 * æ³¨æ„ä¸èƒ½æ”¾åœ¨ mybatis扫描的mapper包下面,否则会报错
 */
@Mapper(
        unmappedTargetPolicy = ReportingPolicy.IGNORE, // å¿½ç•¥ç›®æ ‡ä¸­æœªè¢«æ˜ å°„的字段
        componentModel = "spring" // å¦‚果使用 Spring,可生成 Spring ç®¡ç†çš„ Bean
)
public interface PreparationOrderConvert {
    PreparationOrderConvert INSTANCE = Mappers.getMapper(PreparationOrderConvert.class);
    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)// å¿½ç•¥ null å­—段
    PreparationOrder convert(PreparationOrderAndDetailDto dto);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/BaseTools.java
@@ -108,4 +108,9 @@
    @DateTimeFormat(pattern="yyyy-MM-dd")
    @ApiModelProperty(value = "更新时间")
    private Date updateTime;
    /**工具图片*/
    @Excel(name = "工具图片", width = 15)
    @ApiModelProperty(value = "工具图片")
    private String toolPicture;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/OutboundDetail.java
@@ -5,6 +5,7 @@
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -22,6 +23,7 @@
 * @Version: V1.0
 */
@Data
@Accessors(chain = true)
@TableName("tms_outbound_detail")
@ApiModel(value="tms_outbound_detail对象", description="出库申请单明细")
public class OutboundDetail implements Serializable {
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/OutboundOrder.java
@@ -5,6 +5,8 @@
import java.util.Date;
import com.baomidou.mybatisplus.annotation.*;
import liquibase.pro.packaged.E;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -20,6 +22,7 @@
 * @Version: V1.0
 */
@Data
@Accessors(chain = true)
@TableName("tms_outbound_order")
@ApiModel(value="tms_outbound_order对象", description="tms_outbound_order")
public class OutboundOrder implements Serializable {
@@ -98,6 +101,42 @@
    @Excel(name = "备注", width = 15)
    @ApiModelProperty(value = "备注")
    private String remark;
    /**准备单编号*/
    @Excel(name = "准备单编号", width = 15)
    @ApiModelProperty(value = "准备单编号")
    private String preparationOrderId;
    /**零件图号*/
    @Excel(name = "零件图号", width = 15)
    @ApiModelProperty(value = "零件图号")
    private String partDrawingNo;
    /**零件名称*/
    @Excel(name = "零件名称", width = 15)
    @ApiModelProperty(value = "零件名称")
    private String partName;
    /**零件材料*/
    @Excel(name = "零件材料", width = 15)
    @ApiModelProperty(value = "零件材料")
    private String partMaterial;
    /**加工批次*/
    @Excel(name = "工序(工步号)", width = 15)
    @ApiModelProperty(value = "工序(工步号)")
    private String productionProcessesNo;
    /**加工批次*/
    @Excel(name = "加工批次", width = 15)
    @ApiModelProperty(value = "加工批次")
    private String batchCode;
    /**加工数量*/
    @Excel(name = "加工数量", width = 15)
    @ApiModelProperty(value = "加工数量")
    private String machiningCount;
    /**加工设备*/
    @Excel(name = "加工设备", width = 15)
    @ApiModelProperty(value = "加工设备")
    private String equipmentCode;
    /**程序名*/
    @Excel(name = "程序名", width = 15)
    @ApiModelProperty(value = "程序名")
    private String ncName;
    /**租户号*/
    @Excel(name = "租户号", width = 15)
    @ApiModelProperty(value = "租户号")
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/PreparationOrder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,111 @@
package org.jeecg.modules.tms.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
@Data
@Accessors(chain = true)
@TableName("tms_preparation_order")
@ApiModel(value="tms_preparation_order对象", description="刀具准备单")
public class PreparationOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    /**主键*/
    @TableId(type = IdType.ASSIGN_ID)
    @ApiModelProperty(value = "主键")
    private String id;
    /**准备单编号*/
    @Excel(name = "准备单编号", width = 15)
    @ApiModelProperty(value = "准备单编号")
    private String preparationOrderNum;
    /**零件图号*/
    @Excel(name = "零件图号", width = 15)
    @ApiModelProperty(value = "零件图号")
    private String partDrawingNo;
    /**零件名称*/
    @Excel(name = "零件名称", width = 15)
    @ApiModelProperty(value = "零件名称")
    private String partName;
    /**零件材料*/
    @Excel(name = "零件材料", width = 15)
    @ApiModelProperty(value = "零件材料")
    private String partMaterial;
    /**工序(工步号)*/
    @Excel(name = "工序(工步号)", width = 15)
    @ApiModelProperty(value = "工序(工步号)")
    private String productionProcessesNo;
    /**加工批次*/
    @Excel(name = "加工批次", width = 15)
    @ApiModelProperty(value = "加工批次")
    private String batchCode;
    /**加工数量*/
    @Excel(name = "加工数量", width = 15)
    @ApiModelProperty(value = "加工数量")
    private String machiningCount;
    /**加工设备*/
    @Excel(name = "加工设备", width = 15)
    @ApiModelProperty(value = "加工设备")
    private String equipmentCode;
    /**程序名*/
    @Excel(name = "程序名", width = 15)
    @ApiModelProperty(value = "程序名")
    private String ncName;
    /**准备单出库数量*/
    @Excel(name = "准备单出库数量", width = 15)
    @ApiModelProperty(value = "准备单出库数量")
    private java.math.BigDecimal outboundQuantity;
    /**单子状态;1.未审核;2.调机员已审核;3.已转出库申请*/
    @Dict(dicCode = "preparation_order_status")
    @Excel(name = "单子状态;1.未审核;2.调机员已审核;3.已转出库申请", width = 15)
    @ApiModelProperty(value = "单子状态;1.未审核;2.调机员已审核;3.已转出库申请")
    private String orderStatus;
    /**准备单提交时间;提交至出库申请单的时间*/
    @Excel(name = "准备单提交时间;提交至出库申请单的时间", width = 15, format = "yyyy-MM-dd HH:mm")
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
    @ApiModelProperty(value = "准备单提交时间;提交至出库申请单的时间")
    private Date outboundTime;
    /**备注*/
    @Excel(name = "备注", width = 15)
    @ApiModelProperty(value = "备注")
    private String remark;
    /**租户号*/
    @Excel(name = "租户号", width = 15)
    @ApiModelProperty(value = "租户号")
    private String tenantId;
    /**创建人*/
    @ApiModelProperty(value = "创建人")
    private String createBy;
    /**创建时间;DNC推送数据时间*/
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
    @ApiModelProperty(value = "创建时间;DNC推送数据时间")
    private Date createTime;
    /**更新人*/
    @ApiModelProperty(value = "更新人")
    private String updateBy;
    /**更新时间*/
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
    @ApiModelProperty(value = "更新时间")
    private Date updateTime;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/PreparationOrderDetail.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,98 @@
package org.jeecg.modules.tms.entity;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.jeecg.common.aspect.annotation.Dict;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•明细
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
@Data
@TableName("tms_preparation_order_detail")
@ApiModel(value="tms_preparation_order_detail对象", description="刀具准备单明细")
public class PreparationOrderDetail implements Serializable {
    private static final long serialVersionUID = 1L;
    /**主键*/
    @TableId(type = IdType.ASSIGN_ID)
    @ApiModelProperty(value = "主键")
    private String id;
    /**准备单号*/
    @ApiModelProperty(value = "准备单号")
    private String preparationOrderId;
    /**刀具编码*/
    @Excel(name = "刀具编码", width = 15)
    @ApiModelProperty(value = "刀具编码(tms_base_tool表id字段)")
    private String toolCode;
    /**刀具编号*/
    @Excel(name = "刀具编号", width = 15)
    @ApiModelProperty(value = "刀具编号")
    private String toolId;
    /**申请出库数量*/
    @Excel(name = "申请出库数量", width = 15)
    @ApiModelProperty(value = "申请出库数量")
    private java.math.BigDecimal outboundQuantity;
    /**租户号*/
    @Excel(name = "租户号", width = 15)
    @ApiModelProperty(value = "租户号")
    private String tenantId;
    /**创建人*/
    @ApiModelProperty(value = "创建人")
    private String createBy;
    /**创建时间*/
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern="yyyy-MM-dd")
    @ApiModelProperty(value = "创建时间")
    private Date createTime;
    /**更新人*/
    @ApiModelProperty(value = "更新人")
    private String updateBy;
    /**更新时间*/
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern="yyyy-MM-dd")
    @ApiModelProperty(value = "更新时间")
    private Date updateTime;
    /**刀具编码(tms_base_tool表tool_code字段)*/
    @TableField(exist = false)
    @ApiModelProperty(value = "刀具编码(tms_base_tool表tool_code字段)")
    private String toolNum;
    /**中文名称*/
    @TableField(exist = false)
    @ApiModelProperty(value = "中文名称")
    private String chineseName;
    /**型号/图号*/
    @TableField(exist = false)
    @ApiModelProperty(value = "型号/图号")
    private String toolModel;
    /**工具类型*/
    @TableField(exist = false)
    @ApiModelProperty(value = "工具类型")
    @Dict(dicCode = "application_type")
    private String applicationType;
    /**刀具材料*/
    @TableField(exist = false)
    @ApiModelProperty(value = "刀具材料")
    private String toolMaterial;
    /**零件材料*/
    @TableField(exist = false)
    @ApiModelProperty(value = "零件材料")
    private String partMaterial;
    /**厂家*/
    @TableField(exist = false)
    @ApiModelProperty(value = "厂家")
    private String supplierId;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/dto/PreparationOrderAndDetailDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
package org.jeecg.modules.tms.entity.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecg.modules.tms.entity.PreparationOrderDetail;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
@Data
public class PreparationOrderAndDetailDto {
    /**主键*/
    @ApiModelProperty(value = "主键")
    private String id;
    /**准备单编号*/
    @ApiModelProperty(value = "准备单编号")
    private String preparationOrderNum;
    /**零件图号*/
    @ApiModelProperty(value = "零件图号")
    private String partDrawingNo;
    /**零件名称*/
    @ApiModelProperty(value = "零件名称")
    private String partName;
    /**零件材料*/
    @ApiModelProperty(value = "零件材料")
    private String partMaterial;
    /**工序(工步号)*/
    @ApiModelProperty(value = "工序(工步号)")
    private String productionProcessesNo;
    /**加工批次*/
    @ApiModelProperty(value = "加工批次")
    private String batchCode;
    /**加工数量*/
    @ApiModelProperty(value = "加工数量")
    private String machiningCount;
    /**加工设备*/
    @ApiModelProperty(value = "加工设备")
    private String equipmentCode;
    /**程序名*/
    @ApiModelProperty(value = "程序名")
    private String ncName;
    /**准备单出库数量*/
    @ApiModelProperty(value = "准备单出库数量")
    private java.math.BigDecimal outboundQuantity;
    /**单子状态;1.未审核;2.调机员已审核;3.已转出库申请*/
    @ApiModelProperty(value = "单子状态;1.未审核;2.调机员已审核;3.已转出库申请")
    private String orderStatus;
    /**准备单提交时间;提交至出库申请单的时间*/
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
    @ApiModelProperty(value = "准备单提交时间;提交至出库申请单的时间")
    private Date outboundTime;
    /**备注*/
    @ApiModelProperty(value = "备注")
    private String remark;
    /**刀具准备单明细*/
    @ApiModelProperty(value = "刀具准备单明细")
    private List<PreparationOrderDetail> preparationOrderDetailList;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaBladeVo.java
@@ -163,4 +163,7 @@
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "工具图片")
    private String toolPicture;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaCommonToolVo.java
@@ -94,4 +94,7 @@
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "工具图片")
    private String toolPicture;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaHolesToolsVo.java
@@ -188,4 +188,7 @@
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "工具图片")
    private String toolPicture;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaMillToolVo.java
@@ -191,4 +191,7 @@
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "工具图片")
    private String toolPicture;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaThreadingToolVo.java
@@ -160,4 +160,7 @@
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "工具图片")
    private String toolPicture;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/vo/ParaTurningToolsVo.java
@@ -198,4 +198,7 @@
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "工具图片")
    private String toolPicture;
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/enums/OutStorehouseType.java
@@ -8,7 +8,8 @@
    TOOL_BORROW("1", "工具借用"),
    MAINTENANCE_OUTBOUND("2", "维修出库"),
    CALIBRATION_OUTBOUND("3", "检定出库"),
    GRINDING_OUTBOUND("4", "刃磨出库");
    GRINDING_OUTBOUND("4", "刃磨出库"),
    PREPARATION_OUTBOUND("5", "准备单出库");
    private final String value;
    private final String description;
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/enums/PreparationOrderStatus.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package org.jeecg.modules.tms.enums;
import lombok.Getter;
import java.util.Objects;
/**
 * åˆ€å…·å‡†å¤‡å•状态枚举类
 */
@Getter
public enum PreparationOrderStatus {
    /**
     * å¾…审核状态,值为1
     */
    PENDING_AUDIT("1", "未审核"),
    /**
     * å®¡æ ¸é€šè¿‡çŠ¶æ€ï¼Œå€¼ä¸º2
     */
    AUDITED("2", "调机员已审核"),
    /**
     * è½¬å‡ºåº“申请状态,值为3
     */
    CONVERT("3", "已转出库申请");
    private final String value;
    private final String description;
    /**
     * æž„造方法
     *
     * @param value       çŠ¶æ€å€¼
     * @param description çŠ¶æ€æè¿°
     */
    PreparationOrderStatus(String value, String description) {
        this.value = value;
        this.description = description;
    }
    /**
     * æ ¹æ®çŠ¶æ€å€¼èŽ·å–å¯¹åº”çš„æžšä¸¾å®žä¾‹
     *
     * @param value çŠ¶æ€å€¼
     * @return å¯¹åº”的枚举实例,如果找不到匹配的值则返回null
     */
    public static PreparationOrderStatus fromValue(String value) {
        for (PreparationOrderStatus status : values()) {
            if (Objects.equals(status.getValue(), value)) {
                return status;
            }
        }
        return null;
    }
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/PreparationOrderDetailMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package org.jeecg.modules.tms.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jeecg.modules.tms.entity.PreparationOrderDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•明细
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
public interface PreparationOrderDetailMapper extends BaseMapper<PreparationOrderDetail> {
    /**
     * é€šè¿‡ä¸»è¡¨id删除子表数据
     *
     * @param mainId ä¸»è¡¨id
     * @return boolean
     */
    public boolean deleteByMainId(@Param("mainId") String mainId);
    /**
     * é€šè¿‡ä¸»è¡¨id查询子表数据
     *
     * @param mainId ä¸»è¡¨id
     * @return List<PreparationOrderDetail>
     */
    public List<PreparationOrderDetail> selectByMainId(@Param("mainId") String mainId);
    IPage<PreparationOrderDetail> queryPageList(Page<PreparationOrderDetail> page,
                                                @Param(Constants.WRAPPER) Wrapper<PreparationOrderDetail> queryWrapper);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/PreparationOrderMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package org.jeecg.modules.tms.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.tms.entity.PreparationOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
public interface PreparationOrderMapper extends BaseMapper<PreparationOrder> {
    IPage<PreparationOrder> queryPageList(Page<PreparationOrder> page,
                                          @Param(Constants.WRAPPER) Wrapper<PreparationOrder> queryWrapper);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/BaseToolsMapper.xml
@@ -13,6 +13,7 @@
            t.standard_code standardCode,
            t.tool_model toolModel,
            t.parama_table_name paramaTableName,
            t.tool_picture toolPicture,
            t1.application_type applicationType,
            t1.supplier_id supplierId,
            t1.province_city provinceCity,
@@ -81,6 +82,7 @@
            t.standard_code standardCode,
            t.tool_model toolModel,
            t.parama_table_name paramaTableName,
            t.tool_picture toolPicture,
            t1.application_type applicationType,
            t1.supplier_id supplierId,
            t1.province_city provinceCity,
@@ -113,6 +115,7 @@
            t.standard_code standardCode,
            t.tool_model toolModel,
            t.parama_table_name paramaTableName,
            t.tool_picture toolPicture,
            t1.application_type applicationType,
            t1.supplier_id supplierId,
            t1.province_city provinceCity,
@@ -171,6 +174,7 @@
            t.standard_code standardCode,
            t.tool_model toolModel,
            t.parama_table_name paramaTableName,
            t.tool_picture toolPicture,
            t1.application_type applicationType,
            t1.supplier_id supplierId,
            t1.province_city provinceCity,
@@ -238,6 +242,7 @@
            t.standard_code standardCode,
            t.tool_model toolModel,
            t.parama_table_name paramaTableName,
            t.tool_picture toolPicture,
            t1.application_type applicationType,
            t1.supplier_id supplierId,
            t1.province_city provinceCity,
@@ -309,6 +314,7 @@
            t.standard_code standardCode,
            t.tool_model toolModel,
            t.parama_table_name paramaTableName,
            t.tool_picture toolPicture,
            t1.application_type applicationType,
            t1.supplier_id supplierId,
            t1.province_city provinceCity,
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/PreparationOrderDetailMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,93 @@
<?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="org.jeecg.modules.tms.mapper.PreparationOrderDetailMapper">
    <delete id="deleteByMainId" parameterType="java.lang.String">
        DELETE
        FROM  tms_preparation_order_detail
        WHERE
            preparation_order_id = #{mainId}
    </delete>
    <select id="selectByMainId" parameterType="java.lang.String" resultType="org.jeecg.modules.tms.entity.PreparationOrderDetail">
        SELECT *
        FROM  tms_preparation_order_detail
        WHERE
            preparation_order_id = #{mainId}
    </select>
    <select id="queryPageList" resultType="org.jeecg.modules.tms.entity.PreparationOrderDetail">
        SELECT
            t1.id id,
            t1.preparation_order_id preparationOrderId,
            t1.tool_code toolCode,
            t1.outbound_quantity outboundQuantity,
            t1.tenant_id tenantId,
            t1.create_by createBy,
            t1.create_time createTime,
            t1.update_by updateBy,
            t1.update_time updateTime,
            t2.tool_code toolNum,
            t2.chinese_name chineseName,
            t2.tool_model toolModel,
            t2.parama_table_name paramaTableName,
            t3.application_type applicationType,
            t3.supplier_id supplierId,
        <choose>
            <when test="ew.paramNameValuePairs.paramaTableName == '1'">
                t4.tool_material toolMaterial,
                t4.part_material partMaterial
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '2'">
                t5.tool_material toolMaterial,
                t5.part_material partMaterial
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '3'">
                t6.tool_material toolMaterial,
                t6.part_material partMaterial
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '4'">
                t7.tool_material toolMaterial,
                t7.part_material partMaterial
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '5'">
                t8.tool_material toolMaterial,
                t8.part_material partMaterial
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '6'">
                t9.tool_material toolMaterial,
                t9.part_material partMaterial
            </when>
            <otherwise>
                t10.tool_material toolMaterial,
                t10.part_material partMaterial
            </otherwise>
        </choose>
        FROM tms_preparation_order_detail t1
        LEFT JOIN tms_base_tools t2 on t1.tool_code = t2.id
        LEFT JOIN tms_tools_config_property t3 on t3.tool_code = t2.id
        <choose>
            <when test="ew.paramNameValuePairs.paramaTableName == '1'">
                LEFT JOIN tms_para_common_tool t4 on t4.tool_code = t2.id
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '2'">
                LEFT JOIN tms_para_hole_tools t5 on t5.tool_code = t2.id
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '3'">
                LEFT JOIN tms_para_threading_tool t6 on t6.tool_code = t2.id
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '4'">
                LEFT JOIN tms_para_mill_tool t7 on t7.tool_code = t2.id
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '5'">
                LEFT JOIN tms_para_turning_tools t8 on t8.tool_code = t2.id
            </when>
            <when test="ew.paramNameValuePairs.paramaTableName == '6'">
                LEFT JOIN tms_para_blade t9 on t9.tool_code = t2.id
            </when>
            <otherwise>
                LEFT JOIN tms_para_common_tool t10 on t10.tool_code = t2.id
            </otherwise>
        </choose>
        ${ew.customSqlSegment}
    </select>
</mapper>
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/PreparationOrderMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
<?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="org.jeecg.modules.tms.mapper.PreparationOrderMapper">
    <select id="queryPageList" resultType="org.jeecg.modules.tms.entity.PreparationOrder">
        SELECT
            t.id AS id,
            t.preparation_order_num AS preparationOrderNum,
            t.part_drawing_no AS partDrawingNo,
            t.part_name AS partName,
            t.part_material AS partMaterial,
            t.production_processes_no AS productionProcessesNo,
            t.batch_code AS batchCode,
            t.machining_count AS machiningCount,
            t.equipment_code AS equipmentCode,
            t.nc_name AS ncName,
            t.outbound_quantity AS outboundQuantity,
            t.order_status AS orderStatus,
            t.outbound_time AS outboundTime,
            t.remark AS remark,
            t.tenant_id AS tenantId,
            t.create_by AS createBy,
            t.create_time AS createTime,
            t.update_by AS updateBy,
            t.update_time AS updateTime
        FROM tms_preparation_order t
        ${ew.customSqlSegment}
    </select>
</mapper>
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IPreparationOrderDetailService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package org.jeecg.modules.tms.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jeecg.modules.tms.entity.PreparationOrderDetail;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•明细
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
public interface IPreparationOrderDetailService extends IService<PreparationOrderDetail> {
  /**
   * é€šè¿‡ä¸»è¡¨id查询子表数据
   *
   * @param mainId
   * @return List<PreparationOrderDetail>
   */
    public List<PreparationOrderDetail> selectByMainId(String mainId);
    IPage<PreparationOrderDetail> queryPageList(Page<PreparationOrderDetail> page, Map<String, String[]> parameterMap);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IPreparationOrderService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package org.jeecg.modules.tms.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jeecg.modules.tms.entity.PreparationOrderDetail;
import org.jeecg.modules.tms.entity.PreparationOrder;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.tms.entity.dto.PreparationOrderAndDetailDto;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
public interface IPreparationOrderService extends IService<PreparationOrder> {
    /**
     * åˆ é™¤ä¸€å¯¹å¤š
     *
     * @param id
     */
    public void delMain (String id);
    /**
     * æ‰¹é‡åˆ é™¤ä¸€å¯¹å¤š
     *
     * @param idList
     */
    public void delBatchMain (Collection<? extends Serializable> idList);
    void editTotal(PreparationOrderAndDetailDto preparationOrderAndDetailDto);
    List<String> convertToOutboundOrder(List<String> preparationOrderIds);
    IPage<PreparationOrder> queryPageList(Page<PreparationOrder> page, Map<String, String[]> parameterMap);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/InboundOrderServiceImpl.java
@@ -262,6 +262,7 @@
                        num++;
                        //转换回字符串并保留前导零
                        String result = String.format("%0" + currentCode.length() + "d", num);
                        //打印二维码
                        //保存入库流水
                        InStoreDetail inStoreDetail = new InStoreDetail();
                        inStoreDetail.setInboundTime(inboundTime);
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/OutboundOrderServiceImpl.java
@@ -83,6 +83,8 @@
    private OutboundOrderMapper outboundOrderMapper;
    @Autowired
    private OutboundDetailMapper outboundDetailMapper;
    @Autowired
    private OutboundOrderConvert outboundOrderConvert;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -103,7 +105,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addTotal(OutboundOrderAndDetailDto outboundOrder) {
        OutboundOrder order = OutboundOrderConvert.INSTANCE.convert(outboundOrder);
        OutboundOrder order = outboundOrderConvert.convert(outboundOrder);
        order.setHandler(Objects.requireNonNull(getCurrentUser()).getId());
        order.setOutNum(businessCodeRuleService.generateBusinessCodeSeq("outBoundOrder"));
        order.setOrderStatus(OutBillStatus.DRAFT.getValue());
@@ -155,7 +157,7 @@
        //删除所有明细
        outboundDetailService.remove(new LambdaQueryWrapper<OutboundDetail>()
                .eq(OutboundDetail::getOutStorehouseId, outboundOrder.getId()));
        OutboundOrder outboundOrderUpdate = BeanUtil.copyProperties(outboundOrder, OutboundOrder.class);
        OutboundOrder outboundOrderUpdate = outboundOrderConvert.convert(outboundOrder);
        outboundOrderMapper.updateById(outboundOrderUpdate);
        List<OutboundDetail> detailList = CollectionUtil.newArrayList();
        outboundOrder.getOutboundDetailList().forEach(item->{
@@ -175,13 +177,14 @@
        if (!Objects.equals(outboundOrder.getOrderStatus(), OutBillStatus.DRAFT.getValue())) {
            throw new JeecgBootException("无法提交非草稿状态的出库申请单!");
        }
        //锁定申请单明细中工具库存
        if (lockOutboundStock(id)) {
        if (!OutStorehouseType.PREPARATION_OUTBOUND.getValue().equals(outboundOrder.getOutStorehouseType())) {
            //不是从准备单转入的出库申请,执行锁库
            lockOutboundStock(id);
        }
            //启动流程
            if (triggerProcess(outboundOrder)) {
                outboundOrder.setOrderStatus(OutBillStatus.SUBMITTED.getValue());
                updateById(outboundOrder);
            }
        }
    }
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/PreparationOrderDetailServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package org.jeecg.modules.tms.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jeecg.modules.tms.entity.PreparationOrderDetail;
import org.jeecg.modules.tms.mapper.PreparationOrderDetailMapper;
import org.jeecg.modules.tms.service.IPreparationOrderDetailService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•明细
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
@Service
public class PreparationOrderDetailServiceImpl extends ServiceImpl<PreparationOrderDetailMapper, PreparationOrderDetail> implements IPreparationOrderDetailService {
    @Autowired
    private PreparationOrderDetailMapper preparationOrderDetailMapper;
    @Override
    public List<PreparationOrderDetail> selectByMainId(String mainId) {
        return preparationOrderDetailMapper.selectByMainId(mainId);
    }
    @Override
    public IPage<PreparationOrderDetail> queryPageList(Page<PreparationOrderDetail> page, Map<String, String[]> parameterMap) {
        QueryWrapper<PreparationOrderDetail> queryWrapper = Wrappers.query();
        String[] preparationOrderIds = parameterMap.get("preparationOrderId");
        if (preparationOrderIds != null && preparationOrderIds.length > 0) {
            queryWrapper.eq("t1.preparation_order_id", preparationOrderIds[0]);
        }
        return this.baseMapper.queryPageList(page, queryWrapper);
    }
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/PreparationOrderServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,235 @@
package org.jeecg.modules.tms.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.system.service.ISysBusinessCodeRuleService;
import org.jeecg.modules.tms.convert.PreparationOrderConvert;
import org.jeecg.modules.tms.entity.*;
import org.jeecg.modules.tms.entity.dto.PreparationOrderAndDetailDto;
import org.jeecg.modules.tms.enums.*;
import org.jeecg.modules.tms.mapper.PreparationOrderDetailMapper;
import org.jeecg.modules.tms.mapper.PreparationOrderMapper;
import org.jeecg.modules.tms.service.*;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @Description: åˆ€å…·å‡†å¤‡å•
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
@Service
public class PreparationOrderServiceImpl extends ServiceImpl<PreparationOrderMapper, PreparationOrder> implements IPreparationOrderService {
    @Autowired
    private PreparationOrderMapper preparationOrderMapper;
    @Autowired
    private PreparationOrderDetailMapper preparationOrderDetailMapper;
    @Autowired
    private IPreparationOrderDetailService preparationOrderDetailService;
    @Autowired
    private IToolLedgerService toolLedgerService;
    @Autowired
    private IToolLedgerDetailService toolLedgerDetailService;
    @Autowired
    private IOutboundOrderService outboundOrderService;
    @Autowired
    private IOutboundDetailService outboundDetailService;
    @Autowired
    private ISysBusinessCodeRuleService businessCodeRuleService;
    @Autowired
    private IBaseToolsService baseToolsService;
    @Autowired
    private PreparationOrderConvert preparationOrderConvert;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delMain(String id) {
        preparationOrderDetailMapper.deleteByMainId(id);
        preparationOrderMapper.deleteById(id);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for(Serializable id:idList) {
            preparationOrderDetailMapper.deleteByMainId(id.toString());
            preparationOrderMapper.deleteById(id);
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editTotal(PreparationOrderAndDetailDto preparationOrderAndDetailDto) {
        //先删除所有明细
        preparationOrderDetailMapper.delete(new LambdaQueryWrapper<PreparationOrderDetail>()
                .eq(PreparationOrderDetail::getPreparationOrderId, preparationOrderAndDetailDto.getId()));
        PreparationOrder preparationOrder = preparationOrderConvert.convert(preparationOrderAndDetailDto);
        updateById(preparationOrder);
        List<PreparationOrderDetail> detailUpdateList = CollectionUtil.newArrayList();
        preparationOrderAndDetailDto.getPreparationOrderDetailList().forEach(item->{
            item.setPreparationOrderId(preparationOrder.getId());
            detailUpdateList.add(item);
        });
        preparationOrderDetailService.saveBatch(detailUpdateList);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<String> convertToOutboundOrder(List<String> preparationOrderIds) {
        List<String> resultMessage = CollectionUtil.newArrayList();
        List<PreparationOrder> preparationOrderList = listByIds(preparationOrderIds);
        //校验准备单明细中的数量
        for (PreparationOrder preparationOrder : preparationOrderList) {
            if (PreparationOrderStatus.PENDING_AUDIT.getValue().equals(preparationOrder.getOrderStatus())) {
                resultMessage.add("准备单【" + preparationOrder.getPreparationOrderNum() + "】未审核,无法转出库申请!");
                continue;
            }
            if (PreparationOrderStatus.CONVERT.getValue().equals(preparationOrder.getOrderStatus())) {
                resultMessage.add("准备单【" + preparationOrder.getPreparationOrderNum() + "】已经转出,请勿重复提交!");
                continue;
            }
            List<PreparationOrderDetail> preparationOrderDetailList = preparationOrderDetailService.list(new LambdaQueryWrapper<PreparationOrderDetail>()
                    .eq(PreparationOrderDetail::getPreparationOrderId, preparationOrder.getId()));
            Map<String, BigDecimal> preparationOrderToolCodeMap = preparationOrderDetailList.stream().collect(Collectors.toMap(PreparationOrderDetail::getToolCode,
                    PreparationOrderDetail::getOutboundQuantity, (k1, k2) -> k1));
            List<ToolLedgerDetail> toolLedgerDetailList = toolLedgerDetailService.list(new LambdaQueryWrapper<ToolLedgerDetail>()
                    .in(ToolLedgerDetail::getToolCode, preparationOrderToolCodeMap.keySet())
                    .eq(ToolLedgerDetail::getQuantity, BigDecimal.ONE)
                    .eq(ToolLedgerDetail::getStatus, ToolCirculationStatus.IN_STOCK.getValue()));
            Map<String, List<ToolLedgerDetail>> ledgerDetailToolCodeMap = toolLedgerDetailList.stream().collect(Collectors.groupingBy(ToolLedgerDetail::getToolCode));
            List<OutboundDetail> outboundDetailList = CollectionUtil.newArrayList();
            for (PreparationOrderDetail preparationOrderDetail : preparationOrderDetailList) {
                String toolCode = preparationOrderDetail.getToolCode();
                BigDecimal needQuantity = preparationOrderDetail.getOutboundQuantity();
                List<ToolLedgerDetail> toolLedgerDetails = ledgerDetailToolCodeMap.get(toolCode);
                BigDecimal stockQuantity = Optional.ofNullable(toolLedgerDetails).orElse(Collections.emptyList()).stream()
                        .map(ToolLedgerDetail::getQuantity)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                if (CollectionUtil.isEmpty(toolLedgerDetails) || stockQuantity.compareTo(needQuantity) < 0) {
                    BaseTools tools = baseToolsService.getById(toolCode);
                    resultMessage.add("准备单【" + preparationOrder.getPreparationOrderNum() +"】中,编码为【" + tools.getToolCode() + "】的工具,库存不足,转出库申请单失败!");
                    break;
                } else {
                    //从库存明细中取出需要的数量,指定到把
                    List<ToolLedgerDetail> selectedTools = toolLedgerDetails.subList(0, needQuantity.intValue());
                    //生成申请单明细
                    selectedTools.forEach(item->{
                        OutboundDetail detail = new OutboundDetail()
                                .setToolCode(item.getToolCode())
                                .setToolId(item.getToolId())
                                .setOutboundQuantity(item.getQuantity())
                                .setStorageLocation(item.getWarehouseId())
                                .setOutboundLocation(item.getPositionCode())
                                .setStatus(OutBoundStatusEnum.NOT_OUTBOUND.getValue())
                                .setCreateBy(Objects.requireNonNull(getCurrentUser()).getUsername())
                                .setCreateTime(new Date());
                        outboundDetailList.add(detail);
                    });
                }
            }
            BigDecimal totalOutboundQuantity = preparationOrderDetailList.stream()
                    .map(detail -> Optional.ofNullable(detail.getOutboundQuantity()).orElse(BigDecimal.ZERO))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            if (outboundDetailList.size() == totalOutboundQuantity.intValue()) {
                //指定到把的数量与需求数量一致,满足转出库申请单的条件,生成出库申请单
                OutboundOrder order = new OutboundOrder()
                        .setOutNum(businessCodeRuleService.generateBusinessCodeSeq("outBoundOrder"))
                        .setOutStorehouseType(OutStorehouseType.PREPARATION_OUTBOUND.getValue())
                        .setHandler(Objects.requireNonNull(getCurrentUser()).getId())
                        .setReviewer(Objects.requireNonNull(getCurrentUser()).getUsername())
                        .setOrderStatus(OutBillStatus.DRAFT.getValue())
                        .setSubjectMatter("刀具准备单转入")
                        .setPreparationOrderId(preparationOrder.getId())
                        .setPartDrawingNo(preparationOrder.getPartDrawingNo())
                        .setPartName(preparationOrder.getPartName())
                        .setPartMaterial(preparationOrder.getPartMaterial())
                        .setProductionProcessesNo(preparationOrder.getProductionProcessesNo())
                        .setBatchCode(preparationOrder.getBatchCode())
                        .setMachiningCount(preparationOrder.getMachiningCount())
                        .setEquipmentCode(preparationOrder.getEquipmentCode())
                        .setNcName(preparationOrder.getNcName())
                        .setCreateBy(Objects.requireNonNull(getCurrentUser()).getUsername())
                        .setCreateTime(new Date());
                outboundOrderService.save(order);
                outboundDetailList.forEach(item -> item.setOutStorehouseId(order.getId()));
                outboundDetailService.saveBatch(outboundDetailList);
                //锁定库存台账明细库存
                LambdaQueryWrapper<ToolLedgerDetail> queryWrapper = new LambdaQueryWrapper<>();
                String codeIdString = outboundDetailList.stream()
                        .map(detail -> "'" + detail.getToolCode() + ":" + detail.getToolId() + "'")
                        .collect(Collectors.joining(","));
                String sql = "(tool_code + ':' + tool_id) IN (" + codeIdString + ")";
                queryWrapper.apply(sql);
                toolLedgerDetailService.update(new ToolLedgerDetail().setQuantity(BigDecimal.ZERO), queryWrapper);
                //锁定库存台账主表
                List<ToolLedger> toolLedgerList = toolLedgerService.list(new LambdaQueryWrapper<ToolLedger>()
                        .in(ToolLedger::getToolId, preparationOrderToolCodeMap.keySet()));
                toolLedgerList.forEach(item -> {
                    BigDecimal outboundQuantity = preparationOrderToolCodeMap.getOrDefault(item.getToolId(), BigDecimal.ZERO);
                    item.setAvailableCount(Optional.ofNullable(item.getAvailableCount()).orElse(BigDecimal.ZERO).subtract(outboundQuantity));
                });
                toolLedgerService.updateBatchById(toolLedgerList);
                //更新准备单状态
                updateById(new PreparationOrder()
                        .setId(preparationOrder.getId())
                        .setOutboundTime(new Date())
                        .setOrderStatus(PreparationOrderStatus.CONVERT.getValue()));//3.已转出库申请
                resultMessage.add("准备单【" + preparationOrder.getPreparationOrderNum() + "】转出库申请单成功!");
            }
        }
        return resultMessage;
    }
    @Override
    public IPage<PreparationOrder> queryPageList(Page<PreparationOrder> page, Map<String, String[]> parameterMap) {
        QueryWrapper<PreparationOrder> queryWrapper = Wrappers.query();
        String[] preparationOrderNums = parameterMap.get("preparationOrderNum");
        if (preparationOrderNums != null && preparationOrderNums.length > 0) {
            queryWrapper.like("t.preparation_order_num", preparationOrderNums[0]);
        }
        String[] orderStatuses = parameterMap.get("orderStatus");
        if (orderStatuses != null && orderStatuses.length > 0) {
            queryWrapper.eq("t.order_status", orderStatuses[0]);
        }
        String[] beginTimes = parameterMap.get("beginTime");
        if (beginTimes != null && beginTimes.length > 0) {
            queryWrapper.ge("t.create_time", beginTimes[0]);
        }
        String[] endTimes = parameterMap.get("endTime");
        if (endTimes != null && endTimes.length > 0) {
            queryWrapper.le("t.create_time", endTimes[0]);
        }
        queryWrapper.orderByAsc("t.create_time");
        return this.baseMapper.queryPageList(page, queryWrapper);
    }
    private LoginUser getCurrentUser() {
        // èŽ·å–å½“å‰è®¤è¯çš„ç™»å½•ç”¨æˆ·ä¿¡æ¯
        Subject currentUser = SecurityUtils.getSubject();
        if (currentUser != null && currentUser.isAuthenticated()) {
            Object principal = currentUser.getPrincipal();
            if (principal instanceof LoginUser) {
                return (LoginUser) principal;
            }
        }
        return null;
    }
}