cuijian
2025-06-16 ec1bf4658e36a17f971a54007920a44c5378b7dc
Merge remote-tracking branch 'origin/master'
已重命名3个文件
已添加34个文件
已修改87个文件
已删除1个文件
4387 ■■■■ 文件已修改
lxzn-boot-base-core/src/main/java/org/jeecg/config/Swagger2Config.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/constant/DncPassLogPassType.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/controller/CutterController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/ComponentHierarchy.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/ProcessTraceChain.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/TransferPackage.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/DocInfo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/ProductMix.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/ext/NcTxtFilePathInfo.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/listener/FileListener.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ComponentInfoMapper.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/PartsInfoMapper.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProcessSpecVersionMapper.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProcessStreamMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProductInfoMapper.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProductMixMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/WorkStepMapper.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/xml/ComponentInfoMapper.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/xml/PermissionStreamNewMapper.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/DataPackageStrategy.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/ICutterService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/IProductInfoService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/IProductMixService.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ComponentInfoSeServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/CutterServiceImpl.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DataImportService.java 455 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DataPackageService.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DevicePermissionServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DocInfoServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FileFerryService.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FullHierarchyTraceService.java 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/PartsInfoServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessPackageStrategy.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessSpecVersionServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessStreamServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessionDepartmentServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductInfoServiceImpl.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductMixServiceImpl.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductPermissionServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/SecurityService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/WorkStepPackageStrategy.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/WorkStepServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/CompressionUtils.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/JsonUtils.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/TreeBuilder.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/IAssignFileStreamService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/impl/AssignFileStreamServiceImpl.java 143 ●●●● 补丁 | 查看 | 原始文档 | 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/entity/EamSecondMaintenanceOrder.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamThirdMaintenanceOrder.java 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/entity/MdcEquipment.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentMapper.xml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentServiceImpl.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/controller/DtBoardController.java 18 ●●●● 补丁 | 查看 | 原始文档 | 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 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/service/impl/DtBoardServiceImpl.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquAndon.java 20 ●●●●● 补丁 | 查看 | 原始文档 | 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/mdc/controller/AndonOrderController.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/controller/MdcEquipmentPunchController.java 85 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/controller/MdcEquipmentPunchRateController.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/dto/MdcEquipmentPunchExportDTO.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/AndonOrder.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/MdcEquipmentPunch.java 104 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/MdcEquipmentPunchRate.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/DailyPunchRateJob.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/AndonOrderMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentAlarmMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | 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/MdcEquipmentPunchRateMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/AndonOrderMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentAlarmMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcDowntimeMapper.xml 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcDowntimeOperatorMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentPunchMapper.xml 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentPunchRateMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcWorkshopInfoMapper.xml 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IAndonOrderService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentAlarmService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentPunchRateService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentPunchService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/AndonOrderServiceImpl.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentAlarmServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentPunchRateServiceImpl.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentPunchServiceImpl.java 69 ●●●●● 补丁 | 查看 | 原始文档 | 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/system/service/IMdcProductionService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/MdcProductionServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-start/src/main/resources/application-prod.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/PreparationOrderController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/ToolSharpeningController.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/ToolsStocktakingBoundController.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/ToolsToDncController.java 138 ●●●● 补丁 | 查看 | 原始文档 | 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 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/PreparationOrderDetail.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/ToolsStocktakingBoundDetail.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/dto/ToolQueryParamDto.java 104 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaBladeMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaHoleToolsMapper.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaMillToolMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaThreadingToolMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaTurningToolsMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/BaseToolsMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaBladeMapper.xml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaHoleToolsMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaMillToolMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaThreadingToolMapper.xml 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaTurningToolsMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ToolsStocktakingBoundDetailMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IParaBladeService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IParaThreadingToolService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IPreparationOrderService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/OutboundOrderServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaBladeServiceImpl.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaHoleToolsServiceImpl.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaMillToolServiceImpl.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaThreadingToolServiceImpl.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaTurningToolsServiceImpl.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/PreparationOrderServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-boot-base-core/src/main/java/org/jeecg/config/Swagger2Config.java
@@ -178,6 +178,24 @@
                .groupName("eam");
    }
    @Bean(value = "defaultApiBoard")
    public Docket activitiApiBoard() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //此包路径下的类,才生成接口文档
                .apis(RequestHandlerSelectors.basePackage("org.jeecg.modules.board"))
                //加了ApiOperation注解的类,才生成接口文档
                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build()
                .securitySchemes(Collections.singletonList(securityScheme()))
                .securityContexts(securityContexts())
                .globalOperationParameters(setHeaderToken())
                .groupName("数字孪生看板");
    }
    /***
     * oauth2配置
     * éœ€è¦å¢žåŠ swagger授权回调地址
lxzn-module-dnc/pom.xml
@@ -58,6 +58,12 @@
            <artifactId>fastutil</artifactId>
            <version>8.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.jeecgframework.boot</groupId>
            <artifactId>lxzn-module-tms</artifactId>
            <version>3.4.3</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/constant/DncPassLogPassType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package org.jeecg.modules.dnc.constant;
public enum DncPassLogPassType {
    //NC文件
    DOCUMENT("01", "nc文件"),
    //nc文件
    NCFILE("02", "NC文件"),
    //产品结构树
    PRODUCTSTRUCTURE("03", "产品结构树"),
    //程序加工确认表
    PROGRAMPROCESSING("04", "程序加工确认表");
    private String code;
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    DncPassLogPassType() {
    }
    DncPassLogPassType(String code, String name) {
        this.code = code;
        this.name = name;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/controller/CutterController.java
@@ -110,4 +110,17 @@
        return service.extractAndSaveFromContent(docId,attributionId,attributionType);
    }
    /**
     * å‘送刀具系统
     * @param docId æ–‡æ¡£Id
     * @return
     */
    @AutoLog(value = "刀具信息-发送刀具系统")
    @ApiOperation(value = "刀具信息-发送刀具系统", notes = "刀具信息-发送刀具系统")
    @GetMapping("/sendCutterInfo/{docId}/{attributionType}/{attributionId}")
    public Result<?> sendCutterInfo(@PathVariable("docId") String docId
            ,@PathVariable("attributionType") Integer attributionType
            ,@PathVariable("attributionId") String attributionId) {
        return service.sendToCutterSystem(docId,attributionId,attributionType);
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/ComponentHierarchy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package org.jeecg.modules.dnc.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.jeecg.modules.dnc.entity.ComponentInfo;
import org.jeecg.modules.dnc.entity.ProductInfo;
import java.util.ArrayList;
import java.util.List;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ComponentHierarchy {
    private ProductInfo rootProduct;
    private final List<ComponentInfo> components = new ArrayList<>(); // ä»Žæ ¹éƒ¨ä»¶åˆ°åº•层部件的顺序
    public void addComponentToTop(ComponentInfo component) {
        components.add(0, component);
    }
    public List<ComponentInfo> getComponentsFromTop() {
        return new ArrayList<>(components);
    }
    public ComponentInfo getLeafComponent() {
        return components.isEmpty() ? null : components.get(components.size() - 1);
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/ProcessTraceChain.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,86 @@
package org.jeecg.modules.dnc.dto;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
import org.jeecg.modules.dnc.entity.*;
import java.util.List;
/**
 * @Description: æ¶‰å¯†ç½‘同步工控网需要的数据
 * @Author: lyh
 * @Date:   2025-06-13
 * @Version: V1.0
 * @remark: åŽç»­éœ€è¦å¢žåŠ ï¼Œæ·»åŠ å¯¹åº”å‚æ•°ä¸Žç»“æž„æ•°æ®ï¼Œé‡‡ç”¨JSON序列化与反序列化进行传输,方便传输(加密操作,避免数据污染)
 */
@Data
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class ProcessTraceChain {
    /**程序加工确认表*/
    private GuideCardBatch guideCardBatch;
    /**刀具列表*/
    private List<Cutter> cutterList;
    /**文件*/
    private DocFile docFile;
    /**设备文档对应关系*/
    private DocRelative docRelative;
    /**文档*/
    private DocInfo docInfo;
    /**设备类*/
    private DeviceType deviceType;
    /**设备类对应关系*/
    private DeviceManagement deviceManagement;
    /**工步*/
    private WorkStep workStep;
    /**工序*/
    private ProcessStream process;
    /**工艺规程版本*/
    private ProcessSpecVersion processSpec;
    /**零件*/
    private PartsInfo parts;
    /**部件*/
    private ComponentHierarchy componentHierarchy;
    /**产品*/
    private ProductInfo product;
    /**产品树路径*/
    private List<ProductMix> treePath;
    /**权限表*/
    private List<PermissionStreamNew> permissionStreamNewList;
    @JsonCreator
    public ProcessTraceChain(
            @JsonProperty("guideCardBatch") GuideCardBatch guideCardBatch,
            @JsonProperty("cutterList") List<Cutter> cutterList,
            @JsonProperty("docFile") DocFile docFile,
            @JsonProperty("docRelative") DocRelative docRelative,
            @JsonProperty("docInfo") DocInfo docInfo,
            @JsonProperty("deviceType") DeviceType deviceType,
            @JsonProperty("deviceManagement") DeviceManagement deviceManagement,
            @JsonProperty("workStep") WorkStep workStep,
            @JsonProperty("process") ProcessStream process,
            @JsonProperty("processSpec") ProcessSpecVersion processSpec,
            @JsonProperty("parts") PartsInfo parts,
            @JsonProperty("componentHierarchy") ComponentHierarchy componentHierarchy,
            @JsonProperty("product") ProductInfo product,
            @JsonProperty("treePath") List<ProductMix> treePath,
            @JsonProperty("permissionStreamNewList") List<PermissionStreamNew> permissionStreamNewList
    ) {
        this.guideCardBatch = guideCardBatch;
        this.cutterList = cutterList;
        this.docFile = docFile;
        this.docRelative = docRelative;
        this.docInfo = docInfo;
        this.deviceType = deviceType;
        this.deviceManagement = deviceManagement;
        this.workStep = workStep;
        this.process = process;
        this.processSpec = processSpec;
        this.parts = parts;
        this.componentHierarchy = componentHierarchy;
        this.product = product;
        this.treePath = treePath;
        this.permissionStreamNewList = permissionStreamNewList;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/TransferPackage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package org.jeecg.modules.dnc.dto;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
import org.jeecg.modules.dnc.entity.DocRelative;
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class TransferPackage {
    public enum DataType { PROCESS, WORKSTEP }
    private final DataType dataType;
    private final DocRelative docRelative;
    private final ProcessTraceChain traceChain;
    @JsonCreator
    public TransferPackage(
            @JsonProperty("dataType") DataType dataType,
            @JsonProperty("docRelative")  DocRelative docRelative,
            @JsonProperty("traceChain") ProcessTraceChain traceChain
    ) {
        this.dataType = dataType;
        this.docRelative = docRelative;
        this.traceChain = traceChain;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/DocInfo.java
@@ -82,6 +82,9 @@
    //所属节点代号
    @TableField(exist = false)
    private String nodeCode;
    //所属节点id
    @TableField(exist = false)
    private String nodeId;
    //设备类名称
    @TableField(exist = false)
    private String deviceName;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/ProductMix.java
@@ -6,7 +6,6 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@@ -14,7 +13,6 @@
import java.util.Date;
import java.util.List;
@Getter
@Data
@NoArgsConstructor
@TableName(value = "nc_product_mix")
@@ -29,13 +27,13 @@
    private Long parentId;
    // åç§°
    @TableField(value = "tree_name")
    private String name;
    private String treeName;
    // code
    @TableField(value = "tree_code")
    private String code;
    private String treeCode;
    // ç±»åž‹
    @TableField(value = "tree_type")
    private Integer type;
    private Integer treeType;
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @TableField(value = "create_time")
    private Date createTime;
@@ -43,17 +41,20 @@
    //展示名称
    private transient String label;
    //类型方便前端展示
    private transient Integer type;
    private transient List<ProductMix> children = new ArrayList<>();
    public ProductMix(Long id, Long parentId, String name, String code, Integer type, Date createTime) {
    public ProductMix(Long id, Long parentId, String treeName, String treeCode, Integer type, Date createTime) {
        this.id = id;
        this.parentId = parentId;
        this.name = name;
        this.code = code;
        this.treeName = treeName;
        this.treeCode = treeCode;
        this.type = type;
        this.children = new ArrayList<>();
        this.label="["+code+"]"+name;
        this.label="["+treeCode+"]"+treeName;
        this.createTime = createTime;
    }
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/ext/NcTxtFilePathInfo.java
@@ -24,6 +24,18 @@
    private Integer fileAddOrDelete;
    /*文件大小*/
    private String fileSize;
    /*产品添加执行语句*/
    private String productAddSql;
    /*部件添加执行语句*/
    private String componentAddSql;
    /*零件添加执行语句*/
    private String partAddSql;
    /*工艺规程版本添加执行语句*/
    private String processVersionAddSql;
    /*工序版本添加执行语句*/
    private String processAddSql;
    /*工步版本添加执行语句*/
    private String processStepAddSql;
    @Override
    public String toString() {
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/listener/FileListener.java
@@ -1,14 +1,13 @@
package org.jeecg.modules.dnc.listener;
import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.jeecg.common.util.FileUtil;
import org.jeecg.modules.dnc.service.IDocInfoService;
import org.jeecg.modules.dnc.utils.file.FileUtilS;
import org.jeecg.modules.message.enums.DeployEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
@@ -17,16 +16,12 @@
@Component
public class FileListener implements FileAlterationListener {
    private static final Logger log = LoggerFactory.getLogger(FileListener.class);
    @Value("${deploy.deployType}")
    private String deployType;    //工控网/涉密网部署 0为工控网 1为涉密网
    @Autowired
    private IDocInfoService docInfoService;  // æ–‡æ¡£æœåŠ¡
    @Override
    public void onStart(FileAlterationObserver observer) {
        log.info("开始监听目录: {}", observer.getDirectory().getAbsolutePath());
//        log.info("开始监听目录: {}", observer.getDirectory().getAbsolutePath());
    }
    @Override
@@ -48,17 +43,6 @@
    public void onFileCreate(File file) {
        String filePath = file.getAbsolutePath();
        log.info("[新建]: {}", filePath);
        if (DeployEnum.GW.getCode().equals(deployType)) {
            //工控网解析涉密网传过来的NC文件与nc文件进行解析
            if (filePath.startsWith("D:\\hy_test\\ncFile")) {
                handleIndustrialDocFile(file);
            }
        }else {
            //涉密网解析工控网传过来的NC文件与nc文件进行解析(程序回传)
            if (filePath.startsWith("D:\\hy_test\\ncFile")) {
                handleSecretDocFile(file);
            }
        }
    }
    @Override
    public void onFileChange(File file) {
@@ -72,7 +56,7 @@
    @Override
    public void onStop(FileAlterationObserver observer) {
        log.info("结束监听目录: {}", observer.getDirectory().getAbsolutePath());
//        log.info("结束监听目录: {}", observer.getDirectory().getAbsolutePath());
    }
    /**
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ComponentInfoMapper.java
@@ -1,9 +1,9 @@
package org.jeecg.modules.dnc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.dnc.dto.ComponentExt;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.dnc.dto.ComponentExt;
import org.jeecg.modules.dnc.entity.ComponentInfo;
import java.util.List;
@@ -38,4 +38,10 @@
     */
    List<ComponentExt> getByParentIdAndUserPerms(@Param("parentId") String parentId, @Param("userId") String userId);
    @Select("SELECT * FROM nc_component_info WHERE component_id = #{componentId}")
    ComponentInfo selectById(@Param("componentId") String componentId);
    // é€’归查询部件层级结构
    List<ComponentInfo> findComponentHierarchy(@Param("componentId") String componentId);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/PartsInfoMapper.java
@@ -1,8 +1,9 @@
package org.jeecg.modules.dnc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.dnc.entity.PartsInfo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.dnc.entity.PartsInfo;
import java.util.List;
@@ -14,4 +15,7 @@
     * @return
     */
    List<PartsInfo> getByUserPerms(@Param("userId") String userId);
    @Select("SELECT * FROM nc_parts_info WHERE parts_id = #{partsId}")
    PartsInfo selectById(@Param("partsId") String partsId);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProcessSpecVersionMapper.java
@@ -1,8 +1,9 @@
package org.jeecg.modules.dnc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.dnc.entity.ProcessSpecVersion;
import org.jeecg.modules.dnc.entity.WorkStep;
import java.util.List;
@@ -14,4 +15,7 @@
     * @return
     */
    List<ProcessSpecVersion> getByUserPerms(String userId);
    @Select("SELECT * FROM nc_process_spec_version WHERE id = #{id}")
    ProcessSpecVersion selectById(@Param("id") String id);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProcessStreamMapper.java
@@ -1,6 +1,8 @@
package org.jeecg.modules.dnc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.dnc.entity.ProcessStream;
import java.util.List;
@@ -22,4 +24,6 @@
     */
    List<ProcessStream> findByPartsAndComponents(String productId, List<String> componentIds, List<String> partsIds);
    @Select("SELECT * FROM nc_process_stream WHERE process_id = #{processId}")
    ProcessStream selectById(@Param("processId") String processId);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProductInfoMapper.java
@@ -1,8 +1,9 @@
package org.jeecg.modules.dnc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.dnc.entity.ProductInfo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.dnc.entity.ProductInfo;
import java.util.List;
@@ -13,4 +14,7 @@
     * @return
     */
    List<ProductInfo> getByUserPerms(@Param("userId") String userId);
    @Select("SELECT * FROM nc_product_info WHERE product_id = #{productId}")
    ProductInfo selectById(@Param("productId") String productId);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProductMixMapper.java
@@ -1,7 +1,29 @@
package org.jeecg.modules.dnc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.dnc.entity.ProductMix;
public interface ProductMixMapper extends BaseMapper<ProductMix> {
    @Select("SELECT * FROM nc_product_mix WHERE id = #{productId} AND tree_type = 1")
    ProductMix findByProductId(@Param("productId") String productId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{componentId} AND tree_type = 2")
    ProductMix findByComponentId(@Param("componentId") String componentId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{partsId} AND tree_type = 3")
    ProductMix findByPartsId(@Param("partsId") String partsId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{operationId} AND tree_type = 4")
    ProductMix findByOperationId(@Param("operationId") String operationId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{processId} AND tree_type = 5")
    ProductMix findByProcessId(@Param("operationId") String processId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{worksiteId} AND tree_type = 6")
    ProductMix findByWorksiteId(@Param("operationId") String worksiteId);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/WorkStepMapper.java
@@ -1,7 +1,8 @@
package org.jeecg.modules.dnc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.dnc.entity.SynchronizedFlag;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.ibatis.annotations.Select;
import org.jeecg.modules.dnc.entity.WorkStep;
import java.util.List;
@@ -13,4 +14,10 @@
     * @return
     */
    List<WorkStep> getByUserPerms(String userId);
    @Select("SELECT * FROM nc_work_step WHERE id = #{workStepId}")
    WorkStep selectById(@Param("workStepId") String workStepId);
    @Select("SELECT * FROM nc_work_step WHERE process_id = #{processId}")
    List<WorkStep> selectByProcessId(@Param("processId") String processId);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/xml/ComponentInfoMapper.xml
@@ -158,4 +158,26 @@
        on comp.component_id=s.component_id
        where delete_flag = 0 and parent_id=#{parentId}
    </select>
    <select id="findComponentHierarchy" resultType="org.jeecg.modules.dnc.entity.ComponentInfo">
        WITH component_tree AS (
            SELECT
                *,
                0 AS LEVEL
            FROM
                nc_component_info
            WHERE
                component_id = #{componentId} UNION ALL
            SELECT
                c.*,
                ct.level + 1
            FROM
                nc_component_info c
                    INNER JOIN component_tree ct ON c.component_id = ct.parent_id
        ) SELECT
            *
        FROM
            component_tree
        ORDER BY
            LEVEL ASC
    </select>
</mapper>
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/xml/PermissionStreamNewMapper.xml
@@ -4,8 +4,8 @@
    <select id="loadProductMix" resultType="org.jeecg.modules.dnc.entity.ProductMix">
        SELECT DISTINCT
            mix.id,
            mix.tree_code 'code',
                mix.tree_name 'name',
            mix.tree_code,
            mix.tree_name,
            mix.parent_id,
            mix.tree_type AS 'type',
                mix.extend,
@@ -31,8 +31,8 @@
    </select>
    <select id="loadProductMixAll" resultType="org.jeecg.modules.dnc.entity.ProductMix">
        SELECT DISTINCT mix.id,
                        mix.tree_code    'code',
                        mix.tree_name    'name',
                        mix.tree_code,
                        mix.tree_name   ,
                        mix.parent_id,
                        mix.tree_type AS 'type',
                        mix.extend,
@@ -92,8 +92,8 @@
        )
        SELECT DISTINCT
            mix.id,
            mix.tree_code 'code',
            mix.tree_name 'name',
            mix.tree_code,
            mix.tree_name,
            mix.parent_id,
            mix.tree_type AS 'type',
            mix.extend,
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/DataPackageStrategy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package org.jeecg.modules.dnc.service;
import org.jeecg.modules.dnc.dto.TransferPackage;
// æ•°æ®å°è£…策略接口
public interface DataPackageStrategy {
    /**
     * å°è£…业务数据为传输包
     * @param id ä¸šåŠ¡å®žä½“ID(工序ID或工步ID)
     * @return å°è£…好的传输包
     */
    TransferPackage packageData(String id);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/ICutterService.java
@@ -40,5 +40,9 @@
     */
    Result<?> extractAndSaveFromContent(String docId,String attributionId,Integer attributionType);
    /**
     * å‘送刀具列表到刀具系统
     * @param docId
     */
    Result<?> sendToCutterSystem(String docId,String attributionId,Integer attributionType);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/IProductInfoService.java
@@ -221,7 +221,7 @@
    /**
     * èŽ·å–å…·ä½“å±‚çº§å®žä½“
     * @param id,type
     * @param id,treeType
     * @return
     */
    Result<?> getTreeById(String id, Integer type);
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/IProductMixService.java
@@ -1,8 +1,6 @@
package org.jeecg.modules.dnc.service;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dnc.entity.ProductMix;
import java.util.List;
@@ -10,8 +8,20 @@
public interface IProductMixService extends IService<ProductMix> {
    //获取封装产品结构树
    public List<ProductMix> getTree();
    List<ProductMix> getTree();
    //模拟生成产品结构树
    /**
     * æŸ¥è¯¢å¯¹åº”id的所有父级(权限分配使用)
     * @param id
     * @return
     */
    List<ProductMix> getParentList(String id);
    /**
     * æŸ¥è¯¢å¯¹åº”id的所有子节点(权限分配使用)
     * @param id
     * @return
     */
    List<ProductMix> getChildrenList(String id);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ComponentInfoSeServiceImpl.java
@@ -189,8 +189,8 @@
        boolean b = super.updateById(componentInfo);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(componentInfo.getComponentName());
        productMix.setCode(componentInfo.getComponentCode());
        productMix.setTreeName(componentInfo.getComponentName());
        productMix.setTreeCode(componentInfo.getComponentCode());
        productMixService.updateById(productMix);
        if(!b)
            return false;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/CutterServiceImpl.java
@@ -10,15 +10,19 @@
import org.jeecg.modules.dnc.entity.Cutter;
import org.jeecg.modules.dnc.entity.DocFile;
import org.jeecg.modules.dnc.entity.DocInfo;
import org.jeecg.modules.dnc.entity.GuideCardBatch;
import org.jeecg.modules.dnc.exception.ExceptionCast;
import org.jeecg.modules.dnc.mapper.CutterMapper;
import org.jeecg.modules.dnc.response.CommonCode;
import org.jeecg.modules.dnc.service.ICutterService;
import org.jeecg.modules.dnc.service.IDocFileService;
import org.jeecg.modules.dnc.service.IDocInfoService;
import org.jeecg.modules.dnc.service.IGuideCardBatchService;
import org.jeecg.modules.dnc.utils.ValidateUtil;
import org.jeecg.modules.dnc.utils.file.FileUtilS;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.tms.entity.PreparationOrderDetail;
import org.jeecg.modules.tms.entity.dto.PreparationOrderAndDetailDto;
import org.jeecg.modules.tms.service.IPreparationOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -40,8 +44,10 @@
    private IDocFileService docFileService;
    @Autowired
    private ISysDictService sysDictService;
    private IGuideCardBatchService guideCardBatchService;
    @Autowired
    private IPreparationOrderService preparationOrderService;
    /**
     * æ–°å¢žåˆ€å…·ä¿¡æ¯
     * @param cutter
@@ -194,13 +200,54 @@
                return Result.error("未发现刀具的参数信息注释,无法提取刀具信息");
            }
            this.saveBatch(newCutterList);
            //TODO发送刀具管理数据
            return Result.OK("提取刀具信息成功");
        }else {
            return Result.error("未发现刀具的参数信息注释,无法提取刀具信息");
        }
    }
    @Override
    public Result<?> sendToCutterSystem(String docId,String attributionId,Integer attributionType){
        List<Cutter> cutterList = this.list(new QueryWrapper<Cutter>()
                .eq("doc_id", docId)
                .eq(StrUtil.isNotEmpty(attributionId),"attribution_id",attributionId)
                .eq("attribution_type",attributionType));
        if (cutterList == null || cutterList.isEmpty()) {
            return Result.error("未发现刀具信息,无法发送到刀具系统");
        }
        if (cutterList.stream().anyMatch(item -> item.getCutterCode() == null)) {
            return Result.error("未发现刀具编号信息,无法发送到刀具系统");
        }
        //获取最新数控程序加工确认表
        List<GuideCardBatch> guideCardBatchList = guideCardBatchService.list(new QueryWrapper<GuideCardBatch>()
                .eq("doc_id", docId)
                .isNotNull("serial_number")
                .orderByDesc("SUBSTRING(serial_number, LEN(serial_number)-3, 4)"));
        if (guideCardBatchList == null || guideCardBatchList.isEmpty()) {
            return Result.error("未发现程序加工确认表信息,无法发送到刀具系统");
        }
        GuideCardBatch guideCardBatch = guideCardBatchList.get(0);
        PreparationOrderAndDetailDto dto = new PreparationOrderAndDetailDto();
        dto.setPartDrawingNo(guideCardBatch.getPartsCode());
        dto.setPartName(guideCardBatch.getPartsName());
        dto.setPartMaterial(guideCardBatch.getMaterielDesp());
        dto.setProductionProcessesNo(guideCardBatch.getProcessWorkCode());
        dto.setBatchCode(guideCardBatch.getProcessingBatch());
        dto.setMachiningCount(guideCardBatch.getProcessingQuantity());
        dto.setEquipmentCode(guideCardBatch.getProcessingEquipment());
        dto.setNcName(guideCardBatch.getDocName());
        List<PreparationOrderDetail> detailList = new ArrayList<>();
        cutterList.forEach(item -> {
            PreparationOrderDetail detail = new PreparationOrderDetail();
            detail.setToolCode(item.getCutterCode());
            detail.setToolId(item.getToolsId());
            detailList.add(detail);
        });
        dto.setPreparationOrderDetailList(detailList);
        preparationOrderService.addPreparationOrderFromDnc(dto);
        return Result.OK("发送到刀具系统成功");
    }
    public List<Cutter> extractToolAfterM6(DocInfo docInfo, List<String> ncLines) {
        List<Cutter> cutterList = new ArrayList<>();
        String currentToolCode = null; // ç”¨äºŽè¿½è¸ªå½“前换刀指令的刀具号
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DataImportService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,455 @@
package org.jeecg.modules.dnc.service.impl;
import cn.hutool.core.util.StrUtil;
import com.jeecg.weibo.exception.BusinessException;
import org.jeecg.modules.dnc.dto.ComponentHierarchy;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.mapper.*;
import org.jeecg.modules.dnc.service.*;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.jeecg.modules.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class DataImportService {
    private static final Logger logger = LoggerFactory.getLogger(DataImportService.class);
    @Autowired
    private ProductInfoMapper productMapper;
    @Autowired
    private ComponentInfoMapper componentMapper;
    @Autowired
    private PartsInfoMapper partsMapper;
    @Autowired
    private ProcessSpecVersionMapper psvMapper;
    @Autowired
    private ProcessStreamMapper processMapper;
    @Autowired
    private WorkStepMapper workStepMapper;
    @Autowired
    private ProductMixMapper productMixMapper;
    @Autowired
    private PermissionStreamNewMapper permissionStreamNewMapper;
    @Autowired
    private DeviceManagementMapper deviceManagementMapper;
    @Autowired
    private DeviceTypeMapper deviceTypeMapper;
    @Autowired
    private DocInfoMapper docInfoMapper;
    @Autowired
    private DocFileMapper docFileMapper;
    @Autowired
    private DocRelativeMapper docRelativeMapper;
    @Autowired
    private CutterMapper cutterMapper;
    @Autowired
    private GuideCardBatchMapper guideCardBatchMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IMdcProductionService mdcProductionService;
    @Autowired
    private IProductPermissionService productPermissionService;
    @Autowired
    private IProductDepartmentService productDepartmentService;
    @Autowired
    private IComponentPermissionService componentPermissionService;
    @Autowired
    private IComponentDepartmentService componentDepartmentService;
    @Autowired
    private IPartsPermissionService partsPermissionService;
    @Autowired
    private IPartsDepartmentService partsDepartmentService;
    @Autowired
    private IProcessSpecVersionPermissionService processSpecVersionPermissionService;
    @Autowired
    private IProcessSpecVersionDepartmentService processSpecVersionDepartmentService;
    @Autowired
    private IProcessStreamPermissionService processStreamPermissionService;
    @Autowired
    private IProcessionDepartmentService processionDepartmentService;
    @Autowired
    private IWorkStepPermissionService workStepPermissionService;
    @Autowired
    private IWorkStepDepartmentService workStepDepartmentService;
    @Transactional(rollbackFor = Exception.class)
    public void importTransferPackage(TransferPackage transferPackage) {
        try {
            logger.info("开始导入传输包数据, ç±»åž‹: {}", transferPackage.getDataType());
            // ä¿å­˜äº§å“
            if (transferPackage.getTraceChain() != null &&
                    transferPackage.getTraceChain().getProduct() != null) {
                saveProduct(transferPackage.getTraceChain().getProduct());
            }
            // ä¿å­˜éƒ¨ä»¶å±‚级
            if (transferPackage.getTraceChain() != null &&
                    transferPackage.getTraceChain().getComponentHierarchy() != null) {
                saveComponentHierarchy(transferPackage.getTraceChain().getComponentHierarchy());
            }
            // ä¿å­˜é›¶ä»¶
            if (transferPackage.getTraceChain() != null &&
                    transferPackage.getTraceChain().getParts() != null) {
                saveParts(transferPackage.getTraceChain().getParts());
            }
            // ä¿å­˜å·¥è‰ºè§„程
            if (transferPackage.getTraceChain() != null &&
                    transferPackage.getTraceChain().getProcessSpec() != null) {
                saveProcessSpec(transferPackage.getTraceChain().getProcessSpec());
            }
            // ä¿å­˜å·¥åº
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getProcess() != null) {
                saveProcess(transferPackage.getTraceChain().getProcess());
            }
            // ä¿å­˜å·¥æ­¥
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getWorkStep() != null) {
                saveWorkSteps(transferPackage.getTraceChain().getWorkStep());
            }
            // ä¿å­˜ç»“构树
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getTreePath() != null) {
                saveTreePath(transferPackage.getTraceChain().getTreePath());
            }
            //保存权限
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getPermissionStreamNewList() != null) {
                savePermissionStreamNewList(transferPackage.getTraceChain().getPermissionStreamNewList());
            }
            // ä¿å­˜è®¾å¤‡ç±»
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getDeviceManagement() != null) {
                saveDeviceManagement(transferPackage.getTraceChain().getDeviceManagement());
            }
            // ä¿å­˜è®¾å¤‡ç±»å¯¹åº”信息
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getDeviceType() != null) {
                saveDeviceType(transferPackage.getTraceChain().getDeviceType());
            }
            // ä¿å­˜æ–‡æ¡£
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getDocInfo() != null) {
                saveDocInfo(transferPackage.getTraceChain().getDocInfo());
            }
            // ä¿å­˜æ–‡ä»¶
            if (transferPackage.getTraceChain() !=null&&
                    transferPackage.getTraceChain().getDocFile() != null) {
                saveDocFile(transferPackage.getTraceChain().getDocFile());
            }
            // ä¿å­˜æ–‡æ¡£æ–‡ä»¶å¯¹åº”关系
            if (transferPackage.getDocRelative() !=null){
                saveDocRelative(transferPackage.getDocRelative());
            }
            // ä¿å­˜åˆ€å…·ç³»ç»Ÿ
            if (transferPackage.getTraceChain() !=null&&
                    transferPackage.getTraceChain().getCutterList() != null) {
                saveCutterList(transferPackage.getTraceChain().getCutterList());
            }
            //保存数控程序加工确认表
            if (transferPackage.getTraceChain() !=null&&
                    transferPackage.getTraceChain().getGuideCardBatch() != null) {
                saveGuideCardBatch(transferPackage.getTraceChain().getGuideCardBatch());
            }
            logger.info("数据导入成功");
        } catch (DuplicateKeyException e) {
            logger.warn("主键冲突: {}", e.getMessage());
            throw new BusinessException("数据已存在,无法重复导入");
        } catch (DataIntegrityViolationException e) {
            logger.error("数据完整性违反: {}", e.getMessage());
            throw new BusinessException("数据不完整,请检查必填字段");
        } catch (Exception e) {
            logger.error("数据导入失败: {}", e.getMessage(), e);
            throw new BusinessException("数据导入失败: " + e.getMessage());
        }
    }
    private void saveProduct(ProductInfo product) {
        if (productMapper.selectById(product.getProductId()) == null) {
            productMapper.insert(product);
            logger.debug("产品已保存: {}", product.getProductId());
        } else {
            logger.debug("产品已存在: {}", product.getProductId());
        }
    }
    private void saveComponentHierarchy(ComponentHierarchy hierarchy) {
        for (ComponentInfo component : hierarchy.getComponents()) {
            if (componentMapper.selectById(component.getComponentId()) == null) {
                componentMapper.insert(component);
                logger.debug("部件已保存: {}", component.getComponentId());
            } else {
                logger.debug("部件已存在: {}", component.getComponentId());
            }
        }
    }
    private void saveParts(PartsInfo parts) {
        if (partsMapper.selectById(parts.getPartsId()) == null) {
            partsMapper.insert(parts);
            logger.debug("零件已保存: {}", parts.getPartsId());
        } else {
            logger.debug("零件已存在: {}", parts.getPartsId());
        }
    }
    private void saveProcessSpec(ProcessSpecVersion processSpec) {
        if (psvMapper.selectById(processSpec.getId()) == null) {
            psvMapper.insert(processSpec);
            logger.debug("工艺规程已保存: {}", processSpec.getId());
        } else {
            logger.debug("工艺规程已存在: {}", processSpec.getId());
        }
    }
    private void saveProcess(ProcessStream process) {
        if (processMapper.selectById(process.getProcessId()) == null) {
            processMapper.insert(process);
            logger.debug("工序已保存: {}", process.getProcessId());
        } else {
            logger.debug("工序已存在: {}", process.getProcessId());
        }
    }
    private void saveWorkSteps(WorkStep workStep) {
        if (workStepMapper.selectById(workStep.getId()) == null) {
            workStepMapper.insert(workStep);
            logger.debug("工步已保存: {}", workStep.getId());
        } else {
            logger.debug("工步已存在: {}", workStep.getId());
        }
    }
    private void saveTreePath(List<ProductMix> productMixList){
        for (ProductMix productMix : productMixList) {
            if (productMixMapper.selectById(productMix.getId()) == null) {
                productMixMapper.insert(productMix);
                logger.debug("产品组合已保存: {}", productMix.getId());
            } else {
                logger.debug("产品组合已存在: {}", productMix.getId());
            }
        }
    }
    private void savePermissionStreamNewList(List<PermissionStreamNew> permissionStreamNewList) {
        for (PermissionStreamNew permissionStreamNew : permissionStreamNewList) {
            if (permissionStreamNew.getUserId() != null) {
                String id=sysUserService.getUserByName(permissionStreamNew.getUserId()).getId();
                if (id!=null){
                    permissionStreamNew.setUserId(id);
                }
            }
            if (permissionStreamNew.getDepartId() != null) {
                String id=mdcProductionService.findByOrgCode(permissionStreamNew.getDepartId()).getId();
                if (id!=null){
                permissionStreamNew.setDepartId(id);
                }
            }
            permissionStreamNewMapper.insert(permissionStreamNew);
            logger.debug("权限已保存: {}", permissionStreamNew.getId());
        }
        //分批添加产品、部件、零件、工艺规程、工序、工步权限
        permissionStreamNewList.forEach(item -> {
            switch (item.getBusinessType()){
                case "1":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        ProductPermission productPermission = new ProductPermission();
                        productPermission.setProductId(item.getBusinessId());
                        productPermission.setUserId(item.getUserId());
                        productPermissionService.save(productPermission);
                    }else {
                        ProductDepartment productDepartment = new ProductDepartment();
                        productDepartment.setProductId(item.getBusinessId());
                        productDepartment.setDepartId(item.getDepartId());
                        productDepartmentService.save(productDepartment);
                    }
                    break;
                case "2":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        ComponentPermission componentPermission = new ComponentPermission();
                        componentPermission.setComponentId(item.getBusinessId());
                        componentPermission.setUserId(item.getUserId());
                        componentPermissionService.save(componentPermission);
                    }else {
                        ComponentDepartment componentDepartment = new ComponentDepartment();
                        componentDepartment.setComponentId(item.getBusinessId());
                        componentDepartment.setDepartId(item.getDepartId());
                        componentDepartmentService.save(componentDepartment);
                    }
                    break;
                case "3":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        PartsPermission partsPermission = new PartsPermission();
                        partsPermission.setPartsId(item.getBusinessId());
                        partsPermission.setUserId(item.getUserId());
                        partsPermissionService.save(partsPermission);
                    }else {
                        PartsDepartment partsDepartment = new PartsDepartment();
                        partsDepartment.setPartsId(item.getBusinessId());
                        partsDepartment.setDepartId(item.getDepartId());
                        partsDepartmentService.save(partsDepartment);
                    }
                    break;
                case "4":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        ProcessSpecVersionPermission processSpecVersionPermission = new ProcessSpecVersionPermission();
                        processSpecVersionPermission.setPsvId(item.getBusinessId());
                        processSpecVersionPermission.setUserId(item.getUserId());
                        processSpecVersionPermissionService.save(processSpecVersionPermission);
                    }else {
                        ProcessSpecVersionDepartment processSpecVersionDepartment = new ProcessSpecVersionDepartment();
                        processSpecVersionDepartment.setPsvId(item.getBusinessId());
                        processSpecVersionDepartment.setDepartId(item.getDepartId());
                        processSpecVersionDepartmentService.save(processSpecVersionDepartment);
                    }
                    break;
                case "5":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        ProcessionPermission processionPermission = new ProcessionPermission();
                        processionPermission.setProcessId(item.getBusinessId());
                        processionPermission.setUserId(item.getUserId());
                        processStreamPermissionService.save(processionPermission);
                    }else {
                        ProcessionDepartment processionDepartment = new ProcessionDepartment();
                        processionDepartment.setProcessId(item.getBusinessId());
                        processionDepartment.setDepartId(item.getDepartId());
                        processionDepartmentService.save(processionDepartment);
                    }
                    break;
                case  "6":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        WorkStepPermission workStepPermission = new WorkStepPermission();
                        workStepPermission.setStepId(item.getBusinessId());
                        workStepPermission.setUserId(item.getUserId());
                        workStepPermissionService.save(workStepPermission);
                    }else {
                        WorkStepDepartment workStepDepartment = new WorkStepDepartment();
                        workStepDepartment.setStepId(item.getBusinessId());
                        workStepDepartment.setDepartId(item.getDepartId());
                        workStepDepartmentService.save(workStepDepartment);
                    }
                    break;
                    default:
            }
        });
    }
    private void saveDeviceManagement(DeviceManagement deviceManagement) {
        if (deviceManagementMapper.selectById(deviceManagement.getId()) == null) {
            deviceManagementMapper.insert(deviceManagement);
            logger.debug("设备类信息已保存: {}", deviceManagement.getId());
        } else {
            logger.debug("设备类信息已存在: {}", deviceManagement.getId());
        }
    }
    private void saveDeviceType(DeviceType deviceType) {
        if (deviceTypeMapper.selectById(deviceType.getId()) == null) {
            deviceTypeMapper.insert(deviceType);
            logger.debug("设备类已保存: {}", deviceType.getId());
        } else {
            logger.debug("设备类已存在: {}", deviceType.getId());
        }
    }
    private void saveDocInfo(DocInfo docInfo) {
        if (docInfoMapper.selectById(docInfo.getDocId()) == null) {
            docInfoMapper.insert(docInfo);
            logger.debug("文档已保存: {}", docInfo.getDocId());
        } else {
            logger.debug("文档已存在: {}", docInfo.getDocId());
        }
    }
    private void saveDocFile(DocFile docFile) {
        if (docFileMapper.selectById(docFile.getFileId()) == null) {
            docFileMapper.insert(docFile);
            logger.debug("文档文件已保存: {}", docFile.getFileId());
        } else {
            logger.debug("文档文件已存在: {}", docFile.getFileId());
        }
    }
    private void saveDocRelative(DocRelative docRelative) {
        if (docRelativeMapper.selectById(docRelative.getId()) == null) {
            docRelativeMapper.insert(docRelative);
            logger.debug("文档对应关系已保存: {}", docRelative.getId());
        } else {
            logger.debug("文档对应关系已存在: {}", docRelative.getId());
        }
    }
    private void saveCutterList(List<Cutter> cutterList) {
        for (Cutter cutter : cutterList) {
            if (cutterMapper.selectById(cutter.getId()) == null) {
                cutterMapper.insert(cutter);
                logger.debug("刀具已保存: {}", cutter.getId());
            } else {
                cutterMapper.updateById(cutter);
            }
        }
    }
    private void saveGuideCardBatch(GuideCardBatch guideCardBatch) {
        if (guideCardBatchMapper.selectById(guideCardBatch.getId()) == null) {
            guideCardBatchMapper.insert(guideCardBatch);
            logger.debug("刀片批次已保存: {}", guideCardBatch.getId());
        } else {
            logger.debug("刀片批次已存在: {}", guideCardBatch.getId());
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DataPackageService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package org.jeecg.modules.dnc.service.impl;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.service.DataPackageStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
@Service
public class DataPackageService {
    private final Map<TransferPackage.DataType, DataPackageStrategy> strategies;
    @Autowired
    public DataPackageService(List<DataPackageStrategy> strategyList) {
        strategies = new EnumMap<>(TransferPackage.DataType.class);
        strategyList.forEach(strategy -> {
            if (strategy instanceof ProcessPackageStrategy) {
                strategies.put(TransferPackage.DataType.PROCESS, strategy);
            } else if (strategy instanceof WorkStepPackageStrategy) {
                strategies.put(TransferPackage.DataType.WORKSTEP, strategy);
            }
        });
    }
    public TransferPackage packageData(TransferPackage.DataType type, String id) {
        DataPackageStrategy strategy = strategies.get(type);
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的数据类型: " + type);
        }
        return strategy.packageData(id);
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DevicePermissionServiceImpl.java
@@ -196,9 +196,9 @@
        populateEquipmentNodes(treeList, equipmentMap, userRealNameMap);
    }
/**
        * èŽ·å–æŽˆæƒè®¾å¤‡ID集合
 */
    /**
     * èŽ·å–æŽˆæƒè®¾å¤‡ID集合
    */
    private Set<String> getAuthorizedDeviceIds(String userId) {
        return super.list(new QueryWrapper<DevicePermission>().select("device_id").eq("user_id", userId))
                .stream()
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DocInfoServiceImpl.java
@@ -342,10 +342,20 @@
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean addDocInfoAnalysisSmwNcService(String pathFile,File fileRec){
        //todo ç¨‹åºå›žä¼ 
        //确认解析目录
        return true;
    }
    /**
     * æ–‡æ¡£è§£æž
     * todo ä¿®æ”¹åˆ›å»ºæ–‡ä»¶å…³è”关系,改成固定docId,去除创建DocInfo
     * @param equipmentId
     * @param fileRec
     * @param fileNameSuffix
     * @param fileNameNew
     * @param filePath
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean addDocInfoRecService(String equipmentId,File fileRec,String fileNameSuffix,String fileNameNew,String filePath ) {
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FileFerryService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,254 @@
package org.jeecg.modules.dnc.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.dnc.dto.ComponentHierarchy;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.exception.ExceptionCast;
import org.jeecg.modules.dnc.response.ActivitiCode;
import org.jeecg.modules.dnc.response.DocumentCode;
import org.jeecg.modules.dnc.service.IDocClassificationService;
import org.jeecg.modules.dnc.service.IDocInfoService;
import org.jeecg.modules.dnc.service.IDocRelativeService;
import org.jeecg.modules.dnc.utils.JsonUtils;
import org.jeecg.modules.dnc.utils.file.FileUtilS;
import org.jeecg.modules.mdc.entity.MdcEquipment;
import org.jeecg.modules.mdc.mapper.MdcEquipmentMapper;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
@Service
public class FileFerryService {
    private final DataPackageService dataPackageService;
    private final SecurityService securityService;
    private static final Logger logger = LoggerFactory.getLogger(FileFerryService.class);
    @Value("${deploy.secretFolder}")
    private String ferryPath;
    @Value("${fileHomePath}")
    private String fileHomePath;
    @Autowired
    private MdcEquipmentMapper mdcEquipmentMapper;
    @Autowired
    private IMdcProductionService mdcProductionService;
    @Autowired
    private IDocClassificationService classificationService;
    @Autowired
    private IDocRelativeService docRelativeService;
    @Autowired
    private IDocInfoService docInfoService;
    @Autowired
    public FileFerryService(DataPackageService dataPackageService, SecurityService securityService) {
        this.dataPackageService = dataPackageService;
        this.securityService = securityService;
    }
    public String exportData(TransferPackage.DataType type, String id,String fileName) {
        // 1. èŽ·å–å°è£…æ•°æ®
        TransferPackage transferPackage = dataPackageService.packageData(type, id);
        // 2. åŽ‹ç¼©å±‚çº§ç»“æž„
        compressHierarchy(transferPackage);
        // 3. JSON序列化
        String json = JsonUtils.toJson(transferPackage);
//        // 4. åŽ‹ç¼©åŠ å¯†
//        byte[] compressed = CompressionUtils.gzipCompress(json.getBytes(StandardCharsets.UTF_8));
//        byte[] encrypted = securityService.encrypt(compressed);
        //暂时不加密
        byte[] compressed = json.getBytes(StandardCharsets.UTF_8);
        // 5. ç”Ÿæˆæ–‡ä»¶
        Path filePath = Paths.get(ferryPath,fileName);
        try {
            Files.createDirectories(filePath.getParent());
            Files.write(filePath, compressed);
            return filePath.toString();
        } catch (IOException e) {
            throw new RuntimeException("文件写入失败", e);
        }
    }
    public TransferPackage importData(String filePath) {
        try {
            // 1. è¯»å–文件
            Path path = Paths.get(filePath);
            String fileName = path.getFileName().toString();
            byte[] encrypted = Files.readAllBytes(path);
            logger.debug("读取文件完成, å¤§å°: {} å­—节", encrypted.length);
            // 2. è§£å¯† (当前已注释)
            // byte[] compressed = securityService.decrypt(encrypted);
            // 3. è§£åŽ‹ç¼©
//            byte[] jsonBytes = CompressionUtils.gzipDecompress(encrypted);
            String json = new String(encrypted, StandardCharsets.UTF_8);
            logger.debug("解压缩完成, JSON长度: {} å­—符", json.length());
            // è®°å½•JSON内容用于调试
            logger.trace("原始JSON内容:\n{}", json);
            // 4. JSON反序列化
            logger.debug("开始反序列化...");
            TransferPackage pkg = JsonUtils.fromJson(json, TransferPackage.class);
            // 5. å¤„理文件名 - ç¤ºä¾‹: 10A20250614000026_3102038
            String[] split = fileName.split("_");
            if (split.length < 2) {
                throw new IllegalArgumentException("无效的文件名格式: " + fileName);
            }
            String id = split[0];
            String equipmentId = split[1].split("\\.")[0];
            // æå–前缀和数字部分
            int aIndex = id.indexOf("A");
            if (aIndex == -1 || aIndex == id.length() - 1) {
                throw new IllegalArgumentException("无效的ID格式: " + id);
            }
            String prefix = id.substring(0, aIndex + 1);
            String numericPart = id.substring(aIndex + 1);
            // è®¡ç®—前一个文件名
            long number = Long.parseLong(numericPart);
            number--;  // èŽ·å–å‰ä¸€ä¸ªåºåˆ—å·
            // ä¿æŒç›¸åŒä½æ•°æ ¼å¼
            String newNumeric = String.format("%0" + numericPart.length() + "d", number);
            String ncFileName = prefix + newNumeric + "_" + equipmentId+".NC";
            String ncFilePath = path.getParent().resolve(ncFileName).toString();
            // 6. èŽ·å–æ–‡ä»¶å¤åˆ¶ç›®æ ‡è·¯å¾„
            DocFile docFile = pkg.getTraceChain().getDocFile();
            DocInfo docInfo = pkg.getTraceChain().getDocInfo();
            if (docFile == null) {
                throw new IllegalStateException("传输包中缺少文档文件信息");
            }
            // æž„建目标路径
            String targetDirectory = fileHomePath + docFile.getFilePath();
            String targetPath = Paths.get(targetDirectory, docFile.getFileEncodeName()).toString();
            // ç¡®ä¿ç›®æ ‡ç›®å½•存在
            File targetDir = new File(targetDirectory);
            if (!targetDir.exists() && !targetDir.mkdirs()) {
                throw new IOException("无法创建目标目录: " + targetDirectory);
            }
            // 7. å¤åˆ¶æ–‡ä»¶å¹¶é‡å‘½å
            logger.info("复制文件: {} â†’ {}", ncFilePath, targetPath);
            Path source = Paths.get(ncFilePath);
            Files.copy(source, Paths.get(targetPath), StandardCopyOption.REPLACE_EXISTING);
            // 8. æŸ¥è¯¢è®¾å¤‡id
            MdcEquipment mdcEquipment=mdcEquipmentMapper.selectOne(new QueryWrapper<MdcEquipment>().eq("equipment_id",equipmentId));
            if (mdcEquipment == null) {
                throw new IllegalArgumentException("无效的设备ID: " + equipmentId);
            }
            // 9.传输文件到设备下
            List<String> strings = mdcProductionService.findListParentTreeAll(mdcEquipment.getId());
            if (strings != null && !strings.isEmpty()) {
                DocInfo deviceDoc = docInfoService.getByDocAttrAndDocId(docInfo.getDocId(), 7, mdcEquipment.getId());
                if (deviceDoc == null) {
                    DocClassification classification = classificationService.getByCode("send");
                    if(classification == null)
                        ExceptionCast.cast(DocumentCode.DOC_CLASS_ERROR);
                    DocRelative docRelative = new DocRelative();
                    docRelative.setDocId(docInfo.getDocId());
                    docRelative.setClassificationId(classification.getClassificationId());
                    docRelative.setAttributionType(7);
                    docRelative.setAttributionId(mdcEquipment.getId());
                    docRelativeService.save(docRelative);
                }
                String sendPath = StringUtils.join(strings.toArray(), "/");
                boolean copyFileNc = FileUtilS.copyFileNc(docFile.getFilePath(), sendPath + "/" + mdcEquipment.getEquipmentId(),
                        docFile.getFileEncodeName(),
                        docFile.getFileName(), docFile.getFileSuffix());
                if (!copyFileNc) {
                    ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR);
                } else {
                    FileUtilS.deleteZipFromToSend(sendPath + "/" + mdcEquipment.getEquipmentId(),
                            docFile.getFileName(), docFile.getFileSuffix());
                }
            } else {
                throw new RuntimeException("文件传输路径获取失败");
            }
            // 10.删除临时NC文件与json文件
            logger.info("删除临时文件: {}", ncFilePath);
            Files.delete(source);
            Files.delete(path);
            return JsonUtils.fromJson(json, TransferPackage.class);
        } catch (NumberFormatException e) {
            throw new RuntimeException("文件名中的数字格式无效: " + e.getMessage(), e);
        } catch (IOException e) {
            throw new RuntimeException("文件操作失败: " + e.getMessage(), e);
        } catch (Exception e) {
            logger.error("文件导入失败 [路径: {}]", filePath, e);
            throw new RuntimeException("文件导入失败: " + e.getMessage(), e);
        }
    }
    private void compressHierarchy(TransferPackage pkg) {
        if (pkg.getTraceChain() == null ||
                pkg.getTraceChain().getComponentHierarchy() == null ||
                pkg.getTraceChain().getComponentHierarchy().getComponents().size() < 4) {
            return;
        }
        ComponentHierarchy hierarchy = pkg.getTraceChain().getComponentHierarchy();
        List<ComponentInfo> compressed = new ArrayList<>();
        // ä¿ç•™æ ¹éƒ¨ä»¶
        compressed.add(hierarchy.getComponents().get(0));
        // ä¿ç•™å…³é”®ä¸­é—´èŠ‚ç‚¹
        int step = Math.max(1, hierarchy.getComponents().size() / 3);
        for (int i = step; i < hierarchy.getComponents().size() - 1; i += step) {
            compressed.add(hierarchy.getComponents().get(i));
        }
        // ä¿ç•™å¶å­éƒ¨ä»¶
        compressed.add(hierarchy.getLeafComponent());
        // æ›´æ–°å±‚级
        hierarchy.getComponents().clear();
        hierarchy.getComponents().addAll(compressed);
    }
    private String generateFilename(TransferPackage.DataType type, String id) {
        return String.format("%s_%s_%d.ferry",
                type.name().toLowerCase(),
                id,
                System.currentTimeMillis());
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FullHierarchyTraceService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,236 @@
package org.jeecg.modules.dnc.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jeecg.modules.dnc.constant.DocAttributionTypeEnum;
import org.jeecg.modules.dnc.dto.ComponentHierarchy;
import org.jeecg.modules.dnc.dto.ProcessTraceChain;
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.mapper.*;
import org.jeecg.modules.dnc.service.IPermissionStreamNewService;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
public class FullHierarchyTraceService {
    @Autowired
    private ProductMixMapper productMixMapper;
    @Autowired
    private ProductInfoMapper productMapper;
    @Autowired
    private ComponentInfoMapper componentMapper;
    @Autowired
    private PartsInfoMapper partsMapper;
    @Autowired
    private ProcessSpecVersionMapper psvMapper;
    @Autowired
    private ProcessStreamMapper processMapper;
    @Autowired
    private WorkStepMapper workStepMapper;
    @Autowired
    private DeviceTypeMapper deviceTypeMapper;
    @Autowired
    private DeviceManagementMapper deviceManagementMapper;
    @Autowired
    private DocInfoMapper docInfoMapper;
    @Autowired
    private DocFileMapper docFileMapper;
    @Autowired
    private CutterMapper cutterMapper;
    @Autowired
    private GuideCardBatchMapper guideCardBatchMapper;
    @Autowired
    private IPermissionStreamNewService permissionStreamNewService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IMdcProductionService mdcProductionService;
    public ProcessTraceChain traceFromProcess(DocRelative docRelative) {
        ProcessTraceChain chain = initChainWithDocInfo(docRelative);
        DeviceType deviceType = deviceTypeMapper.selectById(docRelative.getAttributionId());
        chain.setDeviceType(deviceType);
        if (isProcessType(deviceType)) {
            chain.setDeviceManagement(deviceManagementMapper.selectById(deviceType.getDeviceManagementId()));
            traceProcessChain(chain, deviceType.getAttributionId());
        }
        completeChainWithProductInfo(chain);
        List<ProductMix> productMixList=buildFullTreePath(chain);
        chain.setTreePath(productMixList);
        chain.setPermissionStreamNewList(buildFullTreePathPermission(productMixList));
        return chain;
    }
    public ProcessTraceChain traceFromWorkStep(DocRelative docRelative) {
        ProcessTraceChain chain = initChainWithDocInfo(docRelative);
        DeviceType deviceType = deviceTypeMapper.selectById(docRelative.getAttributionId());
        chain.setDeviceType(deviceType);
        if (isWorkSiteType(deviceType)) {
            chain.setDeviceManagement(deviceManagementMapper.selectById(deviceType.getDeviceManagementId()));
            traceWorkStepChain(chain, deviceType.getAttributionId());
        }
        completeChainWithProductInfo(chain);
        List<ProductMix> productMixList=buildFullTreePath(chain);
        chain.setTreePath(productMixList);
        chain.setPermissionStreamNewList(buildFullTreePathPermission(productMixList));
        return chain;
    }
    private ProcessTraceChain initChainWithDocInfo(DocRelative docRelative) {
        ProcessTraceChain chain = ProcessTraceChain.builder().docRelative(docRelative).build();
        Optional.ofNullable(docInfoMapper.selectById(docRelative.getDocId()))
                .ifPresent(doc -> {
                    chain.setDocInfo(doc);
                    chain.setDocFile(docFileMapper.selectById(doc.getPublishFileId()));
                    chain.setCutterList(getCuttersByDocId(doc.getDocId()));
                    getLatestGuideCardBatch(doc.getDocId()).ifPresent(chain::setGuideCardBatch);
                });
        return chain;
    }
    private List<Cutter> getCuttersByDocId(String docId) {
        return cutterMapper.selectList(new QueryWrapper<Cutter>().eq("doc_id", docId));
    }
    private Optional<GuideCardBatch> getLatestGuideCardBatch(String docId) {
        List<GuideCardBatch> batches = guideCardBatchMapper.selectList(
                new QueryWrapper<GuideCardBatch>()
                        .eq("doc_id", docId)
                        .orderByDesc("SUBSTRING(serial_number, LEN(serial_number)-3, 4)"));
        return CollectionUtils.isEmpty(batches) ? Optional.empty() : Optional.of(batches.get(0));
    }
    private boolean isProcessType(DeviceType deviceType) {
        return deviceType != null &&
                Objects.equals(deviceType.getAttributionType(), DocAttributionTypeEnum.PROCESS.getCode());
    }
    private boolean isWorkSiteType(DeviceType deviceType) {
        return deviceType != null &&
                Objects.equals(deviceType.getAttributionType(), DocAttributionTypeEnum.WORKSITE.getCode());
    }
    private void traceProcessChain(ProcessTraceChain chain, String processId) {
        ProcessStream process = processMapper.selectById(processId);
        if (process == null) return;
        chain.setProcess(process);
        if (process.getPsvId() != null) {
            ProcessSpecVersion psv = psvMapper.selectById(process.getPsvId());
            chain.setProcessSpec(psv);
            if (psv != null && psv.getPartsId() != null) {
                PartsInfo parts = partsMapper.selectById(psv.getPartsId());
                chain.setParts(parts);
                if (parts != null && parts.getComponentId() != null) {
                    chain.setComponentHierarchy(traceComponentHierarchy(parts.getComponentId()));
                }
            }
        } else if (process.getComponentId() != null) {
            chain.setComponentHierarchy(traceComponentHierarchy(process.getComponentId()));
        }
    }
    private void traceWorkStepChain(ProcessTraceChain chain, String workStepId) {
        WorkStep workStep = workStepMapper.selectById(workStepId);
        if (workStep == null) return;
        chain.setWorkStep(workStep);
        traceProcessChain(chain, workStep.getProcessId());
    }
    private ComponentHierarchy traceComponentHierarchy(String componentId) {
        ComponentHierarchy hierarchy = new ComponentHierarchy();
        ComponentInfo current = componentMapper.selectById(componentId);
        while (current != null) {
            hierarchy.addComponentToTop(current);
            if (current.getParentId() == null || current.getParentId().isEmpty()) {
                Optional.ofNullable(current.getProductId())
                        .map(productMapper::selectById)
                        .ifPresent(hierarchy::setRootProduct);
                break;
            }
            current = componentMapper.selectById(current.getParentId());
        }
        return hierarchy;
    }
    private void completeChainWithProductInfo(ProcessTraceChain chain) {
        Optional.ofNullable(chain.getComponentHierarchy())
                .map(ComponentHierarchy::getComponents)
                .filter(components -> !components.isEmpty())
                .map(components -> components.get(0))
                .map(ComponentInfo::getProductId)
                .map(productMapper::selectById)
                .ifPresent(chain::setProduct);
    }
    private List<ProductMix> buildFullTreePath(ProcessTraceChain chain) {
        List<ProductMix> path = new ArrayList<>();
        Optional.ofNullable(chain.getProduct())
                .map(ProductInfo::getProductId)
                .map(productMixMapper::findByProductId)
                .ifPresent(path::add);
        Optional.ofNullable(chain.getComponentHierarchy())
                .map(ComponentHierarchy::getComponentsFromTop)
                .ifPresent(components -> components.stream()
                        .map(ComponentInfo::getComponentId)
                        .map(productMixMapper::findByComponentId)
                        .filter(Objects::nonNull)
                        .forEach(path::add));
        Optional.ofNullable(chain.getParts())
                .map(PartsInfo::getPartsId)
                .map(productMixMapper::findByPartsId)
                .ifPresent(path::add);
        Optional.ofNullable(chain.getProcessSpec())
                .map(ProcessSpecVersion::getId)
                .map(productMixMapper::findByOperationId)
                .ifPresent(path::add);
        Optional.ofNullable(chain.getProcess())
                .map(ProcessStream::getProcessId)
                .map(productMixMapper::findByProcessId)
                .ifPresent(path::add);
        Optional.ofNullable(chain.getWorkStep())
                .map(WorkStep::getId)
                .map(productMixMapper::findByWorksiteId)
                .ifPresent(path::add);
        return path;
    }
    private List<PermissionStreamNew> buildFullTreePathPermission(List<ProductMix> productMixList) {
        List<Long> ids=productMixList.stream().map(ProductMix::getId).collect(Collectors.toList());
        List<PermissionStreamNew> path = permissionStreamNewService
                .list(new QueryWrapper<PermissionStreamNew>().in("business_id",ids)
                        .eq("delete_flag",0));
        path.forEach(item->{
            if (item.getDepartId()!=null){
                item.setDepartId(mdcProductionService.getById(item.getDepartId()).getOrgCode());
            }
            if (item.getUserId()!=null){
                item.setUserId(sysUserService.getById(item.getUserId()).getUsername());
            }
        });
        return path;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/PartsInfoServiceImpl.java
@@ -151,8 +151,8 @@
        boolean b = super.updateById(partsInfo);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(partsInfo.getPartsName());
        productMix.setCode(partsInfo.getPartsCode());
        productMix.setTreeName(partsInfo.getPartsName());
        productMix.setTreeCode(partsInfo.getPartsCode());
        productMixService.updateById(productMix);
        if(!b)
            return false;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessPackageStrategy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package org.jeecg.modules.dnc.service.impl;
import org.jeecg.modules.dnc.constant.DocAttributionTypeEnum;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.entity.DeviceType;
import org.jeecg.modules.dnc.entity.DocRelative;
import org.jeecg.modules.dnc.entity.ProcessStream;
import org.jeecg.modules.dnc.mapper.DeviceTypeMapper;
import org.jeecg.modules.dnc.mapper.DocRelativeMapper;
import org.jeecg.modules.dnc.mapper.ProcessStreamMapper;
import org.jeecg.modules.dnc.service.DataPackageStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProcessPackageStrategy implements DataPackageStrategy {
    @Autowired
    private ProcessStreamMapper processMapper;
    @Autowired
    private DeviceTypeMapper deviceTypeMapper;
    @Autowired
    private FullHierarchyTraceService traceService;
    @Autowired
    private DocRelativeMapper docRelativeMapper;
    @Override
    public TransferPackage packageData(String relativeId) {
        DocRelative docRelative=docRelativeMapper.selectById(relativeId);
        DeviceType deviceType=deviceTypeMapper.selectById(docRelative.getAttributionId());
        if (deviceType!=null&&deviceType.getAttributionType().equals(DocAttributionTypeEnum.PROCESS.getCode())) {
            ProcessStream process = processMapper.selectById(deviceType.getAttributionId());
            if (process == null) {
                throw new IllegalArgumentException("设备类对应的工序不存在: " + deviceType.getDeviceManagementId());
            }
        }
        return TransferPackage.builder()
                .dataType(TransferPackage.DataType.PROCESS)
                .docRelative(docRelative)
                .traceChain(traceService.traceFromProcess(docRelative))
                .build();
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessSpecVersionServiceImpl.java
@@ -205,8 +205,8 @@
        boolean b = super.updateById(processSpecVersion);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(processSpecVersion.getProcessSpecVersionName());
        productMix.setCode(processSpecVersion.getProcessSpecVersionCode());
        productMix.setTreeName(processSpecVersion.getProcessSpecVersionName());
        productMix.setTreeCode(processSpecVersion.getProcessSpecVersionCode());
        productMixService.updateById(productMix);
        if(!b)
            return false;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessStreamServiceImpl.java
@@ -61,7 +61,6 @@
    private IDocInfoService docInfoService;
    @Autowired
    private IDeviceTypeService deviceTypeService;
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean addProcessStream(ProcessStream stream) {
@@ -177,8 +176,8 @@
        boolean b = super.updateById(stream);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(stream.getProcessName());
        productMix.setCode(stream.getProcessCode());
        productMix.setTreeName(stream.getProcessName());
        productMix.setTreeCode(stream.getProcessCode());
        productMixService.updateById(productMix);
        if(!b)
            ExceptionCast.cast(CommonCode.FAIL);
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessionDepartmentServiceImpl.java
ÎļþÃû´Ó lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessionDepartmentService.java ÐÞ¸Ä
@@ -10,10 +10,11 @@
import org.jeecg.modules.system.entity.MdcProduction;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
@Service
public class ProcessionDepartmentService extends ServiceImpl<ProcessionDepartmentMapper, ProcessionDepartment> implements IProcessionDepartmentService {
public class ProcessionDepartmentServiceImpl extends ServiceImpl<ProcessionDepartmentMapper, ProcessionDepartment> implements IProcessionDepartmentService {
    @Override
    public boolean deleteByProcessId(String processId) {
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductInfoServiceImpl.java
@@ -164,8 +164,8 @@
        boolean b = super.updateById(productInfo);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(productInfo.getProductName());
        productMix.setCode(productInfo.getProductNo());
        productMix.setTreeName(productInfo.getProductName());
        productMix.setTreeCode(productInfo.getProductNo());
        productMixService.updateById(productMix);
        if (!b)
            return false;
@@ -422,6 +422,7 @@
     * @param paramId      äº§å“æ ‘节点id
     * @param relativeFlag 1 æ˜¯ 2 å¦
     * @param userIds      æ·»åŠ ç”¨æˆ·ids
     * todo优化结构,采用mix表进行父子递归查询,分类进行权限分配(单表查询)
     * @return
     */
    @Override
@@ -457,6 +458,7 @@
     * @param paramId       äº§å“æ ‘节点id
     * @param relativeFlag  1 æ˜¯ 2 å¦
     * @param departmentIds æ·»åŠ éƒ¨é—¨ids
     * todo优化结构,采用mix表进行父子递归查询,分类进行权限分配(单表查询)
     * @return
     */
    @Override
@@ -492,6 +494,7 @@
     * @param paramId      äº§å“æ ‘节点id
     * @param relativeFlag 1 æ˜¯ 2 å¦
     * @param userIds      ç§»é™¤ç”¨æˆ·ids
     * todo优化结构,采用mix表进行父子递归查询,分类进行权限分配(单表查询)
     * @return
     */
    @Override
@@ -526,6 +529,7 @@
     * @param paramId       äº§å“æ ‘节点id
     * @param relativeFlag  1 æ˜¯ 2 å¦
     * @param departmentIds ç§»é™¤éƒ¨é—¨ids
     * todo优化结构,采用mix表进行父子递归查询,分类进行权限分配(单表查询)
     * @return
     */
    @Override
@@ -1179,31 +1183,37 @@
                        ProductInfo productInfo=this.getById(docInfo.getAttributionId());
                        docInfo.setNodeName(productInfo.getProductName());
                        docInfo.setNodeCode(productInfo.getProductNo());
                        docInfo.setNodeId(productInfo.getProductId());
                        break;
                    case 2:
                        ComponentInfo componentInfo=componentInfoService.getById(docInfo.getAttributionId());
                        docInfo.setNodeName(componentInfo.getComponentName());
                        docInfo.setNodeCode(componentInfo.getComponentCode());
                        docInfo.setNodeId(componentInfo.getComponentId());
                        break;
                    case 3:
                        PartsInfo partsInfo=partsInfoService.getById(docInfo.getAttributionId());
                        docInfo.setNodeCode(partsInfo.getPartsCode());
                        docInfo.setNodeName(partsInfo.getPartsName());
                        docInfo.setNodeId(partsInfo.getPartsId());
                        break;
                    case 4:
                        ProcessSpecVersion processSpecVersion=processSpecVersionService.getById(docInfo.getAttributionId());
                        docInfo.setNodeName(processSpecVersion.getProcessSpecVersionName());
                        docInfo.setNodeCode(processSpecVersion.getProcessSpecVersionCode());
                        docInfo.setNodeId(processSpecVersion.getId());
                        break;
                    case 5:
                        ProcessStream processStream=processStreamService.getById(docInfo.getAttributionId());
                        docInfo.setNodeName(processStream.getProcessName());
                        docInfo.setNodeCode(processStream.getProcessCode());
                        docInfo.setNodeId(processStream.getProcessId());
                        break;
                    case 6:
                        WorkStep workStep=workStepService.getById(docInfo.getAttributionId());
                        docInfo.setNodeName(workStep.getStepName());
                        docInfo.setNodeCode(workStep.getStepName());
                        docInfo.setNodeId(workStep.getId());
                        break;
                }
            });
@@ -1225,11 +1235,13 @@
                    ProcessStream processStream=processStreamService.getById(deviceType.getAttributionId());
                    docInfo.setNodeName(processStream.getProcessName());
                    docInfo.setNodeCode(processStream.getProcessCode());
                    docInfo.setNodeId(processStream.getProcessId());
                }else {
                    //工步下的设备类
                    WorkStep workStep=workStepService.getById(deviceType.getAttributionId());
                    docInfo.setNodeName(workStep.getStepName());
                    docInfo.setNodeCode(workStep.getStepName());
                    docInfo.setNodeId(workStep.getId());
                }
            });
        }
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductMixServiceImpl.java
@@ -48,4 +48,67 @@
        result.sort(Comparator.comparing(ProductMix::getCreateTime, Comparator.nullsLast(Date::compareTo)));
        return result;
    }
    @Override
    public List<ProductMix> getParentList(String id) {
        List<ProductMix> parentList = new ArrayList<>();
        // 1. æ ¹æ®ID查询当前节点
        ProductMix current = this.getById(id);
        if (current == null) {
            return parentList; // èŠ‚ç‚¹ä¸å­˜åœ¨æ—¶è¿”å›žç©ºåˆ—è¡¨
        }
        // 2. ä»Žå½“前节点开始向上查找父节点
        Long parentId = current.getParentId();
        while ( parentId != 0L) {
            ProductMix parent = this.getById(parentId.toString());
            if (parent == null) {
                break;
            }
            parentList.add(parent);
            parentId = parent.getParentId();
        }
        return parentList;
    }
    @Override
    public List<ProductMix> getChildrenList(String id) {
        List<ProductMix> childrenList = new ArrayList<>();
        ProductMix current = this.getById(id);
        if (current == null) {
            return childrenList;
        }
        // ä½¿ç”¨é˜Ÿåˆ—进行BFS
        Queue<ProductMix> queue = new LinkedList<>();
        queue.add(current); // åŠ å…¥å½“å‰èŠ‚ç‚¹ä½œä¸ºèµ·ç‚¹
        // è®°å½•已访问节点的ID,避免循环引用
        Set<String> visited = new HashSet<>();
        visited.add(id); // èµ·å§‹èŠ‚ç‚¹å·²è®¿é—®
        while (!queue.isEmpty()) {
            ProductMix node = queue.poll();
            // è·³è¿‡èµ·å§‹èŠ‚ç‚¹ï¼ˆå³ä¼ å…¥çš„èŠ‚ç‚¹ï¼‰ï¼Œä¸åŠ å…¥ç»“æžœåˆ—è¡¨
            if (!node.getId().toString().equals(id)) {
                childrenList.add(node);
            }
            // æŸ¥è¯¢å½“前节点的直接子节点
            List<ProductMix> directChildren = this.lambdaQuery().eq(ProductMix::getParentId, node.getId()).list();
            if (directChildren != null && !directChildren.isEmpty()) {
                for (ProductMix child : directChildren) {
                    String childId = child.getId().toString();
                    // å¦‚果该子节点还未访问过
                    if (!visited.contains(childId)) {
                        visited.add(childId);
                        queue.add(child);
                    }
                    // å¦åˆ™å¿½ç•¥ï¼Œé¿å…å¾ªçŽ¯å¼•ç”¨å¯¼è‡´çš„æ­»å¾ªçŽ¯
                }
            }
        }
        return childrenList;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductPermissionServiceImpl.java
@@ -143,7 +143,7 @@
                break;
            default:
                // å¤„理未知类型
                throw new IllegalArgumentException("Unknown permission type: " + type);
                throw new IllegalArgumentException("Unknown permission treeType: " + type);
        }
    }
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/SecurityService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package org.jeecg.modules.dnc.service.impl;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
@Service
public class SecurityService {
    private static final String ALGORITHM = "SM4/ECB/PKCS5Padding";
    private final String secretKey;
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    @Autowired
    public SecurityService(@Value("${security.encryption-key}") String secretKey) {
        this.secretKey = secretKey;
    }
    public byte[] encrypt(byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "SM4");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            return cipher.doFinal(data);
        } catch (Exception e) {
            throw new RuntimeException("加密失败", e);
        }
    }
    public byte[] decrypt(byte[] encryptedData) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "SM4");
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            return cipher.doFinal(encryptedData);
        } catch (Exception e) {
            throw new RuntimeException("解密失败", e);
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/WorkStepPackageStrategy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package org.jeecg.modules.dnc.service.impl;
import org.jeecg.modules.dnc.constant.DocAttributionTypeEnum;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.entity.DeviceType;
import org.jeecg.modules.dnc.entity.DocRelative;
import org.jeecg.modules.dnc.entity.WorkStep;
import org.jeecg.modules.dnc.mapper.DeviceTypeMapper;
import org.jeecg.modules.dnc.mapper.DocRelativeMapper;
import org.jeecg.modules.dnc.mapper.WorkStepMapper;
import org.jeecg.modules.dnc.service.DataPackageStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class WorkStepPackageStrategy implements DataPackageStrategy {
    @Autowired
    private WorkStepMapper workStepMapper;
    @Autowired
    private FullHierarchyTraceService traceService;
    @Autowired
    private DeviceTypeMapper deviceTypeMapper;
    @Autowired
    private DocRelativeMapper docRelativeMapper;
    @Override
    public TransferPackage packageData(String relativeId) {
        DocRelative docRelative=docRelativeMapper.selectById(relativeId);
        DeviceType deviceType=deviceTypeMapper.selectById(docRelative.getAttributionId());
        if (deviceType!=null&&deviceType.getAttributionType().equals(DocAttributionTypeEnum.WORKSITE.getCode())) {
            WorkStep workStep = workStepMapper.selectById(deviceType.getAttributionId());
            if (workStep == null) {
                throw new IllegalArgumentException("设备类对应的工步不存在: " + deviceType.getDeviceManagementId());
            }
        }
        return TransferPackage.builder()
                .dataType(TransferPackage.DataType.WORKSTEP)
                .docRelative(docRelative)
                .traceChain(traceService.traceFromWorkStep(docRelative))
                .build();
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/WorkStepServiceImpl.java
@@ -175,8 +175,8 @@
            ExceptionCast.cast(ProcessInfoCode.WORKSTEP_NOT_EXIST);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(workStep.getStepName());
        productMix.setCode(workStep.getStepCode());
        productMix.setTreeName(workStep.getStepName());
        productMix.setTreeCode(workStep.getStepCode());
        productMixService.updateById(productMix);
        return super.updateById(workStep);
    }
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/CompressionUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package org.jeecg.modules.dnc.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class CompressionUtils {
    public static byte[] gzipCompress(byte[] data) {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             GZIPOutputStream gzip = new GZIPOutputStream(bos)) {
            gzip.write(data);
            gzip.finish();
            return bos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("GZIP压缩失败", e);
        }
    }
    public static byte[] gzipDecompress(byte[] compressed) {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
             GZIPInputStream gzip = new GZIPInputStream(bis);
             ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = gzip.read(buffer)) > 0) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("GZIP解压失败", e);
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/JsonUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package org.jeecg.modules.dnc.utils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.text.SimpleDateFormat;
public class JsonUtils {
    private static final ObjectMapper objectMapper = createObjectMapper();
    private static ObjectMapper createObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        // é…ç½®æ—¥æœŸæ ¼å¼
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        mapper.registerModule(new JavaTimeModule());
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // é…ç½®åºåˆ—化选项
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // é…ç½®ååºåˆ—化选项
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
        return mapper;
    }
    public static String toJson(Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            throw new RuntimeException("JSON序列化失败: " + e.getMessage(), e);
        }
    }
    public static <T> T fromJson(String json, Class<T> valueType) {
        try {
            return objectMapper.readValue(json, valueType);
        } catch (Exception e) {
            throw new RuntimeException("JSON反序列化失败: " + e.getMessage() + "\nJSON内容: " + json, e);
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/TreeBuilder.java
@@ -108,8 +108,8 @@
            ProductMix newNode = new ProductMix(
                    node.getId(),
                    node.getParentId(),
                    node.getName(),
                    node.getCode(),
                    node.getTreeName(),
                    node.getTreeCode(),
                    node.getType(),
                    node.getCreateTime()
            );
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/IAssignFileStreamService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dnc.entity.DocFile;
import org.jeecg.modules.dnc.response.QueryPageResponseResult;
import org.jeecg.modules.dncFlow.entity.AssignFileStream;
import org.jeecg.modules.dncFlow.ext.AssignFileStreamExt;
@@ -9,6 +10,7 @@
import org.jeecg.modules.dncFlow.request.AssignFileRequest;
import org.jeecg.modules.dncFlow.request.AssignFileStreamQueryRequest;
import org.jeecg.modules.dncFlow.vo.AssignFlowTaskVo;
import org.jeecg.modules.mdc.entity.MdcEquipment;
public interface IAssignFileStreamService extends IService<AssignFileStream> {
    /**
@@ -41,9 +43,7 @@
    /**
     * å®¡æ‰¹æœåŠ¡
     * @param taskId
     * @param streamId
     * @param stream
     * @param assignFlowTaskVo
     * @return
     */
    boolean approveAssignFile(AssignFlowTaskVo assignFlowTaskVo);
@@ -84,4 +84,6 @@
     * @return
     */
    Boolean getFlowableEnable();
    void handleFileTransfer(MdcEquipment mdcEquipment, DocFile docFile);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/impl/AssignFileStreamServiceImpl.java
@@ -16,11 +16,14 @@
import org.flowable.task.api.Task;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.dnc.constant.DncPassLogPassType;
import org.jeecg.modules.dnc.constant.DocAttributionTypeEnum;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.exception.ExceptionCast;
import org.jeecg.modules.dnc.ext.NcTxtFilePathInfo;
import org.jeecg.modules.dnc.response.*;
import org.jeecg.modules.dnc.service.*;
import org.jeecg.modules.dnc.service.impl.FileFerryService;
import org.jeecg.modules.dnc.utils.ValidateUtil;
import org.jeecg.modules.dnc.utils.date.DateUtil;
import org.jeecg.modules.dnc.utils.file.FileUtilS;
@@ -42,7 +45,6 @@
import org.jeecg.modules.flowable.service.IFlowTaskService;
import org.jeecg.modules.mdc.entity.MdcEquipment;
import org.jeecg.modules.mdc.service.IMdcEquipmentService;
import org.jeecg.modules.message.enums.DeployEnum;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -51,23 +53,17 @@
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
@Service("IAssignFileStreamService")
public class AssignFileStreamServiceImpl extends ServiceImpl<AssignFileStreamMapper, AssignFileStream> implements IAssignFileStreamService , FlowCallBackServiceI {
    private static final String PROCESS_KEY = "assign_nc_to_device";
    private static final String APPLY_VARIABLE = "apply_user";
    private static final String APPROVE_VARIABLE = "approve_users";
    private static final String SEND_CODE = "SEND";
    @Value("${flowable.enable}")
    private Boolean flowableEnable;
    @Value("${fileHomePath}")
    private String fileHomePath;
    @Autowired
    private IDocInfoService docInfoService;
    @Autowired
@@ -98,11 +94,10 @@
    private PermissionService permissionService;
    @Autowired
    private IDncPassLogService dncPassLogService;
    @Value("${deploy.deployType}")
    private String deployType;    //工控网/涉密网部署 0为工控网 1为涉密网
    @Value("${deploy.secretFolder}")
    private String secretFolder;    //涉密网传输nc文件夹
    @Autowired
    private FileFerryService ferryService;
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result applyAssignFile(AssignFileStream stream) {
@@ -253,11 +248,19 @@
            }
        }
        handleFileTransfer(mdcEquipment, docFile);
        //注意----区分工控网与涉密网!!!  æ¶‰å¯†ç½‘进行NC文件的拷贝,工控网负责进行解析NC文件
        if (deployType.equals(DeployEnum.SMW.getCode())) {
            handleFileProcessing(docFile, mdcEquipment, secretFolder);
        List<DocRelative> docRelativeList=docRelativeService.
                list(new QueryWrapper<DocRelative>()
                        .eq("attribution_type",stream.getAttributionType())
                        .eq("attribution_id",stream.getAttributionId())
                        .eq("doc_id",stream.getDocId()));
        if (docRelativeList.isEmpty()){
            ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR);
        }
        handleFileTransfer(mdcEquipment, docFile);
        //NC文件的拷贝
        handleFileProcessing(docFile, mdcEquipment, secretFolder);
        //对应产品结构树拷贝
        handleProductTree(docInfo,docRelativeList.get(0),mdcEquipment.getEquipmentId());
        synchronizedFlagService.updateFlag(2);
        return Result.OK("操作成功");
    }
@@ -383,10 +386,20 @@
                    }
                }
            }
            //注意----区分工控网与涉密网!!!  æ¶‰å¯†ç½‘进行NC文件的拷贝,工控网负责进行解析NC文件
            if (deployType.equals(DeployEnum.SMW.getCode())) {
                handleFileProcessing(docFile, mdcEquipment, secretFolder);
            List<DocRelative> docRelativeList=docRelativeService.
                    list(new QueryWrapper<DocRelative>()
                            .eq("attribution_type",en.getAttributionType())
                            .eq("attribution_id",en.getAttributionId())
                            .eq("doc_id",en.getDocId()));
            if (docRelativeList.isEmpty()){
                ExceptionCast.cast(ActivitiCode.ACT_APPROVE_ERROR);
            }
            //涉密网进行NC文件的拷贝
            handleFileTransfer(mdcEquipment, docFile);
            //NC文件的拷贝
            handleFileProcessing(docFile, mdcEquipment, secretFolder);
            //对应产品结构树拷贝
            handleProductTree(docInfo,docRelativeList.get(0),mdcEquipment.getEquipmentId());
            return synchronizedFlagService.updateFlag(1);
        }else if(up.getStatus() == 3) {
            //拒绝操作 ä»€ä¹ˆä¹Ÿä¸åš
@@ -579,7 +592,8 @@
    }
    //插入文件传输任务表
    private void handleFileTransfer(MdcEquipment mdcEquipment, DocFile docFile) {
    @Override
    public void handleFileTransfer(MdcEquipment mdcEquipment, DocFile docFile) {
        List<String> strings = iMdcProductionService.findListParentTreeAll(mdcEquipment.getId());
        if (strings != null && !strings.isEmpty()) {
            String path = StringUtils.join(strings.toArray(), "/");
@@ -600,7 +614,6 @@
    //封装处理文件
    private void handleFileProcessing(DocFile docFile, MdcEquipment mdcEquipment, String secretFolder) {
        if (!docFile.getFileSuffix().equals("zip") && !docFile.getFileSuffix().equals("rar")) {
            String size = FileUtilS.fileSizeNC(docFile.getFilePath(), docFile.getFileEncodeName());
            List<String> strings = iMdcProductionService.findListParentTreeAll(mdcEquipment.getId());
            if (strings != null && !strings.isEmpty()) {
                DncPassLog passInfoTxt = new DncPassLog();
@@ -611,23 +624,14 @@
                /*查询最后一条记录*/
                //休眠 500毫秒
                DncPassLog dncPassLog  = dncPassLogService.findDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY));
                int fileTxt = 0, fileNc =0;
                int fileNc =0;
                if (dncPassLog !=null) {
                    fileTxt = dncPassLog.getSequenceNumber() + 1;
                    fileNc = dncPassLog.getSequenceNumber() + 1;
                } else {
                    fileTxt =  1;
                    fileNc =  1;
                }
                fileNc = fileTxt + 1;
                //处理文件名称  æ–‡ä»¶è·¯å¾„
                String sequence = String.format("%06d",fileTxt);
                String sequenceNc = String.format("%06d",fileNc);
                passInfoTxt.setSequenceNumber(fileTxt);
                passInfoTxt.setSequenceOrder(sequence);
                passInfoTxt.setCreateTime(dateFirst);
                System.out.println(DateUtil.format(dateFirst,DateUtil.STR_DATE_TIME));
                passInfoTxt.setPassType("02");
                dncPassLogService.save(passInfoTxt);
                DncPassLog passInfoNc = new DncPassLog();
                passInfoNc.setSequenceNumber(fileNc);
                passInfoNc.setSequenceOrder(sequenceNc);
@@ -642,41 +646,50 @@
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                dncPassLogService.save(passInfoNc);
                NcTxtFilePathInfo ncTxt = new NcTxtFilePathInfo();
                ncTxt.setEquipmentId(mdcEquipment.getEquipmentId());
                ncTxt.setFileNcName("10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)+sequenceNc);
                ncTxt.setFileTxtName("10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)+sequence);
                ncTxt.setFilePath(path + "/" + mdcEquipment.getEquipmentId() + "/");
                ncTxt.setOrigFileName(docFile.getFileName());
                ncTxt.setOrigFileSuffix(docFile.getFileSuffix());
                ncTxt.setFileAddOrDelete(1);
                String loFilePath = secretFolder +"/"+ ncTxt.getFileTxtName() + ".nc";
                try {
                    String allList = ncTxt.getFileTxtName() + "\n"
                            + ncTxt.getFileNcName() + "\n"
                            + ncTxt.getOrigFileName() + "\n"
                            + ncTxt.getOrigFileSuffix() + "\n"
                            + ncTxt.getFilePath() + "\n"
                            + ncTxt.getEquipmentId() + "\n"
                            + ncTxt.getFileAddOrDelete().toString() + "\n"
                            + size + "\n";
                    FileUtilS.fileWriterSql(loFilePath, allList);
                    boolean copyFileNc = FileUtilS.copyFileUpName(path + "/" + mdcEquipment.getEquipmentId() + "/send/" +
                                    docFile.getFileName(),
                            secretFolder +"/"+ncTxt.getFileNcName(),
                            docFile.getFileSuffix(), "NC");
                    if (!copyFileNc) {
                        FileUtilS.deleteNcFile(loFilePath);
                    }
                } catch (IOException e) {
                    throw new RuntimeException("文件处理失败", e);
                }
                FileUtilS.copyFileUpName(path + "/" + mdcEquipment.getEquipmentId() + "/send/" +
                                docFile.getFileName(),
                        secretFolder +"/"+"10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)+sequenceNc+"_"+mdcEquipment.getEquipmentId(),
                        docFile.getFileSuffix(), "NC");
            }
        }
    }
    /**
     * å¤„理对应产品结构树、nc文件、刀具列表、程序加工确认表封装
     * @param docInfo
     */
    private void handleProductTree(DocInfo docInfo,DocRelative docRelative,String equipmentId) {
        /*查询最后一条记录*/
        //休眠 500毫秒
        DncPassLog passInfoTxt = new DncPassLog();
        Date dateFirst = DateUtil.getNow();
        passInfoTxt.setDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY));
        DncPassLog dncPassLog  = dncPassLogService.findDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY));
        int fileTxt = 0, fileNc =0;
        if (dncPassLog !=null) {
            fileTxt = dncPassLog.getSequenceNumber() + 1;
        } else {
            fileTxt =  1;
        }
        String sequence = String.format("%06d",fileTxt);
        passInfoTxt.setSequenceNumber(fileTxt);
        passInfoTxt.setCreateTime(dateFirst);
        passInfoTxt.setSequenceOrder(sequence);
        System.out.println(DateUtil.format(dateFirst,DateUtil.STR_DATE_TIME));
        passInfoTxt.setPassType(DncPassLogPassType.PRODUCTSTRUCTURE.getCode());
        dncPassLogService.save(passInfoTxt);
        String fileName="10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY);
        if (Objects.equals(docInfo.getAttributionType(), DocAttributionTypeEnum.PROCESS.getCode())){
            //工序对应设备类
            String filePath = ferryService.exportData(TransferPackage.DataType.PROCESS, docRelative.getId(),fileName+sequence+"_"+equipmentId+".ferry");
            System.out.println("工序数据已导出: " + filePath);
        }else {
            //工步对应设备类
            String filePath = ferryService.exportData(TransferPackage.DataType.WORKSTEP, docRelative.getId(),fileName+sequence+"_"+equipmentId+".ferry");
            System.out.println("工步数据已导出: " + filePath);
        }
    }
    @Override
    public void afterFlowHandle(FlowMyBusiness business) {
        business.getTaskNameId();//接下来审批的节点
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/entity/EamSecondMaintenanceOrder.java
lxzn-module-eam-common/src/main/java/org/jeecg/modules/eam/entity/EamThirdMaintenanceOrder.java
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/entity/MdcEquipment.java
@@ -164,6 +164,12 @@
    @ApiModelProperty(value = "是否MDC设备")
    private String deviceTypeMdc;
    /**
     * è®¾å¤‡å›¾ç‰‡
     */
    @ApiModelProperty(value = "设备图片")
    private String equipmentImage;
    /**部门名称*/
    @Excel(name = "部门名称", width = 15)
    private transient String orgCodeTxt;
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentMapper.xml
@@ -106,19 +106,34 @@
    <!--查询设备监控信息-->
    <select id="checkStatusFromEquipmentIds" resultType="org.jeecg.modules.mdc.entity.MdcEquipmentMonitor">
        SELECT
            t1.equipment_id,
            t2.CollectTime,
            t1.equipment_name,
            t2.Oporation,
            t1.id,
            t1.equipment_status,
            t1.equipment_type equipmentType,
            t3.equipment_type_pictures
          t1.equipment_id,
          t2.CollectTime,
          t1.equipment_name,
        CASE
            WHEN repair.count > 0 THEN
            '5' ELSE t2.Oporation
          END AS Oporation,
          t1.id,
          t1.equipment_status,
          t1.equipment_type equipmentType,
          t1.equipment_image equipmentTypePictures
        FROM
            mdc_equipment t1
            LEFT JOIN Equipment t2 ON t1.equipment_id = t2.EquipmentID
            LEFT JOIN mdc_equipment_type t3 ON t1.equipment_type = t3.equipment_type_name
        WHERE equipment_id IN
          mdc_equipment t1
          LEFT JOIN Equipment t2 ON t1.equipment_id = t2.EquipmentID
          LEFT JOIN (
            SELECT
              e1.equipment_code,
              COUNT(1) COUNT
            FROM
              eam_report_repair r1
              INNER JOIN eam_equipment e1 ON e1.id = r1.equipment_id
            WHERE
              r1.report_status NOT IN ('COMPLETE', 'ABOLISH')
          GROUP BY
            e1.equipment_code) repair ON repair.equipment_code = t1.equipment_id
        WHERE t1.equipment_id IN
        <foreach collection="equipmentIds" index="index" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
lxzn-module-mdc-common/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentServiceImpl.java
@@ -430,6 +430,9 @@
                        case 22:
                            mdcEquipmentMonitor.setOporationDict("报警");
                            break;
                        case 5:
                            mdcEquipmentMonitor.setOporationDict("故障");
                            break;
                        default:
                            mdcEquipmentMonitor.setOporationDict("关机");
                            break;
@@ -1049,7 +1052,7 @@
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = user.getId();
        if (StringUtils.isNotEmpty(user.getEquipmentIds())) {
            return this.baseMapper.selectList(new LambdaQueryWrapper<MdcEquipment>().eq(MdcEquipment::getEquipmentId, Arrays.asList(user.getEquipmentIds().split(StringPool.COMMA))));
            return this.baseMapper.selectList(new LambdaQueryWrapper<MdcEquipment>().in(MdcEquipment::getEquipmentId, Arrays.asList(user.getEquipmentIds().split(StringPool.COMMA))));
        }
        //获取所有产线数据
        List<MdcProduction> productionList = mdcProductionService.list(new LambdaQueryWrapper<MdcProduction>().eq(MdcProduction::getDelFlag, CommonConstant.DEL_FLAG_0.toString()).orderByAsc(MdcProduction::getProductionOrder));
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/controller/DtBoardController.java
@@ -85,11 +85,19 @@
        return Result.OK(result);
    }
//    @ApiOperation(value = "数字孪生看板-设备故障", notes = "数字孪生看板-设备故障")
//    @GetMapping("/equAlarmList")
//    public Result<?> equAlarmList(@ApiParam(value = "productionId", required = true) String productionId) {
//        dtBoardService.
//    }
    @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);
    }
    @ApiOperation(value = "数字孪生看板-设备安灯信息", notes = "数字孪生看板-设备安灯信息")
    @GetMapping("/equAndonList")
    public Result<?> equAndonList(@ApiParam(value = "productionId", required = true) String productionId) {
        List<EquAndon> result = dtBoardService.equAndonList(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
@@ -27,4 +27,9 @@
    List<EquDowntimeInfo> equDowntimeStatistics(String productionId);
    List<EquAlarm> equAlarmList(String productionId);
    List<EquRepair> equRepairList(String productionId);
    List<EquAndon> equAndonList(String productionId);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/service/impl/DtBoardServiceImpl.java
@@ -5,8 +5,10 @@
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.*;
@@ -14,12 +16,15 @@
import org.jeecg.modules.system.entity.MdcProduction;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
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;
@@ -63,6 +68,12 @@
    @Resource
    private IMdcAlarmInfoService mdcAlarmInfoService;
    @Resource
    private DtBoardMapper dtBoardMapper;
    @Resource
    private IAndonOrderService andonOrderService;
    /**
     * è½¦é—´ä¿¡æ¯
@@ -319,7 +330,7 @@
        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"));
        List<EquipmentAlarm> equipmentAlarmList = equipmentAlarmService.equAlarmList(equipmentIdList);
        if (equipmentAlarmList == null || equipmentAlarmList.isEmpty()) {
            return null;
        }
@@ -337,4 +348,40 @@
        return result;
    }
    /**
     * è®¾å¤‡æ•…éšœ
     */
    @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;
    }
    /**
     * è®¾å¤‡å®‰ç¯é—®é¢˜
     */
    @Override
    public List<EquAndon> equAndonList(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;
        }
        List<EquAndon> result = andonOrderService.equAndonList(equipmentIdList);
        return result;
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/board/vo/EquAndon.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package org.jeecg.modules.board.vo;
import lombok.Data;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-12
 * @Description: å®‰ç¯ä¿¡æ¯
 */
@Data
public class EquAndon {
    /**
     * è®¾å¤‡ç¼–号
     */
    private String equipmentId;
    /**
     * å®‰ç¯é—®é¢˜
     */
    private String andonInfo;
}
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/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
@@ -16,55 +16,56 @@
/**
 * @Description: mdc_equipment_punch
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Date: 2025-06-09
 * @Version: V1.0
 */
@Api(tags="上下班打卡记录表")
@Api(tags = "上下班打卡记录表")
@RestController
@RequestMapping("/mdcEquipmentPunch")
@Slf4j
public class MdcEquipmentPunchController extends JeecgController<MdcEquipmentPunch, IMdcEquipmentPunchService> {
    @Autowired
    private IMdcEquipmentPunchService mdcEquipmentPunchService;
    @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());
    }
    private static final String msg = "打卡成功!";
    /**
     *   ä¸Šç­æ‰“卡
     *
     * @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);
    }
    /**
     * æŸ¥è¯¢å½“前登录人所负责设备打卡情况
     *
     * @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 = "/workDown")
    public Result<String> workDown(@RequestBody MdcEquipmentPunch mdcEquipmentPunch) {
        mdcEquipmentPunchService.workDown(mdcEquipmentPunch);
        return Result.OK(msg);
    }
    /**
     * ä¸Šç­æ‰“卡
     *
     * @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/controller/MdcEquipmentPunchRateController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package org.jeecg.modules.mdc.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.common.system.query.QueryGenerator;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunchRate;
import org.jeecg.modules.mdc.service.IMdcEquipmentPunchRateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
 * @Description: mdc_equipment_punch_rate
 * @Author: jeecg-boot
 * @Date: 2025-06-09
 * @Version: V1.0
 */
@Api(tags = "设备打卡率报表")
@RestController
@RequestMapping("/mdcEquipmentPunchRate")
@Slf4j
public class MdcEquipmentPunchRateController extends JeecgController<MdcEquipmentPunchRate, IMdcEquipmentPunchRateService> {
    @Autowired
    private IMdcEquipmentPunchRateService mdcEquipmentPunchService;
    /**
     * åˆ†é¡µåˆ—表查询
     *
     * @param mdEquipmentPunch æŸ¥è¯¢å‚æ•°
     * @param pageNo           å½“前页码
     * @param pageSize         æ¯é¡µæ¡æ•°
     * @param req              è¯·æ±‚对象
     * @return
     */
    @ApiOperation(value = "设备打卡率-分页列表查询", notes = "设备打卡率-分页列表查询")
    @AutoLog(value = "设备打卡率-分页列表查询")
    @GetMapping(value = "/queryPageList")
    public Result<IPage<MdcEquipmentPunchRate>> queryPageList(MdcEquipmentPunchRate mdEquipmentPunch,
                                                          @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                          @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                          HttpServletRequest req) {
        QueryWrapper<MdcEquipmentPunchRate> queryWrapper = QueryGenerator.initQueryWrapper(mdEquipmentPunch, req.getParameterMap());
        Page<MdcEquipmentPunchRate> page = new Page<MdcEquipmentPunchRate>(pageNo, pageSize);
        IPage<MdcEquipmentPunchRate> pageList = mdcEquipmentPunchService.page(page, queryWrapper);
        return Result.OK(pageList);
    }
    /**
     * å¯¼å‡ºexcel
     *
     * @param request
     * @param mdcEquipmentPunchRate
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, MdcEquipmentPunchRate mdcEquipmentPunchRate) {
        return super.exportXls(request, mdcEquipmentPunchRate, MdcEquipmentPunchRate.class, "设备打卡率报表");
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/dto/MdcEquipmentPunchExportDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,98 @@
package org.jeecg.modules.mdc.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecg.common.aspect.annotation.Dict;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class MdcEquipmentPunchExportDTO {
    @ApiModelProperty(value = "设备编号")
    private String equipmentId;
    @ApiModelProperty(value = "打卡用户")
    @Dict(dicCode = "id", dictTable = "sys_user", dicText = "realname")
    private String punchUser;
    @ApiModelProperty(value = "上班时间")
    private Date checkInTime;
    /**
     * ä¸‹ç­æ—¶é—´
     */
    @ApiModelProperty(value = "下班时间")
    private Date checkOutTime;
    /**
     * è®°å½•日期
     */
    @ApiModelProperty(value = "记录日期")
    private String recordDate;
    @ApiModelProperty(value = "班次")
    @Dict(dicCode = "shift_schedule")
    private Integer shiftSchedule;
    @ApiModelProperty(value = "是否缺卡")
    private Integer isAbsent;
    @ApiModelProperty(value = "是否迟到")
    private Integer isLate;
    @ApiModelProperty(value = "是否早退")
    private Integer isEarly;
    /**
     * æ—©ç­ä¸Šç­æ‰“卡率
     */
    @ApiModelProperty(value = "早班上班打卡率")
    private BigDecimal morningShiftInRate;
    /**
     * æ™šç­ä¸Šç­æ‰“卡率
     */
    @ApiModelProperty(value = "晚班上班打卡率")
    private BigDecimal eveningShiftInRate;
    @ApiModelProperty(value = "早班下班打卡率")
    private BigDecimal morningShiftOutRate;
    @ApiModelProperty(value = "晚班下班打卡率")
    private BigDecimal eveningShiftOutRate;
    @ApiModelProperty(value = "白班上班打卡设备数量")
    private Integer morningShiftInDeviceNum;
    @ApiModelProperty(value = "白班下班打卡设备数量")
    private Integer morningShiftOutDeviceNum;
    @ApiModelProperty(value = "夜班上班打卡设备数量")
    private Integer eveningShiftInDeviceNum;
    @ApiModelProperty(value = "夜班下班打卡设备数量")
    private Integer eveningShiftOutDeviceNum;
    @ApiModelProperty(value = "设备总数")
    private Integer deviceCountNum;
    private String punchUserRealName;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/AndonOrder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,167 @@
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.jeecg.common.constant.CommonConstant;
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 = "安灯类型")
    @Dict(dicCode = "andon_type")
    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 = "安灯状态;待响应、待处理、已完成")
    @Dict(dicCode = "order_status")
    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 = CommonConstant.DEL_FLAG_0;
    /**
     * åˆ›å»ºäºº
     */
    @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
@@ -1,22 +1,24 @@
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.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
 * @Description: mdc_equipment_punch
@@ -29,7 +31,7 @@
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "mdc_equipment_punch对象", description = "mdc_equipment_punch")
public class MdcEquipmentPunch implements Serializable {
public class MdcEquipmentPunch extends JeecgEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
@@ -49,18 +51,18 @@
     */
    @Excel(name = "打卡用户", width = 15)
    @ApiModelProperty(value = "打卡用户")
    @Dict(dicCode = "id", dictTable = "sys_user", dicText = "realname")
    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;
@@ -87,7 +89,7 @@
    @ApiModelProperty(value = "记录日期")
    private String recordDate;
    /**
     * ç­æ¬¡
     *  ç­æ¬¡
     */
    @Excel(name = "班次", width = 15)
    @ApiModelProperty(value = "班次")
@@ -107,7 +109,7 @@
    @ApiModelProperty(value = "是否缺卡")
    private Integer isAbsent;
    /**
     * æ˜¯å¦è¿Ÿåˆ°
     * æ˜¯å¦è¿Ÿåˆ°ï¼ˆ0未早退,1早退)
     */
    @Excel(name = "是否迟到", width = 15)
    @ApiModelProperty(value = "是否迟到")
@@ -118,28 +120,74 @@
    @Excel(name = "是否早退", width = 15)
    @ApiModelProperty(value = "是否早退")
    private Integer isEarly;
    /**
     * åˆ›å»ºäºº
     * æ—©ç­ä¸Šç­æ‰“卡率
     */
    @ApiModelProperty(value = "创建人")
    private String createBy;
    @TableField(exist = false)
    @Excel(name = "早班上班打卡率", width = 15)
    @ApiModelProperty(value = "早班上班打卡率")
    private BigDecimal morningShiftInRate;
    /**
     * åˆ›å»ºæ—¶é—´
     * æ™šç­ä¸Šç­æ‰“卡率
     */
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "创建时间")
    private Date createTime;
    @TableField(exist = false)
    @Excel(name = "晚班上班打卡率", width = 15)
    @ApiModelProperty(value = "晚班上班打卡率")
    private BigDecimal eveningShiftInRate;
    /**
     * æ›´æ–°äºº
     * æ—©ç­ä¸‹ç­æ‰“卡率
     */
    @ApiModelProperty(value = "更新人")
    private String updateBy;
    @TableField(exist = false)
    @Excel(name = "早班下班打卡率", width = 15)
    @ApiModelProperty(value = "早班下班打卡率")
    private BigDecimal morningShiftOutRate;
    /**
     * æ›´æ–°æ—¶é—´
     * æ™šç­ä¸‹ç­æ‰“卡率
     */
    @JsonFormat(timezone = "GMT+8", pattern = DatePattern.NORM_DATETIME_PATTERN)
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    @ApiModelProperty(value = "更新时间")
    private Date updateTime;
    @TableField(exist = false)
    @Excel(name = "晚班下班打卡率", width = 15)
    @ApiModelProperty(value = "晚班下班打卡率")
    private BigDecimal eveningShiftOutRate;
    /**
     * ç™½ç­ä¸Šç­æ‰“卡设备数量
     */
    @TableField(exist = false)
    @Excel(name = "白班上班打卡设备数量", width = 15)
    @ApiModelProperty(value = "白班上班打卡设备数量")
    private Integer morningShiftInDeviceNum;
    /**
     * ç™½ç­ä¸‹ç­æ‰“卡设备数量
     */
    @TableField(exist = false)
    @Excel(name = "白班下班打卡设备数量", width = 15)
    @ApiModelProperty(value = "白班下班打卡设备数量")
    private Integer morningShiftOutDeviceNum;
    /**
     * å¤œç­ä¸Šç­æ‰“卡设备数量
     */
    @TableField(exist = false)
    @Excel(name = "夜班上班打卡设备数量", width = 15)
    @ApiModelProperty(value = "夜班上班打卡设备数量")
    private Integer eveningShiftInDeviceNum;
    /**
     * å¤œç­ä¸‹ç­æ‰“卡设备数量
     */
    @TableField(exist = false)
    @Excel(name = "夜班下班打卡设备数量", width = 15)
    @ApiModelProperty(value = "夜班下班打卡设备数量")
    private Integer eveningShiftOutDeviceNum;
    /**
     * è®¾å¤‡æ€»æ•°
     */
    @TableField(exist = false)
    @Excel(name = "设备总数", width = 15)
    @ApiModelProperty(value = "设备总数")
    private Integer deviceCountNum;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/entity/MdcEquipmentPunchRate.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,129 @@
package org.jeecg.modules.mdc.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
import java.math.BigDecimal;
/**
 * @Description: mdc_equipment_punch_rate
 * @Author: jeecg-boot
 * @Date: 2025-06-09
 * @Version: V1.0
 */
@Data
@TableName("mdc_equipment_punch_rate")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "mdc_equipment_punch_rate对象", description = "mdc_equipment_punch_rate")
public class MdcEquipmentPunchRate extends JeecgEntity 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 theDate;
    /**
     * ç­æ¬¡
     */
    @Excel(name = "班次", width = 15)
    @ApiModelProperty(value = "班次")
    @Dict(dicCode = "shift_schedule")
    private Integer shiftSchedule;
    /**
     * æ—©ç­ä¸Šç­æ‰“卡率
     */
    @Excel(name = "早班上班打卡率(%)", width = 15)
    @ApiModelProperty(value = "早班上班打卡率")
    private BigDecimal mornShiftInRate;
    /**
     * æ™šç­ä¸Šç­æ‰“卡率
     */
    @Excel(name = "晚班上班打卡率(%)", width = 15)
    @ApiModelProperty(value = "晚班上班打卡率")
    private BigDecimal evenShiftInRate;
    /**
     * æ—©ç­ä¸‹ç­æ‰“卡率
     */
    @Excel(name = "早班下班打卡率(%)", width = 15)
    @ApiModelProperty(value = "早班下班打卡率")
    private BigDecimal mornShiftOutRate;
    /**
     * æ™šç­ä¸‹ç­æ‰“卡率
     */
    @Excel(name = "晚班下班打卡率(%)", width = 15)
    @ApiModelProperty(value = "晚班下班打卡率")
    private BigDecimal evenShiftOutRate;
    /**
     * ç™½ç­ä¸Šç­æ‰“卡设备数量
     */
    @Excel(name = "白班上班打卡设备数量", width = 15)
    @ApiModelProperty(value = "白班上班打卡设备数量")
    private Integer mornShiftInNum;
    /**
     * ç™½ç­ä¸‹ç­æ‰“卡设备数量
     */
    @Excel(name = "白班下班打卡设备数量", width = 15)
    @ApiModelProperty(value = "白班下班打卡设备数量")
    private Integer mornShiftOutNum;
    /**
     * å¤œç­ä¸Šç­æ‰“卡设备数量
     */
    @Excel(name = "夜班上班打卡设备数量", width = 15)
    @ApiModelProperty(value = "夜班上班打卡设备数量")
    private Integer evenShiftInNum;
    /**
     * å¤œç­ä¸‹ç­æ‰“卡设备数量
     */
    @Excel(name = "夜班下班打卡设备数量", width = 15)
    @ApiModelProperty(value = "夜班下班打卡设备数量")
    private Integer evenShiftOutNum;
    /**
     * è®¾å¤‡æ€»æ•°
     */
    @Excel(name = "设备总数", width = 15)
    @ApiModelProperty(value = "设备总数")
    private Integer deviceCountNum;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/DailyPunchRateJob.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,108 @@
package org.jeecg.modules.mdc.job;
import cn.hutool.core.date.DatePattern;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunch;
import org.jeecg.modules.mdc.service.IMdcEquipmentPunchRateService;
import org.jeecg.modules.mdc.service.IMdcEquipmentPunchService;
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.ISysAnnouncementService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
/**
 * @Description: æ¯æ—¥å‡Œæ™¨å®šæ—¶è®¡ç®—前一天的设备打卡率,并入库
 * @Author: Lius
 * @CreateTime: 2025-06-12
 */
@Slf4j
public class DailyPunchRateJob implements Job {
    private String parameter; // å¯é€‰å‚数:指定日期(如 "2025-06-11")
    public void setParameter(String parameter) {
        this.parameter = parameter;
    }
    @Resource
    private IQuartzJobService quartzJobService;
    @Resource
    private ISysQuartzLogService sysQuartzLogService;
    @Resource
    private ISysAnnouncementService sysAnnouncementService;
    @Resource
    private IMdcEquipmentPunchService mdcEquipmentPunchService;
    @Resource
    private IMdcEquipmentPunchRateService mdcEquipmentPunchRateService;
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        SysQuartzLog quartzLog = new SysQuartzLog();
        quartzLog.setCreateTime(new Date());
        List<QuartzJob> jobList = this.quartzJobService.findByJobClassName(this.getClass().getName());
        if (jobList != null && !jobList.isEmpty()) {
            quartzLog.setJobId(jobList.get(0).getId());
        }
        log.info("【开始执行每日设备打卡率统计任务】");
        long startTime = System.currentTimeMillis();
        try {
            String yesterdayStr;
            if (parameter != null && !parameter.isEmpty()) {
                yesterdayStr = parameter; // æ”¯æŒæ‰‹åŠ¨ä¼ å‚
            } else {
                LocalDate yesterday = LocalDate.now().minusDays(1);
                 yesterdayStr = yesterday.format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATE_PATTERN)); // æ ¼å¼åŒ–为 "yyyy-MM-dd"
            }
            log.info("✅ æˆåŠŸå®Œæˆæ¯æ—¥è®¾å¤‡æ‰“å¡çŽ‡ç»Ÿè®¡æ•°æ®", yesterdayStr);
            // Step 1:获取昨日打卡数据
            List<MdcEquipmentPunch> punchRecords = mdcEquipmentPunchService.getYesterdayRecords(yesterdayStr);
            log.info("✅ æˆåŠŸå®Œæˆæ¯æ—¥è®¾å¤‡æ‰“å¡çŽ‡ç»Ÿè®¡æ•°æ®", punchRecords);
            if (punchRecords == null || punchRecords.isEmpty()) {
                log.warn("⚠️ æ²¡æœ‰æ‰¾åˆ°æ˜¨æ—¥è®¾å¤‡æ‰“卡数据");
                quartzLog.setIsSuccess(0);
                return;
            }
            // Step 2:保存到打卡率表
            mdcEquipmentPunchRateService.savePunchRates(yesterdayStr, punchRecords);
            quartzLog.setIsSuccess(0);
            log.info("✅ æˆåŠŸå®Œæˆæ¯æ—¥è®¾å¤‡æ‰“å¡çŽ‡ç»Ÿè®¡ï¼Œå…±å¤„ç† {} æ¡è®°å½•,日期:{}", punchRecords.size(), yesterdayStr);
        } catch (Exception e) {
            quartzLog.setIsSuccess(-1);
            quartzLog.setExceptionDetail(e.getMessage());
            log.error("❌ è®¾å¤‡æ‰“卡率统计任务执行失败", e);
            sysAnnouncementService.jobSendMessage("设备打卡率统计任务", e.getMessage());
        }
        // è®°å½•执行时间
        long endTime = System.currentTimeMillis();
        quartzLog.setExecutionTime((int)(endTime - startTime));
        sysQuartzLogService.save(quartzLog);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/AndonOrderMapper.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.AndonOrder;
import java.util.List;
/**
 * @Description: andon_order
 * @Author: jeecg-boot
 * @Date:   2025-06-11
 * @Version: V1.0
 */
public interface AndonOrderMapper extends BaseMapper<AndonOrder> {
    List<AndonOrder> equAndonList(@Param("equipmentIdList") List<String> equipmentIdList);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentAlarmMapper.java
@@ -1,11 +1,15 @@
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.EquipmentAlarm;
import java.util.List;
/**
 * @author: LiuS
 * @create: 2023-04-12 16:39
 */
public interface EquipmentAlarmMapper extends BaseMapper<EquipmentAlarm> {
    List<EquipmentAlarm> equAlarmList(@Param("equipmentIdList") List<String> equipmentIdList);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcEquipmentPunchMapper.java
@@ -15,4 +15,22 @@
public interface MdcEquipmentPunchMapper extends BaseMapper<MdcEquipmentPunch> {
    List<MdcEquipmentPunch> list(@Param("equipmentIds") List<String> equipmentIds, @Param("date") String date);
    // æŸ¥è¯¢æ—©ç­ä¸Šç­æ‰“卡设备数
    int countMorningShiftIn(@Param("date") String date);
    // æŸ¥è¯¢æ™šç­ä¸Šç­æ‰“卡设备数
    int countEveningShiftIn(@Param("date") String date);
    // æŸ¥è¯¢æ—©ç­ä¸‹ç­æ‰“卡设备数
    int countMorningShiftOut(@Param("date") String date);
    // æŸ¥è¯¢æ™šç­ä¸‹ç­æ‰“卡设备数
    int countEveningShiftOut(@Param("date") String date);
    /**
     * èŽ·å–æ‰€æœ‰è®¾å¤‡æ•°
     */
    int getTotalDeviceCount();
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/MdcEquipmentPunchRateMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package org.jeecg.modules.mdc.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunchRate;
/**
 * @Description: mdc_equipment_punch_rate
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
public interface MdcEquipmentPunchRateMapper extends BaseMapper<MdcEquipmentPunchRate> {
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/AndonOrderMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
<?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">
    <select id="equAndonList" resultType="org.jeecg.modules.mdc.entity.AndonOrder">
        SELECT
            *
        FROM
            andon_order
        WHERE
            CONVERT ( DATE, create_time ) = CONVERT ( DATE, GETDATE( ) )
          AND equipment_id IN
        <foreach collection="equipmentIdList" index="index" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
        ORDER BY
            create_time
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentAlarmMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
<?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.EquipmentAlarmMapper">
    <select id="equAlarmList" resultType="org.jeecg.modules.mdc.entity.EquipmentAlarm">
        SELECT TOP 15 *
        FROM
            EquipmentAlarm
        WHERE EquipmentID IN
        <foreach collection="equipmentIdList" index="index" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
        AND alarmNo != ''
        ORDER BY collecttime DESC
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcDowntimeMapper.xml
@@ -44,7 +44,7 @@
    <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
            SUM ( DATEDIFF( SECOND, t1.start_date, t1.end_date ) ) / 3600.0 AS duration
        FROM
            mdc_downtime t1
                LEFT JOIN mdc_downtime_reason t2 ON t1.reason_id = t2.id
@@ -57,7 +57,5 @@
        </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/MdcDowntimeOperatorMapper.xml
@@ -9,6 +9,6 @@
            t2.downtime_description downtimeDescription
        FROM mdc_downtime t1 LEFT JOIN mdc_downtime_reason t2 ON t1.reason_id = t2.id
        ${ew.customSqlSegment}
        ORDER BY t1.create_time DESC
        ORDER BY t1.equipment_id DESC, t1.start_date ASC
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentPunchMapper.xml
@@ -4,31 +4,31 @@
    <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
        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)
        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=",">
@@ -39,4 +39,47 @@
        </if>
        order by p.equipment_id desc, p.shift_schedule asc
    </select>
    <!--查询所有设备数量-->
    <select id="getTotalDeviceCount" resultType="int">
        SELECT COUNT(*)
        FROM mdc_equipment
    </select>
    <!-- æ—©ç­ ä¸Šç­æ‰“卡 -->
    <select id="countMorningShiftIn" resultType="int">
        SELECT COUNT(DISTINCT equipment_id)
        FROM mdc_equipment_punch
        WHERE record_date = #{date, jdbcType=VARCHAR}
          AND shift_schedule = '1'
          AND check_in_time IS NOT NULL
    </select>
    <!-- æ™šç­ ä¸Šç­æ‰“卡 -->
    <select id="countEveningShiftIn" resultType="int">
        SELECT COUNT(DISTINCT equipment_id)
        FROM mdc_equipment_punch
        WHERE record_date = #{date, jdbcType=VARCHAR}
          AND shift_schedule = '2'
          AND check_in_time IS NOT NULL
    </select>
    <!-- æ—©ç­ ä¸‹ç­æ‰“卡 -->
    <select id="countMorningShiftOut" resultType="int">
        SELECT COUNT(DISTINCT equipment_id)
        FROM mdc_equipment_punch
        WHERE record_date = #{date, jdbcType=VARCHAR}
          AND shift_schedule = '1'
          AND check_out_time IS NOT NULL
    </select>
    <!-- æ™šç­ ä¸‹ç­æ‰“卡 -->
    <select id="countEveningShiftOut" resultType="int">
        SELECT COUNT(DISTINCT equipment_id)
        FROM mdc_equipment_punch
        WHERE record_date = #{date, jdbcType=VARCHAR}
          AND shift_schedule = '2'
          AND check_out_time IS NOT NULL
    </select>
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcEquipmentPunchRateMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
<?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.MdcEquipmentPunchRateMapper">
</mapper>
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/MdcWorkshopInfoMapper.xml
@@ -9,8 +9,12 @@
            a.EquipmentID equipmentId,
            me.equipment_name equipmentName,
            me.equipment_type equipmentType,
            met.equipment_type_pictures equipmentImage,
            a.Oporation equipmentStatus,
            me.equipment_image equipmentImage,
            CASE
                WHEN repair.count > 0 THEN
                    '5' ELSE a.Oporation
                END AS equipmentStatus,
            mew.coordinate_left coordinateLeft,
            mew.coordinate_top coordinateTop,
            mew.vw vw,
@@ -24,6 +28,17 @@
            INNER JOIN mdc_equipment_type met ON me.equipment_type = met.equipment_type_name
            AND a.CollectTime= b.maxgdtime
            AND mew.workshop_id = #{ workshopId }
            LEFT JOIN (
                SELECT
                    e1.equipment_code,
                    COUNT(1) COUNT
                FROM
                    eam_report_repair r1
                    INNER JOIN eam_equipment e1 ON e1.id = r1.equipment_id
                WHERE
                    r1.report_status NOT IN ('COMPLETE', 'ABOLISH')
                GROUP BY
                    e1.equipment_code) repair ON repair.equipment_code = me.equipment_id
    </select>
    <select id="listByUser" resultType="org.jeecg.modules.mdc.entity.MdcWorkshopInfo">
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IAndonOrderService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package org.jeecg.modules.mdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.board.vo.EquAndon;
import org.jeecg.modules.mdc.entity.AndonOrder;
import java.util.List;
/**
 * @Description: andon_order
 * @Author: jeecg-boot
 * @Date:   2025-06-11
 * @Version: V1.0
 */
public interface IAndonOrderService extends IService<AndonOrder> {
    void procedureCall(AndonOrder andonOrder);
    List<EquAndon> equAndonList(List<String> equipmentIdList);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentAlarmService.java
@@ -12,4 +12,6 @@
 */
public interface IEquipmentAlarmService extends IService<EquipmentAlarm> {
    List<EquipmentAlarm> findEquipmentAlarmByDate(String equipmentId, Date startTime, Date endTime);
    List<EquipmentAlarm> equAlarmList(List<String> equipmentIdList);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentPunchRateService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package org.jeecg.modules.mdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunch;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunchRate;
import java.util.List;
/**
 * @Description: mdc_equipment_punch
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
public interface IMdcEquipmentPunchRateService extends IService<MdcEquipmentPunchRate> {
    void savePunchRates(String targetDate, List<MdcEquipmentPunch> punchRecords);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcEquipmentPunchService.java
@@ -18,4 +18,10 @@
    void workUp(MdcEquipmentPunch mdcEquipmentPunch);
    void workDown(MdcEquipmentPunch mdcEquipmentPunch);
    void fillPunchRates(List<MdcEquipmentPunch> punchList);
    /**
     * æŸ¥è¯¢æŒ‡å®šæ—¥æœŸçš„设备打卡数据(通常是昨天)
     */
    List<MdcEquipmentPunch> getYesterdayRecords(String targetDate);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/AndonOrderServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,125 @@
package org.jeecg.modules.mdc.service.impl;
import cn.hutool.core.date.DatePattern;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.common.util.TranslateDictTextUtils;
import org.jeecg.modules.board.vo.EquAndon;
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.ISysDictService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
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;
    @Resource
    private ISysDictService sysDictService;
    @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.setOrderStatus(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.setRepairTime(StringPool.EMPTY);
                andonOrderWebSocketVo.setFaultInfo(StringPool.EMPTY);
                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());
        }
    }
    /**
     * å®‰ç¯é—®é¢˜åˆ—表
     */
    @Override
    public List<EquAndon> equAndonList(List<String> equipmentIdList) {
        List<EquAndon> result = new ArrayList<>();
        List<AndonOrder> andonOrderList = this.baseMapper.equAndonList(equipmentIdList);
        if (andonOrderList != null && !andonOrderList.isEmpty()) {
            andonOrderList.forEach(andonOrder -> {
                EquAndon equAndon = new EquAndon();
                equAndon.setEquipmentId(andonOrder.getEquipmentId());
                StringBuilder infoBuilder = new StringBuilder();
                infoBuilder.append("安灯类型: ").append(sysDictService.queryDictTextByKey("andon_type",andonOrder.getAndonType())).append("\n");
                infoBuilder.append("安灯人: ").append(sysDictService.queryTableDictTextByKey("sys_user", "realname", "id", andonOrder.getOperator())).append("\n");
                infoBuilder.append("安灯时间: ").append(DateUtils.format(andonOrder.getOperateTime(), DateUtils.STR_DATE_TIME_SMALL)).append("\n");
                infoBuilder.append("安灯状态: ").append(sysDictService.queryDictTextByKey("order_status",andonOrder.getOrderStatus())).append("\n");
                equAndon.setAndonInfo(infoBuilder.toString());
                result.add(equAndon);
            });
        }
        return result;
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentAlarmServiceImpl.java
@@ -7,6 +7,7 @@
import org.jeecg.modules.mdc.service.IEquipmentAlarmService;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@@ -22,4 +23,9 @@
                .ge(EquipmentAlarm::getCollecttime, startTime).le(EquipmentAlarm::getCollecttime, endTime)
                .eq(EquipmentAlarm::getEquipmentid, equipmentId).orderByDesc(EquipmentAlarm::getCollecttime));
    }
    @Override
    public List<EquipmentAlarm> equAlarmList(List<String> equipmentIdList) {
        return this.baseMapper.equAlarmList(equipmentIdList);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentPunchRateServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package org.jeecg.modules.mdc.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunch;
import org.jeecg.modules.mdc.entity.MdcEquipmentPunchRate;
import org.jeecg.modules.mdc.mapper.MdcEquipmentPunchMapper;
import org.jeecg.modules.mdc.mapper.MdcEquipmentPunchRateMapper;
import org.jeecg.modules.mdc.service.IMdcEquipmentPunchRateService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.UUID;
/**
 * @Description: mdc_equipment_punch
 * @Author: jeecg-boot
 * @Date:   2025-06-09
 * @Version: V1.0
 */
@Service
public class MdcEquipmentPunchRateServiceImpl extends ServiceImpl<MdcEquipmentPunchRateMapper, MdcEquipmentPunchRate> implements IMdcEquipmentPunchRateService {
    @Resource
    private MdcEquipmentPunchRateMapper mdcEquipmentPunchRateMapper;
    @Resource
    private MdcEquipmentPunchMapper mdcEquipmentPunchMapper;
    @Override
    public void savePunchRates(String targetDate, List<MdcEquipmentPunch> punchRecords) {
        int morningIn = mdcEquipmentPunchMapper.countMorningShiftIn(targetDate);
        int eveningIn = mdcEquipmentPunchMapper.countEveningShiftIn(targetDate);
        int morningOut = mdcEquipmentPunchMapper.countMorningShiftOut(targetDate);
        int eveningOut = mdcEquipmentPunchMapper.countEveningShiftOut(targetDate);
        for (MdcEquipmentPunch punch : punchRecords) {
            MdcEquipmentPunchRate rate = new MdcEquipmentPunchRate();
            rate.setId(UUID.randomUUID().toString()); // ç”Ÿæˆå”¯ä¸€ID
            rate.setEquipmentId(punch.getEquipmentId());
            rate.setTheDate(targetDate);
            rate.setShiftSchedule(punch.getShiftSchedule());
            // è®¾ç½®è®¾å¤‡æ•°é‡
            rate.setMornShiftInNum(morningIn);
            rate.setMornShiftOutNum(eveningIn);
            rate.setEvenShiftInNum(morningOut);
            rate.setEvenShiftOutNum(eveningOut);
            // èŽ·å–æ€»è®¾å¤‡æ•°
            int totalDevices = mdcEquipmentPunchMapper.getTotalDeviceCount();
            if (totalDevices == 0) return;
            rate.setDeviceCountNum(totalDevices);
            // è®¡ç®—打卡率(保留两位小数)
            rate.setMornShiftInRate(calculateRate(morningIn, totalDevices));
            rate.setMornShiftOutRate(calculateRate(eveningIn, totalDevices));
            rate.setEvenShiftInRate(calculateRate(morningOut, totalDevices));
            rate.setEvenShiftOutRate(calculateRate(eveningOut, totalDevices));
            this.save(rate);
        }
    }
    private BigDecimal calculateRate(int actual, int total) {
        if (total == 0) return BigDecimal.ZERO;
        return new BigDecimal(actual)
                .divide(new BigDecimal(total), 4, RoundingMode.DOWN)
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.DOWN); // ä¿ç•™ä¸¤ä½å°æ•°ï¼Œä¸è¿›è¡Œå››èˆäº”å…¥
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcEquipmentPunchServiceImpl.java
@@ -3,6 +3,7 @@
import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -19,6 +20,10 @@
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@@ -30,7 +35,8 @@
 */
@Service
public class MdcEquipmentPunchServiceImpl extends ServiceImpl<MdcEquipmentPunchMapper, MdcEquipmentPunch> implements IMdcEquipmentPunchService {
    @Resource
    private MdcEquipmentPunchMapper mdcEquipmentPunchMapper;
    @Resource
    private IMdcEquipmentService mdcEquipmentService;
@@ -136,13 +142,16 @@
            MdcEquipmentPunch equipmentPunch = new MdcEquipmentPunch();
            if (first.isPresent()) {
                equipmentPunch = first.get();
                //已存在记录说明已打下班卡,故将是否缺卡置为否
                equipmentPunch.setIsAbsent(0);
            }else {
                equipmentPunch.setEquipmentId(equipment);
                equipmentPunch.setPunchUser(userId);
                equipmentPunch.setRecordDate(currentDate);
                equipmentPunch.setShiftSchedule(mdcEquipmentPunch.getShiftSchedule());
                equipmentPunch.setIsAbsent(0);
                equipmentPunch.setIsEarly(0);
                //正常打卡时先将是否缺卡置为“是”,防止未打下班卡时无法调整状态
                equipmentPunch.setIsAbsent(1);
            }
            equipmentPunch.setCheckInTime(mdcEquipmentPunch.getCheckInTime());
            //打卡时间大于8:30/17:00时为迟到打卡
@@ -214,6 +223,7 @@
            MdcEquipmentPunch equipmentPunch = new MdcEquipmentPunch();
            if (mdcEquipmentPunchOptional.isPresent()) {
                equipmentPunch = mdcEquipmentPunchOptional.get();
                equipmentPunch.setIsAbsent(0);
            }else {
                equipmentPunch.setIsAbsent(1);
                equipmentPunch.setIsLate(0);
@@ -231,4 +241,59 @@
        this.saveOrUpdateBatch(list);
    }
    @Override
    public void fillPunchRates(List<MdcEquipmentPunch> punchList) {
        // èŽ·å–æ˜¨å¤©æ—¥æœŸ
        LocalDate yesterday = LocalDate.now().minusDays(1);
        String yesterdayStr = yesterday.format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATE_PATTERN)); // æ ¼å¼åŒ–为 "yyyy-MM-dd"
        // èŽ·å–æ€»è®¾å¤‡æ•°
        int totalDevices = mdcEquipmentPunchMapper.getTotalDeviceCount();
        if (totalDevices == 0) return;
        // ç»Ÿè®¡å„类型打卡人数
        int morningIn = mdcEquipmentPunchMapper.countMorningShiftIn(yesterdayStr);
        int eveningIn = mdcEquipmentPunchMapper.countEveningShiftIn(yesterdayStr);
        int morningOut = mdcEquipmentPunchMapper.countMorningShiftOut(yesterdayStr);
        int eveningOut = mdcEquipmentPunchMapper.countEveningShiftOut(yesterdayStr);
        // è®¾ç½®æ‰“卡率到每个 DTO
        for (MdcEquipmentPunch dto : punchList) {
            dto.setMorningShiftInRate(calculateRate(morningIn, totalDevices));
            dto.setEveningShiftInRate(calculateRate(eveningIn, totalDevices));
            dto.setMorningShiftOutRate(calculateRate(morningOut, totalDevices));
            dto.setEveningShiftOutRate(calculateRate(eveningOut, totalDevices));
            // è®¾ç½®æ‰“卡设备数量字段
            dto.setMorningShiftInDeviceNum(morningIn);
            dto.setMorningShiftOutDeviceNum(morningOut);
            dto.setEveningShiftInDeviceNum(eveningIn);
            dto.setEveningShiftOutDeviceNum(eveningOut);
            dto.setDeviceCountNum(totalDevices);
        }
    }
    // è®¡ç®—百分比并保留两位小数
    private BigDecimal calculateRate(int actual, int total) {
        if (total == 0) return BigDecimal.ZERO;
        return new BigDecimal(actual)
                .divide(new BigDecimal(total), 4, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100))
                .setScale(2, RoundingMode.HALF_UP); // ä¿ç•™ä¸¤ä½å°æ•°
    }
    @Override
    public List<MdcEquipmentPunch> getYesterdayRecords(String  targetDate) {
        // æž„造查询条件:record_date = targetDate.toString()
        QueryWrapper<MdcEquipmentPunch> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("record_date", targetDate);
        // æ‰§è¡ŒæŸ¥è¯¢å¹¶è¿”回结果
        return baseMapper.selectList(queryWrapper);
    }
}
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/system/service/IMdcProductionService.java
@@ -185,4 +185,11 @@
    String findProName(String equipmentId);
    /**
     * æ ¹æ®äº§çº¿orgCode查询产线
     * @param orgCode
     * @return
     */
    MdcProduction findByOrgCode(String orgCode);
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/MdcProductionServiceImpl.java
@@ -637,4 +637,9 @@
    public String findProName(String equipmentId) {
        return this.baseMapper.findProName(equipmentId);
    }
    @Override
    public MdcProduction findByOrgCode(String orgCode){
        return this.baseMapper.selectOne(new LambdaQueryWrapper<MdcProduction>().eq(MdcProduction::getOrgCode, orgCode));
    }
}
lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml
@@ -309,9 +309,7 @@
#staticAccessPath: /api/ffile/** # å½“前项目的静态资源访问配置在nginx中
#工控网/涉密网部署相关配置------------通过光盘摆渡
deploy:
    #工控网/涉密网部署 0为涉密网 1为工控网
    deployType: 0
    #涉密网传输工控网nc文件夹(指派设备nc文件)    å·¥æŽ§ç½‘传输涉密网nc文件夹(解析回传后的nc文件)
    #涉密网传输工控网nc文件夹(指派设备nc文件)
    secretFolder: D:\\test\\a
file:
  monitor:
@@ -321,3 +319,5 @@
      - D:\\hy_test\\b
      - D:\\hy_test\\c
    interval: 10000  # ç›‘控间隔(ms)
security:
  encryption-key: 1234567890abcdef # åŠ è§£å¯†ç§˜é’¥
lxzn-module-system/lxzn-system-start/src/main/resources/application-prod.yml
@@ -291,4 +291,4 @@
      client-id: ??
      # appSecret
      client-secret: ??
      agent-id: ??
      agent-id: ??
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/PreparationOrderController.java
@@ -94,6 +94,15 @@
        return Result.OK("添加成功!");
    }
    @AutoLog(value = "刀具准备单-从DNC系统写入刀具准备单及明细")
    @ApiOperation(value="刀具准备单-从DNC系统写入刀具准备单及明细", notes="刀具准备单-从DNC系统写入刀具准备单及明细")
    //@RequiresPermissions("org.jeecg.modules:tms_preparation_order:add")
    @PostMapping(value = "/addPreparationOrderFromDnc")
    public Result<String> addPreparationOrderFromDnc(@RequestBody PreparationOrderAndDetailDto preparationOrderAndDetailDto) {
        preparationOrderService.addPreparationOrderFromDnc(preparationOrderAndDetailDto);
        return Result.OK("添加成功!");
    }
    /**
     *  ç¼–辑
     * @param preparationOrder
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/ToolSharpeningController.java
@@ -36,19 +36,7 @@
    @Autowired
    private IToolsSharpeningService toolSharpeningService;
    /**
     * åˆ†é¡µæŸ¥è¯¢
     */
//    @GetMapping("/list")
//    @ApiOperation(value = "分页查询", notes = "分页查询")
//    public Result<IPage<ToolSharpening>> queryPageList(ToolSharpening toolSharpening,
//                                                       @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
//                                                       @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
//        Page<ToolSharpening> page = new Page<>(pageNo, pageSize);
//        QueryWrapper<ToolSharpening> queryWrapper = new QueryWrapper<>(toolSharpening);
//        IPage<ToolSharpening> iPage = toolSharpeningService.page(page, queryWrapper);
//        return Result.OK(iPage);
//    }
    @ApiOperation(value="报损申请单明细-通过主表ID查询", notes="报损申请单明细-通过主表ID查询")
@@ -93,17 +81,29 @@
        toolSharpeningService.save(toolSharpening);
        return Result.OK("添加成功!");
    }
//    /**
//     * ä¿®æ”¹
//     */
//    @PutMapping
//    @ApiOperation(value = "修改", notes = "修改")
//    public Result<ToolSharpening> edit(@RequestBody ToolSharpening toolSharpening) {
//        toolSharpeningService.updateById(toolSharpening);
//        return Result.OK(toolSharpening);
//    }
    /**
     * ä¿®æ”¹
     *  ç¼–辑
     *
     * @param toolSharpening
     * @return
     */
    @PutMapping
    @ApiOperation(value = "修改", notes = "修改")
    public Result<ToolSharpening> edit(@RequestBody ToolSharpening toolSharpening) {
    @AutoLog(value = "tms_tool_sharpening-编辑")
    @ApiOperation(value="tms_tool_sharpening-编辑", notes="tms_tool_sharpening-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
    public Result<String> edit(@RequestBody ToolSharpening toolSharpening) {
        toolSharpeningService.updateById(toolSharpening);
        return Result.OK(toolSharpening);
        return Result.OK("编辑成功!");
    }
    /**
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/ToolsStocktakingBoundController.java
@@ -1,5 +1,6 @@
package org.jeecg.modules.tms.controller;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -15,10 +16,7 @@
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.system.service.ISysBusinessCodeRuleService;
import org.jeecg.modules.tms.entity.BaseTools;
import org.jeecg.modules.tms.entity.ToolSharpening;
import org.jeecg.modules.tms.entity.ToolsStocktakingBound;
import org.jeecg.modules.tms.entity.ToolsStocktakingBoundDetail;
import org.jeecg.modules.tms.entity.*;
import org.jeecg.modules.tms.entity.dto.LossBoundFlowDto;
import org.jeecg.modules.tms.entity.dto.StocktakingBoundFlowDto;
import org.jeecg.modules.tms.entity.vo.ToolsStocktakingVo;
@@ -38,6 +36,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -172,27 +171,42 @@
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    @Transactional(rollbackFor = {Exception.class})
    public Result<String> edit(@RequestBody ToolsStocktakingBound toolsStocktakingBound) {
        if (toolsStocktakingBound == null || StringUtils.isBlank(toolsStocktakingBound.getId())) {
            return Result.error("参数错误");
        }
        toolsStocktakingBoundDetailService.remove(new LambdaQueryWrapper<ToolsStocktakingBoundDetail>()
        toolsStocktakingBoundService.updateById(toolsStocktakingBound);
        // åˆ é™¤ç”³è¯·å•明细数据
                toolsStocktakingBoundDetailService.remove(new LambdaQueryWrapper<ToolsStocktakingBoundDetail>()
                .eq(ToolsStocktakingBoundDetail::getStocktakingBoundId, toolsStocktakingBound.getId()));
        ToolsStocktakingBound stocktakingBound = new ToolsStocktakingBound();
        BeanUtils.copyProperties(stocktakingBound, toolsStocktakingBound);
        toolsStocktakingBoundMapper.updateById(stocktakingBound);
        List<ToolsStocktakingBoundDetail> detailList = toolsStocktakingBound.getToolsStocktakingBoundDetailList();
        if (CollectionUtils.isEmpty(detailList)) {
            return Result.error("明细不能为空");
        }
        for (ToolsStocktakingBoundDetail item : detailList) {
            item.setStocktakingBoundId(toolsStocktakingBound.getId());
            item.setToolId(item.getToolId());
            item.setToolCode(item.getToolCode());
            item.setRemark(item.getRemark());
            item.setStocktakingDate(item.getStocktakingDate());
            item.setBookQuantity(item.getBookQuantity());
            item.setAvailableQuantity(item.getAvailableQuantity());
            item.setPracticalQuantity(item.getPracticalQuantity());
            item.setSurplusDeficit(item.getSurplusDeficit());
            item.setDifferenceValue(item.getDifferenceValue());
            item.setParamaTableName(item.getParamaTableName());
            item.setForeignLanguageName(item.getForeignLanguageName());
            item.setChineseName(item.getChineseName());
            item.setSupplierId(item.getSupplierId());
            item.setStorageLocation(item.getStorageLocation());
            item.setToolMaterial(item.getToolMaterial());
            item.setToolModel(item.getToolModel());
            item.setPositionCode(item.getPositionCode());
            item.setClassifyId(item.getClassifyId());
            item.setApplicationType(item.getApplicationType());
            toolsStocktakingBoundDetailService.saveOrUpdate(item);
        }
        toolsStocktakingBoundDetailService.saveOrUpdateBatch(detailList);
        return Result.OK("操作成功!");
        detailList.forEach(item -> item.setStocktakingBoundId(stocktakingBound.getId()));
        toolsStocktakingBoundDetailService.saveBatch(detailList);
        return Result.OK("编辑成功");
    }
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/controller/ToolsToDncController.java
@@ -1,15 +1,14 @@
package org.jeecg.modules.tms.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.modules.tms.entity.ToolsClassify;
import org.jeecg.modules.tms.entity.dto.ToolQueryParamDto;
import org.jeecg.modules.tms.entity.vo.ParaHolesToolsVo;
import org.jeecg.modules.tms.entity.vo.ParaMillToolVo;
import org.jeecg.modules.tms.entity.vo.ParaTurningToolsVo;
import org.jeecg.modules.tms.entity.vo.*;
import org.jeecg.modules.tms.enums.ToolParaType;
import org.jeecg.modules.tms.service.*;
import org.springframework.beans.factory.annotation.Autowired;
@@ -18,9 +17,10 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/tms/toolsToDnc")
@@ -34,57 +34,125 @@
    private IParaMillToolService paraMillToolService;
    @Autowired
    private IParaTurningToolsService paraTurningToolsService;
    @Autowired
    private IParaThreadingToolService paraThreadingToolService;
    @Autowired
    private IParaBladeService paraBladeService;
    @ApiOperation(value = "通过工具简称查询工具分类信息,选刀页面工具类型下拉框用", notes = "通过工具简称查询工具分类信息,选刀页面工具类型下拉框用")
    @GetMapping("/queryToolClassifyByParam")
    public Result<?> queryToolClassifyByParam(@RequestParam("aliasLabel") String aliasLabel) {
        List<ToolsClassify> classifyList = toolsClassifyService.list(new LambdaQueryWrapper<ToolsClassify>()
                .eq(ToolsClassify::getAliasLabel, aliasLabel)
                .eq(ToolsClassify::getStatus, CommonConstant.STATUS_1));
        List<Map<String, String>> list = classifyList.stream()
                .map(classify -> new HashMap<String, String>() {{
                    put("value", classify.getId());
                    put("label", classify.getTypeName());
                }})
                .collect(Collectors.toList());
        return Result.ok(list);
    }
    /**
     * é€šè¿‡å·¥å…·ç®€ç§°/直径参数查询具体工具参数信息(给DNC提供接口),参数示例:3E(3为工具直径参数、E为加工中心刀具简称)
     *
     * @param queryParam
     * @return
     */
    @ApiOperation(value = "通过工具简称/直径参数查询具体工具参数信息(给DNC提供接口)", notes = "通过工具简称/直径参数查询具体工具参数信息(给DNC提供接口)")
    @GetMapping("/queryToolByParam")
    public Result<?> queryToolByParam(@RequestParam("param") ToolQueryParamDto queryParam){
        String param = queryParam.getParam();
        // æ­£åˆ™è¡¨è¾¾å¼ï¼šå‰åŠéƒ¨åˆ†ä¸ºæ•°å­—(支持小数),后半部分为大写或小写字母
        String regex = "^([\\d.]+)([A-Za-z]+)$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(param);
        if (matcher.find()) {
            String diameter = matcher.group(1);
            String toolAliasName = matcher.group(2);
    public Result<?> queryToolByParam(ToolQueryParamDto queryParam) {
        String aliasLabel = queryParam.getAliasLabel();
        String diameter = queryParam.getDiameter();
        if (StrUtil.isBlank(aliasLabel)) {
            return Result.error("缺少必要参数");
        }
        Result<Object> res = Result.OK();
        Map<String, Object> result = new HashMap<>();
        int pageNo = Objects.isNull(queryParam.getPageNo()) || queryParam.getPageNo() < 1 ? 1 : queryParam.getPageNo();
        int pageSize = Objects.isNull(queryParam.getPageSize()) || queryParam.getPageSize() < 1 ? 10 : queryParam.getPageSize();
        List<Object> toolList = CollectionUtil.newArrayList();
        String classifyId = queryParam.getClassifyId();
        if (StrUtil.isNotBlank(classifyId)) {
            //已经进入了选刀页面,工具分类已经确定
            ToolsClassify toolsClassify = toolsClassifyService.getById(classifyId);
            ToolParaType toolParaType = ToolParaType.fromValue(toolsClassify.getParaTypeFlag());
            matchTypeSelectTools(queryParam, toolList, toolParaType);
        } else {
            //第一次进入选刀页面,根据刀具简称和直径参数查询工具分类
            List<ToolsClassify> classifyList = toolsClassifyService.list(new LambdaQueryWrapper<ToolsClassify>()
                    .eq(ToolsClassify::getAliasLabel, toolAliasName)
                    .eq(ToolsClassify::getAliasLabel, aliasLabel)
                    .eq(ToolsClassify::getStatus, CommonConstant.STATUS_1));
            if (CollectionUtil.isEmpty(classifyList)) {
                return Result.error("未找到匹配的工具分类");
                result.put("records", CollectionUtil.newArrayList());
                result.put("total", 0);
                result.put("current", pageNo);
                result.put("size", pageSize);
                res.setResult(result);
                return res;
            }
            List<Object> toolList = CollectionUtil.newArrayList();
            for (ToolsClassify classify : classifyList) {
                String paraTypeFlag = classify.getParaTypeFlag();
                queryParam.setClassifyId(classify.getId());
                queryParam.setDiameter(diameter);
                ToolParaType toolParaType = ToolParaType.fromValue(paraTypeFlag);
                if (toolParaType != null) {
                    switch (toolParaType) {
                        case HOLE:
                            List<ParaHolesToolsVo> paraHoleToolsList = paraHoleToolsService.selectByClassifyAndDiameter(queryParam);
                            toolList.addAll(paraHoleToolsList);
                            break;
                        case MILL:
                            List<ParaMillToolVo> paraMillToolList = paraMillToolService.selectByClassifyAndDiameter(queryParam);
                            toolList.addAll(paraMillToolList);
                            break;
                        case TURNING:
                            List<ParaTurningToolsVo> paraTurningToolsList = paraTurningToolsService.selectByClassifyAndDiameter(queryParam);
                            toolList.addAll(paraTurningToolsList);
                            break;
                        default:
                    }
                }
                matchTypeSelectTools(queryParam, toolList, toolParaType);
            }
            return Result.OK(toolList);
        }
        // ====== åˆ†é¡µé€»è¾‘ start ======
        int total = toolList.size();
        int fromIndex = (pageNo - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);
        List<Object> pagedList;
        if (fromIndex > total) {
            pagedList = Collections.emptyList();
        } else {
            return Result.error("参数格式不正确");
            pagedList = toolList.subList(fromIndex, toIndex);
        }
        result.put("records", pagedList);
        result.put("total", total);
        result.put("current", pageNo);
        result.put("size", pageSize);
        res.setResult(result);
        return res;
        // ====== åˆ†é¡µé€»è¾‘ end ======
    }
    private void matchTypeSelectTools(ToolQueryParamDto queryParam, List<Object> toolList, ToolParaType toolParaType) {
        if (toolParaType != null) {
            String diameter = queryParam.getDiameter();
            switch (toolParaType) {
                case HOLE:
                    List<ParaHolesToolsVo> paraHoleToolsList = paraHoleToolsService.selectByClassifyAndDiameter(queryParam);
                    toolList.addAll(paraHoleToolsList);
                    break;
                case THREADING://螺纹刀具没有直径参数,如果传入直径,直接略过
                    if (StrUtil.isBlank(diameter)) {
                        List<ParaThreadingToolVo> paraThreadingToolList = paraThreadingToolService.selectByClassifyAndParam(queryParam);
                        toolList.addAll(paraThreadingToolList);
                    }
                    break;
                case MILL:
                    List<ParaMillToolVo> paraMillToolList = paraMillToolService.selectByClassifyAndDiameter(queryParam);
                    toolList.addAll(paraMillToolList);
                    break;
                case TURNING:
                    List<ParaTurningToolsVo> paraTurningToolsList = paraTurningToolsService.selectByClassifyAndDiameter(queryParam);
                    toolList.addAll(paraTurningToolsList);
                    break;
                case BLADE://刀片没有直径参数,如果传入直径,直接略过
                    if (StrUtil.isBlank(diameter)) {
                        List<ParaBladeVo> paraBladeToolsList = paraBladeService.selectByClassifyAndParam(queryParam);
                        toolList.addAll(paraBladeToolsList);
                    }
                    break;
                default:
            }
        }
    }
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
@@ -2,17 +2,24 @@
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
@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/PreparationOrderDetail.java
@@ -7,6 +7,7 @@
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
@@ -21,6 +22,7 @@
 * @Version: V1.0
 */
@Data
@Accessors(chain = true)
@TableName("tms_preparation_order_detail")
@ApiModel(value="tms_preparation_order_detail对象", description="刀具准备单明细")
public class PreparationOrderDetail implements Serializable {
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/ToolsStocktakingBoundDetail.java
@@ -131,6 +131,11 @@
    @TableField(exist = false)
    private String classifyId;
    @Dict(dicCode = "application_type")
    @TableField(exist = false)
    private String applicationType;
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/entity/dto/ToolQueryParamDto.java
@@ -9,13 +9,23 @@
 */
@Data
public class ToolQueryParamDto {
    /**复合参数(工具简称/直径参数),例如:3E*/
    @ApiModelProperty(value = "复合参数(工具简称/直径参数),例如:3E")
    private String param;
    /**工具简称*/
    @ApiModelProperty(value = "工具简称")
    private String aliasLabel;
    /**刀具直径*/
    @ApiModelProperty(value = "刀具直径")
    private String diameter;
    /**刀具分类ID(不用前端传,后台记录参数用)*/
    private String classifyId;
    /**刀具直径(不用前端传,后台记录参数用)*/
    private String diameter;
    /**工具编码*/
    @ApiModelProperty(value = "工具编码(tms_base_tool表tool_code字段)")
    private String toolCode;
    /**型号/图号*/
    @ApiModelProperty(value = "型号/图号")
    private String toolModel;
    /**中文名称*/
    @ApiModelProperty(value = "中文名称")
    private String chineseName;
    /**刀具总长*/
    @ApiModelProperty(value = "刀具总长")
    private String totalLength;
@@ -23,7 +33,7 @@
    @ApiModelProperty(value = "刀具材料")
    private String toolMaterial;
    /**切削刃长*/
    @ApiModelProperty(value = "切削刃长(孔加工刀具、铣削刀具)")
    @ApiModelProperty(value = "切削刃长(孔加工刀具、铣削刀具、螺纹刀具)")
    private String edgeLength;
    /**刃数(孔加工刀具)*/
    @ApiModelProperty(value = "刃数(孔加工刀具)")
@@ -69,7 +79,7 @@
    @ApiModelProperty(value = "悬伸长度(铣削刀具)")
    private String overhangingLength;
    /**螺距*/
    @ApiModelProperty(value = "螺距(铣削刀具)")
    @ApiModelProperty(value = "螺距(铣削刀具、螺纹刀具、刀片)")
    private String pitch;
    /**最小加工直径*/
    @ApiModelProperty(value = "最小加工直径(铣削刀具)")
@@ -78,7 +88,7 @@
    @ApiModelProperty(value = "配套刀片号(车削刀具)")
    private String matchingNumber;
    /**切削方向*/
    @ApiModelProperty(value = "切削方向(车削刀具)")
    @ApiModelProperty(value = "切削方向(车削刀具、刀片)")
    private String cuttingDirection;
    /**刀片尺寸*/
    @ApiModelProperty(value = "刀片尺寸(车削刀具)")
@@ -87,7 +97,7 @@
    @ApiModelProperty(value = "镗杆直径(车削刀具)")
    private String boringBarDiameter;
    /**刀杆长度*/
    @ApiModelProperty(value = "刀杆长度(车削刀具)")
    @ApiModelProperty(value = "刀杆长度(车削刀具、刀片)")
    private String bladeLength;
    /**刀杆方向*/
    @ApiModelProperty(value = "刀杆方向(车削刀具)")
@@ -96,7 +106,7 @@
    @ApiModelProperty(value = "刀杆高度(车削刀具)")
    private String bladeHeight;
    /**刀杆宽度*/
    @ApiModelProperty(value = "刀杆宽度(车削刀具)")
    @ApiModelProperty(value = "刀杆宽度(车削刀具、刀片)")
    private String bladeWide;
    /**刀片槽宽*/
    @ApiModelProperty(value = "刀片槽宽(车削刀具)")
@@ -108,9 +118,81 @@
    @ApiModelProperty(value = "最大切槽深度(车削刀具)")
    private String maxDepth;
    /**刀板厚度*/
    @ApiModelProperty(value = "刀板厚度(车削刀具)")
    @ApiModelProperty(value = "刀板厚度(车削刀具、刀片厚度)")
    private String bladeThickness;
    /**最小加工直径*/
    @ApiModelProperty(value = "最小加工直径(车削刀具)")
    private String minDiameter;
    /**螺纹代号*/
    @ApiModelProperty(value = "螺纹代号(螺纹刀具)")
    private String threadCode;
    /**螺纹旋向*/
    @ApiModelProperty(value = "螺纹旋向(螺纹刀具)")
    private String rotationDirection;
    /**螺纹公差带代号/精度等级*/
    @ApiModelProperty(value = "螺纹公差带代号/精度等级(螺纹刀具)")
    private String tolerancezoneLevel;
    /**外型尺寸*/
    @ApiModelProperty(value = "外型尺寸(螺纹刀具)")
    private String externalDimensions;
    /**柄部规格*/
    @ApiModelProperty(value = "柄部规格(螺纹刀具)")
    private String handleSpecifications;
    /**螺孔类型*/
    @ApiModelProperty(value = "螺孔类型(螺纹刀具)")
    private String screwHoleType;
    /**螺纹标准*/
    @ApiModelProperty(value = "螺纹标准(螺纹刀具、刀片)")
    private String threadStandard;
    /**排屑槽型*/
    @ApiModelProperty(value = "排屑槽型(螺纹刀具)")
    private String fluteSoltType;
    /**螺纹类型*/
    @ApiModelProperty(value = "螺纹类型(螺纹刀具)")
    private String threadType;
    /**导向尺寸*/
    @ApiModelProperty(value = "导向尺寸(螺纹刀具)")
    private String guidingSize;
    /**连接孔径*/
    @ApiModelProperty(value = "连接孔径(螺纹刀具)")
    private String connectionAperture;
    /**连接键槽*/
    @ApiModelProperty(value = "连接键槽(螺纹刀具)")
    private String connectingKeyway;
    /**刀片形状*/
    @ApiModelProperty(value = "刀片形状(刀片)")
    private String bladeShape;
    /**切削刃数*/
    @ApiModelProperty(value = "切削刃数(刀片)")
    private String cuttingEdgeCount;
    /**夹固型式*/
    @ApiModelProperty(value = "夹固型式(刀片)")
    private String clampingType;
    /**刀尖R*/
    @ApiModelProperty(value = "刀尖R(刀片)")
    private String noseAngleR;
    /**加工分类*/
    @ApiModelProperty(value = "加工分类(刀片)")
    private String processingClassify;
    /**刀片后角*/
    @ApiModelProperty(value = "刀片后角(刀片)")
    private String bladePosterior;
    /**刀片尺寸*/
    @ApiModelProperty(value = "刀片尺寸(刀片)")
    private String bladeSize;
    /**内外螺纹*/
    @ApiModelProperty(value = "内外螺纹(刀片)")
    private String inOutThread;
    /**牙型角度*/
    @ApiModelProperty(value = "牙型角度(刀片)")
    private String dentalAngle;
    /**最小加工内螺纹公称直径*/
    @ApiModelProperty(value = "最小加工内螺纹公称直径(刀片)")
    private String minInternalThread;
    //分页参数
    @ApiModelProperty(value = "页码")
    private Integer pageNo = 1;   // å½“前页码,默认第一页
    @ApiModelProperty(value = "每页数量")
    private Integer pageSize = 10; // æ¯é¡µæ•°é‡ï¼Œé»˜è®¤10条
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaBladeMapper.java
@@ -2,9 +2,14 @@
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.commons.math3.analysis.function.Constant;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.tms.entity.ParaBlade;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.tms.entity.vo.ParaBladeVo;
/**
 * @Description: tms_para_blade
@@ -14,4 +19,5 @@
 */
public interface ParaBladeMapper extends BaseMapper<ParaBlade> {
    List<ParaBladeVo> selectByClassifyAndParam(@Param(Constants.WRAPPER) Wrapper<ParaBlade> queryWrapper);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaHoleToolsMapper.java
@@ -2,6 +2,7 @@
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
@@ -18,5 +19,5 @@
public interface ParaHoleToolsMapper extends BaseMapper<ParaHoleTools> {
    List<ParaHolesToolsVo> selectByClassifyAndDiameter(@Param(Constants.WRAPPER)
                                                       LambdaQueryWrapper<ParaHolesToolsVo> queryWrapper);
                                                       Wrapper<ParaHoleTools> queryWrapper);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaMillToolMapper.java
@@ -2,7 +2,7 @@
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.tms.entity.ParaMillTool;
@@ -18,5 +18,5 @@
public interface ParaMillToolMapper extends BaseMapper<ParaMillTool> {
    List<ParaMillToolVo> selectByClassifyAndDiameter(@Param(Constants.WRAPPER)
                                                     LambdaQueryWrapper<ParaMillTool> queryWrapper);
                                                     Wrapper<ParaMillTool> queryWrapper);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaThreadingToolMapper.java
@@ -2,9 +2,13 @@
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.tms.entity.ParaThreadingTool;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.tms.entity.vo.ParaThreadingToolVo;
/**
 * @Description: tms_para_threading_tool
@@ -14,4 +18,5 @@
 */
public interface ParaThreadingToolMapper extends BaseMapper<ParaThreadingTool> {
    List<ParaThreadingToolVo> selectByClassifyAndParam(@Param(Constants.WRAPPER) Wrapper<ParaThreadingTool> queryWrapper);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/ParaTurningToolsMapper.java
@@ -2,7 +2,7 @@
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.tms.entity.ParaTurningTools;
@@ -18,5 +18,5 @@
public interface ParaTurningToolsMapper extends BaseMapper<ParaTurningTools> {
    List<ParaTurningToolsVo> selectByClassifyAndDiameter(@Param(Constants.WRAPPER)
                                                         LambdaQueryWrapper<ParaTurningTools> queryWrapper);
                                                         Wrapper<ParaTurningTools> queryWrapper);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/BaseToolsMapper.xml
@@ -366,20 +366,22 @@
    <select id="pageWithLedgerAndConfig" resultType="org.jeecg.modules.tms.entity.vo.StocktakingPoundVo">
        SELECT
        t.id,
        t.tool_id  AS toolId,
        t1.classify_id AS classifyId,
        t.create_time AS createTime,
        t.tool_code AS toolCode,
        t2.tool_model AS toolModel,
        t2.parama_table_name AS paramaTableName,
        t1.total_count AS totalCount,
        t1.available_count AS availableCount,
        t.tool_id AS toolId,
        t3.position_code AS positionCode,
        t3.application_type AS applicationType,
        t2.chinese_name AS chineseName,
        t3.chinese_name AS chineseName,
        t3.supplier_id AS supplierId,
        t3.storage_location AS storageLocation,
        t3.main_unit AS mainUnit,
        t1.available_count AS availableCount,
        t1.total_count AS totalCount,
        t3.warehouse_id AS warehouseId,
        t4.classify_id AS classifyId,
        t3.province_city AS provinceCity,
        <!-- åŠ¨æ€å­—æ®µé€‰æ‹©ï¼Œä½¿ç”¨è¡¨åˆ«åï¼ˆéœ€ç¡®ä¿è¡¨å·²å…³è”ï¼‰ -->
        <choose>
            <when test="ew.paramNameValuePairs.paramaTableName == '1'">
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaBladeMapper.xml
@@ -2,4 +2,43 @@
<!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.ParaBladeMapper">
    <select id="selectByClassifyAndParam" resultType="org.jeecg.modules.tms.entity.vo.ParaBladeVo">
        SELECT
            t.id,
            t.classify_id AS classifyId,
            t2.classify_id AS classifyNum,
            t2.type_name AS classifyName,
            t1.id AS toolId,
            t1.tool_code AS toolCode,
            t1.parama_table_name AS paramaTableName,
            t.sign_code AS signCode,
            t.chinese_name AS chineseName,
            t.foreign_language_name AS foreignLanguageName,
            t.standard_level AS standardLevel,
            t.standard_code AS standardCode,
            t.position_code AS positionCode,
            t.tool_model AS toolModel,
            t.tool_material AS toolMaterial,
            t.part_material AS partMaterial,
            t.technical_conditions AS technicalConditions,
            t.conditions_info AS conditionsInfo,
            t.brand,
            t.types,
            <!-- åˆ€ç‰‡ç‰¹æœ‰å­—段 -->
            t.blade_shape AS bladeShape,
            t.cutting_edge_count AS cuttingEdgeCount,
            t.clamping_type AS clampingType,
            t.nose_angle_r AS noseAngleR,
            t.processing_classify AS processingClassify,
            t.blade_posterior AS bladePosterior,
            t.blade_size AS bladeSize,
            t.in_out_thread AS inOutThread,
            t.dental_angle AS dentalAngle,
            t.min_internal_thread AS minInternalThread,
            t.thread_standard AS threadStandard
        FROM tms_para_blade t
        LEFT JOIN tms_base_tools t1 ON t.tool_code = t1.id
        LEFT JOIN tms_tools_classify t2 ON t.classify_id = t2.id
        ${ew.customSqlSegment}
    </select>
</mapper>
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaHoleToolsMapper.xml
@@ -10,6 +10,7 @@
            t2.type_name AS classifyName,
            t1.id AS toolId,
            t1.tool_code AS toolCode,
            t1.parama_table_name AS paramaTableName,
            t.sign_code AS signCode,
            t.chinese_name AS chineseName,
            t.foreign_language_name AS foreignLanguageName,
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaMillToolMapper.xml
@@ -9,7 +9,8 @@
            t2.classify_id AS classifyNum,
            t2.type_name AS classifyName,
            t1.id AS toolId,
            t.tool_code AS toolCode,
            t1.tool_code AS toolCode,
            t1.parama_table_name AS paramaTableName,
            t.sign_code AS signCode,
            t.chinese_name AS chineseName,
            t.foreign_language_name AS foreignLanguageName,
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaThreadingToolMapper.xml
@@ -2,4 +2,49 @@
<!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.ParaThreadingToolMapper">
    <select id="selectByClassifyAndParam" resultType="org.jeecg.modules.tms.entity.vo.ParaThreadingToolVo">
        SELECT
            t.id,
            t.classify_id AS classifyId,
            t2.classify_id AS classifyNum,
            t2.type_name AS classifyName,
            t1.id AS toolId,
            t1.tool_code AS toolCode,
            t1.parama_table_name AS paramaTableName,
            t.sign_code AS signCode,
            t.chinese_name AS chineseName,
            t.foreign_language_name AS foreignLanguageName,
            t.standard_level AS standardLevel,
            t.standard_code AS standardCode,
            t.position_code AS positionCode,
            t.tool_model AS toolModel,
            t.edge_length AS edgeLength,
            t.total_length AS totalLength,
            t.tool_material AS toolMaterial,
            t.part_material AS partMaterial,
            t.paintcoat_flag AS paintcoatFlag,
            t.handle_specifications AS handleSpecifications,
            t.cooling_method AS coolingMethod,
            t.technical_conditions AS technicalConditions,
            t.conditions_info AS conditionsInfo,
            t.brand,
            t.types,
            <!-- èžºçº¹åˆ€å…·ç‰¹æœ‰å­—段 -->
            t.thread_code AS threadCode,
            t.rotation_direction AS rotationDirection,
            t.tolerancezone_level AS tolerancezoneLevel,
            t.external_dimensions AS externalDimensions,
            t.handle_specifications AS handleSpecifications,
            t.screw_hole_type AS screwHoleType,
            t.thread_standard AS threadStandard,
            t.flute_solt_type AS fluteSoltType,
            t.thread_type AS threadType,
            t.guiding_size AS guidingSize,
            t.connection_aperture AS connectionAperture,
            t.connecting_keyway AS connectingKeyway
        FROM tms_para_threading_tool t
        LEFT JOIN tms_base_tools t1 ON t.tool_code = t1.id
        LEFT JOIN tms_tools_classify t2 ON t.classify_id = t2.id
        ${ew.customSqlSegment}
    </select>
</mapper>
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ParaTurningToolsMapper.xml
@@ -10,6 +10,7 @@
            t2.type_name AS classifyName,
            t1.id AS toolId,
            t1.tool_code AS toolCode,
            t1.parama_table_name AS paramaTableName,
            t.sign_code AS signCode,
            t.chinese_name AS chineseName,
            t.foreign_language_name AS foreignLanguageName,
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/mapper/xml/ToolsStocktakingBoundDetailMapper.xml
@@ -17,12 +17,12 @@
    <select id="selectByMainId" resultType="org.jeecg.modules.tms.entity.ToolsStocktakingBoundDetail">
        SELECT
        t.*,
        t2.tool_code AS toolCode,  <!-- ä¿®æ­£ï¼šå°†t1改为t2 -->
        t2.parama_table_name paramaTableName,
        t2.classify_id AS classifyId,
        t4.classify_id AS classifyId,
        t3.storage_location AS storageLocation,
        t3.chinese_name AS chineseName,
        t2.tool_model AS toolModel,
        t3.application_type AS applicationType,
        t3.supplier_id AS supplierId,
        <choose>
@@ -56,9 +56,14 @@
                c.part_material AS partMaterial
            </otherwise>
        </choose>
        FROM tms_stocktaking_bound_detail t
        LEFT JOIN tms_base_tools t2 on t.tool_id = t2.id
        LEFT JOIN tms_tools_config_property t3 on t3.tool_code = t2.id
        left join tms_tool_ledger t1 ON  t1.tool_id= t.tool_Code
        left join tms_tool_ledger_detail t5 ON  t5.tool_Code= t.tool_id
        left join tms_tools_classify t4 on t4.id = t1.classify_id
        left join tms_base_tools t2 on t2.id = t.tool_code
        left join tms_tools_config_property t3 on t3.tool_code = t.tool_code
        <choose>
            <when test="ew.paramNameValuePairs.paramaTableName == '1'">
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IParaBladeService.java
@@ -2,6 +2,10 @@
import org.jeecg.modules.tms.entity.ParaBlade;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.tms.entity.dto.ToolQueryParamDto;
import org.jeecg.modules.tms.entity.vo.ParaBladeVo;
import java.util.List;
/**
 * @Description: tms_para_blade
@@ -11,4 +15,5 @@
 */
public interface IParaBladeService extends IService<ParaBlade> {
    List<ParaBladeVo> selectByClassifyAndParam(ToolQueryParamDto queryParam);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IParaThreadingToolService.java
@@ -2,6 +2,10 @@
import org.jeecg.modules.tms.entity.ParaThreadingTool;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.tms.entity.dto.ToolQueryParamDto;
import org.jeecg.modules.tms.entity.vo.ParaThreadingToolVo;
import java.util.List;
/**
 * @Description: tms_para_threading_tool
@@ -11,4 +15,5 @@
 */
public interface IParaThreadingToolService extends IService<ParaThreadingTool> {
    List<ParaThreadingToolVo> selectByClassifyAndParam(ToolQueryParamDto queryParam);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/IPreparationOrderService.java
@@ -40,4 +40,6 @@
    List<String> convertToOutboundOrder(List<String> preparationOrderIds);
    IPage<PreparationOrder> queryPageList(Page<PreparationOrder> page, Map<String, String[]> parameterMap);
    void addPreparationOrderFromDnc(PreparationOrderAndDetailDto preparationOrderAndDetailDto);
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/OutboundOrderServiceImpl.java
@@ -85,6 +85,8 @@
    private OutboundOrderMapper outboundOrderMapper;
    @Autowired
    private OutboundDetailMapper outboundDetailMapper;
    @Autowired
    private OutboundOrderConvert outboundOrderConvert;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -105,7 +107,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());
@@ -157,7 +159,7 @@
        //删除所有明细
        outboundDetailService.remove(new LambdaQueryWrapper<OutboundDetail>()
                .eq(OutboundDetail::getOutStorehouseId, outboundOrder.getId()));
        OutboundOrder outboundOrderUpdate = OutboundOrderConvert.INSTANCE.convert(outboundOrder);
        OutboundOrder outboundOrderUpdate = outboundOrderConvert.convert(outboundOrder);
        outboundOrderMapper.updateById(outboundOrderUpdate);
        List<OutboundDetail> detailList = CollectionUtil.newArrayList();
        outboundOrder.getOutboundDetailList().forEach(item->{
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaBladeServiceImpl.java
@@ -1,11 +1,19 @@
package org.jeecg.modules.tms.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.jeecg.modules.tms.entity.ParaBlade;
import org.jeecg.modules.tms.entity.dto.ToolQueryParamDto;
import org.jeecg.modules.tms.entity.vo.ParaBladeVo;
import org.jeecg.modules.tms.mapper.ParaBladeMapper;
import org.jeecg.modules.tms.service.IParaBladeService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Collections;
import java.util.List;
/**
 * @Description: tms_para_blade
@@ -16,4 +24,32 @@
@Service
public class ParaBladeServiceImpl extends ServiceImpl<ParaBladeMapper, ParaBlade> implements IParaBladeService {
    @Override
    public List<ParaBladeVo> selectByClassifyAndParam(ToolQueryParamDto paramDto) {
        QueryWrapper<ParaBlade> queryWrapper = Wrappers.query();
        if (paramDto != null) {
            // åˆ€ç‰‡ç›¸å…³å‚数字段
            queryWrapper
                    .like(StrUtil.isNotBlank(paramDto.getToolCode()), "t1.tool_code", paramDto.getToolCode())
                    .like(StrUtil.isNotBlank(paramDto.getToolModel()), "t.tool_model", paramDto.getToolModel())
                    .like(StrUtil.isNotBlank(paramDto.getChineseName()), "t.chinese_name", paramDto.getChineseName())
                    .eq(StrUtil.isNotBlank(paramDto.getClassifyId()), "t.classify_id", paramDto.getClassifyId())
                    .eq(StrUtil.isNotBlank(paramDto.getPitch()), "t.pitch", paramDto.getPitch())
                    .eq(StrUtil.isNotBlank(paramDto.getCuttingDirection()), "t.cutting_direction", paramDto.getCuttingDirection())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeLength()), "t.blade_length", paramDto.getBladeLength())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeWide()), "t.blade_wide", paramDto.getBladeWide())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeShape()), "t.blade_shape", paramDto.getBladeShape())
                    .eq(StrUtil.isNotBlank(paramDto.getCuttingEdgeCount()), "t.cutting_edge_count", paramDto.getCuttingEdgeCount())
                    .eq(StrUtil.isNotBlank(paramDto.getClampingType()), "t.clamping_type", paramDto.getClampingType())
                    .eq(StrUtil.isNotBlank(paramDto.getNoseAngleR()), "t.nose_angle_r", paramDto.getNoseAngleR())
                    .eq(StrUtil.isNotBlank(paramDto.getProcessingClassify()), "t.processing_classify", paramDto.getProcessingClassify())
                    .eq(StrUtil.isNotBlank(paramDto.getBladePosterior()), "t.blade_posterior", paramDto.getBladePosterior())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeSize()), "t.blade_size", paramDto.getBladeSize())
                    .eq(StrUtil.isNotBlank(paramDto.getInOutThread()), "t.in_out_thread", paramDto.getInOutThread())
                    .eq(StrUtil.isNotBlank(paramDto.getDentalAngle()), "t.dental_angle", paramDto.getDentalAngle())
                    .eq(StrUtil.isNotBlank(paramDto.getMinInternalThread()), "t.min_internal_thread", paramDto.getMinInternalThread())
                    .eq(StrUtil.isNotBlank(paramDto.getThreadStandard()), "t.thread_standard", paramDto.getThreadStandard());
        }
        return this.baseMapper.selectByClassifyAndParam(queryWrapper);
    }
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaHoleToolsServiceImpl.java
@@ -27,23 +27,26 @@
    @Override
    public List<ParaHolesToolsVo> selectByClassifyAndDiameter(ToolQueryParamDto paramDto) {
        LambdaQueryWrapper<ParaHolesToolsVo> queryWrapper = new LambdaQueryWrapper<>();
        QueryWrapper<ParaHoleTools> queryWrapper = Wrappers.query();
        if (paramDto != null) {
            // å­”加工刀具相关参数字段
            queryWrapper
                    .eq(StrUtil.isNotBlank(paramDto.getClassifyId()), ParaHolesToolsVo::getClassifyId, paramDto.getClassifyId())
                    .eq(StrUtil.isNotBlank(paramDto.getDiameter()), ParaHolesToolsVo::getDiameter, paramDto.getDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getTotalLength()), ParaHolesToolsVo::getTotalLength, paramDto.getTotalLength())
                    .eq(StrUtil.isNotBlank(paramDto.getToolMaterial()), ParaHolesToolsVo::getToolMaterial, paramDto.getToolMaterial())
                    .eq(StrUtil.isNotBlank(paramDto.getEdgeLength()), ParaHolesToolsVo::getEdgeLength, paramDto.getEdgeLength())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeCount()), ParaHolesToolsVo::getBladeCount, paramDto.getBladeCount())
                    .eq(StrUtil.isNotBlank(paramDto.getEffectiveLength()), ParaHolesToolsVo::getEffectiveLength, paramDto.getEffectiveLength())
                    .eq(StrUtil.isNotBlank(paramDto.getLatestBoringDiameter()), ParaHolesToolsVo::getLatestBoringDiameter, paramDto.getLatestBoringDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getMaxBoringDiameter()), ParaHolesToolsVo::getMaxBoringDiameter, paramDto.getMaxBoringDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getKnifeDiameter()), ParaHolesToolsVo::getKnifeDiameter, paramDto.getKnifeDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getBoreDiameter()), ParaHolesToolsVo::getBoreDiameter, paramDto.getBoreDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getHeadsNumber()), ParaHolesToolsVo::getHeadsNumber, paramDto.getHeadsNumber())
                    .eq(StrUtil.isNotBlank(paramDto.getSmallDiameter()), ParaHolesToolsVo::getSmallDiameter, paramDto.getSmallDiameter());
                    .like(StrUtil.isNotBlank(paramDto.getToolCode()), "t1.tool_code", paramDto.getToolCode())
                    .like(StrUtil.isNotBlank(paramDto.getToolModel()), "t.tool_model", paramDto.getToolModel())
                    .like(StrUtil.isNotBlank(paramDto.getChineseName()), "t.chinese_name", paramDto.getChineseName())
                    .eq(StrUtil.isNotBlank(paramDto.getClassifyId()), "t.classify_id", paramDto.getClassifyId())
                    .eq(StrUtil.isNotBlank(paramDto.getDiameter()), "t.diameter", paramDto.getDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getTotalLength()), "t.total_length", paramDto.getTotalLength())
                    .eq(StrUtil.isNotBlank(paramDto.getToolMaterial()), "t.tool_material", paramDto.getToolMaterial())
                    .eq(StrUtil.isNotBlank(paramDto.getEdgeLength()), "t.edge_length", paramDto.getEdgeLength())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeCount()), "t.blade_count", paramDto.getBladeCount())
                    .eq(StrUtil.isNotBlank(paramDto.getEffectiveLength()), "t.effective_length", paramDto.getEffectiveLength())
                    .eq(StrUtil.isNotBlank(paramDto.getLatestBoringDiameter()), "t.latest_boring_diameter", paramDto.getLatestBoringDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getMaxBoringDiameter()), "t.max_boring_diameter", paramDto.getMaxBoringDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getKnifeDiameter()), "t.knife_diameter", paramDto.getKnifeDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getBoreDiameter()), "t.bore_diameter", paramDto.getBoreDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getHeadsNumber()), "t.heads_number", paramDto.getHeadsNumber())
                    .eq(StrUtil.isNotBlank(paramDto.getSmallDiameter()), "t.small_diameter", paramDto.getSmallDiameter());
        }
        return this.baseMapper.selectByClassifyAndDiameter(queryWrapper);
    }
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaMillToolServiceImpl.java
@@ -2,6 +2,8 @@
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.toolkit.Wrappers;
import org.jeecg.modules.tms.entity.ParaMillTool;
import org.jeecg.modules.tms.entity.dto.ToolQueryParamDto;
import org.jeecg.modules.tms.entity.vo.ParaMillToolVo;
@@ -25,24 +27,27 @@
    @Override
    public List<ParaMillToolVo> selectByClassifyAndDiameter(ToolQueryParamDto paramDto) {
        LambdaQueryWrapper<ParaMillTool> queryWrapper = new LambdaQueryWrapper<>();
        QueryWrapper<ParaMillTool> queryWrapper = Wrappers.query();
        if (paramDto != null) {
            //铣削刀具相关参数字段
            queryWrapper
                    .eq(StrUtil.isNotBlank(paramDto.getClassifyId()), ParaMillTool::getClassifyId, paramDto.getClassifyId())
                    .eq(StrUtil.isNotBlank(paramDto.getDiameter()), ParaMillTool::getDiameter, paramDto.getDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getTotalLength()), ParaMillTool::getTotalLength, paramDto.getTotalLength())
                    .eq(StrUtil.isNotBlank(paramDto.getToolMaterial()), ParaMillTool::getToolMaterial, paramDto.getToolMaterial())
                    .eq(StrUtil.isNotBlank(paramDto.getEdgeLength()), ParaMillTool::getEdgeLength, paramDto.getEdgeLength())
                    .eq(StrUtil.isNotBlank(paramDto.getNumberOfTeeth()), ParaMillTool::getNumberOfTeeth, paramDto.getNumberOfTeeth())
                    .eq(StrUtil.isNotBlank(paramDto.getNeckDiameter()), ParaMillTool::getNeckDiameter, paramDto.getNeckDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getSmallDiameter()), ParaMillTool::getSmallDiameter, paramDto.getSmallDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getHandleLength()), ParaMillTool::getHandleLength, paramDto.getHandleLength())
                    .eq(StrUtil.isNotBlank(paramDto.getDeepestDepth()), ParaMillTool::getDeepestDepth, paramDto.getDeepestDepth())
                    .eq(StrUtil.isNotBlank(paramDto.getHandleNeckLength()), ParaMillTool::getHandleNeckLength, paramDto.getHandleNeckLength())
                    .eq(StrUtil.isNotBlank(paramDto.getOverhangingLength()), ParaMillTool::getOverhangingLength, paramDto.getOverhangingLength())
                    .eq(StrUtil.isNotBlank(paramDto.getPitch()), ParaMillTool::getPitch, paramDto.getPitch())
                    .eq(StrUtil.isNotBlank(paramDto.getRecentlyDiameter()), ParaMillTool::getRecentlyDiameter, paramDto.getRecentlyDiameter());
                    .like(StrUtil.isNotBlank(paramDto.getToolCode()), "t1.tool_code", paramDto.getToolCode())
                    .like(StrUtil.isNotBlank(paramDto.getToolModel()), "t.tool_model", paramDto.getToolModel())
                    .like(StrUtil.isNotBlank(paramDto.getChineseName()), "t.chinese_name", paramDto.getChineseName())
                    .eq(StrUtil.isNotBlank(paramDto.getClassifyId()), "t.classify_id", paramDto.getClassifyId())
                    .eq(StrUtil.isNotBlank(paramDto.getDiameter()), "t.diameter", paramDto.getDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getTotalLength()), "t.total_length", paramDto.getTotalLength())
                    .eq(StrUtil.isNotBlank(paramDto.getToolMaterial()), "t.tool_material", paramDto.getToolMaterial())
                    .eq(StrUtil.isNotBlank(paramDto.getEdgeLength()), "t.edge_length", paramDto.getEdgeLength())
                    .eq(StrUtil.isNotBlank(paramDto.getNumberOfTeeth()), "t.number_of_teeth", paramDto.getNumberOfTeeth())
                    .eq(StrUtil.isNotBlank(paramDto.getNeckDiameter()), "t.neck_diameter", paramDto.getNeckDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getSmallDiameter()), "t.small_diameter", paramDto.getSmallDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getHandleLength()), "t.handle_length", paramDto.getHandleLength())
                    .eq(StrUtil.isNotBlank(paramDto.getDeepestDepth()), "t.deepest_depth", paramDto.getDeepestDepth())
                    .eq(StrUtil.isNotBlank(paramDto.getHandleNeckLength()), "t.handle_neck_length", paramDto.getHandleNeckLength())
                    .eq(StrUtil.isNotBlank(paramDto.getOverhangingLength()), "t.overhanging_length", paramDto.getOverhangingLength())
                    .eq(StrUtil.isNotBlank(paramDto.getPitch()), "t.pitch", paramDto.getPitch())
                    .eq(StrUtil.isNotBlank(paramDto.getRecentlyDiameter()), "t.recently_diameter", paramDto.getRecentlyDiameter());
        }
        return this.baseMapper.selectByClassifyAndDiameter(queryWrapper);
    }
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaThreadingToolServiceImpl.java
@@ -1,11 +1,19 @@
package org.jeecg.modules.tms.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.jeecg.modules.tms.entity.ParaThreadingTool;
import org.jeecg.modules.tms.entity.dto.ToolQueryParamDto;
import org.jeecg.modules.tms.entity.vo.ParaThreadingToolVo;
import org.jeecg.modules.tms.mapper.ParaThreadingToolMapper;
import org.jeecg.modules.tms.service.IParaThreadingToolService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Collections;
import java.util.List;
/**
 * @Description: tms_para_threading_tool
@@ -16,4 +24,30 @@
@Service
public class ParaThreadingToolServiceImpl extends ServiceImpl<ParaThreadingToolMapper, ParaThreadingTool> implements IParaThreadingToolService {
    @Override
    public List<ParaThreadingToolVo> selectByClassifyAndParam(ToolQueryParamDto paramDto) {
        QueryWrapper<ParaThreadingTool> queryWrapper = Wrappers.query();
        if (paramDto != null) {
            // èžºçº¹åˆ€å…·ç›¸å…³å‚数字段
            queryWrapper
                    .like(StrUtil.isNotBlank(paramDto.getToolCode()), "t1.tool_code", paramDto.getToolCode())
                    .like(StrUtil.isNotBlank(paramDto.getToolModel()), "t.tool_model", paramDto.getToolModel())
                    .like(StrUtil.isNotBlank(paramDto.getChineseName()), "t.chinese_name", paramDto.getChineseName())
                    .eq(StrUtil.isNotBlank(paramDto.getClassifyId()), "t.classify_id", paramDto.getClassifyId())
                    .eq(StrUtil.isNotBlank(paramDto.getThreadCode()), "t.thread_code", paramDto.getThreadCode())
                    .eq(StrUtil.isNotBlank(paramDto.getPitch()), "t.pitch", paramDto.getPitch())
                    .eq(StrUtil.isNotBlank(paramDto.getRotationDirection()), "t.rotation_direction", paramDto.getRotationDirection())
                    .eq(StrUtil.isNotBlank(paramDto.getTolerancezoneLevel()), "t.tolerancezone_level", paramDto.getTolerancezoneLevel())
                    .eq(StrUtil.isNotBlank(paramDto.getExternalDimensions()), "t.external_dimensions", paramDto.getExternalDimensions())
                    .eq(StrUtil.isNotBlank(paramDto.getHandleSpecifications()), "t.handle_specifications", paramDto.getHandleSpecifications())
                    .eq(StrUtil.isNotBlank(paramDto.getScrewHoleType()), "t.screw_hole_type", paramDto.getScrewHoleType())
                    .eq(StrUtil.isNotBlank(paramDto.getThreadStandard()), "t.thread_standard", paramDto.getThreadStandard())
                    .eq(StrUtil.isNotBlank(paramDto.getFluteSoltType()), "t.flute_solt_type", paramDto.getFluteSoltType())
                    .eq(StrUtil.isNotBlank(paramDto.getThreadType()), "t.thread_type", paramDto.getThreadType())
                    .eq(StrUtil.isNotBlank(paramDto.getGuidingSize()), "t.guiding_size", paramDto.getGuidingSize())
                    .eq(StrUtil.isNotBlank(paramDto.getConnectionAperture()), "t.connection_aperture", paramDto.getConnectionAperture())
                    .eq(StrUtil.isNotBlank(paramDto.getConnectingKeyway()), "t.connecting_keyway", paramDto.getConnectingKeyway());
        }
        return this.baseMapper.selectByClassifyAndParam(queryWrapper);
    }
}
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/ParaTurningToolsServiceImpl.java
@@ -2,6 +2,8 @@
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.toolkit.Wrappers;
import org.jeecg.modules.tms.entity.ParaTurningTools;
import org.jeecg.modules.tms.entity.dto.ToolQueryParamDto;
import org.jeecg.modules.tms.entity.vo.ParaTurningToolsVo;
@@ -25,28 +27,31 @@
    @Override
    public List<ParaTurningToolsVo> selectByClassifyAndDiameter(ToolQueryParamDto paramDto) {
        LambdaQueryWrapper<ParaTurningTools> queryWrapper = new LambdaQueryWrapper<>();
        QueryWrapper<ParaTurningTools> queryWrapper = Wrappers.query();
        if (paramDto != null) {
            //车削刀具相关参数字段
            queryWrapper
                    .eq(StrUtil.isNotBlank(paramDto.getClassifyId()), ParaTurningTools::getClassifyId, paramDto.getClassifyId())
                    .eq(StrUtil.isNotBlank(paramDto.getDiameter()), ParaTurningTools::getToolDiameter, paramDto.getDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getTotalLength()), ParaTurningTools::getTotalLength, paramDto.getTotalLength())
                    .eq(StrUtil.isNotBlank(paramDto.getToolMaterial()), ParaTurningTools::getToolMaterial, paramDto.getToolMaterial())
                    .eq(StrUtil.isNotBlank(paramDto.getSmallDiameter()), ParaTurningTools::getSmallDiameter, paramDto.getSmallDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getCuttingDirection()), ParaTurningTools::getCuttingDirection, paramDto.getCuttingDirection())
                    .eq(StrUtil.isNotBlank(paramDto.getKnifeSize()), ParaTurningTools::getKnifeSize, paramDto.getKnifeSize())
                    .eq(StrUtil.isNotBlank(paramDto.getBoringBarDiameter()), ParaTurningTools::getBoringBarDiameter, paramDto.getBoringBarDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeLength()), ParaTurningTools::getBladeLength, paramDto.getBladeLength())
                    .eq(StrUtil.isNotBlank(paramDto.getBarDirection()), ParaTurningTools::getBarDirection, paramDto.getBarDirection())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeHeight()), ParaTurningTools::getBladeHeight, paramDto.getBladeHeight())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeWide()), ParaTurningTools::getBladeWide, paramDto.getBladeWide())
                    .eq(StrUtil.isNotBlank(paramDto.getSlotWidth()), ParaTurningTools::getSlotWidth, paramDto.getSlotWidth())
                    .eq(StrUtil.isNotBlank(paramDto.getMaxDiameter()), ParaTurningTools::getMaxDiameter, paramDto.getMaxDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getMaxDepth()), ParaTurningTools::getMaxDepth, paramDto.getMaxDepth())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeThickness()), ParaTurningTools::getBladeThickness, paramDto.getBladeThickness())
                    .eq(StrUtil.isNotBlank(paramDto.getMinDiameter()), ParaTurningTools::getMinDiameter, paramDto.getMinDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getMatchingNumber()), ParaTurningTools::getMatchingNumber, paramDto.getMatchingNumber());
                    .like(StrUtil.isNotBlank(paramDto.getToolCode()), "t1.tool_code", paramDto.getToolCode())
                    .like(StrUtil.isNotBlank(paramDto.getToolModel()), "t.tool_model", paramDto.getToolModel())
                    .like(StrUtil.isNotBlank(paramDto.getChineseName()), "t.chinese_name", paramDto.getChineseName())
                    .eq(StrUtil.isNotBlank(paramDto.getClassifyId()), "t.classify_id", paramDto.getClassifyId())
                    .eq(StrUtil.isNotBlank(paramDto.getDiameter()), "t.tool_diameter", paramDto.getDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getTotalLength()), "t.total_length", paramDto.getTotalLength())
                    .eq(StrUtil.isNotBlank(paramDto.getToolMaterial()), "t.tool_material", paramDto.getToolMaterial())
                    .eq(StrUtil.isNotBlank(paramDto.getSmallDiameter()), "t.small_diameter", paramDto.getSmallDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getCuttingDirection()), "t.cutting_direction", paramDto.getCuttingDirection())
                    .eq(StrUtil.isNotBlank(paramDto.getKnifeSize()), "t.knife_size", paramDto.getKnifeSize())
                    .eq(StrUtil.isNotBlank(paramDto.getBoringBarDiameter()), "t.boring_bar_diameter", paramDto.getBoringBarDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeLength()), "t.blade_length", paramDto.getBladeLength())
                    .eq(StrUtil.isNotBlank(paramDto.getBarDirection()), "t.bar_direction", paramDto.getBarDirection())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeHeight()), "t.blade_height", paramDto.getBladeHeight())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeWide()), "t.blade_wide", paramDto.getBladeWide())
                    .eq(StrUtil.isNotBlank(paramDto.getSlotWidth()), "t.slot_width", paramDto.getSlotWidth())
                    .eq(StrUtil.isNotBlank(paramDto.getMaxDiameter()), "t.max_diameter", paramDto.getMaxDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getMaxDepth()), "t.max_depth", paramDto.getMaxDepth())
                    .eq(StrUtil.isNotBlank(paramDto.getBladeThickness()), "t.blade_thickness", paramDto.getBladeThickness())
                    .eq(StrUtil.isNotBlank(paramDto.getMinDiameter()), "t.min_diameter", paramDto.getMinDiameter())
                    .eq(StrUtil.isNotBlank(paramDto.getMatchingNumber()), "t.matching_number", paramDto.getMatchingNumber());
        }
        return this.baseMapper.selectByClassifyAndDiameter(queryWrapper);
    }
lxzn-module-tms/src/main/java/org/jeecg/modules/tms/service/impl/PreparationOrderServiceImpl.java
@@ -54,6 +54,8 @@
    private ISysBusinessCodeRuleService businessCodeRuleService;
    @Autowired
    private IBaseToolsService baseToolsService;
    @Autowired
    private PreparationOrderConvert preparationOrderConvert;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -77,7 +79,7 @@
        //先删除所有明细
        preparationOrderDetailMapper.delete(new LambdaQueryWrapper<PreparationOrderDetail>()
                .eq(PreparationOrderDetail::getPreparationOrderId, preparationOrderAndDetailDto.getId()));
        PreparationOrder preparationOrder = PreparationOrderConvert.INSTANCE.convert(preparationOrderAndDetailDto);
        PreparationOrder preparationOrder = preparationOrderConvert.convert(preparationOrderAndDetailDto);
        updateById(preparationOrder);
        List<PreparationOrderDetail> detailUpdateList = CollectionUtil.newArrayList();
        preparationOrderAndDetailDto.getPreparationOrderDetailList().forEach(item->{
@@ -218,7 +220,23 @@
        return this.baseMapper.queryPageList(page, queryWrapper);
    }
    private LoginUser getCurrentUser() {
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addPreparationOrderFromDnc(PreparationOrderAndDetailDto preparationOrderAndDetailDto) {
        PreparationOrder preparationOrder = preparationOrderConvert.convert(preparationOrderAndDetailDto);
        preparationOrder
                .setId(null)
                .setPreparationOrderNum(businessCodeRuleService.generateBusinessCodeSeq("ToolPreparationOrder"))
                .setOrderStatus(PreparationOrderStatus.PENDING_AUDIT.getValue());
        save(preparationOrder);
        List<PreparationOrderDetail> preparationOrderDetailList = preparationOrderAndDetailDto.getPreparationOrderDetailList();
        preparationOrderDetailList.forEach(item -> {
            item.setId(null).setPreparationOrderId(preparationOrder.getId());
        });
        preparationOrderDetailService.saveBatch(preparationOrderDetailList);
    }
    private LoginUser getCurrentUser() {
        // èŽ·å–å½“å‰è®¤è¯çš„ç™»å½•ç”¨æˆ·ä¿¡æ¯
        Subject currentUser = SecurityUtils.getSubject();
        if (currentUser != null && currentUser.isAuthenticated()) {