buhuazhen
7 天以前 47768d890fbfc1a5f3e93ca26137847361415e9e
Merge branch 'master' into pim_meet
已添加147个文件
已修改53个文件
11627 ■■■■■ 文件已修改
src/main/java/com/ruoyi/account/service/AccountExpenseService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/AccountIncomeService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/impl/AccountExpenseServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/impl/AccountIncomeServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/StorageBlobDTO.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/StorageAttachmentMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/StorageAttachment.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/StorageBlob.java 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/StorageAttachmentService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/StorageBlobService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/StorageAttachmentServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/StorageBlobServiceImpl.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/controller/StaffContactsPersonalController.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/dto/StaffContactsPersonalDTO.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/mapper/StaffContactsPersonalMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/pojo/DutyPlan.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/pojo/StaffContactsPersonal.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/service/StaffContactsPersonalService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/service/impl/StaffContactsPersonalServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/utils/MinioUtils.java 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/utils/OrderUtils.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/controller/DeviceDefectRecordController.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/controller/DeviceRepairController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/dto/DeviceDefectRecordDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/dto/DeviceLedgerDto.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/mapper/DeviceDefectRecordMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/pojo/DeviceDefectRecord.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/pojo/DeviceLedger.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/DeviceDefectRecordService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/impl/DeviceDefectRecordServiceImpl.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/impl/DeviceRepairServiceImpl.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/framework/config/SwaggerConfig.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/StorageAttachmentRecordType.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/controller/InspectionTaskController.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/controller/QrCodeController.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/controller/QrCodeScanRecordController.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/controller/TimingTaskController.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/dto/InspectionTaskDto.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/dto/QrCodeDto.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/dto/QrCodeScanRecordDto.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/dto/TimingTaskDto.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/mapper/InspectionTaskMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/mapper/QrCodeMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/mapper/QrCodeScanRecordMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/mapper/TimingTaskMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTask.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/pojo/QrCode.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/pojo/QrCodeScanRecord.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/pojo/TimingTask.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/InspectionTaskService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/QrCodeScanRecordService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/QrCodeService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/TimingTaskService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java 257 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/QrCodeScanRecordServiceImpl.java 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/QrCodeServiceImpl.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/QuartzConfig.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/SpringContextHolder.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskJob.java 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskScheduler.java 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java 450 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsController.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/dto/SparePartsDto.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/SparePartsMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/pojo/SpareParts.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsServiceImpl.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/controller/OaProjectController.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/controller/OaProjectPhaseController.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/controller/OaProjectPhaseTaskController.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/dto/OaProjectDto.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/dto/OaProjectPhaseDto.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/mapper/OaProjectMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/mapper/OaProjectPhaseMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/mapper/OaProjectPhaseTaskMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/pojo/OaProject.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/pojo/OaProjectPhase.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/pojo/OaProjectPhaseTask.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/service/OaProjectPhaseService.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/service/OaProjectPhaseTaskService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/service/OaProjectService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/service/impl/OaProjectPhaseServiceImpl.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/service/impl/OaProjectPhaseTaskServiceImpl.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/oA/service/impl/OaProjectServiceImpl.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/InboundManagementController.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementPlanController.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementPriceManagementController.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/ReturnManagementController.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementDto.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementManagementUpdateDto.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDto.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDtoCopy.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/mapper/InboundManagementMapper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementPlanMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementPriceManagementMapper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/mapper/ReturnManagementMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/InboundManagement.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementPlan.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementPriceManagement.java 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ReturnManagement.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/InboundManagementService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/ProcurementPlanService.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/ProcurementPriceManagementService.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/ReturnManagementService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/InboundManagementServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementPlanServiceImpl.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementPriceManagementServiceImpl.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/common/CommonController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/PaymentShippingController.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalesQuotationController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/SalespersonManagementController.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/ReceiptPaymentDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/PaymentShippingMapper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/ReceiptPaymentMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/SalesQuotationMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/SalesQuotationProductMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/SalespersonManagementMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/ShippingInfoMapper.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/PaymentShipping.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesQuotation.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalespersonManagement.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/PaymentShippingService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/SalesQuotationProductService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/SalesQuotationService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/SalespersonManagementService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ShippingInfoService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/PaymentShippingServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesQuotationProductServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalespersonManagementServiceImpl.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/pojo/StaffJoinLeaveRecord.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/warehouse/controller/DocumentationBorrowManagementController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/warehouse/service/DocumentationBorrowManagementService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/warehouse/service/impl/DocumentationBorrowManagementServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-bdsm.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-bhmy.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-cmny.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-demo.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dhdc.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hbkj.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hbxm.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hckx.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hcmy.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hsmy.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hsxny.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hxgy.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hxsj.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-hysn.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-jjxm.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-jlsn.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-jsyny.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-mkzs.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-mqsp.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-nydl.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-phmk.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-prod.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-qlmc.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-tymk.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-zyrq.yml 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/collaborativeApproval/StaffContactsPersonalMapper.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/device/DeviceDefectRecordMapper.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/device/DeviceLedgerMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/inspectiontask/TimingTaskMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/oA/OaProjectMapper.xml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/oA/OaProjectPhaseMapper.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/oA/OaProjectPhaseTaskMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/InboundManagementMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementPlanMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementPriceManagementMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/InvoiceLedgerMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/PaymentShippingMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ReceiptPaymentMapper.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesQuotationMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesQuotationProductMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalespersonManagementMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ShippingInfoMapper.xml 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysUserMapper.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/service/AccountExpenseService.java
@@ -7,6 +7,7 @@
import com.ruoyi.account.dto.AccountDto2;
import com.ruoyi.account.dto.AccountDto3;
import com.ruoyi.account.pojo.AccountExpense;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.dto.DateQueryDto;
import javax.servlet.http.HttpServletResponse;
@@ -24,4 +25,6 @@
    List<AccountDto3> reportExpense();
    Map<String,List<String>> analysis();
    AccountExpense getByInvoiceNumber(String purchaseContractNumber);
}
src/main/java/com/ruoyi/account/service/AccountIncomeService.java
@@ -18,4 +18,6 @@
    void accountIncomeExport(HttpServletResponse response, AccountIncome accountIncome);
    List<AccountDto3> reportIncome();
    AccountIncome getByInvoiceNumber(String purchaseContractNumber);
}
src/main/java/com/ruoyi/account/service/impl/AccountExpenseServiceImpl.java
@@ -152,5 +152,11 @@
        return result;
    }
    @Override
    public AccountExpense getByInvoiceNumber(String purchaseContractNumber) {
        return accountExpenseMapper.selectOne(Wrappers.<AccountExpense>lambdaQuery()
                .eq(AccountExpense::getInvoiceNumber, purchaseContractNumber));
    }
}
src/main/java/com/ruoyi/account/service/impl/AccountIncomeServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.account.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -74,4 +75,11 @@
        }
        return accountDto3s;
    }
    @Override
    public AccountIncome getByInvoiceNumber(String purchaseContractNumber) {
        AccountIncome accountIncome = accountIncomeMapper.selectOne(new LambdaQueryWrapper<AccountIncome>()
                .eq(AccountIncome::getInvoiceNumber, purchaseContractNumber));
        return accountIncome;
    }
}
src/main/java/com/ruoyi/basic/dto/StorageBlobDTO.java
@@ -6,4 +6,6 @@
@Data
public class StorageBlobDTO extends StorageBlob {
    private String url;
    private String downloadUrl;
}
src/main/java/com/ruoyi/basic/mapper/StorageAttachmentMapper.java
@@ -2,7 +2,6 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.basic.pojo.StorageAttachment;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
@@ -12,7 +11,6 @@
 * @author ruoyi
 * @since 2025-05-29
 */
@Mapper
public interface StorageAttachmentMapper extends BaseMapper<StorageAttachment> {
}
src/main/java/com/ruoyi/basic/pojo/StorageAttachment.java
@@ -36,6 +36,9 @@
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    /**
     * é€»è¾‘删除
     */
@@ -62,6 +65,7 @@
    @TableField(value = "storage_blob_id")
    private Long storageBlobId;
    @TableField(exist = false)
    private StorageBlobDTO storageBlobDTO;
    public StorageAttachment(String fileType, Long recordType, Long recordId) {
src/main/java/com/ruoyi/basic/pojo/StorageBlob.java
@@ -1,13 +1,13 @@
package com.ruoyi.basic.pojo;
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 com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
@@ -28,16 +28,11 @@
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /** åˆ›å»ºæ—¶é—´ */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    /**
     * èµ„源id
     */
    @TableField(value = "key")
    private String key;
    @TableField(value = "resource_key")
    private String resourceKey;
    /**
     * èµ„源类型,例如JPG图片的资源类型为image/jpg
     */
@@ -64,4 +59,34 @@
     */
    @TableField(value = "byte_size")
    private Long byteSize;
    /**
     * 0生产前 1生产后 2生产问题
     */
    @TableField(value = "type")
    private Long type;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty(value = "创建该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "记录创建时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "最后修改该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "记录最后更新时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
src/main/java/com/ruoyi/basic/service/StorageAttachmentService.java
@@ -34,6 +34,9 @@
     */
    public void saveStorageAttachment(List<StorageAttachment> attachments, Long recordId, StorageAttachmentRecordType recordType, StorageAttachmentConstants fileType);
    public void saveStorageAttachment(List<StorageAttachment> attachments, Long recordId, StorageAttachmentRecordType recordType, String fileType);
    /**
     * åˆ é™¤é€šç”¨æ–‡ä»¶ä¸Šä¼ çš„附件信息
     * @param storageAttachment æ–‡ä»¶ä¿¡æ¯
src/main/java/com/ruoyi/basic/service/StorageBlobService.java
@@ -26,6 +26,9 @@
     */
    List<StorageBlobDTO> updateStorageBlobs(List<MultipartFile> files, String bucketName);
    List<StorageBlobDTO> updateStorageBlobs(List<MultipartFile> files, String bucketName,Long type);
    /**
     * æ‰¹é‡åˆ é™¤æ–‡ä»¶
     * @param attachment
src/main/java/com/ruoyi/basic/service/impl/StorageAttachmentServiceImpl.java
@@ -78,6 +78,22 @@
    }
    @Override
    public void saveStorageAttachment(List<StorageAttachment> attachments, Long recordId, StorageAttachmentRecordType recordType, String fileType) {
        // åˆ é™¤æ—§å›¾
        deleteStorageAttachment(new StorageAttachment(fileType, (long) recordType.ordinal(), recordId));
        for (StorageAttachment attachment : attachments) {
            // èŽ·å–å…³è”è®°å½•
            StorageBlob storageBlob = attachment.getStorageBlobDTO();
            attachment.setName(fileType);
            attachment.setRecordType((long) recordType.ordinal());
            attachment.setRecordId(recordId);
            attachment.setStorageBlobId(storageBlob.getId());
            storageAttachmentMapper.insert(attachment);
        }
    }
    @Override
    public int deleteStorageAttachment(StorageAttachment storageAttachment) {
        // å…ˆåˆ é™¤æ˜Žç»†è¡¨
        storageBlobService.deleteStorageBlobs(storageAttachment);
src/main/java/com/ruoyi/basic/service/impl/StorageBlobServiceImpl.java
@@ -9,6 +9,7 @@
import com.ruoyi.basic.pojo.StorageAttachment;
import com.ruoyi.basic.pojo.StorageBlob;
import com.ruoyi.basic.service.StorageBlobService;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.exception.file.InvalidExtensionException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MinioUtils;
@@ -16,11 +17,15 @@
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.framework.web.domain.MinioResult;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@@ -61,9 +66,8 @@
                dto.setBucketFilename(res.getBucketFileName());
                dto.setOriginalFilename(res.getOriginalName());
                dto.setByteSize(file.getSize());
                dto.setKey(IdUtils.simpleUUID());
                dto.setResourceKey(IdUtils.simpleUUID());
                dto.setBucketName(bucketName);
                dto.setCreateTime(DateUtils.getNowDate());
                dto.setUrl(minioUtils.getPreviewUrl(res.getBucketFileName(), bucketName, false));
                // æ’入数据库
                storageBlobMapper.insert(dto);
@@ -79,12 +83,95 @@
    }
    @Override
    public List<StorageBlobDTO> updateStorageBlobs(List<MultipartFile> files, String bucketName, Long type) {
        // è‹¥æ²¡ä¼ å…¥bucketName,则使用默认bucketName
        if (StringUtils.isEmpty(bucketName)) {
            bucketName = minioUtils.getDefaultBucket();
        }
        List<StorageBlobDTO> storageBlobDTOs = new ArrayList<>();
        for (MultipartFile file : files) {
            try {
                validateFileExtension(file);
                MinioResult res = minioUtils.upload(bucketName, file, false);
                StorageBlobDTO dto = buildStorageBlobDTO(file, res, bucketName, type);
                storageBlobMapper.insert(dto);
                storageBlobDTOs.add(dto);
            } catch (InvalidExtensionException e) {
                throw new RuntimeException("不支持的文件类型:" + file.getOriginalFilename(), e);
            } catch (Exception e) {
                throw new RuntimeException("上传文件失败:" + file.getOriginalFilename(), e);
            }
        }
        return storageBlobDTOs;
    }
    private StorageBlobDTO buildStorageBlobDTO(MultipartFile file, MinioResult res, String bucketName, Long type) {
        StorageBlobDTO dto = new StorageBlobDTO();
        dto.setContentType(file.getContentType());
        dto.setBucketFilename(res.getBucketFileName());
        dto.setOriginalFilename(res.getOriginalName());
        dto.setByteSize(file.getSize());
        dto.setResourceKey(IdUtils.simpleUUID());
        dto.setBucketName(bucketName);
        dto.setUrl(minioUtils.getPreviewUrl(res.getBucketFileName(), bucketName, false));
        dto.setDownloadUrl(minioUtils.getDownloadUrl(res.getBucketFileName(), bucketName));
        if (type != null) {
            dto.setType(type);
        }
        return dto;
    }
    private void validateFileExtension(MultipartFile file) throws InvalidExtensionException {
        String filename = file.getOriginalFilename();
        String extension = FilenameUtils.getExtension(filename).toLowerCase();
        List<String> allowedExtensions = Arrays.asList(
                // å›¾ç‰‡
                "jpg", "jpeg", "png", "gif", "bmp", "webp", "tiff", "ico", "svg",
                // æ–‡æ¡£
                "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "rtf", "md", "csv", "odt",
                // è§†é¢‘
                "mp4", "mov", "avi", "wmv", "flv", "mkv", "webm", "mpeg", "3gp", "MOV",
                // éŸ³é¢‘
                "mp3", "wav", "ogg", "aac", "flac", "m4a", "wma", "amr",
                // åŽ‹ç¼©åŒ…
                "zip", "rar", "7z", "tar", "gz", "bz2", "xz",
                // ç¼–程代码文件
                "java", "py", "js", "ts", "html", "css", "cpp", "c", "cs", "json", "xml", "sql", "yaml", "yml", "sh", "bat",
                // å®‰è£…程序 & äºŒè¿›åˆ¶
                "exe", "apk", "dmg", "msi", "bin", "iso",
                // è®¾è®¡ç±»
                "psd", "ai", "xd", "sketch", "fig"
        );
        if (!allowedExtensions.contains(extension)) {
            throw new BaseException("文件类型不被允许:" + extension);
        }
    }
    @Override
    public int deleteStorageBlobs(StorageAttachment attachment) {
        List<StorageAttachment> attachments = storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordId, attachment.getRecordId())
                .eq(StorageAttachment::getRecordType, attachment.getRecordType())
                .eq(StorageAttachment::getName, attachment.getName()));
        List<Long> ids = attachments.stream().map(StorageAttachment::getStorageBlobId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(ids)){
            return 0;
        }
        List<StorageBlob> storageBlobs = storageBlobMapper.selectList(new LambdaQueryWrapper<StorageBlob>()
                .in(StorageBlob::getId, ids));
        if (!storageBlobs.isEmpty()) {
src/main/java/com/ruoyi/collaborativeApproval/controller/StaffContactsPersonalController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.collaborativeApproval.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.collaborativeApproval.dto.StaffContactsPersonalDTO;
import com.ruoyi.collaborativeApproval.pojo.StaffContactsPersonal;
import com.ruoyi.collaborativeApproval.service.StaffContactsPersonalService;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/staffContactsPersonal")
@AllArgsConstructor
public class StaffContactsPersonalController {
    @Autowired
    private StaffContactsPersonalService staffContactsPersonalService;
    @GetMapping("/getList")
    @ApiOperation("分页查询")
    public AjaxResult listPage(Page page, StaffContactsPersonalDTO staffContactsPersonalDTO ){
        return AjaxResult.success(staffContactsPersonalService.listPage(page, staffContactsPersonalDTO));
    }
    @PostMapping("/add")
    @ApiOperation("新增")
    public AjaxResult add(@RequestBody StaffContactsPersonal staffContactsPersonal){
        return AjaxResult.success(staffContactsPersonalService.save(staffContactsPersonal));
    }
    @DeleteMapping("/delete/{id}")
    @ApiOperation("删除")
    public AjaxResult delete(@PathVariable("id") Long id){
//        if (CollectionUtils.isEmpty(id)) {
//            throw new RuntimeException("请传入要删除的ID");
//        }
        return AjaxResult.success(staffContactsPersonalService.removeById(id));
    }
}
src/main/java/com/ruoyi/collaborativeApproval/dto/StaffContactsPersonalDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.ruoyi.collaborativeApproval.dto;
import com.ruoyi.collaborativeApproval.pojo.StaffContactsPersonal;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import lombok.Data;
@Data
public class StaffContactsPersonalDTO extends StaffContactsPersonal {
    private String staffNo;
    private String staffName;
    private String sex;
    private String postJob;
    private String adress;
    private String profession;
    private String identityCard;
    private String phone;
}
src/main/java/com/ruoyi/collaborativeApproval/mapper/StaffContactsPersonalMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.collaborativeApproval.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.collaborativeApproval.dto.StaffContactsPersonalDTO;
import com.ruoyi.collaborativeApproval.pojo.StaffContactsPersonal;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface StaffContactsPersonalMapper extends BaseMapper<StaffContactsPersonal> {
    IPage listPage(Page page,@Param("staffContactsPersonalDTO") StaffContactsPersonalDTO staffContactsPersonalDTO);
}
src/main/java/com/ruoyi/collaborativeApproval/pojo/DutyPlan.java
@@ -91,6 +91,31 @@
    @TableField(value = "tags",typeHandler = ListToStringTypeHandler.class,jdbcType = JdbcType.VARCHAR)
    private List<String> tags;
    /**
     * åˆ›å»ºè€…
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹äºº
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
src/main/java/com/ruoyi/collaborativeApproval/pojo/StaffContactsPersonal.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.ruoyi.collaborativeApproval.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@TableName("staff_contacts_personal")
@Data
public class StaffContactsPersonal {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
//    /**
//     * ç”¨æˆ·ID(所属者)
//     */
//    @ApiModelProperty("用户ID(所属者)")
//    private Integer userId;
    /**
     * å‘˜å·¥ID
     */
    @ApiModelProperty("员工ID")
    private Integer contactId;
    /**
     * åˆ›å»ºè€…
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/collaborativeApproval/service/StaffContactsPersonalService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.collaborativeApproval.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.collaborativeApproval.dto.StaffContactsPersonalDTO;
import com.ruoyi.collaborativeApproval.pojo.StaffContactsPersonal;
public interface StaffContactsPersonalService extends IService<StaffContactsPersonal> {
    IPage listPage(Page page, StaffContactsPersonalDTO staffContactsPersonalDTO);
}
src/main/java/com/ruoyi/collaborativeApproval/service/impl/StaffContactsPersonalServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.collaborativeApproval.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.collaborativeApproval.dto.StaffContactsPersonalDTO;
import com.ruoyi.collaborativeApproval.mapper.StaffContactsPersonalMapper;
import com.ruoyi.collaborativeApproval.pojo.StaffContactsPersonal;
import com.ruoyi.collaborativeApproval.service.StaffContactsPersonalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class StaffContactsPersonalServiceImpl extends ServiceImpl<StaffContactsPersonalMapper, StaffContactsPersonal> implements StaffContactsPersonalService {
    @Autowired
    private StaffContactsPersonalMapper staffContactsPersonalMapper;
    @Override
    public IPage listPage(Page page, StaffContactsPersonalDTO staffContactsPersonalDTO) {
        return staffContactsPersonalMapper.listPage(page, staffContactsPersonalDTO);
    }
}
src/main/java/com/ruoyi/common/enums/StorageAttachmentRecordType.java
@@ -9,7 +9,10 @@
@AllArgsConstructor
public enum StorageAttachmentRecordType {
    // ä¾‹å­ å®žé™…开发请删除
    Template("Template","范例");
    Template("Template","范例"),
    Archives("Archives","文档管理"),
    InspectionTasks("InspectionTasks","生产巡检"),
    QrCodeScanRecords("QrCodeScanRecords","二维码扫码记录文件");
    private final String code;
src/main/java/com/ruoyi/common/utils/MinioUtils.java
@@ -21,12 +21,10 @@
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -306,4 +304,130 @@
        return null;
    }
    /**
     * ç”Ÿæˆé¢„览URL
     * @param bucketFilename æ–‡ä»¶åœ¨MinIO中的唯一标识
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param useDefaultExpiry æ˜¯å¦ä½¿ç”¨é»˜è®¤è¿‡æœŸæ—¶é—´ï¼ˆtrue=使用默认过期时间,false=永久有效)
     * @return é¢„览URL
     */
    public String getPreviewUrls(String bucketFilename, String bucketName, boolean useDefaultExpiry) {
        if (StringUtils.isBlank(bucketFilename)) {
            return null;
        }
        try {
            // éªŒè¯æ–‡ä»¶å­˜åœ¨æ€§
            minioClient.statObject(StatObjectArgs.builder()
                    .bucket(bucketName)
                    .object(bucketFilename)
                    .build());
            GetPresignedObjectUrlArgs.Builder builder = GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(bucketName)
                    .object(bucketFilename);
            // è®¾ç½®è¿‡æœŸæ—¶é—´ï¼šuseDefaultExpiry=true ä½¿ç”¨é…ç½®çš„过期时间
            if (useDefaultExpiry) {
                builder.expiry(previewExpiry, TimeUnit.HOURS);
            }
            return minioClient.getPresignedObjectUrl(builder.build());
        } catch (Exception e) {
            throw new UtilException("生成预览URL失败: " + e.getMessage(), e);
        }
    }
    /**
     * ç”Ÿæˆä¸‹è½½URL(强制浏览器下载)
     * @param bucketFilename æ–‡ä»¶åœ¨MinIO中的唯一标识
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param originalFileName åŽŸå§‹æ–‡ä»¶åï¼ˆç”¨äºŽä¸‹è½½æ—¶æ˜¾ç¤ºï¼‰
     * @param useDefaultExpiry æ˜¯å¦ä½¿ç”¨é»˜è®¤è¿‡æœŸæ—¶é—´ï¼ˆtrue=使用默认,false=无过期时间)
     * @return ä¸‹è½½URL
     */
    public String getDownloadUrls(String bucketFilename, String bucketName, String originalFileName, boolean useDefaultExpiry) {
        if (StringUtils.isBlank(bucketFilename)) {
            return null;
        }
        try {
            // éªŒè¯æ–‡ä»¶å­˜åœ¨æ€§
            minioClient.statObject(StatObjectArgs.builder()
                    .bucket(bucketName)
                    .object(bucketFilename)
                    .build());
            // æ­£ç¡®ç¼–码文件名:替换 + ä¸º %20
            String encodedFileName = URLEncoder.encode(originalFileName, String.valueOf(StandardCharsets.UTF_8))
                    .replace("+", "%20");
            Map<String, String> reqParams = new HashMap<>();
            reqParams.put("response-content-disposition",
                    "attachment; filename=\"" + encodedFileName + "\"");
            GetPresignedObjectUrlArgs.Builder builder = GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(bucketName)
                    .object(bucketFilename)
                    .extraQueryParams(reqParams);
            // æ ¹æ®å‚数决定是否设置过期时间
            if (useDefaultExpiry) {
                // ä½¿ç”¨é»˜è®¤è¿‡æœŸæ—¶é—´ï¼ˆä»Žé…ç½®è¯»å–)
                builder.expiry(previewExpiry, TimeUnit.HOURS);
            } else {
                // ä¸è®¾ç½®è¿‡æœŸæ—¶é—´ï¼ˆMinIO é»˜è®¤7天)
            }
            return minioClient.getPresignedObjectUrl(builder.build());
        } catch (Exception e) {
            throw new UtilException("生成下载URL失败: " + e.getMessage(), e);
        }
    }
    public String getDownloadUrl(String bucketFileName, String bucketName) {
        if (StringUtils.isNotBlank(bucketFileName)) {
            try {
                // æ£€æŸ¥æ–‡ä»¶æ˜¯å¦å­˜åœ¨
                minioClient.statObject(StatObjectArgs.builder()
                        .bucket(bucketName)
                        .object(bucketFileName)
                        .build());
                // è®¾ç½®å“åº”头
                Map<String, String> reqParams = new HashMap<>();
                // æå–原始文件名(如果存储时保留了原始名称)
                String originalFileName = extractOriginalFileName(bucketFileName);
                reqParams.put("response-content-disposition",
                        "attachment; filename=\"" + URLEncoder.encode(originalFileName, String.valueOf(StandardCharsets.UTF_8)) + "\"");
                // æž„建预签名URL参数
                GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(bucketFileName)
                        .expiry(previewExpiry, TimeUnit.HOURS)
                        .extraQueryParams(reqParams)
                        .build();
                return minioClient.getPresignedObjectUrl(args);
            } catch (Exception e) {
                throw new UtilException("MinioUtils:生成下载链接异常", e);
            }
        }
        return null;
    }
    private String extractOriginalFileName(String bucketFileName) {
        // ç¤ºä¾‹ï¼šå¦‚果存储格式为 "原始文件名_UUID"
        int underscoreIndex = bucketFileName.lastIndexOf("_");
        if (underscoreIndex > 0) {
            return bucketFileName.substring(0, underscoreIndex);
        }
        // å¦‚果没有特殊格式,直接返回完整文件名
        return bucketFileName;
    }
}
src/main/java/com/ruoyi/common/utils/OrderUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
package com.ruoyi.common.utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * @author :yys
 * @date : 2025/9/15 15:31
 */
public class OrderUtils {
    /**
     * æŸ¥è¯¢å½“天(基于createTime字段)的记录数量
     * @param mapper å®žä½“类对应的BaseMapper
     * @param <T> å®žä½“类泛型
     * @return å½“天记录数量
     */
    public static <T> String countTodayByCreateTime(BaseMapper<T> mapper,String preFix) {
        // èŽ·å–å½“å¤©å¼€å§‹æ—¶é—´ï¼ˆ00:00:00)
        LocalDateTime todayStart = LocalDateTime.of(
                LocalDateTime.now().toLocalDate(),
                LocalTime.MIN
        );
        // èŽ·å–å½“å¤©ç»“æŸæ—¶é—´ï¼ˆ23:59:59.999)
        LocalDateTime todayEnd = LocalDateTime.of(
                LocalDateTime.now().toLocalDate(),
                LocalTime.MAX
        );
        // è½¬æ¢ä¸ºDate类型(如果实体类中createTime是LocalDateTime可直接使用)
        Date startDate = Date.from(todayStart.atZone(ZoneId.systemDefault()).toInstant());
        Date endDate = Date.from(todayEnd.atZone(ZoneId.systemDefault()).toInstant());
        // æž„建查询条件
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("create_time", startDate)  // å¤§äºŽç­‰äºŽå½“天开始
                .lt("create_time", endDate);   // å°äºŽå½“天结束(避免毫秒精度问题)
        // æ‰§è¡ŒæŸ¥è¯¢
        Long aLong = mapper.selectCount(queryWrapper);
        // æ‹¼æŽ¥è®¢å•编号 preFix + æ—¶é—´ï¼ˆyyyyMMdd) + è®¢å•数量(001)
        return preFix + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE).replaceAll("-", "") + String.format("%03d", (aLong + 1));}
}
src/main/java/com/ruoyi/device/controller/DeviceDefectRecordController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.ruoyi.device.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.device.dto.DeviceDefectRecordDto;
import com.ruoyi.device.dto.DeviceRepairDto;
import com.ruoyi.device.pojo.DeviceDefectRecord;
import com.ruoyi.device.pojo.DeviceLedger;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.device.service.DeviceDefectRecordService;
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Api(tags = "设备缺陷记录管理")
@RequestMapping("/defect")
@RestController
public class DeviceDefectRecordController {
    @Autowired
    private DeviceDefectRecordService deviceDefectRecordService;
    @ApiModelProperty("设备缺陷记录列表")
    @GetMapping("/page")
    public AjaxResult page(Page page , DeviceDefectRecordDto deviceDefectRecordDto) {
        return AjaxResult.success(deviceDefectRecordService.listPage(page,deviceDefectRecordDto));
    }
    @ApiModelProperty("设备id查询设备缺陷记录列表")
    @GetMapping("/find/{deviceLedgerId}")
    public AjaxResult find(@PathVariable Long deviceLedgerId) {
        DeviceDefectRecordDto deviceDefectRecordDto = new DeviceDefectRecordDto();
        deviceDefectRecordDto.setDeviceLedgerId(deviceLedgerId);
        return AjaxResult.success(deviceDefectRecordService.listPage(new Page<>(1,-1),deviceDefectRecordDto));
    }
    @PostMapping("/add")
    @ApiModelProperty("添加设备缺陷记录")
    public AjaxResult add(@RequestBody DeviceDefectRecord deviceDefectRecord) {
        return AjaxResult.success(deviceDefectRecordService.add(deviceDefectRecord));
    }
    @PostMapping("/update")
    @ApiModelProperty("修改设备缺陷记录")
    public AjaxResult update(@RequestBody DeviceDefectRecord deviceDefectRecord) {
        return AjaxResult.success(deviceDefectRecordService.updateByDDR(deviceDefectRecord));
    }
    @DeleteMapping("/delete")
    @ApiModelProperty("删除设备缺陷记录")
    public AjaxResult delete(@PathVariable Long id) {
        return AjaxResult.success(deviceDefectRecordService.removeById(id));
    }
}
src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java
@@ -15,6 +15,7 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ArrayUtils;
import org.ehcache.spi.service.MaintainableService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -101,7 +102,7 @@
    }
    @GetMapping("scanDevice")
    @ApiModelProperty("获取设备台账")
    @ApiOperation("获取设备台账")
    @Anonymous
    public AjaxResult scanDevice(Long id) {
        List<DeviceMaintenance> list = deviceMaintenanceMapper.list1(id);
src/main/java/com/ruoyi/device/controller/DeviceRepairController.java
@@ -37,9 +37,6 @@
    @PostMapping()
    @ApiModelProperty("添加设备报修")
    public AjaxResult add( @RequestBody DeviceRepair deviceRepair) {
        DeviceLedger byId = deviceLedgerService.getById(deviceRepair.getDeviceLedgerId());
        deviceRepair.setDeviceName(byId.getDeviceName());
        deviceRepair.setDeviceModel(byId.getDeviceModel());
        return deviceRepairService.saveDeviceRepair(deviceRepair);
    }
src/main/java/com/ruoyi/device/dto/DeviceDefectRecordDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.device.dto;
import com.ruoyi.device.pojo.DeviceDefectRecord;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class DeviceDefectRecordDto extends DeviceDefectRecord {
    @ApiModelProperty("设备名称")
    private String deviceName;
    @ApiModelProperty("设备型号")
    private String deviceModel;
}
src/main/java/com/ruoyi/device/dto/DeviceLedgerDto.java
@@ -5,10 +5,12 @@
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.dto.DateQueryDto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
@@ -99,4 +101,25 @@
     * ç§Ÿæˆ·ID
     */
    private Long tenantId;
    @ApiModelProperty("状态")
    private String status;
    @ApiModelProperty("计划运行时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate planRuntimeTime;
    @ApiModelProperty("开始运行时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime startRuntimeTime;
    @ApiModelProperty("结束运行时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endRuntimeTime;
    @ApiModelProperty("运行时长")
    private String runtimeDuration;
}
src/main/java/com/ruoyi/device/mapper/DeviceDefectRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.device.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.device.dto.DeviceDefectRecordDto;
import com.ruoyi.device.pojo.DeviceDefectRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface DeviceDefectRecordMapper extends BaseMapper<DeviceDefectRecord> {
    IPage<DeviceDefectRecordDto> listPage(Page page,@Param("deviceDefectRecordDto") DeviceDefectRecordDto deviceDefectRecordDto);
}
src/main/java/com/ruoyi/device/pojo/DeviceDefectRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package com.ruoyi.device.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Data
@TableName("device_defect_record")
public class DeviceDefectRecord {
    @ApiModelProperty("设备缺陷记录id")
    private Long id;
    @ApiModelProperty("设备台账id")
    private Long deviceLedgerId;
    @ApiModelProperty("缺陷描述")
    private String defectDescription;
    @ApiModelProperty("状态")
    private String status;
    @ApiModelProperty("消除时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime eliminateTime;
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @ApiModelProperty("创建人")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty("更新人")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty("租户id")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/device/pojo/DeviceLedger.java
@@ -108,4 +108,27 @@
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    /* ***************************     è¿è¡Œç®¡ç†        ***************************   */
    @ApiModelProperty("状态")
    private String status;
    @ApiModelProperty("计划运行时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate planRuntimeTime;
    @ApiModelProperty("开始运行时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime startRuntimeTime;
    @ApiModelProperty("结束运行时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endRuntimeTime;
    @ApiModelProperty("运行时长")
    private String runtimeDuration;
}
src/main/java/com/ruoyi/device/service/DeviceDefectRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.device.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.device.dto.DeviceDefectRecordDto;
import com.ruoyi.device.pojo.DeviceDefectRecord;
public interface DeviceDefectRecordService extends IService<DeviceDefectRecord> {
    IPage<DeviceDefectRecordDto> listPage(Page page, DeviceDefectRecordDto deviceDefectRecordDto);
    boolean updateByDDR(DeviceDefectRecord deviceDefectRecord);
    boolean add(DeviceDefectRecord deviceDefectRecord);
}
src/main/java/com/ruoyi/device/service/impl/DeviceDefectRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.ruoyi.device.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.dto.DeviceDefectRecordDto;
import com.ruoyi.device.mapper.DeviceDefectRecordMapper;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceDefectRecord;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.device.service.DeviceDefectRecordService;
import com.ruoyi.device.service.IDeviceRepairService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Date;
@Service
@Transactional(rollbackFor = Exception.class)
public class DeviceDefectRecordServiceImpl extends ServiceImpl<DeviceDefectRecordMapper, DeviceDefectRecord> implements DeviceDefectRecordService {
    @Autowired
    private DeviceDefectRecordMapper deviceDefectRecordMapper;
    @Autowired
    private DeviceRepairMapper deviceRepairMapper;
    @Override
    public IPage<DeviceDefectRecordDto> listPage(Page page, DeviceDefectRecordDto deviceDefectRecordDto) {
        return deviceDefectRecordMapper.listPage(page, deviceDefectRecordDto);
    }
    @Override
    public boolean add(DeviceDefectRecord deviceDefectRecord) {
        String status = deviceDefectRecord.getStatus();
        if (status.equals("严重缺陷")) {
            DeviceRepair deviceRepair = new DeviceRepair();
            deviceRepair.setDeviceLedgerId(deviceDefectRecord.getDeviceLedgerId());
            deviceRepair.setRemark(deviceDefectRecord.getDefectDescription());
            //获取当前登录用户
            deviceRepair.setRepairName(SecurityUtils.getUsername());
            deviceRepair.setRepairTime(new Date());
            deviceRepairMapper.insert(deviceRepair);
            return deviceDefectRecordMapper.insert(deviceDefectRecord) > 0;
        } else if (status.equals("一般缺陷")) {
            return deviceDefectRecordMapper.insert(deviceDefectRecord) > 0;
        }
        return false;
    }
    @Override
    public boolean updateByDDR(DeviceDefectRecord deviceDefectRecord) {
        String status = deviceDefectRecord.getStatus();
        if (status.equals("严重缺陷")) {
//            deviceDefectRecord.setStatus("正常");
//            deviceDefectRecord.setEliminateTime(LocalDateTime.now());
            throw new RuntimeException("严重缺陷-设备维修后更新为正常状态");
        } else if (status.equals("一般缺陷")) {
            deviceDefectRecord.setStatus("正常");
        }
        deviceDefectRecord.setEliminateTime(LocalDateTime.now());
        return updateById(deviceDefectRecord);
    }
}
src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
@@ -23,6 +24,7 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
src/main/java/com/ruoyi/device/service/impl/DeviceRepairServiceImpl.java
@@ -5,10 +5,16 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.device.dto.DeviceDefectRecordDto;
import com.ruoyi.device.dto.DeviceRepairDto;
import com.ruoyi.device.execl.DeviceRepairExeclDto;
import com.ruoyi.device.mapper.DeviceDefectRecordMapper;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceDefectRecord;
import com.ruoyi.device.pojo.DeviceLedger;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.device.service.DeviceDefectRecordService;
import com.ruoyi.device.service.IDeviceLedgerService;
import com.ruoyi.device.service.IDeviceRepairService;
import com.ruoyi.framework.web.domain.AjaxResult;
import lombok.AllArgsConstructor;
@@ -26,10 +32,12 @@
@Slf4j
public class DeviceRepairServiceImpl extends ServiceImpl<DeviceRepairMapper, DeviceRepair> implements IDeviceRepairService {
    @Autowired
    private DeviceDefectRecordService deviceDefectRecordService;
    @Autowired
    private DeviceRepairMapper deviceRepairMapper;
    @Autowired
    private IDeviceLedgerService deviceLedgerService;
    @Override
    public IPage<DeviceRepairDto> queryPage(Page page, DeviceRepairDto deviceRepairDto) {
@@ -38,6 +46,9 @@
    @Override
    public AjaxResult saveDeviceRepair(DeviceRepair deviceRepair) {
        DeviceLedger byId = deviceLedgerService.getById(deviceRepair.getDeviceLedgerId());
        deviceRepair.setDeviceName(byId.getDeviceName());
        deviceRepair.setDeviceModel(byId.getDeviceModel());
        boolean save = this.save(deviceRepair);
        if (save){
            return AjaxResult.success();
@@ -48,6 +59,18 @@
    @Override
    public AjaxResult updateDeviceRepair(DeviceRepair deviceRepair) {
        if (this.updateById(deviceRepair)) {
            Long id = deviceRepair.getId();
            //
            DeviceDefectRecordDto deviceDefectRecordDto = new DeviceDefectRecordDto();
            deviceDefectRecordDto.setDeviceLedgerId(id);
            deviceDefectRecordDto.setStatus("严重缺陷");
            List<DeviceDefectRecordDto> records = deviceDefectRecordService.listPage(new Page<>(1, -1), deviceDefectRecordDto).getRecords();
            if (!records.isEmpty()){
                records.forEach(deviceDefectRecord -> {
                    deviceDefectRecord.setStatus("正常");
                    deviceDefectRecordService.updateByDDR(deviceDefectRecord);
                });
            }
            return AjaxResult.success();
        }
        return AjaxResult.error();
src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
@@ -63,8 +63,8 @@
                .build()
                /* è®¾ç½®å®‰å…¨æ¨¡å¼ï¼Œswagger可以设置访问token */
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts())
                .pathMapping(pathMapping);
                .securityContexts(securityContexts());
//                .pathMapping(pathMapping);
    }
    /**
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -374,29 +374,31 @@
        }
        // åº”æ”¶
        List<SalesLedger> salesLedgers = salesLedgerMapper.selectList(new LambdaQueryWrapper<SalesLedger>()
                .ge(SalesLedger::getEntryDate, startDate)
                .lt(SalesLedger::getEntryDate, endDate)
//                .ge(SalesLedger::getEntryDate, startDate)
//                .lt(SalesLedger::getEntryDate, endDate)
        );
        BigDecimal receivableMoney = salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // åº”付
        List<PurchaseLedger> procurementRecords = purchaseLedgerMapper.selectList(new LambdaQueryWrapper<PurchaseLedger>()
                .ge(PurchaseLedger::getEntryDate, startDate)
                .lt(PurchaseLedger::getEntryDate, endDate)
//                .ge(PurchaseLedger::getEntryDate, startDate)
//                .lt(PurchaseLedger::getEntryDate, endDate)
        );
        BigDecimal payableMoney = procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // é¢„æ”¶
        List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>()
                .ge(ReceiptPayment::getReceiptPaymentDate, startDate)
                .lt(ReceiptPayment::getReceiptPaymentDate, endDate));
//                .ge(ReceiptPayment::getReceiptPaymentDate, startDate)
//                .lt(ReceiptPayment::getReceiptPaymentDate, endDate)
        );
        BigDecimal advanceMoney = receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        // é¢„付
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new LambdaQueryWrapper<PaymentRegistration>()
                .ge(PaymentRegistration::getPaymentDate, startDate)
                .lt(PaymentRegistration::getPaymentDate, endDate));
//                .ge(PaymentRegistration::getPaymentDate, startDate)
//                .lt(PaymentRegistration::getPaymentDate, endDate)
        );
        BigDecimal prepayMoney = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        StatisticsReceivablePayableDto statisticsReceivablePayableDto = new StatisticsReceivablePayableDto();
        statisticsReceivablePayableDto.setPayableMoney(payableMoney);
        statisticsReceivablePayableDto.setReceivableMoney(receivableMoney);
        statisticsReceivablePayableDto.setPayableMoney(payableMoney.subtract(prepayMoney));
        statisticsReceivablePayableDto.setReceivableMoney(receivableMoney.subtract(advanceMoney));
        statisticsReceivablePayableDto.setAdvanceMoney(advanceMoney);
        statisticsReceivablePayableDto.setPrepayMoney(prepayMoney);
src/main/java/com/ruoyi/inspectiontask/StorageAttachmentRecordType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.inspectiontask;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * é™„件记录类型枚举
 *
 */
@Getter
@AllArgsConstructor
public enum StorageAttachmentRecordType {
    // ä¾‹å­ å®žé™…开发请删除
    Template("Template","范例"),
    Archives("Archives","文档管理"),
    InspectionTasks("InspectionTasks","生产巡检"),
    QrCodeScanRecords("QrCodeScanRecords","二维码扫码记录文件");
    private final String code;
    private final String info;
}
src/main/java/com/ruoyi/inspectiontask/controller/InspectionTaskController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.ruoyi.inspectiontask.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.inspectiontask.dto.InspectionTaskDto;
import com.ruoyi.inspectiontask.pojo.InspectionTask;
import com.ruoyi.inspectiontask.service.InspectionTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
/**
 * @author :yys
 * @date : 2025/9/19 10:52
 */
@RestController
@Api(tags = "巡检任务管理")
@RequestMapping("/inspectionTask")
public class InspectionTaskController extends BaseController {
    @Autowired
    private InspectionTaskService inspectionTaskService;
    /**
     * å·¡æ£€ä»»åŠ¡è¡¨è¡¨æŸ¥è¯¢
     */
    @GetMapping("/list")
    @ApiOperation("巡检任务表表查询")
    public R<IPage<InspectionTaskDto>> list(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto) {
        IPage<InspectionTaskDto> list = inspectionTaskService.selectInspectionTaskList(page,inspectionTaskDto);
        return R.ok(list);
    }
    /**
     * å·¡æ£€ä»»åŠ¡è¡¨æ–°å¢žä¿®æ”¹
     */
    @PostMapping("/addOrEditInspectionTask")
    @ApiOperation("巡检任务表新增修改")
    @Transactional(rollbackFor = Exception.class)
    public R addOrEditInspectionTask(@RequestBody InspectionTaskDto inspectionTaskDto) {
        return R.ok(inspectionTaskService.addOrEditInspectionTask(inspectionTaskDto));
    }
    /**
     * å·¡æ£€ä»»åŠ¡è¡¨åˆ é™¤
     */
    @DeleteMapping("/delInspectionTask")
    @ApiOperation("巡检任务表删除")
    @Transactional(rollbackFor = Exception.class)
    public R remove(@RequestBody Long[] ids) {
        return R.ok(inspectionTaskService.delByIds(ids));
    }
}
src/main/java/com/ruoyi/inspectiontask/controller/QrCodeController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.ruoyi.inspectiontask.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.inspectiontask.dto.QrCodeDto;
import com.ruoyi.inspectiontask.pojo.QrCode;
import com.ruoyi.inspectiontask.service.QrCodeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
 * @author :yys
 * @date : 2025/9/19 10:52
 */
@RestController
@Api(tags = "二维码管理")
@RequestMapping("/qrCode")
public class QrCodeController extends BaseController {
    @Autowired
    private QrCodeService qrCodeService;
    /**
     * äºŒç»´ç ç®¡ç†è¡¨æŸ¥è¯¢
     */
    @GetMapping("/list")
    @ApiOperation("二维码管理表查询")
    public R<IPage<QrCode>> list(Page page, QrCodeDto qrCodeDto) {
        IPage<QrCode> list = qrCodeService.selectQrCodeList(page, qrCodeDto);
        return R.ok(list);
    }
    /**
     * äºŒç»´ç ç®¡ç†è¡¨æ–°å¢žä¿®æ”¹
     */
    @PostMapping("/addOrEditQrCode")
    @ApiOperation("二维码管理表新增修改")
    public R<Long> addOrEditQrCode(@RequestBody QrCodeDto qrCodeDto) {
        return R.ok(qrCodeService.addOrEditQrCode(qrCodeDto));
    }
    /**
     * äºŒç»´ç ç®¡ç†è¡¨åˆ é™¤
     */
    @DeleteMapping("/delQrCode")
    @ApiOperation("二维码管理表删除")
    public R remove(@RequestBody Long[] ids) {
        return R.ok(qrCodeService.delByIds(ids));
    }
}
src/main/java/com/ruoyi/inspectiontask/controller/QrCodeScanRecordController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.ruoyi.inspectiontask.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.inspectiontask.dto.QrCodeScanRecordDto;
import com.ruoyi.inspectiontask.pojo.QrCodeScanRecord;
import com.ruoyi.inspectiontask.service.QrCodeScanRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
 * @author :yys
 * @date : 2025/9/19 10:53
 */
@RestController
@Api(tags = "二维码扫描记录管理")
@RequestMapping("/qrCodeScanRecord")
public class QrCodeScanRecordController extends BaseController {
    @Autowired
    private QrCodeScanRecordService qrCodeScanRecordService;
    /**
     * äºŒç»´ç æ‰«ç è®°å½•表查询
     */
    @GetMapping("/list")
    @ApiOperation("二维码扫码记录表查询")
    public R<IPage<QrCodeScanRecordDto>> list(Page<QrCodeScanRecord> page, QrCodeScanRecordDto qrCodeScanRecordDto) {
        IPage<QrCodeScanRecordDto> list = qrCodeScanRecordService.selectQrCodeScanRecordList(page, qrCodeScanRecordDto);
        return R.ok(list);
    }
    /**
     * äºŒç»´ç æ‰«ç è®°å½•表新增修改
     */
    @PostMapping("/addOrEditQrCodeRecord")
    @ApiOperation("二维码扫码记录表新增修改")
    public R addOrEditQrCodeRecord(@RequestBody QrCodeScanRecordDto qrCodeScanRecordDto) {
        return R.ok(qrCodeScanRecordService.addOrEditQrCodeRecord(qrCodeScanRecordDto));
    }
    /**
     * äºŒç»´ç æ‰«ç è®°å½•表删除
     */
    @DeleteMapping("/delSalesRecord")
    @ApiOperation("二维码扫码记录表删除")
    public R remove(@RequestBody Long[] ids) {
        return R.ok(qrCodeScanRecordService.delByIds(ids));
    }
}
src/main/java/com/ruoyi/inspectiontask/controller/TimingTaskController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.ruoyi.inspectiontask.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.inspectiontask.dto.TimingTaskDto;
import com.ruoyi.inspectiontask.pojo.TimingTask;
import com.ruoyi.inspectiontask.service.TimingTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
 * @author :yys
 * @date : 2025/9/19 10:53
 */
@RestController
@Api(tags = "定时任务管理")
@RequestMapping("/timingTask")
public class TimingTaskController extends BaseController {
    @Autowired
    private TimingTaskService timingTaskService;
    /**
     * å®šæ—¶å·¡æ£€ä»»åŠ¡è¡¨æŸ¥è¯¢
     */
    @GetMapping("/list")
    @ApiOperation(value = "定时任务列表")
    public R<IPage<TimingTaskDto>> list(Page<TimingTask> page, TimingTask timingTask) {
        IPage<TimingTaskDto> list = timingTaskService.selectTimingTaskList(page,timingTask);
        return R.ok(list);
    }
    /**
     * å®šæ—¶å·¡æ£€ä»»åŠ¡è¡¨æ–°å¢žä¿®æ”¹
     */
    @PostMapping("/addOrEditTimingTask")
    @ApiOperation(value = "新增修改定时任务")
    public R addOrEditTimingTask(@RequestBody TimingTaskDto timingTaskDto) throws SchedulerException {
        return R.ok(timingTaskService.addOrEditTimingTask(timingTaskDto));
    }
    /**
     * å®šæ—¶å·¡æ£€ä»»åŠ¡è¡¨åˆ é™¤
     */
    @DeleteMapping("/delTimingTask")
    @ApiOperation(value = "删除定时任务")
    public R remove(@RequestBody Long[] ids) {
        return R.ok(timingTaskService.delByIds(ids));
    }
}
src/main/java/com/ruoyi/inspectiontask/dto/InspectionTaskDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.inspectiontask.dto;
import com.ruoyi.basic.dto.StorageBlobDTO;
import com.ruoyi.basic.pojo.StorageAttachment;
import com.ruoyi.inspectiontask.pojo.InspectionTask;
import lombok.Data;
import java.util.List;
@Data
public class InspectionTaskDto extends InspectionTask {
    private List<StorageBlobDTO> storageBlobDTO;
    private List<StorageBlobDTO> beforeProduction;
    private List<StorageBlobDTO> afterProduction;
    private List<StorageBlobDTO> productionIssues;
    private List<StorageAttachment> attachments;
}
src/main/java/com/ruoyi/inspectiontask/dto/QrCodeDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.ruoyi.inspectiontask.dto;
import com.ruoyi.inspectiontask.pojo.QrCode;
import lombok.Data;
@Data
public class QrCodeDto extends QrCode {
}
src/main/java/com/ruoyi/inspectiontask/dto/QrCodeScanRecordDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.inspectiontask.dto;
import com.ruoyi.basic.dto.StorageBlobDTO;
import com.ruoyi.inspectiontask.pojo.QrCode;
import com.ruoyi.inspectiontask.pojo.QrCodeScanRecord;
import lombok.Data;
import java.util.List;
@Data
public class QrCodeScanRecordDto extends QrCodeScanRecord {
    private QrCode qrCode;
    private String scanner;
    private List<StorageBlobDTO> storageBlobDTO;
}
src/main/java/com/ruoyi/inspectiontask/dto/TimingTaskDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.ruoyi.inspectiontask.dto;
import com.ruoyi.inspectiontask.pojo.TimingTask;
import lombok.Data;
import java.util.List;
@Data
public class TimingTaskDto extends TimingTask {
    private List<String> inspector;
}
src/main/java/com/ruoyi/inspectiontask/mapper/InspectionTaskMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.inspectiontask.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.inspectiontask.pojo.InspectionTask;
/**
 * @author :yys
 * @date : 2025/9/19 10:46
 */
public interface InspectionTaskMapper extends BaseMapper<InspectionTask> {
}
src/main/java/com/ruoyi/inspectiontask/mapper/QrCodeMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.inspectiontask.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.inspectiontask.pojo.QrCode;
/**
 * @author :yys
 * @date : 2025/9/19 10:46
 */
public interface QrCodeMapper extends BaseMapper<QrCode> {
}
src/main/java/com/ruoyi/inspectiontask/mapper/QrCodeScanRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.inspectiontask.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.inspectiontask.pojo.QrCodeScanRecord;
/**
 * @author :yys
 * @date : 2025/9/19 10:46
 */
public interface QrCodeScanRecordMapper extends BaseMapper<QrCodeScanRecord> {
}
src/main/java/com/ruoyi/inspectiontask/mapper/TimingTaskMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.ruoyi.inspectiontask.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.inspectiontask.pojo.TimingTask;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * @author :yys
 * @date : 2025/9/19 10:47
 */
@Mapper
public interface TimingTaskMapper extends BaseMapper<TimingTask> {
    TimingTask getTaskById(@Param("id") Long id);
}
src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
package com.ruoyi.inspectiontask.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
 * @author :yys
 * @date : 2025/9/19 10:25
 */
@Data
@ApiModel
@TableName("inspection_task")
public class InspectionTask {
    private static final long serialVersionUID = 1L;
    /**
     * å·¡æ£€ä»»åŠ¡å”¯ä¸€æ ‡è¯†
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "设备名称")
    private String taskName;
    @ApiModelProperty(value = "设备id")
    private Integer taskId;
    @ApiModelProperty(value = "巡检人ID")
    private String inspectorId;
    @ApiModelProperty(value = "执行巡检的人员姓名")
    private String inspector;
    @ApiModelProperty(value = "任务附加说明或特殊情况记录")
    private String remarks;
    @ApiModelProperty(value = "任务登记人ID")
    private Long registrantId;
    @ApiModelProperty(value = "任务登记人姓名")
    private String registrant;
    @ApiModelProperty(value = "频次")
    private String frequencyType;
    @ApiModelProperty(value = "时间细节")
    private String frequencyDetail;
    @ApiModelProperty(value = "巡检地点详细描述")
    private String inspectionLocation;
    @ApiModelProperty(value = "软删除标志,0=未删除,1=已删除")
    private Integer deleted;
    @ApiModelProperty(value = "创建该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "记录创建时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "最后修改该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "记录最后更新时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "租户")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/inspectiontask/pojo/QrCode.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.ruoyi.inspectiontask.pojo;
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 com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
 * @author :yys
 * @date : 2025/9/19 10:29
 */
@Data
@ApiModel
@TableName("qr_code")
public class QrCode {
    private static final long serialVersionUID = 1L;
    /**
     * äºŒç»´ç å”¯ä¸€æ ‡è¯†
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "设备名称")
    private String deviceName;
    @ApiModelProperty(value = "所在位置描述")
    private String location;
    @ApiModelProperty(value = "租户ID,用于多租户隔离")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty(value = "软删除标志,0=未删除,1=已删除")
    private Integer deleted;
    @ApiModelProperty(value = "创建该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "记录创建时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "最后修改该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "记录最后更新时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
src/main/java/com/ruoyi/inspectiontask/pojo/QrCodeScanRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package com.ruoyi.inspectiontask.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
 * @author :yys
 * @date : 2025/9/19 10:29
 */
@Data
@TableName("qr_code_scan_record")
@ApiModel
public class QrCodeScanRecord {
    private static final long serialVersionUID = 1L;
    /**
     * æ‰«ç è®°å½•唯一标识
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "关联的二维码ID")
    private Long qrCodeId;
    @ApiModelProperty(value = "扫码人用户ID")
    private Long scannerId;
    @ApiModelProperty(value = "设备名称")
    private String deviceName;
    @ApiModelProperty(value = "设备id")
    private Integer deviceId;
    @ApiModelProperty(value = "实际扫码时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime scanTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty(value = "软删除标志,0=未删除,1=已删除")
    private Integer deleted;
    @ApiModelProperty(value = "创建该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "记录创建时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "最后修改该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "记录最后更新时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}
src/main/java/com/ruoyi/inspectiontask/pojo/TimingTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
package com.ruoyi.inspectiontask.pojo;
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 com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
 * @author :yys
 * @date : 2025/9/19 10:27
 */
@Data
@ApiModel
@TableName("timing_task")
public class TimingTask {
    private static final long serialVersionUID = 1L;
    /**
     * ä¸»é”®ID
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "设备名称")
    private String taskName;
    @ApiModelProperty(value = "设备id")
    private Integer taskId;
    @ApiModelProperty(value = "巡检人")
    private String inspectorIds;
    @ApiModelProperty(value = "巡检地点")
    private String inspectionLocation;
    @ApiModelProperty(value = "频次")
    private String frequencyType;
    @ApiModelProperty(value = "频次详情")
    private String frequencyDetail;
    @ApiModelProperty(value = "下次执行时间")
    private LocalDateTime nextExecutionTime;
    @ApiModelProperty(value = "最后执行时间")
    private LocalDateTime lastExecutionTime;
    @ApiModelProperty(value = "是否激活")
    private boolean isActive;
    @ApiModelProperty(value = "备注")
    private String remarks;
    @ApiModelProperty(value = "登记人id")
    private Long registrantId;
    @ApiModelProperty(value = "登记人")
    private String registrant;
    @ApiModelProperty(value = "登记日期")
    private LocalDate registrationDate;
    @ApiModelProperty(value = "状态")
    private String status;
    @ApiModelProperty(value = "软删除标志,0=未删除,1=已删除")
    private Integer deleted;
    @ApiModelProperty(value = "创建该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "记录创建时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "最后修改该记录的用户")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "记录最后更新时间")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/inspectiontask/service/InspectionTaskService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.inspectiontask.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.inspectiontask.dto.InspectionTaskDto;
import com.ruoyi.inspectiontask.pojo.InspectionTask;
/**
 * @author :yys
 * @date : 2025/9/19 10:49
 */
public interface InspectionTaskService extends IService<InspectionTask> {
    IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto);
    int addOrEditInspectionTask(InspectionTaskDto inspectionTaskDto);
    int delByIds(Long[] ids);
}
src/main/java/com/ruoyi/inspectiontask/service/QrCodeScanRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.inspectiontask.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.inspectiontask.dto.QrCodeScanRecordDto;
import com.ruoyi.inspectiontask.pojo.QrCodeScanRecord;
/**
 * @author :yys
 * @date : 2025/9/19 10:50
 */
public interface QrCodeScanRecordService extends IService<QrCodeScanRecord> {
    IPage<QrCodeScanRecordDto> selectQrCodeScanRecordList(Page<QrCodeScanRecord> page, QrCodeScanRecordDto qrCodeScanRecordDto);
    int addOrEditQrCodeRecord(QrCodeScanRecordDto qrCodeScanRecordDto);
    int delByIds(Long[] ids);
}
src/main/java/com/ruoyi/inspectiontask/service/QrCodeService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ruoyi.inspectiontask.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.inspectiontask.dto.QrCodeDto;
import com.ruoyi.inspectiontask.pojo.QrCode;
/**
 * @author :yys
 * @date : 2025/9/19 10:50
 */
public interface QrCodeService extends IService<QrCode>{
    IPage<QrCode> selectQrCodeList(Page page, QrCodeDto qrCodeDto);
    Long addOrEditQrCode(QrCodeDto qrCodeDto);
    int delByIds(Long[] ids);
}
src/main/java/com/ruoyi/inspectiontask/service/TimingTaskService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.inspectiontask.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.inspectiontask.dto.TimingTaskDto;
import com.ruoyi.inspectiontask.pojo.TimingTask;
import org.quartz.SchedulerException;
/**
 * @author :yys
 * @date : 2025/9/19 10:51
 */
public interface TimingTaskService extends IService<TimingTask> {
    IPage<TimingTaskDto> selectTimingTaskList(Page<TimingTask> page, TimingTask timingTask);
    int addOrEditTimingTask(TimingTaskDto timingTaskDto) throws SchedulerException;
    int delByIds(Long[] ids);
    void updateTaskExecutionTime(Long taskId);
}
src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,257 @@
package com.ruoyi.inspectiontask.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.StorageBlobDTO;
import com.ruoyi.basic.mapper.StorageAttachmentMapper;
import com.ruoyi.basic.mapper.StorageBlobMapper;
import com.ruoyi.basic.pojo.StorageAttachment;
import com.ruoyi.basic.pojo.StorageBlob;
import com.ruoyi.basic.service.StorageAttachmentService;
import com.ruoyi.common.utils.MinioUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.inspectiontask.dto.InspectionTaskDto;
import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper;
import com.ruoyi.inspectiontask.pojo.InspectionTask;
import com.ruoyi.inspectiontask.service.InspectionTaskService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.ruoyi.common.constant.StorageAttachmentConstants.StorageAttachmentFile;
import static com.ruoyi.common.enums.StorageAttachmentRecordType.InspectionTasks;
/**
 * @author :yys
 * @date : 2025/9/19 10:54
 */
@Service
@Slf4j
public class InspectionTaskServiceImpl extends ServiceImpl<InspectionTaskMapper, InspectionTask> implements InspectionTaskService {
    @Autowired
    private InspectionTaskMapper inspectionTaskMapper;
    @Autowired
    private StorageAttachmentService storageAttachmentService;
    @Autowired
    private StorageBlobMapper storageBlobMapper;
    @Autowired
    private StorageAttachmentMapper storageAttachmentMapper;
    @Autowired
    private MinioUtils minioUtils;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto) {
        LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(InspectionTask::getCreateTime);
        IPage<InspectionTask> entityPage = inspectionTaskMapper.selectPage(page, queryWrapper);
        //  æ— æ•°æ®æå‰è¿”回
        if (CollectionUtils.isEmpty(entityPage.getRecords())) {
            return new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal());
        }
        // èŽ·å–id集合
        List<Long> ids = entityPage.getRecords().stream().map(InspectionTask::getId).collect(Collectors.toList());
        //登记人ids
        List<Long> registrantIds = entityPage.getRecords().stream().map(InspectionTask::getRegistrantId).collect(Collectors.toList());
        // æ‰¹é‡æŸ¥è¯¢ç™»è®°äºº
        Map<Long, SysUser> sysUserMap;
        if (!registrantIds.isEmpty()) {
            List<SysUser> sysUsers = sysUserMapper.selectList(registrantIds);
            sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
        } else {
            sysUserMap = new HashMap<>();
        }
        //巡检人ids
        List<String> inspectorIds = entityPage.getRecords().stream().map(InspectionTask::getInspectorId).collect(Collectors.toList());
        //获取所有不重复的用户ID
        Set<Long> allUserIds = entityPage.getRecords().stream()
                .map(InspectionTask::getInspectorId) // èŽ·å–"2,3"这样的字符串
                .filter(StringUtils::isNotBlank)
                .flatMap(idsStr -> Arrays.stream(idsStr.split(",")))
                .map(idStr -> {
                    try {
                        return Long.parseLong(idStr.trim());
                    } catch (NumberFormatException e) {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // ä½¿ç”¨SQL批量查询用户信息
        Map<Long, String> userIdToNameMap = allUserIds.isEmpty()
                ? Collections.emptyMap()
                : sysUserMapper.selectUsersByIds(new ArrayList<>(allUserIds))
                .stream()
                .collect(Collectors.toMap(
                        SysUser::getUserId,
                        SysUser::getNickName,
                        (existing, replacement) -> existing));
        //处理附件
        Map<Long, List<StorageAttachment>> attachmentsMap = storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>().in(StorageAttachment::getRecordId, ids)
                        .eq(StorageAttachment::getRecordType, InspectionTasks.ordinal()))
                .stream()
                .collect(Collectors.groupingBy(StorageAttachment::getRecordId));
        //  æ‰¹é‡æŸ¥è¯¢æ‰€æœ‰éœ€è¦çš„æ–‡ä»¶æ•°æ®
        Set<Long> blobIds = attachmentsMap.values()
                .stream()
                .flatMap(List::stream)
                .map(StorageAttachment::getStorageBlobId)
                .collect(Collectors.toSet());
        Map<Long, StorageBlob> blobMap = blobIds.isEmpty()
                ? Collections.emptyMap()
                : storageBlobMapper.selectList(new LambdaQueryWrapper<StorageBlob>().in(StorageBlob::getId, blobIds))
                .stream()
                .collect(Collectors.toMap(StorageBlob::getId, Function.identity()));
        List<InspectionTaskDto> dtoList = entityPage.getRecords().stream().map(inspectionTask -> {
            InspectionTaskDto dto = new InspectionTaskDto();
            BeanUtils.copyProperties(inspectionTask, dto);  // å¤åˆ¶ä¸»å¯¹è±¡å±žæ€§
            // è®¾ç½®ç™»è®°äºº
            SysUser sysUser = sysUserMap.get(inspectionTask.getRegistrantId());
            if (sysUser != null) {
                dto.setRegistrant(sysUser.getNickName());
            }
            // å¤„理巡检人名称
            if (StringUtils.isNotBlank(inspectionTask.getInspectorId())) {
                String inspectorNames = Arrays.stream(inspectionTask.getInspectorId().split(","))
                        .map(String::trim)
                        .map(idStr -> {
                            try {
                                Long userId = Long.parseLong(idStr);
                                return userIdToNameMap.getOrDefault(userId, "未知用户(" + idStr + ")");
                            } catch (NumberFormatException e) {
                                return "无效ID(" + idStr + ")";
                            }
                        })
                        .collect(Collectors.joining(","));
                dto.setInspector(inspectorNames);
            }
            // åˆå§‹åŒ–三个附件列表
            dto.setBeforeProduction(new ArrayList<>());
            dto.setAfterProduction(new ArrayList<>());
            dto.setProductionIssues(new ArrayList<>());
            // å¤„理附件分类
            Optional.ofNullable(attachmentsMap.get(inspectionTask.getId()))
                    .orElse(Collections.emptyList())
                    .forEach(attachment -> {
                        StorageBlob blob = blobMap.get(attachment.getStorageBlobId());
                        if (blob != null) {
                            // åˆ›å»ºé™„ä»¶DTO
                            StorageBlobDTO blobDto = createBlobDto(blob);
                            // æ ¹æ®type分类
                            switch ((int) blob.getType().longValue()) {
                                case 0:
                                    dto.getBeforeProduction().add(blobDto);
                                    break;
                                case 1:
                                    dto.getAfterProduction().add(blobDto);
                                    break;
                                case 2:
                                    dto.getProductionIssues().add(blobDto);
                                    break;
                                default:
                                    // å¯é€‰ï¼šè®°å½•未分类类型
                                    break;
                            }
                        }
                    });
            return dto;
        }).collect(Collectors.toList());
        // 7. æž„建返回分页对象
        IPage<InspectionTaskDto> resultPage = new Page<>();
        BeanUtils.copyProperties(entityPage, resultPage);
        resultPage.setRecords(dtoList);
        return resultPage;
    }
    // æå–创建BlobDTO的公共方法
    private StorageBlobDTO createBlobDto(StorageBlob blob) {
        StorageBlobDTO dto = new StorageBlobDTO();
        BeanUtils.copyProperties(blob, dto);
        // è®¾ç½®URL
        dto.setUrl(minioUtils.getPreviewUrls(
                blob.getBucketFilename(),
                blob.getBucketName(),
                true
        ));
        // è®¾ç½®ä¸‹è½½URL
        dto.setDownloadUrl(minioUtils.getDownloadUrls(
                blob.getBucketFilename(),
                blob.getBucketName(),
                blob.getOriginalFilename(),
                true
        ));
        return dto;
    }
    @Override
    public int addOrEditInspectionTask(InspectionTaskDto inspectionTaskDto) {
        InspectionTask inspectionTask = new InspectionTask();
        BeanUtils.copyProperties(inspectionTaskDto, inspectionTask);
        inspectionTask.setRegistrantId(SecurityUtils.getLoginUser().getUserId());
        inspectionTask.setRegistrant(SecurityUtils.getLoginUser().getUsername());
        int i;
        if (Objects.isNull(inspectionTaskDto.getId())) {
            i = inspectionTaskMapper.insert(inspectionTask);
        } else {
            i = inspectionTaskMapper.updateById(inspectionTask);
        }
        if (inspectionTaskDto.getStorageBlobDTO() != null && !inspectionTaskDto.getStorageBlobDTO().isEmpty()) {
            List<StorageAttachment> attachments = new ArrayList<>();
            for (StorageBlobDTO storageBlobDTO : inspectionTaskDto.getStorageBlobDTO()) {
                StorageAttachment storageAttachment = new StorageAttachment(
                        StorageAttachmentFile,
                        (long) InspectionTasks.ordinal(),
                        inspectionTask.getId()
                );
                storageAttachment.setStorageBlobDTO(storageBlobDTO);
                attachments.add(storageAttachment);
            }
            storageAttachmentService.saveStorageAttachment(attachments, inspectionTask.getId(), InspectionTasks, StorageAttachmentFile);
        }
        return i;
    }
    @Override
    public int delByIds(Long[] ids) {
        // æ£€æŸ¥å‚æ•°
        if (ids == null || ids.length == 0) {
            return 0;
        }
        return inspectionTaskMapper.deleteBatchIds(Arrays.asList(ids));
    }
}
src/main/java/com/ruoyi/inspectiontask/service/impl/QrCodeScanRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,194 @@
package com.ruoyi.inspectiontask.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.StorageBlobDTO;
import com.ruoyi.basic.mapper.StorageAttachmentMapper;
import com.ruoyi.basic.mapper.StorageBlobMapper;
import com.ruoyi.basic.pojo.StorageAttachment;
import com.ruoyi.basic.pojo.StorageBlob;
import com.ruoyi.basic.service.StorageAttachmentService;
import com.ruoyi.common.constant.StorageAttachmentConstants;
import com.ruoyi.common.utils.MinioUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.inspectiontask.dto.QrCodeScanRecordDto;
import com.ruoyi.inspectiontask.mapper.QrCodeMapper;
import com.ruoyi.inspectiontask.mapper.QrCodeScanRecordMapper;
import com.ruoyi.inspectiontask.pojo.QrCode;
import com.ruoyi.inspectiontask.pojo.QrCodeScanRecord;
import com.ruoyi.inspectiontask.service.QrCodeScanRecordService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.ruoyi.common.constant.StorageAttachmentConstants.StorageAttachmentFile;
import static com.ruoyi.common.enums.StorageAttachmentRecordType.QrCodeScanRecords;
/**
 * @author :yys
 * @date : 2025/9/19 10:54
 */
@Service
@Slf4j
public class QrCodeScanRecordServiceImpl extends ServiceImpl<QrCodeScanRecordMapper, QrCodeScanRecord> implements QrCodeScanRecordService {
    @Autowired
    private QrCodeScanRecordMapper qrCodeScanRecordMapper;
    @Autowired
    private QrCodeMapper qrCodeMapper;
    @Autowired
    private StorageAttachmentService storageAttachmentService;
    @Autowired
    private StorageBlobMapper storageBlobMapper;
    @Autowired
    private StorageAttachmentMapper storageAttachmentMapper;
    @Autowired
    private MinioUtils minioUtils;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public IPage<QrCodeScanRecordDto> selectQrCodeScanRecordList(Page<QrCodeScanRecord> page, QrCodeScanRecordDto qrCodeScanRecordDto) {
        // 1. æž„建基础查询条件
        LambdaQueryWrapper<QrCodeScanRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(QrCodeScanRecord::getCreateTime);
        // 2. æ‰§è¡Œåˆ†é¡µæŸ¥è¯¢
        IPage<QrCodeScanRecord> scanRecordIPage = qrCodeScanRecordMapper.selectPage(page, queryWrapper);
        // 3. æ— æ•°æ®æå‰è¿”回
        if (CollectionUtils.isEmpty(scanRecordIPage.getRecords())) {
            return new Page<>(scanRecordIPage.getCurrent(), scanRecordIPage.getSize(), scanRecordIPage.getTotal());
        }
        // 4. æ‰¹é‡èŽ·å–æ‰€æœ‰è®°å½•ID和二维码ID
        List<Long> recordIds = scanRecordIPage.getRecords().stream()
                .map(QrCodeScanRecord::getId)
                .collect(Collectors.toList());
        Set<Long> qrCodeIds = scanRecordIPage.getRecords().stream()
                .map(QrCodeScanRecord::getQrCodeId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // 5. æ‰¹é‡æŸ¥è¯¢å…³è”数据(使用最新API)
        // 5.1 æŸ¥è¯¢äºŒç»´ç ä¿¡æ¯ï¼ˆæ›¿æ¢selectBatchIds为selectByIds)
        Map<Long, QrCode> qrCodeMap = qrCodeIds.isEmpty()
                ? Collections.emptyMap()
                : qrCodeMapper.selectBatchIds(qrCodeIds).stream()
                .collect(Collectors.toMap(QrCode::getId, Function.identity()));
        // 5.2 æŸ¥è¯¢é™„件关联关系
        Map<Long, List<StorageAttachment>> attachmentsMap = storageAttachmentMapper
                .selectList(new LambdaQueryWrapper<StorageAttachment>()
                        .in(StorageAttachment::getRecordId, recordIds)
                        .eq(StorageAttachment::getRecordType, QrCodeScanRecords.ordinal()))
                .stream()
                .collect(Collectors.groupingBy(StorageAttachment::getRecordId));
        // 5.3 æŸ¥è¯¢æ–‡ä»¶æ•°æ®ï¼ˆä½¿ç”¨selectByIds)
        Set<Long> blobIds = attachmentsMap.values().stream()
                .flatMap(List::stream)
                .map(StorageAttachment::getStorageBlobId)
                .collect(Collectors.toSet());
        Map<Long, StorageBlob> blobMap = blobIds.isEmpty()
                ? Collections.emptyMap()
                : storageBlobMapper.selectBatchIds(blobIds).stream()
                .collect(Collectors.toMap(StorageBlob::getId, Function.identity()));
        // 6. ç»„装DTO数据
        List<QrCodeScanRecordDto> dtoList = scanRecordIPage.getRecords().stream().map(record -> {
            QrCodeScanRecordDto dto = new QrCodeScanRecordDto();
            BeanUtils.copyProperties(record, dto);
            SysUser sysUser = sysUserMapper.selectUserById(record.getScannerId());
            dto.setScanner(sysUser.getNickName());
            // 6.1 è®¾ç½®äºŒç»´ç ä¿¡æ¯
            Optional.ofNullable(qrCodeMap.get(record.getQrCodeId()))
                    .ifPresent(qrCode -> {
                        BeanUtils.copyProperties(qrCode, dto); // å¤åˆ¶åˆ°çˆ¶ç±»
                        dto.setQrCode(qrCode); // è®¾ç½®å®Œæ•´å¯¹è±¡
                    });
            // 6.2 è®¾ç½®é™„件信息
            dto.setStorageBlobDTO(
                    Optional.ofNullable(attachmentsMap.get(record.getId()))
                            .orElse(Collections.emptyList())
                            .stream()
                            .map(att -> {
                                StorageBlobDTO blobDTO = new StorageBlobDTO();
                                Optional.ofNullable(blobMap.get(att.getStorageBlobId()))
                                        .ifPresent(blob -> {
                                            BeanUtils.copyProperties(blob, blobDTO);
                                            blobDTO.setUrl(minioUtils.getPreviewUrls(blob.getBucketFilename(), blob.getBucketName(), true));
                                            blobDTO.setDownloadUrl(minioUtils.getDownloadUrls(blob.getBucketFilename(),blob.getBucketName(),blob.getOriginalFilename(),true));
                                        });
                                return blobDTO;
                            })
                            .filter(blobDTO -> blobDTO.getId() != null) // è¿‡æ»¤æ— æ•ˆé™„ä»¶
                            .collect(Collectors.toList())
            );
            return dto;
        }).collect(Collectors.toList());
        // 7. æž„建返回分页对象
        IPage<QrCodeScanRecordDto> resultPage = new Page<>();
        BeanUtils.copyProperties(scanRecordIPage, resultPage);
        resultPage.setRecords(dtoList);
        return resultPage;
    }
    @Override
    public int addOrEditQrCodeRecord(QrCodeScanRecordDto qrCodeScanRecordDto) {
        QrCodeScanRecord qrCodeScanRecord = new QrCodeScanRecord();
        BeanUtils.copyProperties(qrCodeScanRecordDto, qrCodeScanRecord);
        int i;
        if (Objects.isNull(qrCodeScanRecordDto.getId())) {
            i = qrCodeScanRecordMapper.insert(qrCodeScanRecord);
        } else {
            i = qrCodeScanRecordMapper.updateById(qrCodeScanRecord);
        }
        if (qrCodeScanRecordDto.getStorageBlobDTO() != null && !qrCodeScanRecordDto.getStorageBlobDTO().isEmpty()) {
            List<StorageAttachment> attachments = new ArrayList<>();
            for (StorageBlobDTO storageBlobDTO : qrCodeScanRecordDto.getStorageBlobDTO()) {
                StorageAttachment storageAttachment = new StorageAttachment(
                        StorageAttachmentFile,
                        (long) QrCodeScanRecords.ordinal(),
                        qrCodeScanRecord.getId()
                );
                storageAttachment.setStorageBlobDTO(storageBlobDTO);
                attachments.add(storageAttachment);
            }
            storageAttachmentService.saveStorageAttachment(attachments, qrCodeScanRecord.getId(), QrCodeScanRecords, StorageAttachmentFile);
        }
        return i;
    }
    @Override
    public int delByIds(Long[] ids) {
        return qrCodeScanRecordMapper.deleteBatchIds(Arrays.asList(ids));
    }
}
src/main/java/com/ruoyi/inspectiontask/service/impl/QrCodeServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
package com.ruoyi.inspectiontask.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.inspectiontask.dto.QrCodeDto;
import com.ruoyi.inspectiontask.mapper.QrCodeMapper;
import com.ruoyi.inspectiontask.pojo.QrCode;
import com.ruoyi.inspectiontask.service.QrCodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.Objects;
/**
 * @author :yys
 * @date : 2025/9/19 10:55
 */
@Service
@Slf4j
public class QrCodeServiceImpl extends ServiceImpl<QrCodeMapper, QrCode> implements QrCodeService {
    @Autowired
    private QrCodeMapper qrCodeMapper;
    @Override
    public IPage<QrCode> selectQrCodeList(Page page, QrCodeDto qrCodeDto) {
        LambdaQueryWrapper<QrCode> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(QrCode::getCreateTime);
        return qrCodeMapper.selectPage(page, queryWrapper);
    }
    @Override
    public Long addOrEditQrCode(QrCodeDto qrCodeDto) {
        QrCode qrCode = new QrCode();
        BeanUtils.copyProperties(qrCodeDto, qrCode);
        if (Objects.isNull(qrCodeDto.getId())) {
            qrCodeMapper.insert(qrCode);
        } else {
            qrCodeMapper.updateById(qrCode);
        }
        return qrCode.getId();
    }
    @Override
    public int delByIds(Long[] ids) {
        return qrCodeMapper.deleteBatchIds(Arrays.asList(ids));
    }
}
src/main/java/com/ruoyi/inspectiontask/service/impl/QuartzConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package com.ruoyi.inspectiontask.service.impl;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
@Configuration
public class QuartzConfig {
    @Autowired
    private ApplicationContext applicationContext;
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
        // é…ç½®SpringBeanJobFactory,用于支持Job中的依赖注入
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        schedulerFactory.setJobFactory(jobFactory);
        // å…¶ä»–配置...
        return schedulerFactory;
    }
    // è‡ªå®šä¹‰JobFactory,支持自动注入
    public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory
            implements ApplicationContextAware {
        private transient AutowireCapableBeanFactory beanFactory;
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) {
            this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
        }
        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
            Object jobInstance = super.createJobInstance(bundle);
            // å°†Job实例交给Spring容器管理,使其能够进行依赖注入
            beanFactory.autowireBean(jobInstance);
            return jobInstance;
        }
    }
}
src/main/java/com/ruoyi/inspectiontask/service/impl/SpringContextHolder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.inspectiontask.service.impl;
import org.quartz.JobExecutionContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextHolder implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext context) {
        applicationContext = context;
    }
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }
}
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskJob.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,259 @@
package com.ruoyi.inspectiontask.service.impl;
import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper;
import com.ruoyi.inspectiontask.mapper.TimingTaskMapper;
import com.ruoyi.inspectiontask.pojo.InspectionTask;
import com.ruoyi.inspectiontask.pojo.TimingTask;
import com.ruoyi.inspectiontask.service.TimingTaskService;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Component
@DisallowConcurrentExecution // ç¦æ­¢å¹¶å‘执行同一个Job
public class TimingTaskJob implements Job {
    @Autowired
    private TimingTaskMapper timingTaskMapper;
    @Autowired
    private TimingTaskService timingTaskService;
    @Autowired
    private InspectionTaskMapper inspectionTaskMapper;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        // ä¿®å¤ç±»åž‹è½¬æ¢é”™è¯¯ï¼Œæ­£ç¡®èŽ·å–taskId
        Long taskId = jobDataMap.getLong("taskId");
        try {
            // 3. å°è¯•查询你的业务数据
            // é€šè¿‡JDBC模板查询定时任务信息,使用参数化查询防止SQL注入
            String yourSql = "SELECT * FROM timing_task where id = ?";
            List<TimingTask> tasks = jdbcTemplate.query(
                    yourSql,
                    new BeanPropertyRowMapper<>(TimingTask.class),
                    taskId
            );
            TimingTask timingTask = tasks.isEmpty() ? null : tasks.get(0);
            if (timingTask == null) {
                throw new JobExecutionException("找不到定时任务: " + taskId);
            }
//            if (!timingTask.isActive()) {
//                throw new JobExecutionException("定时任务已禁用: " + taskId);
//            }
            // 2. åˆ›å»ºå¹¶ä¿å­˜å·¡æ£€ä»»åŠ¡è®°å½• - è¿™å°±æ˜¯æ‚¨æä¾›çš„代码应该放的位置
            InspectionTask inspectionTask = createInspectionTask(timingTask);
            inspectionTaskMapper.insert(inspectionTask);
            // 3. æ›´æ–°å®šæ—¶ä»»åŠ¡çš„æ‰§è¡Œæ—¶é—´
            if (!tasks.isEmpty()) {
                TimingTask task = tasks.get(0);
                // æ›´æ–°æœ€åŽæ‰§è¡Œæ—¶é—´ä¸ºå½“前时间
                LocalDateTime lastExecutionTime = LocalDateTime.now();
                // è®¡ç®—下次执行时间
                LocalDateTime nextExecutionTime = calculateNextExecutionTime(
                        task.getFrequencyType(),
                        task.getFrequencyDetail(),
                        lastExecutionTime
                );
                // æ‰§è¡Œæ›´æ–°æ“ä½œ
                String updateSql = "UPDATE timing_task " +
                        "SET last_execution_time = ?, next_execution_time = ? " +
                        "WHERE id = ?";
                jdbcTemplate.update(
                        updateSql,
                        lastExecutionTime,
                        nextExecutionTime,
                        taskId
                );
            }
//            timingTaskService.updateTaskExecutionTime(taskId);
            // 4. è®°å½•执行日志
//            timingTaskService.recordExecutionLog(taskId, true, "任务执行成功,生成巡检任务ID: " + inspectionTask.getId());
        } catch (Exception e) {
//            timingTaskService.recordExecutionLog(taskId, false, "任务执行失败: " + e.getMessage());
            throw new JobExecutionException(e);
        }
    }
    // è¿™å°±æ˜¯æ‚¨æä¾›çš„代码封装成的方法
    private InspectionTask createInspectionTask(TimingTask timingTask) {
        InspectionTask inspectionTask = new InspectionTask();
        // å¤åˆ¶åŸºæœ¬å±žæ€§
        inspectionTask.setTaskName(timingTask.getTaskName());
        inspectionTask.setTaskId(timingTask.getTaskId());
        inspectionTask.setInspectorId(timingTask.getInspectorIds());
        inspectionTask.setInspectionLocation(timingTask.getInspectionLocation());
        inspectionTask.setRemarks("自动生成自定时任务ID: " + timingTask.getId());
        inspectionTask.setRegistrantId(timingTask.getRegistrantId());
        inspectionTask.setFrequencyType(timingTask.getFrequencyType());
        inspectionTask.setFrequencyDetail(timingTask.getFrequencyDetail());
        inspectionTask.setTenantId(timingTask.getTenantId());
        return inspectionTask;
    }
    /**
     * è®¡ç®—下次执行时间
     */
    private LocalDateTime calculateNextExecutionTime(String frequencyType,
                                                     String frequencyDetail,
                                                     LocalDateTime currentTime) {
        try {
            switch (frequencyType) {
                case "DAILY":
                    return calculateDailyNextTime(frequencyDetail, currentTime);
                case "WEEKLY":
                    return calculateWeeklyNextTime(frequencyDetail, currentTime);
                case "MONTHLY":
                    return calculateMonthlyNextTime(frequencyDetail, currentTime);
                case "QUARTERLY":
                    return calculateQuarterlyNextTime(frequencyDetail, currentTime);
                default:
                    throw new IllegalArgumentException("不支持的频率类型: " + frequencyType);
            }
        } catch (Exception e) {
            throw new RuntimeException("计算下次执行时间失败: " + e.getMessage(), e);
        }
    }
    /**
     * è®¡ç®—每日任务的下次执行时间
     */
    private LocalDateTime calculateDailyNextTime(String timeStr, LocalDateTime current) {
        LocalTime executionTime = LocalTime.parse(timeStr); // è§£æžæ ¼å¼ "HH:mm"
        LocalDateTime nextTime = LocalDateTime.of(current.toLocalDate(), executionTime);
        // å¦‚果今天的时间已过,则安排明天
        return current.isBefore(nextTime) ? nextTime : nextTime.plusDays(1);
    }
    /**
     * è®¡ç®—每周任务的下次执行时间
     */
    private LocalDateTime calculateWeeklyNextTime(String detail, LocalDateTime current) {
        String[] parts = detail.split(",");
        String dayOfWeekStr = parts[0];  // å¦‚ "MON" æˆ– "MON|WED|FRI"
        LocalTime time = LocalTime.parse(parts[1]); // æ—¶é—´éƒ¨åˆ†
        // è§£æžæ˜ŸæœŸå‡ (支持多个星期)
        Set<DayOfWeek> targetDays = parseDayOfWeeks(dayOfWeekStr);
        // ä»Žå½“前时间开始找下一个符合条件的星期几
        LocalDateTime nextTime = current;
        while (true) {
            nextTime = nextTime.plusDays(1);
            if (targetDays.contains(nextTime.getDayOfWeek())) {
                return LocalDateTime.of(nextTime.toLocalDate(), time);
            }
            // é˜²æ­¢æ— é™å¾ªçޝ(理论上不会发生)
            if (nextTime.isAfter(current.plusYears(1))) {
                throw new RuntimeException("无法找到下次执行时间");
            }
        }
    }
    /**
     * è®¡ç®—每月任务的下次执行时间
     */
    private LocalDateTime calculateMonthlyNextTime(String detail, LocalDateTime current) {
        String[] parts = detail.split(",");
        int dayOfMonth = Integer.parseInt(parts[0]);
        LocalTime time = LocalTime.parse(parts[1]);
        // ä»Žä¸‹ä¸ªæœˆå¼€å§‹è®¡ç®—
        LocalDateTime nextTime = current.plusMonths(1)
                .withDayOfMonth(Math.min(dayOfMonth, current.plusMonths(1).toLocalDate().lengthOfMonth()))
                .with(time);
        return nextTime;
    }
    /**
     * è®¡ç®—每季度任务的下次执行时间
     */
    private LocalDateTime calculateQuarterlyNextTime(String detail, LocalDateTime current) {
        String[] parts = detail.split(",");
        int quarterMonth = Integer.parseInt(parts[0]); // 1=第1个月,2=第2个月,3=第3个月
        int dayOfMonth = Integer.parseInt(parts[1]);
        LocalTime time = LocalTime.parse(parts[2]);
        // è®¡ç®—当前季度
        int currentQuarter = (current.getMonthValue() - 1) / 3 + 1;
        int currentMonthInQuarter = (current.getMonthValue() - 1) % 3 + 1;
        YearMonth targetYearMonth;
        if (currentMonthInQuarter < quarterMonth) {
            // æœ¬å­£åº¦å†…还有执行机会
            targetYearMonth = YearMonth.from(current)
                    .plusMonths(quarterMonth - currentMonthInQuarter);
        } else {
            // éœ€è¦åˆ°ä¸‹ä¸ªå­£åº¦
            targetYearMonth = YearMonth.from(current)
                    .plusMonths(3 - currentMonthInQuarter + quarterMonth);
        }
        // å¤„理月末日期
        int adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth());
        return LocalDateTime.of(
                targetYearMonth.getYear(),
                targetYearMonth.getMonthValue(),
                adjustedDay,
                time.getHour(),
                time.getMinute()
        );
    }
    /**
     * è§£æžæ˜ŸæœŸå‡ å­—符串
     */
    private Set<DayOfWeek> parseDayOfWeeks(String dayOfWeekStr) {
        Set<DayOfWeek> days = new HashSet<>();
        String[] dayStrs = dayOfWeekStr.split("\\|");
        for (String dayStr : dayStrs) {
            switch (dayStr) {
                case "MON": days.add(DayOfWeek.MONDAY); break;
                case "TUE": days.add(DayOfWeek.TUESDAY); break;
                case "WED": days.add(DayOfWeek.WEDNESDAY); break;
                case "THU": days.add(DayOfWeek.THURSDAY); break;
                case "FRI": days.add(DayOfWeek.FRIDAY); break;
                case "SAT": days.add(DayOfWeek.SATURDAY); break;
                case "SUN": days.add(DayOfWeek.SUNDAY); break;
                default: throw new IllegalArgumentException("无效的星期几: " + dayStr);
            }
        }
        return days;
    }
}
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskScheduler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,239 @@
package com.ruoyi.inspectiontask.service.impl;
import com.ruoyi.inspectiontask.pojo.TimingTask;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.Date;
import java.util.stream.Collectors;
@Service
public class TimingTaskScheduler {
    @Autowired
    private Scheduler scheduler;
    /**
     * æ·»åŠ æ–°ä»»åŠ¡åˆ°è°ƒåº¦å™¨
     */
    public void scheduleTimingTask(TimingTask task) throws SchedulerException {
        JobDetail jobDetail = buildJobDetail(task);
        Trigger trigger = buildJobTrigger(task, jobDetail);
        scheduler.scheduleJob(jobDetail, trigger);
    }
    /**
     * æ›´æ–°å·²æœ‰ä»»åŠ¡
     */
    public void rescheduleTimingTask(TimingTask task) throws SchedulerException {
        TriggerKey triggerKey = new TriggerKey("trigger_" + task.getId());
        // èŽ·å–çŽ°æœ‰è§¦å‘å™¨å¹¶è½¬æ¢ä¸º CronTrigger
        Trigger oldTrigger = scheduler.getTrigger(triggerKey);
        if (!(oldTrigger instanceof CronTrigger)) {
            throw new SchedulerException("Existing trigger is not a CronTrigger");
        }
        // æž„建新触发器
        Trigger newTrigger = TriggerBuilder.newTrigger()
                .withIdentity(triggerKey)
                .withDescription(task.getTaskName())
                .withSchedule(CronScheduleBuilder.cronSchedule(convertToCronExpression(task)))
                .startAt(Date.from(task.getNextExecutionTime().atZone(ZoneId.systemDefault()).toInstant()))
                .forJob(oldTrigger.getJobKey())
                .build();
        scheduler.rescheduleJob(triggerKey, newTrigger);
    }
    /**
     * æš‚停任务
     */
    public void pauseTimingTask(Long taskId) throws SchedulerException {
        JobKey jobKey = new JobKey("timingTask_" + taskId);
        scheduler.pauseJob(jobKey);
    }
    /**
     * æ¢å¤ä»»åŠ¡
     */
    public void resumeTimingTask(Long taskId) throws SchedulerException {
        JobKey jobKey = new JobKey("timingTask_" + taskId);
        scheduler.resumeJob(jobKey);
    }
    /**
     * åˆ é™¤ä»»åŠ¡
     */
    public void unscheduleTimingTask(Long taskId) throws SchedulerException {
        JobKey jobKey = new JobKey("timingTask_" + taskId);
        scheduler.deleteJob(jobKey);
    }
    private JobDetail buildJobDetail(TimingTask task) {
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("taskId", task.getId());
        return JobBuilder.newJob(TimingTaskJob.class)
                .withIdentity("timingTask_" + task.getId())
                .withDescription(task.getTaskName())
                .usingJobData(jobDataMap)
                .storeDurably()
                .build();
    }
    private Trigger buildJobTrigger(TimingTask task, JobDetail jobDetail) {
        String cronExpression = convertToCronExpression(task);
            TriggerBuilder<CronTrigger> triggerBuilder = TriggerBuilder.newTrigger()
                .withIdentity("trigger_" + task.getId())
                .withDescription(task.getTaskName())
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression));
        if (jobDetail != null) {
            triggerBuilder.forJob(jobDetail);
        }
        if (task.getNextExecutionTime() != null) {
            triggerBuilder.startAt(Date.from(task.getNextExecutionTime().atZone(ZoneId.systemDefault()).toInstant()));
        }
        return triggerBuilder.build();
    }
    private String convertToCronExpression(TimingTask task) {
        // å‚数校验
        if (task == null || task.getFrequencyType() == null || task.getFrequencyDetail() == null) {
            throw new IllegalArgumentException("任务参数不能为空");
        }
        // ä½¿ç”¨switch确保条件互斥
        String frequencyType = task.getFrequencyType().toUpperCase(); // ç»Ÿä¸€è½¬ä¸ºå¤§å†™æ¯”较
        switch (frequencyType) {
            case "DAILY":
                return convertDailyToCron(task.getFrequencyDetail());
            case "WEEKLY":
                return convertWeeklyToCron(task.getFrequencyDetail());
            case "MONTHLY":
                return convertMonthlyToCron(task.getFrequencyDetail());
            case "QUARTERLY":
                return convertQuarterlyToCron(task.getFrequencyDetail());
            default:
                throw new IllegalArgumentException("不支持的频率类型: " + task.getFrequencyType());
        }
    }
    // æ¯æ—¥ä»»åŠ¡è½¬æ¢
    private String convertDailyToCron(String frequencyDetail) {
        LocalTime time = parseTime(frequencyDetail);
        return String.format("0 %d %d * * ?", time.getMinute(), time.getHour());
    }
    // æ¯å‘¨ä»»åŠ¡è½¬æ¢
    private String convertWeeklyToCron(String frequencyDetail) {
        String[] parts = validateAndSplit(frequencyDetail, ",", 2);
        String daysOfWeek = convertDayNamesToCron(parts[0]);
        LocalTime time = parseTime(parts[1]);
        return String.format("0 %d %d ? * %s", time.getMinute(), time.getHour(), daysOfWeek);
    }
    // æ¯æœˆä»»åŠ¡è½¬æ¢
    private String convertMonthlyToCron(String frequencyDetail) {
        String[] parts = validateAndSplit(frequencyDetail, ",", 2);
        int day = validateDayOfMonth(parts[0]);
        LocalTime time = parseTime(parts[1]);
        return String.format("0 %d %d %d * ?", time.getMinute(), time.getHour(), day);
    }
    // æ¯å­£åº¦ä»»åŠ¡è½¬æ¢
    private String convertQuarterlyToCron(String frequencyDetail) {
        String[] parts = validateAndSplit(frequencyDetail, ",", 3);
        int month = validateMonth(parts[0]);  // éªŒè¯æœˆä»½(1-12)
        int day = validateDayOfMonth(parts[1]);  // éªŒè¯æ—¥æœŸ
        LocalTime time = parseTime(parts[2]);  // è§£æžæ—¶é—´
        // è®¡ç®—季度起始月份(1月=1, 4月=4, 7月=7, 10月=10)
        int quarterStartMonth = ((month - 1) / 3) * 3 + 1;
        return String.format("0 %d %d %d %d/3 ?",
                time.getMinute(),
                time.getHour(),
                day,
                quarterStartMonth);
    }
    // æ–°å¢žéªŒè¯æœˆä»½çš„æ–¹æ³•(1-12)
    private int validateMonth(String monthStr) {
        try {
            int month = Integer.parseInt(monthStr);
            if (month < 1 || month > 12) {
                throw new IllegalArgumentException("月份必须在1-12之间");
            }
            return month;
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("无效的月份格式");
        }
    }
    // è¾…助方法:解析时间
    private LocalTime parseTime(String timeStr) {
        try {
            return LocalTime.parse(timeStr);
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("时间格式必须为HH:mm", e);
        }
    }
    // è¾…助方法:验证并分割字符串
    private String[] validateAndSplit(String input, String delimiter, int expectedParts) {
        String[] parts = input.split(delimiter);
        if (parts.length != expectedParts) {
            throw new IllegalArgumentException(
                    String.format("格式错误,应为%d部分用'%s'分隔", expectedParts, delimiter));
        }
        return parts;
    }
    // è¾…助方法:验证月份中的日
    private int validateDayOfMonth(String dayStr) {
        int day = Integer.parseInt(dayStr);
        if (day < 1 || day > 31) {
            throw new IllegalArgumentException("日期必须在1-31之间");
        }
        return day;
    }
    // è¾…助方法:验证季度中的月
    private int validateMonthInQuarter(String monthStr) {
        int month = Integer.parseInt(monthStr);
        if (month < 1 || month > 3) {
            throw new IllegalArgumentException("季度月份必须是1、2或3");
        }
        return month;
    }
    // è½¬æ¢æ˜ŸæœŸå‡ åç§°
    private String convertDayNamesToCron(String dayNames) {
        return Arrays.stream(dayNames.split("\\|"))
                .map(this::convertSingleDayName)
                .collect(Collectors.joining(","));
    }
    // è½¬æ¢å•个星期几名称
    private String convertSingleDayName(String dayName) {
        switch (dayName.toUpperCase()) {
            case "MON": return "MON";
            case "TUE": return "TUE";
            case "WED": return "WED";
            case "THU": return "THU";
            case "FRI": return "FRI";
            case "SAT": return "SAT";
            case "SUN": return "SUN";
            default: throw new IllegalArgumentException("无效的星期几: " + dayName);
        }
    }
}
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,450 @@
package com.ruoyi.inspectiontask.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.inspectiontask.dto.TimingTaskDto;
import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper;
import com.ruoyi.inspectiontask.mapper.TimingTaskMapper;
import com.ruoyi.inspectiontask.pojo.TimingTask;
import com.ruoyi.inspectiontask.service.TimingTaskService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author :yys
 * @date : 2025/9/19 10:55
 */
@Service
@Slf4j
public class TimingTaskServiceImpl extends ServiceImpl<TimingTaskMapper, TimingTask> implements TimingTaskService {
    @Autowired
    private TimingTaskMapper timingTaskMapper;
    @Autowired
    private InspectionTaskMapper inspectionTaskMapper;
    @Autowired
    private TimingTaskScheduler timingTaskScheduler;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    public IPage<TimingTaskDto> selectTimingTaskList(Page<TimingTask> page, TimingTask timingTask) {
        // 1. å…ˆåˆ†é¡µæŸ¥è¯¢å®šæ—¶ä»»åŠ¡æ•°æ®
        IPage<TimingTask> taskPage = timingTaskMapper.selectPage(page, null);
        // 2. å¦‚果没有数据,直接返回空分页
        if (taskPage.getRecords().isEmpty()) {
            return new Page<>(taskPage.getCurrent(), taskPage.getSize(), taskPage.getTotal());
        }
        // 3. æ”¶é›†æ‰€æœ‰éœ€è¦æŸ¥è¯¢çš„用户ID
        Set<Long> userIds = new HashSet<>();
        // æ”¶é›†ç™»è®°äººID
        taskPage.getRecords().forEach(task -> {
            if (task.getRegistrantId() != null) {
                userIds.add(task.getRegistrantId());
            }
        });
        // æ”¶é›†å·¡æ£€äººID(多个ID以逗号分隔)
        taskPage.getRecords().forEach(task -> {
            if (StringUtils.isNotBlank(task.getInspectorIds())) {
                Arrays.stream(task.getInspectorIds().split(","))
                        .filter(StringUtils::isNotBlank)
                        .map(Long::valueOf)
                        .forEach(userIds::add);
            }
        });
        // 4. æ‰¹é‡æŸ¥è¯¢ç”¨æˆ·ä¿¡æ¯
        Map<Long, String> userNickNameMap = new HashMap<>();
        if (!userIds.isEmpty()) {
            List<SysUser> users = sysUserMapper.selectUserByIds((new ArrayList<>(userIds)));
            users.forEach(user -> userNickNameMap.put(user.getUserId(), user.getNickName()));
        }
        // 5. è½¬æ¢ä¸ºDTO
        List<TimingTaskDto> dtoList = taskPage.getRecords().stream().map(task -> {
            TimingTaskDto dto = new TimingTaskDto();
            // å¤åˆ¶åŸºæœ¬å±žæ€§
            BeanUtils.copyProperties(task, dto);
            // è®¾ç½®ç™»è®°äººæ˜µç§°
            if (task.getRegistrantId() != null) {
                dto.setRegistrant(userNickNameMap.getOrDefault(task.getRegistrantId(), "未知用户"));
            }
            // è®¾ç½®å·¡æ£€äººæ˜µç§°åˆ—表
            if (StringUtils.isNotBlank(task.getInspectorIds())) {
                List<String> inspectorNickNames = new ArrayList<>();
                for (String idStr : task.getInspectorIds().split(",")) {
                    if (StringUtils.isNotBlank(idStr)) {
                        Long id = Long.valueOf(idStr);
                        inspectorNickNames.add(userNickNameMap.getOrDefault(id, "未知用户"));
                    }
                }
                dto.setInspector(inspectorNickNames);
            }
            return dto;
        }).collect(Collectors.toList());
        // 6. æž„建返回的分页对象
        Page<TimingTaskDto> resultPage = new Page<>(taskPage.getCurrent(), taskPage.getSize(), taskPage.getTotal());
        resultPage.setRecords(dtoList);
        return resultPage;
    }
    @Override
    @Transactional
    public int addOrEditTimingTask(TimingTaskDto timingTaskDto) throws SchedulerException {
        TimingTask timingTask = new TimingTask();
        BeanUtils.copyProperties(timingTaskDto, timingTask);
        // è®¾ç½®åˆ›å»ºäººä¿¡æ¯å’Œé»˜è®¤å€¼
        if (Objects.isNull(timingTaskDto.getId())) {
            timingTask.setRegistrationDate(LocalDate.now());
            timingTask.setActive(true);
            // è®¡ç®—首次执行时间
            LocalDateTime firstExecutionTime = calculateFirstExecutionTime(timingTask);
            timingTask.setNextExecutionTime(firstExecutionTime);
            int result = timingTaskMapper.insert(timingTask);
            if (result > 0) {
                // æ–°å¢žæˆåŠŸåŽæ·»åŠ åˆ°è°ƒåº¦å™¨
                timingTaskScheduler.scheduleTimingTask(timingTask);
            }
            return result;
        } else {
            int result = timingTaskMapper.updateById(timingTask);
            if (result > 0) {
                // æ›´æ–°æˆåŠŸåŽé‡æ–°è°ƒåº¦ä»»åŠ¡
                timingTaskScheduler.rescheduleTimingTask(timingTask);
            }
            return result;
        }
    }
    private LocalDateTime calculateFirstExecutionTime(TimingTask task) {
        // æ ¹æ®é¢‘率类型和详情计算首次执行时间
        String frequencyType = task.getFrequencyType();
        if ("DAILY".equals(frequencyType)) {
            // å¦‚果是每天执行,计算今天或明天的具体时间
            return calculateDailyFirstExecution(task.getFrequencyDetail());
        } else if ("WEEKLY".equals(frequencyType)) {
            // å¦‚果是每周执行,计算下周的具体星期几
            return calculateWeeklyFirstExecution(task.getFrequencyDetail());
        } else if ("MONTHLY".equals(frequencyType)) {
            // å¦‚果是每月执行,计算下个月的具体日期
            return calculateMonthlyFirstExecution(task.getFrequencyDetail());
        } else if ("QUARTERLY".equals(frequencyType)) {
            // è‡ªå®šä¹‰é¢‘率,如每小时、每30分钟等
            return calculateCustomFirstExecution(task.getFrequencyDetail());
        } else {
            throw new IllegalArgumentException("不支持的频率类型: " + task.getFrequencyType());
        }
    }
    private LocalDateTime calculateDailyFirstExecution(String frequencyDetail) {
        // frequencyDetail可能是具体时间,如 "14:30"
        LocalTime executionTime = LocalTime.parse(frequencyDetail);
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime todayExecution = LocalDateTime.of(now.toLocalDate(), executionTime);
        // å¦‚果今天的时间已过,则安排明天执行
        return now.isBefore(todayExecution) ? todayExecution : todayExecution.plusDays(1);
    }
    // æ˜ å°„星期简写与DayOfWeek
    private static final Map<String, DayOfWeek> WEEK_DAY_MAP = new HashMap<>();
    static {
        WEEK_DAY_MAP.put("MON", DayOfWeek.MONDAY);
        WEEK_DAY_MAP.put("TUE", DayOfWeek.TUESDAY);
        WEEK_DAY_MAP.put("WED", DayOfWeek.WEDNESDAY);
        WEEK_DAY_MAP.put("THU", DayOfWeek.THURSDAY);
        WEEK_DAY_MAP.put("FRI", DayOfWeek.FRIDAY);
        WEEK_DAY_MAP.put("SAT", DayOfWeek.SATURDAY);
        WEEK_DAY_MAP.put("SUN", DayOfWeek.SUNDAY);
    }
    private LocalDateTime calculateWeeklyFirstExecution(String frequencyDetail) {
        // è§£æžè¾“入参数
        String[] parts = frequencyDetail.split(",");
        if (parts.length != 2) {
            throw new IllegalArgumentException("参数格式错误,应为'MON,13:43'格式");
        }
        String weekDayStr = parts[0].trim();
        String timeStr = parts[1].trim();
        // èŽ·å–å¯¹åº”çš„æ˜ŸæœŸå‡ 
        DayOfWeek targetDay = WEEK_DAY_MAP.get(weekDayStr);
        if (targetDay == null) {
            throw new IllegalArgumentException("无效的星期简写: " + weekDayStr);
        }
        // è§£æžæ—¶é—´
        LocalTime targetTime = LocalTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm"));
        // èŽ·å–å½“å‰æ—¶é—´
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime targetDateTime = now.with(targetDay).with(targetTime);
        // å¦‚果计算出的时间在当前时间之前,则加一周
        if (targetDateTime.isBefore(now)) {
            targetDateTime = targetDateTime.plusWeeks(1);
        }
        return targetDateTime;
    }
    private LocalDateTime calculateMonthlyFirstExecution(String frequencyDetail) {
        // è§£æžè¾“入参数
        String[] parts = frequencyDetail.split(",");
        if (parts.length != 2) {
            throw new IllegalArgumentException("参数格式错误,应为'03,17:00'格式");
        }
        String dayStr = parts[0].trim();
        String timeStr = parts[1].trim();
        // è§£æžæ—¥æœŸ
        int dayOfMonth;
        try {
            dayOfMonth = Integer.parseInt(dayStr);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("无效的日期格式: " + dayStr, e);
        }
        // éªŒè¯æ—¥æœŸæœ‰æ•ˆæ€§ï¼ˆ1-31之间)
        if (dayOfMonth < 1 || dayOfMonth > 31) {
            throw new IllegalArgumentException("日期必须在1-31之间: " + dayOfMonth);
        }
        // è§£æžæ—¶é—´
        LocalTime targetTime;
        try {
            targetTime = LocalTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm"));
        } catch (DateTimeException e) {
            throw new IllegalArgumentException("无效的时间格式: " + timeStr, e);
        }
        // èŽ·å–å½“å‰æ—¶é—´
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime targetDateTime = now.withDayOfMonth(dayOfMonth).with(targetTime);
        // æ£€æŸ¥æ—¥æœŸæ˜¯å¦è¢«è‡ªåŠ¨è°ƒæ•´ï¼ˆå¦‚31日在小月会被调整)
        boolean isDateAdjusted = targetDateTime.getDayOfMonth() != dayOfMonth;
        // å¦‚果目标时间在当前时间之前,或者日期被系统自动调整了
        if (targetDateTime.isBefore(now) || isDateAdjusted) {
            // è®¡ç®—下个月的日期
            LocalDateTime nextMonth = now.plusMonths(1);
            // å°è¯•设置下个月的目标日期
            LocalDateTime nextMonthTarget = nextMonth.withDayOfMonth(dayOfMonth).with(targetTime);
            // å¦‚果下个月的日期也被调整了,就用下个月的最后一天
            if (nextMonthTarget.getDayOfMonth() != dayOfMonth) {
                // æ­£ç¡®èŽ·å–ä¸‹ä¸ªæœˆçš„æœ€åŽä¸€å¤©ï¼ˆä¿®å¤isLeapYear调用问题)
                int lastDayOfMonth = nextMonth.getMonth().length(
                        Year.of(nextMonth.getYear()).isLeap()
                );
                nextMonthTarget = nextMonth.withDayOfMonth(lastDayOfMonth).with(targetTime);
            }
            targetDateTime = nextMonthTarget;
        }
        return targetDateTime;
    }
    private LocalDateTime calculateCustomFirstExecution(String frequencyDetail) {
        return null;
    }
    @Override
    @Transactional
    public void updateTaskExecutionTime(Long taskId) {
        TimingTask task = timingTaskMapper.selectById(taskId);
        if (task == null) {
            throw new RuntimeException("定时任务不存在,ID: " + taskId);
        }
        // æ›´æ–°æœ€åŽæ‰§è¡Œæ—¶é—´ä¸ºå½“前时间
        task.setLastExecutionTime(LocalDateTime.now());
        // è®¡ç®—下次执行时间
        LocalDateTime nextExecutionTime = calculateNextExecutionTime(
                task.getFrequencyType(),
                task.getFrequencyDetail(),
                LocalDateTime.now()
        );
        task.setNextExecutionTime(nextExecutionTime);
        // æ›´æ–°æ•°æ®åº“
        timingTaskMapper.updateById(task);
    }
    /**
     * è®¡ç®—下次执行时间
     */
    private LocalDateTime calculateNextExecutionTime(String frequencyType,
                                                     String frequencyDetail,
                                                     LocalDateTime currentTime) {
        try {
            switch (frequencyType) {
                case "DAILY":
                    return calculateDailyNextTime(frequencyDetail, currentTime);
                case "WEEKLY":
                    return calculateWeeklyNextTime(frequencyDetail, currentTime);
                case "MONTHLY":
                    return calculateMonthlyNextTime(frequencyDetail, currentTime);
                case "QUARTERLY":
                    return calculateQuarterlyNextTime(frequencyDetail, currentTime);
                default:
                    throw new IllegalArgumentException("不支持的频率类型: " + frequencyType);
            }
        } catch (Exception e) {
            throw new RuntimeException("计算下次执行时间失败: " + e.getMessage(), e);
        }
    }
    /**
     * è®¡ç®—每日任务的下次执行时间
     */
    private LocalDateTime calculateDailyNextTime(String timeStr, LocalDateTime current) {
        LocalTime executionTime = LocalTime.parse(timeStr); // è§£æžæ ¼å¼ "HH:mm"
        LocalDateTime nextTime = LocalDateTime.of(current.toLocalDate(), executionTime);
        // å¦‚果今天的时间已过,则安排明天
        return current.isBefore(nextTime) ? nextTime : nextTime.plusDays(1);
    }
    /**
     * è®¡ç®—每周任务的下次执行时间
     */
    private LocalDateTime calculateWeeklyNextTime(String detail, LocalDateTime current) {
        String[] parts = detail.split(",");
        String dayOfWeekStr = parts[0];  // å¦‚ "MON" æˆ– "MON|WED|FRI"
        LocalTime time = LocalTime.parse(parts[1]); // æ—¶é—´éƒ¨åˆ†
        // è§£æžæ˜ŸæœŸå‡ (支持多个星期)
        Set<DayOfWeek> targetDays = parseDayOfWeeks(dayOfWeekStr);
        // ä»Žå½“前时间开始找下一个符合条件的星期几
        LocalDateTime nextTime = current;
        while (true) {
            nextTime = nextTime.plusDays(1);
            if (targetDays.contains(nextTime.getDayOfWeek())) {
                return LocalDateTime.of(nextTime.toLocalDate(), time);
            }
            // é˜²æ­¢æ— é™å¾ªçޝ(理论上不会发生)
            if (nextTime.isAfter(current.plusYears(1))) {
                throw new RuntimeException("无法找到下次执行时间");
            }
        }
    }
    /**
     * è®¡ç®—每月任务的下次执行时间
     */
    private LocalDateTime calculateMonthlyNextTime(String detail, LocalDateTime current) {
        String[] parts = detail.split(",");
        int dayOfMonth = Integer.parseInt(parts[0]);
        LocalTime time = LocalTime.parse(parts[1]);
        // ä»Žä¸‹ä¸ªæœˆå¼€å§‹è®¡ç®—
        LocalDateTime nextTime = current.plusMonths(1)
                .withDayOfMonth(Math.min(dayOfMonth, current.plusMonths(1).toLocalDate().lengthOfMonth()))
                .with(time);
        return nextTime;
    }
    /**
     * è®¡ç®—每季度任务的下次执行时间
     */
    private LocalDateTime calculateQuarterlyNextTime(String detail, LocalDateTime current) {
        String[] parts = detail.split(",");
        int quarterMonth = Integer.parseInt(parts[0]); // 1=第1个月,2=第2个月,3=第3个月
        int dayOfMonth = Integer.parseInt(parts[1]);
        LocalTime time = LocalTime.parse(parts[2]);
        // è®¡ç®—当前季度
        int currentQuarter = (current.getMonthValue() - 1) / 3 + 1;
        int currentMonthInQuarter = (current.getMonthValue() - 1) % 3 + 1;
        YearMonth targetYearMonth;
        if (currentMonthInQuarter < quarterMonth) {
            // æœ¬å­£åº¦å†…还有执行机会
            targetYearMonth = YearMonth.from(current)
                    .plusMonths(quarterMonth - currentMonthInQuarter);
        } else {
            // éœ€è¦åˆ°ä¸‹ä¸ªå­£åº¦
            targetYearMonth = YearMonth.from(current)
                    .plusMonths(3 - currentMonthInQuarter + quarterMonth);
        }
        // å¤„理月末日期
        int adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth());
        return LocalDateTime.of(
                targetYearMonth.getYear(),
                targetYearMonth.getMonthValue(),
                adjustedDay,
                time.getHour(),
                time.getMinute()
        );
    }
    /**
     * è§£æžæ˜ŸæœŸå‡ å­—符串
     */
    private Set<DayOfWeek> parseDayOfWeeks(String dayOfWeekStr) {
        Set<DayOfWeek> days = new HashSet<>();
        String[] dayStrs = dayOfWeekStr.split("\\|");
        for (String dayStr : dayStrs) {
            switch (dayStr) {
                case "MON": days.add(DayOfWeek.MONDAY); break;
                case "TUE": days.add(DayOfWeek.TUESDAY); break;
                case "WED": days.add(DayOfWeek.WEDNESDAY); break;
                case "THU": days.add(DayOfWeek.THURSDAY); break;
                case "FRI": days.add(DayOfWeek.FRIDAY); break;
                case "SAT": days.add(DayOfWeek.SATURDAY); break;
                case "SUN": days.add(DayOfWeek.SUNDAY); break;
                default: throw new IllegalArgumentException("无效的星期几: " + dayStr);
            }
        }
        return days;
    }
    @Override
    public int delByIds(Long[] ids) {
        return timingTaskMapper.deleteBatchIds(Arrays.asList(ids));
    }
}
src/main/java/com/ruoyi/measuringinstrumentledger/controller/SparePartsController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.ruoyi.measuringinstrumentledger.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsDto;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord;
import com.ruoyi.measuringinstrumentledger.pojo.SpareParts;
import com.ruoyi.measuringinstrumentledger.service.SparePartsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/spareParts")
@Api(tags = "备件分类接口")
public class SparePartsController {
    @Autowired
    private SparePartsService sparePartsService;
    @GetMapping("/getTree")
    @ApiOperation("备件分类-树结构")
    public AjaxResult getTree(){
        List<SparePartsDto> tree = sparePartsService.getTree();
        return AjaxResult.success(tree);
    }
    @GetMapping("/listPage")
    @ApiOperation("备件分类-分页查询")
    public AjaxResult listPage(Page page, SpareParts spareParts){
        IPage<SparePartsDto> listPage = sparePartsService.listPage(page, spareParts);
        return AjaxResult.success(listPage);
    }
//    @GetMapping("/list")
//    @ApiOperation("备件分类-查询所有")
//    public AjaxResult list(){
//        return AjaxResult.success(sparePartsService.list());
//    }
    @PostMapping("/add")
    @ApiOperation("备件分类-添加")
    @Log(title = "备件分类-添加", businessType = BusinessType.INSERT)
    public AjaxResult add(@RequestBody SpareParts spareParts){
        return AjaxResult.success(sparePartsService.save(spareParts));
    }
    @PostMapping("/update")
    @ApiOperation("备件分类-更新")
    @Log(title = "备件分类-更新", businessType = BusinessType.UPDATE)
    public AjaxResult update(@RequestBody SpareParts spareParts){
        return AjaxResult.success(sparePartsService.updateById(spareParts));
    }
    @DeleteMapping("/delete/{id}")
    @ApiOperation("备件分类-删除")
    @Log(title = "备件分类-删除", businessType = BusinessType.DELETE)
    public AjaxResult delete(@PathVariable Long id){
        return AjaxResult.success(sparePartsService.removeById(id));
    }
}
src/main/java/com/ruoyi/measuringinstrumentledger/dto/SparePartsDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.measuringinstrumentledger.dto;
import com.ruoyi.measuringinstrumentledger.pojo.SpareParts;
import lombok.Data;
import java.util.List;
@Data
public class SparePartsDto extends SpareParts {
    /**
     * å¤‡ä»¶åˆ†ç±»çˆ¶åç§°
     */
    private String parentName;
    private List<SparePartsDto> children;
}
src/main/java/com/ruoyi/measuringinstrumentledger/mapper/SparePartsMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.measuringinstrumentledger.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsDto;
import com.ruoyi.measuringinstrumentledger.pojo.SpareParts;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SparePartsMapper extends BaseMapper<SpareParts> {
    IPage<SparePartsDto> listPage(Page page,@Param("spareParts") SpareParts spareParts);
}
src/main/java/com/ruoyi/measuringinstrumentledger/pojo/SpareParts.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.ruoyi.measuringinstrumentledger.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Data
@TableName("spare_parts")
public class SpareParts {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * å¤‡ä»¶åˆ†ç±»åç§°
     */
    private String name;
    /**
     * å¤‡ä»¶åˆ†ç±»ç¼–号
     */
    private String sparePartsNo;
    /**
     * å¤‡ä»¶çˆ¶id
     */
    private Long parentId;
    /**
     * å¤‡ä»¶çŠ¶æ€
     */
    private String status;
    /**
     * å¤‡ä»¶åˆ†ç±»æè¿°
     */
    private String description;
    @ApiModelProperty("创建时间")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty("更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @ApiModelProperty("创建人")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty("更新人")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty("租户id")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/SparePartsService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.measuringinstrumentledger.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsDto;
import com.ruoyi.measuringinstrumentledger.pojo.SpareParts;
import java.util.List;
public interface SparePartsService extends IService<SpareParts> {
    IPage<SparePartsDto> listPage(Page page, SpareParts spareParts);
    List<SparePartsDto> getTree();
}
src/main/java/com/ruoyi/measuringinstrumentledger/service/impl/SparePartsServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package com.ruoyi.measuringinstrumentledger.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.measuringinstrumentledger.dto.SparePartsDto;
import com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper;
import com.ruoyi.measuringinstrumentledger.pojo.SpareParts;
import com.ruoyi.measuringinstrumentledger.service.SparePartsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class SparePartsServiceImpl extends ServiceImpl<SparePartsMapper, SpareParts> implements SparePartsService {
    @Autowired
    private SparePartsMapper sparePartsMapper;
    @Override
    public IPage<SparePartsDto> listPage(Page page, SpareParts spareParts) {
        return sparePartsMapper.listPage(page,spareParts);
    }
    @Override
    public List<SparePartsDto> getTree() {
        SpareParts spareParts = new SpareParts();
        IPage<SparePartsDto> sparePartsDtoIPage = sparePartsMapper.listPage(new Page<>(1, -1), spareParts);
        List<SparePartsDto> records = sparePartsDtoIPage.getRecords();
        return buildTree(records);
    }
    /**
     * å°†æ‰å¹³ç»“构数据转换为树形结构
     * @param flatData æ‰å¹³èŠ‚ç‚¹åˆ—è¡¨
     * @return æ ‘形结构根节点列表
     */
    public static List<SparePartsDto> buildTree(List<SparePartsDto> flatData) {
        List<SparePartsDto> result = new ArrayList<>();
        if (flatData == null || flatData.isEmpty()) {
            return result;  // ç©ºè¾“入直接返回空列表
        }
        // 1. åˆ›å»ºèŠ‚ç‚¹æ˜ å°„è¡¨ï¼Œå­˜å‚¨æ‰€æœ‰èŠ‚ç‚¹å¹¶åˆå§‹åŒ–å­èŠ‚ç‚¹åˆ—è¡¨
        Map<Long, SparePartsDto> nodeMap = new HashMap<>();
        for (SparePartsDto node : flatData) {
            // ç¡®ä¿å­èŠ‚ç‚¹åˆ—è¡¨åˆå§‹åŒ–(避免空指针异常)
            if (node.getChildren() == null) {
                node.setChildren(new ArrayList<>());
            }
            nodeMap.put(node.getId(), node);
        }
        // 2. æž„建树形结构
        for (SparePartsDto node : flatData) {
            Long parentId = node.getParentId();
            if (parentId == null || !nodeMap.containsKey(parentId)) {
                // æ— çˆ¶èŠ‚ç‚¹æˆ–çˆ¶èŠ‚ç‚¹ä¸å­˜åœ¨ï¼Œä½œä¸ºæ ¹èŠ‚ç‚¹
                result.add(node);
            } else {
                // æœ‰çˆ¶èŠ‚ç‚¹ï¼Œæ·»åŠ åˆ°çˆ¶èŠ‚ç‚¹çš„å­èŠ‚ç‚¹åˆ—è¡¨
                SparePartsDto parentNode = nodeMap.get(parentId);
                parentNode.getChildren().add(node);
            }
        }
        return result;
    }
}
src/main/java/com/ruoyi/oA/controller/OaProjectController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
package com.ruoyi.oA.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedger;
import com.ruoyi.oA.dto.OaProjectDto;
import com.ruoyi.oA.pojo.OaProject;
import com.ruoyi.oA.service.OaProjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
@Api(tags = "oA项目管理")
@RestController
@RequestMapping("/oA/project")
public class OaProjectController {
    @Autowired
    private OaProjectService oaProjectService;
    @ApiOperation("获取项目列表")
    @GetMapping("/listPage")
    public AjaxResult listPage(Page page, OaProjectDto oaProjectDto) {
        IPage<OaProjectDto> listPage = oaProjectService.listPage(page, oaProjectDto);
        return AjaxResult.success(listPage);
    }
    @ApiOperation("获取项目列表详情")
    @GetMapping("/getList")
    public AjaxResult getList(Page page, OaProjectDto oaProjectDto) {
        IPage<OaProjectDto> listPage = oaProjectService.listPage(page, oaProjectDto);
        HashMap<Object, Object> Map = new HashMap<>();
        listPage.getRecords().forEach(item -> {
            Map.put(item.getProjectId(), item);
        });
        return AjaxResult.success(Map);
    }
    @ApiOperation("增添项目")
    @PostMapping("/add")
    public AjaxResult add(@RequestBody OaProject oaProject) {
        boolean save = oaProjectService.save(oaProject);
        return AjaxResult.success(save);
    }
    @ApiOperation("删除项目")
    @DeleteMapping("/delete/{id}")
    public AjaxResult delete(@PathVariable Long id) {
        boolean remove = oaProjectService.deleteById(id);
        return AjaxResult.success(remove);
    }
    @ApiOperation("更新项目")
    @PostMapping("/update")
    public AjaxResult update(@RequestBody OaProject oaProject) {
        boolean update = oaProjectService.updateById(oaProject);
        return AjaxResult.success(update);
    }
//    @ApiOperation("根据ID获取项目详情")
//    @GetMapping("/getById")
//    public AjaxResult getById(Long id) {
//        OaProject oaProject = oaProjectService.getById(id);
//        return AjaxResult.success(oaProject);
//    }
    @ApiOperation("导出所选项目")
    @PostMapping("/export/{ids}")
    public void export(HttpServletResponse response,@PathVariable("ids") List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new IllegalArgumentException("导出项目列表不能为空");
        }
        oaProjectService.export(response, ids);
    }
}
src/main/java/com/ruoyi/oA/controller/OaProjectPhaseController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package com.ruoyi.oA.controller;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.oA.pojo.OaProjectPhase;
import com.ruoyi.oA.service.OaProjectPhaseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Api(tags = "oA项目阶段管理")
@RestController
@RequestMapping("/oA/projectPhase")
public class OaProjectPhaseController {
    @Autowired
    private OaProjectPhaseService oaProjectPhaseService;
    @ApiOperation("新增项目阶段")
    @PostMapping("/add")
    public AjaxResult add(@RequestBody OaProjectPhase oaProjectPhase) {
        return AjaxResult.success(oaProjectPhaseService.save(oaProjectPhase));
    }
    @ApiOperation("删除项目阶段")
    @DeleteMapping("/delete/{phaseId}")
    public AjaxResult delete(@PathVariable Integer phaseId) {
        return AjaxResult.success(oaProjectPhaseService.deleteById(phaseId));
    }
    @ApiOperation("更新项目阶段")
    @PostMapping("/update")
    public AjaxResult update(@RequestBody OaProjectPhase oaProjectPhase) {
        return AjaxResult.success(oaProjectPhaseService.updateById(oaProjectPhase));
    }
    @ApiOperation("根据项目id查询项目阶段列表")
    @GetMapping("/listByProjectId/{projectId}")
    public AjaxResult listByProjectId(@PathVariable Integer projectId) {
        return AjaxResult.success(oaProjectPhaseService.listByProjectId(projectId));
    }
}
src/main/java/com/ruoyi/oA/controller/OaProjectPhaseTaskController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package com.ruoyi.oA.controller;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.oA.pojo.OaProjectPhaseTask;
import com.ruoyi.oA.service.OaProjectPhaseTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Api(tags = "oA项目阶段任务管理")
@RestController
@RequestMapping("/oA/projectPhaseTask")
public class OaProjectPhaseTaskController {
    @Autowired
    private OaProjectPhaseTaskService oaProjectPhaseTaskService;
    @ApiOperation("新增项目阶段任务")
    @PostMapping("/add")
    public AjaxResult add(@RequestBody OaProjectPhaseTask oaProjectPhaseTask) {
        return AjaxResult.success(oaProjectPhaseTaskService.save(oaProjectPhaseTask));
    }
    @ApiOperation("根据项目阶段id查询项目阶段任务列表")
    @GetMapping("/listByPhaseId/{phaseId}")
    public AjaxResult listByPhaseId(@PathVariable Integer phaseId) {
        return AjaxResult.success(oaProjectPhaseTaskService.listByPhaseId(phaseId));
    }
    @ApiOperation("删除项目阶段任务")
    @DeleteMapping("/delete/{taskId}")
    public AjaxResult delete(@PathVariable Integer taskId) {
        return AjaxResult.success(oaProjectPhaseTaskService.removeById(taskId));
    }
    @ApiOperation("更新项目阶段任务")
    @PostMapping("/update")
    public AjaxResult update(@RequestBody OaProjectPhaseTask oaProjectPhaseTask) {
        return AjaxResult.success(oaProjectPhaseTaskService.updateById(oaProjectPhaseTask));
    }
}
src/main/java/com/ruoyi/oA/dto/OaProjectDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.oA.dto;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.oA.pojo.OaProject;
import com.ruoyi.oA.pojo.OaProjectPhase;
import com.ruoyi.oA.pojo.OaProjectPhaseTask;
import lombok.Data;
import java.util.List;
@Data
public class OaProjectDto extends OaProject {
    /**
     * è´Ÿè´£äººåç§°
     */
    @Excel(name = "负责人名称")
    private String managerName;
    /**
     * é¡¹ç›®é˜¶æ®µåˆ—表
     */
    private List<OaProjectPhaseDto> oaProjectPhasesDto;
//    /**
//     * é¡¹ç›®é˜¶æ®µä»»åŠ¡åˆ—è¡¨
//     */
//    private List<OaProjectPhaseTask> oaProjectPhaseTasks;
}
src/main/java/com/ruoyi/oA/dto/OaProjectPhaseDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.ruoyi.oA.dto;
import com.ruoyi.oA.pojo.OaProjectPhase;
import com.ruoyi.oA.pojo.OaProjectPhaseTask;
import lombok.Data;
import java.util.List;
@Data
public class OaProjectPhaseDto extends OaProjectPhase {
    private List<OaProjectPhaseTask> oaProjectPhaseTasks;
}
src/main/java/com/ruoyi/oA/mapper/OaProjectMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.oA.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.oA.dto.OaProjectDto;
import com.ruoyi.oA.pojo.OaProject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project(OA系统-项目任务协同-项目表)】的数据库操作Mapper
* @createDate 2025-09-24 09:18:46
* @Entity com.ruoyi.oA.pojo.OaProject
*/
public interface OaProjectMapper extends BaseMapper<OaProject> {
    IPage<OaProjectDto> listPage(Page page,@Param("req") OaProjectDto oaProjectDto);
    List<OaProjectDto> selectByIds(List<Long> ids);
}
src/main/java/com/ruoyi/oA/mapper/OaProjectPhaseMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.oA.mapper;
import com.ruoyi.oA.pojo.OaProjectPhase;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project_phase(OA系统-项目阶段表)】的数据库操作Mapper
* @createDate 2025-09-24 09:18:46
* @Entity com.ruoyi.oA.pojo.OaProjectPhase
*/
public interface OaProjectPhaseMapper extends BaseMapper<OaProjectPhase> {
}
src/main/java/com/ruoyi/oA/mapper/OaProjectPhaseTaskMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.oA.mapper;
import com.ruoyi.oA.pojo.OaProjectPhaseTask;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project_phase_task(OA系统-项目阶段-任务表)】的数据库操作Mapper
* @createDate 2025-09-24 09:18:46
* @Entity com.ruoyi.oA.pojo.OaProjectPhaseTask
*/
public interface OaProjectPhaseTaskMapper extends BaseMapper<OaProjectPhaseTask> {
}
src/main/java/com/ruoyi/oA/pojo/OaProject.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
package com.ruoyi.oA.pojo;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * OA系统-项目任务协同-项目表
 * @TableName oa_project
 */
@TableName(value ="oa_project")
@Data
public class OaProject implements Serializable {
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Integer projectId;
    /**
     * é¡¹ç›®åç§°
     */
    @Excel(name = "项目名称")
    private String projectName;
    /**
     * é¡¹ç›®æè¿°
     */
    @Excel(name = "项目描述")
    private String description;
    /**
     * å¼€å§‹æ—¶é—´
     */
    @Excel(name = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate startDate;
    /**
     * ç»“束时间
     */
    @Excel(name = "结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate endDate;
    /**
     * çŠ¶æ€
     */
    @Excel(name = "状态")
    private String status;
    /**
     * å®Œæˆåº¦
     */
    @Excel(name = "完成度")
    private Integer completionRate;
    /**
     * è´Ÿè´£äººid
     */
    private Long managerId;
    /**
     * åˆ›å»ºç”¨æˆ·
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹ç”¨æˆ·
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/oA/pojo/OaProjectPhase.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
package com.ruoyi.oA.pojo;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * OA系统-项目阶段表
 * @TableName oa_project_phase
 */
@TableName(value ="oa_project_phase")
@Data
public class OaProjectPhase implements Serializable {
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Integer phaseId;
    /**
     * é¡¹ç›®é˜¶æ®µåç§°
     */
    private String phaseName;
    /**
     * oa_project表id
     */
    private Integer oaProjectId;
    /**
     * å¼€å§‹æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate startDate;
    /**
     * ç»“束时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate endDate;
    /**
     * çŠ¶æ€
     */
    private String status;
    /**
     * åˆ›å»ºç”¨æˆ·
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹ç”¨æˆ·
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/oA/pojo/OaProjectPhaseTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
package com.ruoyi.oA.pojo;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * OA系统-项目阶段-任务表
 * @TableName oa_project_phase_task
 */
@TableName(value ="oa_project_phase_task")
@Data
public class OaProjectPhaseTask implements Serializable {
    /**
     *
     */
    @TableId(type = IdType.AUTO)
    private Integer taskId;
    /**
     * é¡¹ç›®é˜¶æ®µä»»åŠ¡åç§°
     */
    private String taskName;
    /**
     * oa_project_phase表id
     */
    private Integer phaseId;
    /**
     * å¼€å§‹æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate startDate;
    /**
     * ç»“束时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate endDate;
    /**
     * ç›®æ ‡ä»»åŠ¡å®Œæˆæ—¥æœŸ
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate targetDate;
    /**
     * ç›®æ ‡å€¼
     */
    private Integer targetValue;
    /**
     * å½“前值
     */
    private Integer currentValue;
    /**
     * å•位
     */
    private String unit;
    /**
     * çŠ¶æ€
     */
    private String status;
    /**
     * å®Œæˆåº¦
     */
    private Integer completionRate;
    /**
     * åˆ›å»ºç”¨æˆ·
     */
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹ç”¨æˆ·
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/oA/service/OaProjectPhaseService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ruoyi.oA.service;
import com.ruoyi.oA.dto.OaProjectPhaseDto;
import com.ruoyi.oA.pojo.OaProjectPhase;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project_phase(OA系统-项目阶段表)】的数据库操作Service
* @createDate 2025-09-24 09:18:46
*/
public interface OaProjectPhaseService extends IService<OaProjectPhase> {
    List<OaProjectPhaseDto> listByProjectId(Integer oaProjectId);
    boolean deleteById(Integer phaseId);
}
src/main/java/com/ruoyi/oA/service/OaProjectPhaseTaskService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.ruoyi.oA.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.oA.pojo.OaProjectPhaseTask;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project_phase_task(OA系统-项目阶段-任务表)】的数据库操作Service
* @createDate 2025-09-24 09:18:46
*/
public interface OaProjectPhaseTaskService extends IService<OaProjectPhaseTask> {
    List<OaProjectPhaseTask> listByPhaseId(Integer phaseId);
}
src/main/java/com/ruoyi/oA/service/OaProjectService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.oA.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.oA.dto.OaProjectDto;
import com.ruoyi.oA.pojo.OaProject;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project(OA系统-项目任务协同-项目表)】的数据库操作Service
* @createDate 2025-09-24 09:18:46
*/
public interface OaProjectService extends IService<OaProject> {
    IPage<OaProjectDto> listPage(Page page, OaProjectDto oaProjectDto);
    void export(HttpServletResponse response, List<Long> ids);
    boolean deleteById(Long id);
}
src/main/java/com/ruoyi/oA/service/impl/OaProjectPhaseServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.ruoyi.oA.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.oA.dto.OaProjectPhaseDto;
import com.ruoyi.oA.pojo.OaProjectPhase;
import com.ruoyi.oA.pojo.OaProjectPhaseTask;
import com.ruoyi.oA.service.OaProjectPhaseService;
import com.ruoyi.oA.mapper.OaProjectPhaseMapper;
import com.ruoyi.oA.service.OaProjectPhaseTaskService;
import lombok.val;
import org.hibernate.validator.constraints.br.TituloEleitoral;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project_phase(OA系统-项目阶段表)】的数据库操作Service实现
* @createDate 2025-09-24 09:18:46
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class OaProjectPhaseServiceImpl extends ServiceImpl<OaProjectPhaseMapper, OaProjectPhase>
    implements OaProjectPhaseService{
    @Autowired
    private OaProjectPhaseMapper oaProjectPhaseMapper;
    @Autowired
    private OaProjectPhaseTaskService oaProjectPhaseTaskService;
    @Override
    public List<OaProjectPhaseDto> listByProjectId(Integer oaProjectId) {
        List<OaProjectPhase> oaProjectPhases = oaProjectPhaseMapper.selectList(new LambdaQueryWrapper<OaProjectPhase>()
                .eq(OaProjectPhase::getOaProjectId, oaProjectId));
        List<OaProjectPhaseDto> collect = oaProjectPhases.stream().map(oaProjectPhase -> {
            OaProjectPhaseDto oaProjectPhaseDto = new OaProjectPhaseDto();
            BeanUtils.copyProperties(oaProjectPhase, oaProjectPhaseDto);
//            List<OaProjectPhaseTask> oaProjectPhaseTasks = oaProjectPhaseTaskService.listByPhaseId(oaProjectPhaseDto.getPhaseId());
            oaProjectPhaseDto.setOaProjectPhaseTasks(oaProjectPhaseTaskService.listByPhaseId(oaProjectPhaseDto.getPhaseId()));
            return oaProjectPhaseDto;
        }).collect(Collectors.toList());
        return collect;
    }
    @Override
    public boolean deleteById(Integer phaseId) {
        // å…ˆåˆ é™¤é¡¹ç›®é˜¶æ®µä¸‹çš„任务
        oaProjectPhaseTaskService.remove(new LambdaQueryWrapper<OaProjectPhaseTask>()
                .eq(OaProjectPhaseTask::getPhaseId, phaseId));
        return oaProjectPhaseMapper.deleteById(phaseId) > 0;
    }
}
src/main/java/com/ruoyi/oA/service/impl/OaProjectPhaseTaskServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.ruoyi.oA.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.oA.pojo.OaProjectPhaseTask;
import com.ruoyi.oA.service.OaProjectPhaseTaskService;
import com.ruoyi.oA.mapper.OaProjectPhaseTaskMapper;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project_phase_task(OA系统-项目阶段-任务表)】的数据库操作Service实现
* @createDate 2025-09-24 09:18:46
*/
@Service
public class OaProjectPhaseTaskServiceImpl extends ServiceImpl<OaProjectPhaseTaskMapper, OaProjectPhaseTask>
    implements OaProjectPhaseTaskService{
    @Override
    public List<OaProjectPhaseTask> listByPhaseId(Integer phaseId) {
        return baseMapper.selectList(new LambdaQueryWrapper<OaProjectPhaseTask>()
                .eq(OaProjectPhaseTask::getPhaseId, phaseId));
    }
}
src/main/java/com/ruoyi/oA/service/impl/OaProjectServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
package com.ruoyi.oA.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedgerRecord;
import com.ruoyi.oA.dto.OaProjectDto;
import com.ruoyi.oA.pojo.OaProject;
import com.ruoyi.oA.pojo.OaProjectPhase;
import com.ruoyi.oA.service.OaProjectPhaseService;
import com.ruoyi.oA.service.OaProjectService;
import com.ruoyi.oA.mapper.OaProjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* @author ywx
* @description é’ˆå¯¹è¡¨ã€oa_project(OA系统-项目任务协同-项目表)】的数据库操作Service实现
* @createDate 2025-09-24 09:18:45
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class OaProjectServiceImpl extends ServiceImpl<OaProjectMapper, OaProject>
    implements OaProjectService{
    @Autowired
    private OaProjectMapper oaProjectMapper;
    @Autowired
    private OaProjectPhaseService oaProjectPhaseService;
    @Override
    public IPage<OaProjectDto> listPage(Page page, OaProjectDto oaProjectDto) {
        IPage<OaProjectDto> iPage = oaProjectMapper.listPage(page, oaProjectDto);
        // é¡¹ç›®é˜¶æ®µåˆ—表
        for (OaProjectDto projectDto : iPage.getRecords()) {
            projectDto.setOaProjectPhasesDto(oaProjectPhaseService.listByProjectId(projectDto.getProjectId()));
        }
        return iPage;
    }
    @Override
    public void export(HttpServletResponse response, List<Long> ids) {
        List<OaProjectDto> list = oaProjectMapper.selectByIds(ids);
        ExcelUtil<OaProjectDto> util = new ExcelUtil<OaProjectDto>(OaProjectDto.class);
        util.exportExcel(response, list , "项目数据");
    }
    @Override
    public boolean deleteById(Long id) {
        // å…ˆåˆ é™¤é¡¹ç›®ä¸‹çš„阶段
        List<OaProjectPhase> oaProjectPhases = oaProjectPhaseService.list(new LambdaQueryWrapper<OaProjectPhase>()
                .eq(OaProjectPhase::getOaProjectId, id));
        if (!oaProjectPhases.isEmpty()) {
            oaProjectPhases.forEach(oaProjectPhase -> {
                oaProjectPhaseService.deleteById(oaProjectPhase.getPhaseId());
            });
        }
        return oaProjectMapper.deleteById(id) > 0;
    }
}
src/main/java/com/ruoyi/procurementrecord/controller/InboundManagementController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
package com.ruoyi.procurementrecord.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.pojo.InboundManagement;
import com.ruoyi.procurementrecord.service.InboundManagementService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/16 16:38
 */
@RestController
@Api(tags = "到货管理")
@RequestMapping("/inboundManagement")
public class InboundManagementController extends BaseController {
    @Autowired
    private InboundManagementService inboundManagementService;
    @GetMapping("/listPage")
    @ApiOperation("到货管理-查询")
    public AjaxResult listPage(Page page, InboundManagement inboundManagement) {
        IPage<InboundManagement> result = inboundManagementService.listPage(page, inboundManagement);
        return AjaxResult.success(result);
    }
    @PostMapping("/add")
    @ApiOperation("到货管理-添加")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody InboundManagement inboundManagement) {
        inboundManagement.setArrivalTime(new Date());
        boolean result = inboundManagementService.save(inboundManagement);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
    @PostMapping("/update")
    @ApiOperation("到货管理-修改")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody InboundManagement inboundManagement) {
        boolean result = inboundManagementService.updateById(inboundManagement);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
    @DeleteMapping("/del")
    @ApiOperation("到货管理-删除")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult del(@RequestBody List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)) return AjaxResult.error("请选择至少一条数据");
        boolean result = inboundManagementService.removeByIds(ids);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
}
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementPlanController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.ruoyi.procurementrecord.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.pojo.ProcurementPlan;
import com.ruoyi.procurementrecord.service.ProcurementPlanService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/18 16:13
 */
@RestController
@Api(tags = "采购计划")
@RequestMapping("/procurementPlan")
public class ProcurementPlanController extends BaseController {
    @Autowired
    private ProcurementPlanService procurementPlanService;
    @RequestMapping("/listPage")
    @ApiOperation("采购计划-查询")
    public AjaxResult listPage(Page page, ProcurementPlan procurementPlan){
        IPage<ProcurementPlan> result = procurementPlanService.listPage(page, procurementPlan);
        return AjaxResult.success(result);
    }
    @PostMapping("/add")
    @ApiOperation("采购计划-添加")
    public AjaxResult add(@RequestBody ProcurementPlan procurementPlan){
        boolean result = procurementPlanService.save(procurementPlan);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
    @PostMapping("/update")
    @ApiOperation("采购计划-修改")
    public AjaxResult update(@RequestBody ProcurementPlan procurementPlan){
        boolean result = procurementPlanService.updateById(procurementPlan);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
    @DeleteMapping("/del")
    @ApiOperation("采购计划-删除")
    public AjaxResult del(@RequestBody List<Long> ids){
        boolean result = procurementPlanService.removeByIds(ids);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
    /**
     * å¯¼å‡º
     * @param response
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response) {
        procurementPlanService.export(response);
    }
}
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementPriceManagementController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package com.ruoyi.procurementrecord.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.pojo.ProcurementPriceManagement;
import com.ruoyi.procurementrecord.service.ProcurementPriceManagementService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/17 15:08
 */
@RestController
@Api(tags = "采购价格管理")
@RequestMapping("/procurementPriceManagement")
public class ProcurementPriceManagementController extends BaseController {
    @Autowired
    private ProcurementPriceManagementService procurementPriceManagementService;
    @GetMapping("/listPage")
    @ApiOperation("采购价格管理-查询")
    public AjaxResult listPage(Page page, ProcurementPriceManagement procurementPriceManagement){
        IPage<ProcurementPriceManagement> result = procurementPriceManagementService.listPage(page, procurementPriceManagement);
        return AjaxResult.success(result);
    }
    @PostMapping("/add")
    @ApiOperation("采购价格管理-添加")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody ProcurementPriceManagement procurementPriceManagement){
        boolean result = procurementPriceManagementService.save(procurementPriceManagement);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
    @PostMapping("/update")
    @ApiOperation("采购价格管理-修改")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody ProcurementPriceManagement procurementPriceManagement){
        boolean result = procurementPriceManagementService.updateById(procurementPriceManagement);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
    @DeleteMapping("/del")
    @ApiOperation("采购价格管理-删除")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delete(@RequestBody List<Long> ids){
        if (ids == null || ids.isEmpty()) {
            return AjaxResult.error("请传入要删除的ID");
        }
        boolean result = procurementPriceManagementService.removeByIds(ids);
        return result ? AjaxResult.success() : AjaxResult.error();
    }
    /**
     * å¯¼å‡º
     * @param response
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response) {
        procurementPriceManagementService.export(response);
    }
}
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
@@ -80,6 +80,11 @@
        IPage<ProcurementPageDtoCopy> result =procurementRecordService.listPageCopy(page, procurementDto);
        return AjaxResult.success(result);
    }
    @GetMapping("/getReportList")
    @Log(title = "库存报表查询", businessType = BusinessType.OTHER)
    public AjaxResult getReportList(Page page, ProcurementPageDto procurementDto) {
        return AjaxResult.success(procurementRecordService.getReportList(page, procurementDto));
    }
    /**
     * å¯¼å‡º
src/main/java/com/ruoyi/procurementrecord/controller/ReturnManagementController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
package com.ruoyi.procurementrecord.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper;
import com.ruoyi.procurementrecord.pojo.ReturnManagement;
import com.ruoyi.procurementrecord.service.ReturnManagementService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/17 10:34
 */
@RestController
@Api(tags = "到货管理")
@RequestMapping("/returnManagement")
public class ReturnManagementController extends BaseController {
    @Autowired
    private ReturnManagementService returnManagementService;
    @Autowired
    private ReturnManagementMapper returnManagementMapper;
    @GetMapping("/listPage")
    @ApiOperation("到货管理-查询")
    public AjaxResult listPage(Page page, ReturnManagement returnManagement) {
        IPage<ReturnManagement> result = returnManagementService.listPage(page, returnManagement);
        return AjaxResult.success(result);
    }
    @PostMapping("/add")
    @ApiOperation("到货管理-添加")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody ReturnManagement returnManagement) {
        String rt = OrderUtils.countTodayByCreateTime(returnManagementMapper, "RT");
        returnManagement.setReturnNo(rt);
        boolean result = returnManagementService.save(returnManagement);
        return result ? success() : error();
    }
    @PostMapping("/update")
    @ApiOperation("到货管理-修改")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody ReturnManagement returnManagement) {
        boolean result = returnManagementService.updateById(returnManagement);
        return result ? success() : error();
    }
    @DeleteMapping("/del")
    @ApiOperation("到货管理-删除")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult del(@RequestBody List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) return error("请选择至少一条数据");
        boolean result = returnManagementService.removeByIds(ids);
        return result ? success() : error();
    }
}
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementDto.java
@@ -57,6 +57,11 @@
    private BigDecimal quantity;
    /**
     * æœ€ä½Žåº“存数量
     */
    @Excel(name = "最低库存数量")
    private BigDecimal minStock;
    /**
     * å¾…入库数量
     */
    @Excel(name = "待入库数量")
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementManagementUpdateDto.java
@@ -15,6 +15,7 @@
public class ProcurementManagementUpdateDto {
    private String createBy;
    private BigDecimal minStock;
    private Long createUser;
@@ -23,5 +24,5 @@
    private String entryDate;
    private Integer id;
    private Integer salesLedgerProductId;
}
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDto.java
@@ -1,10 +1,13 @@
package com.ruoyi.procurementrecord.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
@@ -112,5 +115,35 @@
     */
    @Excel(name = "不含税总价")
    private BigDecimal taxExclusiveTotalPrice;
    /**
     * æŠ¥è¡¨æ—¥æŠ¥
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate reportDate;
    /**
     * æŠ¥è¡¨æœˆæŠ¥
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate startMonth;
    /**
     * æŠ¥è¡¨æœˆæŠ¥
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate endMonth;
    /**
     * æŠ¥è¡¨æœˆæŠ¥
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate startDate;
    /**
     * æŠ¥è¡¨æœˆæŠ¥
     */
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate endDate;
}
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementPageDtoCopy.java
@@ -5,6 +5,7 @@
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
@@ -42,8 +43,17 @@
     */
    @Excel(name = "待出库数量")
    private BigDecimal inboundNum0;
    /**
     * å‡ºåº“数量
     */
    @Excel(name = "出库数量")
    private BigDecimal totalInboundNum;
    /**
     * æœ€ä½Žåº“存数量
     */
    @Excel(name = "最低库存数量")
    private BigDecimal minStock;
    /**
     * å‡ºå…¥åº“æ—¶é—´
     */
@@ -124,5 +134,35 @@
     */
    @Excel(name = "不含税总价")
    private BigDecimal taxExclusiveTotalPrice;
    /**
     * æŠ¥è¡¨æ—¥æŠ¥
     */
    @Excel(name = "报表日报")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate reportDate;
    /**
     * æŠ¥è¡¨æœˆæŠ¥
     */
    @Excel(name = "报表月报开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate startMonth;
    /**
     * æŠ¥è¡¨æœˆæŠ¥
     */
    @Excel(name = "报表月报结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate endMonth;
    /**
     * æŠ¥è¡¨æœˆæŠ¥
     */
    @Excel(name = "报表作业开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate startDate;
    /**
     * æŠ¥è¡¨æœˆæŠ¥
     */
    @Excel(name = "报表作业结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private LocalDate endDate;
}
src/main/java/com/ruoyi/procurementrecord/mapper/InboundManagementMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.procurementrecord.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.procurementrecord.pojo.InboundManagement;
import org.apache.ibatis.annotations.Param;
/**
 * @author :yys
 * @date : 2025/9/16 16:33
 */
public interface InboundManagementMapper extends BaseMapper<InboundManagement> {
    /**
     * æŸ¥è¯¢é‡‡è´­å…¥åº“-到货管理列表
     *
     * @param page
     * @param inboundManagement
     * @return
     */
    IPage<InboundManagement> listPage(Page page,@Param("req") InboundManagement inboundManagement);
}
src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementPlanMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.procurementrecord.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.procurementrecord.pojo.ProcurementPlan;
import org.apache.ibatis.annotations.Param;
/**
 * @author :yys
 * @date : 2025/9/18 16:10
 */
public interface ProcurementPlanMapper extends BaseMapper<ProcurementPlan> {
    /**
     * æŸ¥è¯¢é‡‡è´­è®¡åˆ’列表
     *
     * @param page
     * @param procurementPlan
     * @return
     */
    IPage<ProcurementPlan> listPage(Page page,@Param("req") ProcurementPlan procurementPlan);
}
src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementPriceManagementMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.procurementrecord.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.procurementrecord.pojo.ProcurementPriceManagement;
import org.apache.ibatis.annotations.Param;
/**
 * @author :yys
 * @date : 2025/9/17 15:05
 */
public interface ProcurementPriceManagementMapper extends BaseMapper<ProcurementPriceManagement> {
    /**
     * æŸ¥è¯¢é‡‡è´­ä»·æ ¼ç®¡ç†åˆ—表
     *
     * @param page
     * @param procurementPriceManagement
     * @return
     */
    IPage<ProcurementPriceManagement> listPage(Page page,@Param("req") ProcurementPriceManagement procurementPriceManagement);
}
src/main/java/com/ruoyi/procurementrecord/mapper/ReturnManagementMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.procurementrecord.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.procurementrecord.pojo.ReturnManagement;
import org.apache.ibatis.annotations.Param;
/**
 * @author :yys
 * @date : 2025/9/17 10:32
 */
public interface ReturnManagementMapper extends BaseMapper<ReturnManagement> {
    /**
     * æŸ¥è¯¢åˆ—表
     *
     * @param page
     * @return
     */
    IPage<ReturnManagement> listPage(Page page,@Param("req") ReturnManagement returnManagement);
}
src/main/java/com/ruoyi/procurementrecord/pojo/InboundManagement.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
package com.ruoyi.procurementrecord.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * @author :yys
 * @date : 2025/9/16 16:29
 */
@Data
@TableName("inbound_management")
@ApiModel
public class InboundManagement {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "订单号")
    private String orderNo;
    @ApiModelProperty(value = "到货单号")
    private String arrivalNo;
    @ApiModelProperty(value = "供应商名称")
    private String supplierName;
    @ApiModelProperty(value = "到货状态")
    private String status;
    @ApiModelProperty(value = "到货时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date arrivalTime;
    @ApiModelProperty(value = "到货数量")
    private String arrivalQuantity;
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementPlan.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
package com.ruoyi.procurementrecord.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
 * @author :yys
 * @date : 2025/9/18 16:00
 */
@Data
@TableName("procurement_plan")
@ApiModel
public class ProcurementPlan {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "编码")
    @Excel(name = "编码")
    private String code;
    @ApiModelProperty(value = "名称")
    @Excel(name = "名称")
    private String planName;
    @ApiModelProperty(value = "描述")
    @Excel(name = "描述")
    private String description;
    @ApiModelProperty(value = "状态")
    @Excel(name = "状态", readConverterExp = "disabled=禁用,active=启用")
    private String status;
    @ApiModelProperty(value = "是否系统预置")
    private Boolean isSystemPreset;
    @ApiModelProperty(value = "考虑现有库存")
    private Boolean considerExistingStock;
    @ApiModelProperty(value = "仓库运行MRP的控制")
    private Boolean warehouseControl;
    @ApiModelProperty(value = "计算总需求")
    private Boolean calculateTotalDemand;
    @ApiModelProperty(value = "考虑安全库存")
    private Boolean considerSafetyStock;
    @ApiModelProperty(value = "考虑锁库")
    private Boolean considerLockedStock;
    @ApiModelProperty(value = "不考虑物料辅助属性")
    private Boolean notConsiderMaterialAux;
    @ApiModelProperty(value = "负库存作为需求")
    private Boolean negativeStockAsDemand;
    @ApiModelProperty(value = "物料")
    private Boolean summaryMaterial;
    @ApiModelProperty(value = "辅助属性")
    private Boolean summaryAuxAttributes;
    @ApiModelProperty(value = "需求日期")
    private Boolean summaryDemandDate;
    @ApiModelProperty(value = "计算公式")
    @Excel(name = "计算公式")
    private String formula;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "最后计算时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementPriceManagement.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,122 @@
package com.ruoyi.procurementrecord.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * @author :yys
 * @date : 2025/9/17 14:58
 */
@Data
@TableName("procurement_price_management")
@ApiModel
public class ProcurementPriceManagement {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "商品名称")
    @Excel(name = "商品名称")
    private String productName;
    @ApiModelProperty(value = "商品编码")
    @Excel(name = "商品编码")
    private String productCode;
    @ApiModelProperty(value = "规格型号")
    @Excel(name = "规格型号")
    private String specification;
    @ApiModelProperty(value = "供应商名称")
    @Excel(name = "供应商名称")
    private String supplierName;
    @ApiModelProperty(value = "基础价格")
    @Excel(name = "基础价格")
    private String basePrice;
    @ApiModelProperty(value = "状态")
    @TableField(exist = false)
    @Excel(name = "状态")
    private String status;
    @ApiModelProperty(value = "单位")
    private String unit;
    @ApiModelProperty(value = "折扣类型")
    @Excel(name = "折扣类型", readConverterExp = "=无折扣,percentage=百分比折扣,fixed=固定金额")
    private String discountType;
    @ApiModelProperty(value = "折扣值")
    @Excel(name = "折扣值")
    private String discountValue;
    @ApiModelProperty(value = "折扣有效期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date discountEndTime;
    @ApiModelProperty(value = "最低价格")
    @Excel(name = "最低价格")
    private String minPrice;
    @ApiModelProperty(value = "最高价格")
    @Excel(name = "最高价格")
    private String maxPrice;
    @ApiModelProperty(value = "预警阈值(%)")
    private String warningThreshold;
    @ApiModelProperty(value = "生效时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "生效时间", width = 30, dateFormat = "yyyy-MM-dd")
    private Date effectiveTime;
    @ApiModelProperty(value = "失效时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date expireTime;
    @ApiModelProperty(value = "调价原因")
    private String reason;
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementRecordStorage.java
@@ -35,12 +35,17 @@
     * å…¥åº“数量
     */
    private BigDecimal inboundNum;
//    /**
//     * æœ€ä½Žåº“存数量
//     */
//    private BigDecimal minStock;
    /**
     * å…¥åº“用户
     */
    private String createBy;
    /**
     * å…¥åº“用户id
     */
src/main/java/com/ruoyi/procurementrecord/pojo/ReturnManagement.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
package com.ruoyi.procurementrecord.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * @author :yys
 * @date : 2025/9/17 10:28
 */
@Data
@TableName("return_management")
@ApiModel
public class ReturnManagement {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "退货单号")
    private String returnNo;
    @ApiModelProperty(value = "关联单号")
    private String relatedNo;
    @ApiModelProperty(value = "退货类型")
    private String returnType;
    @ApiModelProperty(value = "供应商名称")
    private String supplierName;
    @ApiModelProperty(value = "退货原因")
    private String returnReason;
    @ApiModelProperty(value = "退货状态")
    private String status;
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/procurementrecord/service/InboundManagementService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.procurementrecord.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.procurementrecord.pojo.InboundManagement;
/**
 * @author :yys
 * @date : 2025/9/16 16:36
 */
public interface InboundManagementService extends IService<InboundManagement> {
    /**
     * èŽ·å–åˆ—è¡¨
     *
     * @param page
     * @param inboundManagement
     * @return
     */
    IPage<InboundManagement> listPage(Page page, InboundManagement inboundManagement);
}
src/main/java/com/ruoyi/procurementrecord/service/ProcurementPlanService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.ruoyi.procurementrecord.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.procurementrecord.pojo.ProcurementPlan;
import javax.servlet.http.HttpServletResponse;
/**
 * @author :yys
 * @date : 2025/9/18 16:11
 */
public interface ProcurementPlanService extends IService<ProcurementPlan> {
    /**
     * æŸ¥è¯¢
     * @param page
     * @param procurementPlan
     * @return
     */
    IPage<ProcurementPlan> listPage(Page page, ProcurementPlan procurementPlan);
    void export(HttpServletResponse response);
}
src/main/java/com/ruoyi/procurementrecord/service/ProcurementPriceManagementService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.procurementrecord.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.procurementrecord.pojo.ProcurementPriceManagement;
import javax.servlet.http.HttpServletResponse;
/**
 * @author :yys
 * @date : 2025/9/17 15:06
 */
public interface ProcurementPriceManagementService extends IService<ProcurementPriceManagement> {
    /**
     * é‡‡è´­ä»·æ ¼ç®¡ç†-查询
     *
     * @param page
     * @param procurementPriceManagement
     * @return
     */
    IPage<ProcurementPriceManagement> listPage(Page page, ProcurementPriceManagement procurementPriceManagement);
    void export(HttpServletResponse response);
}
src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
@@ -8,6 +8,7 @@
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
 * @author :yys
@@ -31,4 +32,6 @@
    int updateManagement(ProcurementManagementUpdateDto procurementDto);
    void exportCopy(HttpServletResponse response);
    Map<String, Object> getReportList(Page page, ProcurementPageDto procurementDto);
}
src/main/java/com/ruoyi/procurementrecord/service/ReturnManagementService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.procurementrecord.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.procurementrecord.pojo.ReturnManagement;
/**
 * @author :yys
 * @date : 2025/9/17 10:33
 */
public interface ReturnManagementService extends IService<ReturnManagement> {
    /**
     * æŸ¥è¯¢åˆ—表
     *
     * @param page
     * @param returnManagement
     * @return
     */
    IPage<ReturnManagement> listPage(Page page, ReturnManagement returnManagement);
}
src/main/java/com/ruoyi/procurementrecord/service/impl/InboundManagementServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.procurementrecord.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.procurementrecord.mapper.InboundManagementMapper;
import com.ruoyi.procurementrecord.pojo.InboundManagement;
import com.ruoyi.procurementrecord.service.InboundManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author :yys
 * @date : 2025/9/16 16:37
 */
@Service
@Slf4j
public class InboundManagementServiceImpl extends ServiceImpl<InboundManagementMapper, InboundManagement> implements InboundManagementService {
    @Autowired
    private InboundManagementMapper inboundManagementMapper;
    @Override
    public IPage<InboundManagement> listPage(Page page, InboundManagement inboundManagement) {
        IPage<InboundManagement> result = inboundManagementMapper.listPage(page, inboundManagement);
        return result;
    }
}
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementPlanServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package com.ruoyi.procurementrecord.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.procurementrecord.mapper.ProcurementPlanMapper;
import com.ruoyi.procurementrecord.pojo.ProcurementPlan;
import com.ruoyi.procurementrecord.pojo.ProcurementPriceManagement;
import com.ruoyi.procurementrecord.service.ProcurementPlanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/18 16:12
 */
@Service
@Slf4j
public class ProcurementPlanServiceImpl extends ServiceImpl<ProcurementPlanMapper, ProcurementPlan> implements ProcurementPlanService {
    @Autowired
    private ProcurementPlanMapper procurementPlanMapper;
    @Override
    public IPage<ProcurementPlan> listPage(Page page, ProcurementPlan procurementPlan) {
        IPage<ProcurementPlan> result = procurementPlanMapper.listPage(page, procurementPlan);
        return result;
    }
    @Override
    public void export(HttpServletResponse response) {
        List<ProcurementPlan> procurementPriceManagements = procurementPlanMapper.selectList(null);
        ExcelUtil<ProcurementPlan> util = new ExcelUtil<ProcurementPlan>(ProcurementPlan.class);
        util.exportExcel(response, procurementPriceManagements, "采购计划");
    }
}
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementPriceManagementServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
package com.ruoyi.procurementrecord.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.excel.ExcelUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.procurementrecord.dto.ProcurementPageDto;
import com.ruoyi.procurementrecord.mapper.ProcurementPriceManagementMapper;
import com.ruoyi.procurementrecord.pojo.ProcurementPriceManagement;
import com.ruoyi.procurementrecord.service.ProcurementPriceManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/17 15:07
 */
@Service
@Slf4j
public class ProcurementPriceManagementServiceImpl extends ServiceImpl<ProcurementPriceManagementMapper, ProcurementPriceManagement> implements ProcurementPriceManagementService {
    @Autowired
    private ProcurementPriceManagementMapper procurementPriceManagementMapper;
    @Override
    public IPage<ProcurementPriceManagement> listPage(Page page, ProcurementPriceManagement procurementPriceManagement) {
        IPage<ProcurementPriceManagement> result = procurementPriceManagementMapper.listPage(page, procurementPriceManagement);
        // æ ¹æ®ç”Ÿæ•ˆæ—¶é—´ï¼Œå¤±æ•ˆæ—¶é—´åˆ¤æ–­çŠ¶æ€ æœ‰æ•ˆï¼Œå¾…生效,已过期
        for (ProcurementPriceManagement record : result.getRecords()) {
            if (record.getEffectiveTime() != null) {
                if (record.getEffectiveTime().getTime() <= System.currentTimeMillis()) {
                    record.setStatus("active");
                }
            }
            if (record.getEffectiveTime() != null) {
                if (record.getEffectiveTime().getTime() > System.currentTimeMillis()) {
                    record.setStatus("pending");
                }
            }
            if (record.getExpireTime() != null) {
                if (record.getExpireTime().getTime() <= System.currentTimeMillis()) {
                    record.setStatus("expired");
                }
            }
        }
        return result;
    }
    @Override
    public void export(HttpServletResponse response) {
        List<ProcurementPriceManagement> procurementPriceManagements = procurementPriceManagementMapper.selectList(null);
        for (ProcurementPriceManagement procurementPriceManagement : procurementPriceManagements) {
            if (procurementPriceManagement.getEffectiveTime() != null) {
                if (procurementPriceManagement.getEffectiveTime().getTime() <= System.currentTimeMillis()) {
                    procurementPriceManagement.setStatus("有效");
                }
            }
            if (procurementPriceManagement.getEffectiveTime() != null) {
                if (procurementPriceManagement.getEffectiveTime().getTime() > System.currentTimeMillis()) {
                    procurementPriceManagement.setStatus("待生效");
                }
            }
            if (procurementPriceManagement.getExpireTime() != null) {
                if (procurementPriceManagement.getExpireTime().getTime() <= System.currentTimeMillis()) {
                    procurementPriceManagement.setStatus("已过期");
                }
            }
        }
        ExcelUtil<ProcurementPriceManagement> util = new ExcelUtil<ProcurementPriceManagement>(ProcurementPriceManagement.class);
        util.exportExcel(response, procurementPriceManagements, "采购价格管理");}
}
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -4,7 +4,6 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
@@ -25,9 +24,10 @@
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -177,6 +177,12 @@
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String entryDateStr = procurementDto.getEntryDate() + " 00:00:00";
        String createTimeStr = procurementDto.getCreateTime() + " 00:00:00";
        SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(procurementDto.getSalesLedgerProductId());
        if(salesLedgerProduct == null){
            throw new RuntimeException("销售台账产品不存在");
        }
        salesLedgerProduct.setMinStock(procurementDto.getMinStock());
        salesLedgerProductMapper.updateById(salesLedgerProduct);
        ProcurementRecordStorage procurementRecordStorageById = getProcurementRecordById(procurementDto.getId());
        procurementRecordStorageById.setCreateBy(sysUser.getNickName());
        procurementRecordStorageById.setCreateUser(sysUser.getUserId());
@@ -228,6 +234,104 @@
        }
        ExcelUtil<ProcurementPageDtoCopy> util = new ExcelUtil<ProcurementPageDtoCopy>(ProcurementPageDtoCopy.class);
        util.exportExcel(response, list, "库存管理");
    }
    @Override
    public Map<String, Object> getReportList(Page page, ProcurementPageDto procurementDto) {
        // æž„建报表数据结构
        Map<String, Object> reportData = new HashMap<>();
        // 2. æž„建图表数据
        Map<String, Object> chartData = new HashMap<>();
        IPage<ProcurementPageDtoCopy> procurementPageDtoCopyIPage = procurementRecordMapper.listPageCopy(page, procurementDto);
        List<ProcurementPageDtoCopy> procurementPageDtoCopyList = procurementPageDtoCopyIPage.getRecords();
        // è®¡ç®—待入库数量
        reportData.put("tableData", procurementPageDtoCopyList);
        // æŸ¥è¯¢é‡‡è´­è®°å½•已入库数量
        List<Integer> collect = procurementPageDtoCopyList.stream().map(ProcurementPageDtoCopy::getId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(collect)){
             return reportData;
        }
        LambdaQueryWrapper<ProcurementRecordOut> procurementRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordLambdaQueryWrapper.in(ProcurementRecordOut::getProcurementRecordStorageId, collect);
        List<ProcurementRecordOut> procurementRecords = procurementRecordOutMapper.selectList(procurementRecordLambdaQueryWrapper);
        if(CollectionUtils.isEmpty( procurementRecords)){
             return reportData;
        }
        int totalIn =0;
        int totalOut =0;
        int currentStock =0;
        int turnoverRate =0;
        List<String> dates = new ArrayList<>();
        List<Integer> values = new ArrayList<>();
        List<String> comparisonDates = new ArrayList<>();
        List<Integer> inValues = new ArrayList<>();
        List<Integer> outValues = new ArrayList<>();
        // å®šä¹‰æ—¥æœŸæ ¼å¼åŒ–器,指定为yyyy-MM-dd格式
        DateTimeFormatter dateFormatter = DateTimeFormatter.ISO_LOCAL_DATE;
        for (ProcurementPageDtoCopy dto : procurementPageDtoCopyList) {
            dates.add(dto.getCreateTime().format(dateFormatter));
            comparisonDates.add(dto.getCreateTime().format(dateFormatter));
            // æ ¹æ®é‡‡è´­å°è´¦ID筛选对应的出库记录
            List<ProcurementRecordOut> collect1 = procurementRecords.stream()
                    .filter(ProcurementRecordOut -> ProcurementRecordOut.getProcurementRecordStorageId().equals(dto.getId()))
                    .collect(Collectors.toList());
            // å¦‚果没有相关的出库记录,跳过该条数据
            if(CollectionUtils.isEmpty(collect1)){
                dto.setInboundNum0(dto.getInboundNum());
                continue;
            }
            // è®¡ç®—已出库数量总和,并设置待出库数量
            BigDecimal totalInboundNum = collect1.stream()
                    .map(ProcurementRecordOut::getInboundNum)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            // å¾…出库数量 = æ€»æ•°é‡ - å·²å‡ºåº“数量
            dto.setInboundNum0(dto.getInboundNum().subtract(totalInboundNum));
            // è®¡ç®—总入库数量
            totalIn += dto.getInboundNum().intValue();
            inValues.add(totalIn);
            // è®¡ç®—总出库数量
            totalOut += totalInboundNum.intValue();
            outValues.add(totalOut);
            // è®¡ç®—当前库存
            currentStock += dto.getInboundNum().intValue() - totalInboundNum.intValue();
            values.add(currentStock);
            // è®¡ç®—周转率
            if(totalIn > 0){
                turnoverRate = totalOut * 100 / totalIn;
            }
        }
        // 1. æž„建汇总数据
        Map<String, Object> summary = new HashMap<>();
        summary.put("totalIn", totalIn);          // æ€»å…¥åº“量,实际应从数据计算
        summary.put("totalOut", totalOut);         // æ€»å‡ºåº“量,实际应从数据计算
        summary.put("currentStock", currentStock);     // å½“前库存量,实际应从数据计算
        summary.put("turnoverRate", turnoverRate);      // å‘¨è½¬çŽ‡ï¼Œå®žé™…åº”ä»Žæ•°æ®è®¡ç®—
        reportData.put("summary", summary);
        // 2. æž„建图表数据
//        Map<String, Object> chartData = new HashMap<>();
//        List<String> dates = Arrays.asList("2025-09-15", "2025-09-16", "2025-09-17", "2025-09-18", "2025-09-19");
//        List<Integer> values = Arrays.asList(300, 350, 400, 380, 420);
        chartData.put("dates", dates);
        chartData.put("values", values);
        chartData.put("comparisonDates", comparisonDates);  // å®žé™…应从数据计算
        chartData.put("inValues", inValues);         // å®žé™…应从数据计算
        chartData.put("outValues", outValues);        // å®žé™…应从数据计算
        reportData.put("chartData", chartData);
        // 3. è®¾ç½®è¡¨æ ¼æ•°æ®
        reportData.put("tableData", procurementPageDtoCopyList);
        return reportData;
    }
    @Override
@@ -334,7 +438,8 @@
            BigDecimal totalInboundNum = collect1.stream()
                    .map(ProcurementRecordOut::getInboundNum)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            // å‡ºåº“数量 = æ€»æ•°é‡ - å¾…出库数量
            dto.setTotalInboundNum(totalInboundNum);
            // å¾…出库数量 = æ€»æ•°é‡ - å·²å‡ºåº“数量
            dto.setInboundNum0(dto.getInboundNum().subtract(totalInboundNum));
        }
src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.procurementrecord.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper;
import com.ruoyi.procurementrecord.pojo.ReturnManagement;
import com.ruoyi.procurementrecord.service.ReturnManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author :yys
 * @date : 2025/9/17 10:34
 */
@Service
@Slf4j
public class ReturnManagementServiceImpl extends ServiceImpl<ReturnManagementMapper, ReturnManagement> implements ReturnManagementService {
    @Autowired
    private ReturnManagementMapper returnManagementMapper;
    @Override
    public IPage<ReturnManagement> listPage(Page page, ReturnManagement returnManagement) {
        IPage<ReturnManagement> returnManagementIPage =  returnManagementMapper.listPage(page, returnManagement);
        return returnManagementIPage;
    }
}
src/main/java/com/ruoyi/project/common/CommonController.java
@@ -5,6 +5,11 @@
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.basic.service.StorageBlobService;
import com.ruoyi.framework.web.domain.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,6 +32,7 @@
 * 
 * @author ruoyi
 */
@Api(tags = "通用接口")
@RestController
@RequestMapping("/common")
public class CommonController
@@ -69,6 +75,20 @@
        }
    }
    @Autowired
    private StorageBlobService storageBlobService;
    /**
     * minio通用上传请求(多个)
     */
    @PostMapping("/minioUploads")
    @ApiOperation(value = "minio通用上传请求")
    public AjaxResult minioUploadFiles(List<MultipartFile> files, String bucketName, Long type) throws Exception
    {
        return AjaxResult.success(storageBlobService.updateStorageBlobs(files, bucketName,type));
    }
    /**
     * é€šç”¨ä¸Šä¼ è¯·æ±‚(单个)
     */
src/main/java/com/ruoyi/project/system/mapper/SysUserMapper.java
@@ -1,10 +1,13 @@
package com.ruoyi.project.system.mapper;
import java.util.ArrayList;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import com.ruoyi.project.system.domain.SysUser;
import org.springframework.beans.PropertyValues;
/**
 * ç”¨æˆ·è¡¨ æ•°æ®å±‚
@@ -134,4 +137,8 @@
     * @return ç»“æžœ
     */
    public SysUser checkEmailUnique(String email);
    List<SysUser> selectList(List<Long> registrantIds);
    List<SysUser> selectUsersByIds(@Param("userIds") List<Long> userIds);
}
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -6,6 +6,10 @@
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.pojo.AccountExpense;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountExpenseService;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.mapper.SupplierManageMapper;
@@ -68,7 +72,7 @@
@RequiredArgsConstructor
@Slf4j
public class PurchaseLedgerServiceImpl extends ServiceImpl<PurchaseLedgerMapper, PurchaseLedger> implements IPurchaseLedgerService {
    private final AccountExpenseService accountExpenseService;
    private final PurchaseLedgerMapper purchaseLedgerMapper;
    private final SalesLedgerMapper salesLedgerMapper;
@@ -128,12 +132,39 @@
        purchaseLedger.setRecorderId(purchaseLedgerDto.getRecorderId());
        purchaseLedger.setRecorderName(sysUser.getNickName());
        purchaseLedger.setPhoneNumber(sysUser.getPhonenumber());
        // 2. å¤„理账户收入
        AccountExpense accountExpense = new AccountExpense();
        accountExpense.setExpenseDate(purchaseLedger.getEntryDate());
        accountExpense.setExpenseType("0");
        accountExpense.setSupplierName(purchaseLedger.getSupplierName());
        accountExpense.setExpenseMoney(purchaseLedger.getContractAmount());
        accountExpense.setExpenseDescribed("采购合同:" + purchaseLedger.getPurchaseContractNumber());
        accountExpense.setExpenseMethod("0");
        accountExpense.setInvoiceNumber(purchaseLedger.getPurchaseContractNumber());
        accountExpense.setInputTime(new Date());
        accountExpense.setInputUser(loginUser.getNickName());
        // 3. æ–°å¢žæˆ–更新主表
        if (purchaseLedger.getId() == null) {
            purchaseLedgerMapper.insert(purchaseLedger);
//            accountIncomeService.save(accountIncome);
            accountExpenseService.save(accountExpense);
        } else {
            purchaseLedgerMapper.updateById(purchaseLedger);
            PurchaseLedger purchaseLedgerDB = purchaseLedgerMapper.selectById(purchaseLedger.getId());
            AccountExpense accountExpenseDB = accountExpenseService.getByInvoiceNumber(purchaseLedger.getPurchaseContractNumber());
            if (ObjectUtils.isEmpty(accountExpenseDB)) {
                throw new BaseException("支出管理无该采购合同的支出记录");
            }
            accountExpenseDB.setExpenseDate(purchaseLedgerDB.getEntryDate());
            accountExpenseDB.setExpenseType("0");
            accountExpenseDB.setSupplierName(purchaseLedgerDB.getSupplierName());
            accountExpenseDB.setExpenseMoney(purchaseLedgerDB.getContractAmount());
            accountExpenseDB.setExpenseDescribed("采购合同:" + purchaseLedgerDB.getPurchaseContractNumber());
            accountExpenseDB.setExpenseMethod("0");
            accountExpenseDB.setInvoiceNumber(purchaseLedgerDB.getPurchaseContractNumber());
            accountExpenseService.updateById(accountExpenseDB);
        }
        // 4. å¤„理子表数据
src/main/java/com/ruoyi/sales/controller/PaymentShippingController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.mapper.PaymentShippingMapper;
import com.ruoyi.sales.pojo.PaymentShipping;
import com.ruoyi.sales.service.PaymentShippingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/15 14:02
 */
@RestController
@RequestMapping("/paymentShipping")
@Api(tags = "支付与发货管理")
public class PaymentShippingController extends BaseController {
    @Autowired
    private PaymentShippingService paymentShippingService;
    @Autowired
    private PaymentShippingMapper paymentShippingMapper;
    @GetMapping("/listPage")
    @ApiOperation("分页查询支付与发货信息")
    public AjaxResult listPage(Page page, PaymentShipping paymentShipping) {
        IPage<PaymentShipping> listPage = paymentShippingService.listPage(page, paymentShipping);
        return AjaxResult.success(listPage);
    }
    @PostMapping("/add")
    @ApiOperation("添加支付与发货信息")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody PaymentShipping paymentShipping) {
        String ord = OrderUtils.countTodayByCreateTime(paymentShippingMapper, "ORD");
        paymentShipping.setOrderNo(ord);
        boolean save = paymentShippingService.save(paymentShipping);
        return save ? success() : error();
    }
    @PostMapping("/update")
    @ApiOperation("修改支付与发货信息")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody PaymentShipping paymentShipping) {
        boolean update = paymentShippingService.updateById(paymentShipping);
        return update ? success() : error();
    }
    @DeleteMapping("/delete")
    @ApiOperation("删除支付与发货信息")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delete(@RequestBody List<Long> ids){
        if (CollectionUtils.isEmpty(ids)){
            return AjaxResult.error("请传入要删除的ID");
        }
        return AjaxResult.success(paymentShippingService.removeByIds(ids));
    }
}
src/main/java/com/ruoyi/sales/controller/SalesLedgerController.java
@@ -1,5 +1,6 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -12,6 +13,11 @@
import com.ruoyi.sales.dto.InvoiceLedgerDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.mapper.InvoiceLedgerMapper;
import com.ruoyi.sales.mapper.InvoiceRegistrationProductMapper;
import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.pojo.InvoiceLedger;
import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
import com.ruoyi.sales.pojo.ReceiptPayment;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.service.ICommonFileService;
import com.ruoyi.sales.service.ISalesLedgerService;
@@ -22,6 +28,7 @@
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -44,6 +51,12 @@
    @Autowired
    private InvoiceLedgerMapper invoiceLedgerMapper;
    @Autowired
    private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
    @Autowired
    private ReceiptPaymentMapper receiptPaymentMapper;
    /**
     * æŸ¥è¯¢é”€å”®å°è´¦åˆ—表
     */
@@ -65,10 +78,10 @@
                if (salesLedger.getId().intValue() == invoiceLedgerDto.getSalesLedgerId()) {
                    BigDecimal noInvoiceAmountTotal = salesLedger.getContractAmount().subtract(invoiceLedgerDto.getInvoiceTotal());
                    salesLedger.setNoInvoiceAmountTotal(noInvoiceAmountTotal);
                }
            }
        }
                }
            }
        }
        return getDataTable(list);
    }
@@ -181,6 +194,17 @@
            iPage.setTotal(iPage.getRecords().size());
            return iPage;
        }
        // è®¡ç®—回款金额,待回款金额
        List<InvoiceRegistrationProduct> invoiceRegistrationProducts = invoiceRegistrationProductMapper.selectList(new LambdaQueryWrapper<InvoiceRegistrationProduct>()
                .in(InvoiceRegistrationProduct::getSalesLedgerId, salesLedgerIds));
        List<InvoiceLedger> invoiceLedgers = invoiceLedgerMapper.selectList(new LambdaQueryWrapper<InvoiceLedger>()
                .in(InvoiceLedger::getInvoiceRegistrationProductId, invoiceRegistrationProducts.stream().map(InvoiceRegistrationProduct::getId).collect(Collectors.toList())));
        List<ReceiptPayment> receiptPayments = new ArrayList<>();
        if(!CollectionUtils.isEmpty(invoiceLedgers)){
            receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>()
                    .in(ReceiptPayment::getInvoiceLedgerId, invoiceLedgers.stream().map(InvoiceLedger::getId).collect(Collectors.toList())));
        }
        for (SalesLedger salesLedger : iPage.getRecords()) {
            boolean existFlag = false;
            BigDecimal noInvoiceAmountTotal = BigDecimal.ZERO;
@@ -190,6 +214,26 @@
                    noInvoiceAmountTotal = salesLedger.getContractAmount().subtract(invoiceLedgerDto.getInvoiceTotal());
                    invoiceTotal = invoiceLedgerDto.getInvoiceTotal();
                    existFlag = true;
                    if(!CollectionUtils.isEmpty(receiptPayments)){
                        List<InvoiceRegistrationProduct> collect = invoiceRegistrationProducts.stream()
                                .filter(item -> salesLedger.getId().equals(Long.parseLong(item.getSalesLedgerId().toString())))
                                .collect(Collectors.toList());
                        List<Integer> collect1 = collect.stream()
                                .map(InvoiceRegistrationProduct::getId).collect(Collectors.toList());
                        List<InvoiceLedger> collect2 = invoiceLedgers.stream()
                                .filter(item -> collect1.contains(item.getInvoiceRegistrationProductId()))
                                .collect(Collectors.toList());
                        // èŽ·å–å·²å›žæ¬¾é‡‘é¢
                        List<ReceiptPayment> collect3 = receiptPayments.stream()
                                .filter(item -> collect2.stream().anyMatch(item1 -> item1.getId().equals(item.getInvoiceLedgerId())))
                                .collect(Collectors.toList());
                        BigDecimal receiptPaymentAmountTotal = collect3.stream().map(ReceiptPayment::getReceiptPaymentAmount)
                                .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                        // èŽ·å–å¾…å›žæ¬¾é‡‘é¢
                        BigDecimal noReceiptPaymentAmountTotal = invoiceLedgerDto.getInvoiceTotal().subtract(receiptPaymentAmountTotal);
                        salesLedger.setReceiptPaymentAmountTotal(receiptPaymentAmountTotal);
                        salesLedger.setNoReceiptAmount(noReceiptPaymentAmountTotal);
                    }
                    break;
                }
            }
src/main/java/com/ruoyi/sales/controller/SalesQuotationController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.ruoyi.sales.controller;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.dto.SalesQuotationDto;
import com.ruoyi.sales.service.SalesQuotationService;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/sales/quotation")
public class SalesQuotationController {
    @Autowired
    private SalesQuotationService salesQuotationService;
    @GetMapping("/list")
    public AjaxResult getList(Page page, SalesQuotationDto salesQuotationDto) {
        return AjaxResult.success(salesQuotationService.listPage(page, salesQuotationDto));
    }
    @PostMapping("/add")
    public AjaxResult add(@RequestBody SalesQuotationDto salesQuotationDto) {
        return AjaxResult.success(salesQuotationService.add(salesQuotationDto));
    }
    @PostMapping("/update")
    public AjaxResult update(@RequestBody SalesQuotationDto salesQuotationDto) {
        return AjaxResult.success(salesQuotationService.edit(salesQuotationDto));
    }
    @DeleteMapping("/delete")
    public AjaxResult delete(@RequestBody Long id) {
        return AjaxResult.success(salesQuotationService.delete(id));
    }
}
src/main/java/com/ruoyi/sales/controller/SalespersonManagementController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.dto.InvoiceLedgerDto;
import com.ruoyi.sales.pojo.SalespersonManagement;
import com.ruoyi.sales.service.SalespersonManagementService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/15 10:04
 */
@RestController
@RequestMapping("/salespersonManagement")
@Api(tags = "业务员管理")
public class SalespersonManagementController extends BaseController {
    @Autowired
    private SalespersonManagementService salespersonManagementService;
    @GetMapping("/listPage")
    @ApiOperation("分页查询业务员信息")
    public AjaxResult listPage(Page page, SalespersonManagement salespersonManagement) {
        IPage<SalespersonManagement> listPage = salespersonManagementService.listPage(page, salespersonManagement);
        return AjaxResult.success(listPage);
    }
    @PostMapping("/add")
    @ApiOperation("添加业务员信息")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody SalespersonManagement salespersonManagement) {
        boolean save = salespersonManagementService.save(salespersonManagement);
        return save ? AjaxResult.success() : AjaxResult.error();
    }
    @PostMapping("/update")
    @ApiOperation("修改业务员信息")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody SalespersonManagement salespersonManagement) {
        boolean update = salespersonManagementService.updateById(salespersonManagement);
        return update ? AjaxResult.success() : AjaxResult.error();
    }
    @DeleteMapping("/delete")
    @ApiOperation("删除业务员信息")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return AjaxResult.error("请传入要删除的ID");
        }
        boolean delete = salespersonManagementService.removeByIds(ids);
        return delete ? AjaxResult.success() : AjaxResult.error();
    }
}
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ShippingInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/10/22 9:34
 */
@RestController
@RequestMapping("/shippingInfo")
@Api(tags = "发货信息管理")
public class ShippingInfoController extends BaseController {
    @Autowired
    private ShippingInfoService shippingInfoService;
    @GetMapping("/listPage")
    @ApiOperation("发货信息列表")
    public AjaxResult listPage(Page page, ShippingInfo req) {
        IPage<ShippingInfo> listPage = shippingInfoService.listPage(page,req);
        return AjaxResult.success(listPage);
    }
    @PostMapping("/add")
    @ApiOperation("添加发货信息")
    public AjaxResult add(@RequestBody ShippingInfo req) {
        boolean save = shippingInfoService.save(req);
        return save ? AjaxResult.success() : AjaxResult.error();
    }
    @PostMapping("/update")
    @ApiOperation("修改发货信息")
    public AjaxResult update(@RequestBody ShippingInfo req) {
        ShippingInfo byId = shippingInfoService.getById(req.getId());
        if (byId == null) {
            return AjaxResult.error("发货信息不存在");
        }
        Long userId = getLoginUser().getUserId();
        if(!userId.equals(Long.parseLong(byId.getCreateUser().toString()))){
            return AjaxResult.error("您没有权限修改此发货信息");
        }
        boolean update = shippingInfoService.updateById(req);
        return update ? AjaxResult.success() : AjaxResult.error();
    }
    @DeleteMapping("/delete")
    @ApiOperation("删除发货信息")
    public AjaxResult delete(@RequestBody List<Long> ids) {
        Long userId = getLoginUser().getUserId();
        ids.forEach(id -> {
            ShippingInfo byId = shippingInfoService.getById(id);
            if (byId == null) {
                throw new RuntimeException("发货信息不存在");
            }
            if(!userId.equals(Long.parseLong(byId.getCreateUser().toString()))){
                throw new RuntimeException("您没有权限删除此发货信息");
            }
        });
        boolean delete = shippingInfoService.removeBatchByIds(ids);
        return delete ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }
    @Autowired
    private ShippingInfoMapper shippingInfoMapper;
    /**
     * å¯¼å‡ºå‘货信息管理
     */
    @PostMapping("/export")
    @ApiOperation("导出发货信息")
    public void export(HttpServletResponse response) {
        List<ShippingInfo> list = shippingInfoMapper.listAll();
        ExcelUtil<ShippingInfo> util = new ExcelUtil<ShippingInfo>(ShippingInfo.class);
        util.exportExcel(response, list, "发货信息");
    }
}
src/main/java/com/ruoyi/sales/dto/ReceiptPaymentDto.java
@@ -1,13 +1,16 @@
package com.ruoyi.sales.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.sales.pojo.ReceiptPayment;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
@Data
public class ReceiptPaymentDto extends ReceiptPayment {
@@ -20,6 +23,17 @@
    @Excel(name = "客户名称")
    private String customerName;
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "开票日期",width = 30,dateFormat = "yyyy-MM-dd")
    @ApiModelProperty(value = "开票日期")
    private Date invoiceDate;
    @TableField(exist = false)
    private String invoiceDateStart;
    @TableField(exist = false)
    private String invoiceDateEnd;
    @ApiModelProperty(value = "查询文本")
    private String searchText;
src/main/java/com/ruoyi/sales/dto/SalesQuotationDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.sales.dto;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.pojo.SalesQuotationProduct;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class SalesQuotationDto extends SalesQuotation {
    @ApiModelProperty(value = "报价商品")
    private List<SalesQuotationProduct> products;
}
src/main/java/com/ruoyi/sales/mapper/PaymentShippingMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.sales.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.sales.pojo.PaymentShipping;
import org.apache.ibatis.annotations.Param;
/**
 * @author :yys
 * @date : 2025/9/15 14:00
 */
public interface PaymentShippingMapper extends BaseMapper<PaymentShipping> {
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param page
     * @param paymentShipping
     * @return
     */
    IPage<PaymentShipping> listPage(Page page,@Param("req") PaymentShipping paymentShipping);
}
src/main/java/com/ruoyi/sales/mapper/ReceiptPaymentMapper.java
@@ -26,7 +26,7 @@
     * @param receiptPaymentDto
     * @return
     */
    IPage<ReceiptPaymentDto> bindInvoiceNoRegPage(Page page, @Param("c") ReceiptPaymentDto receiptPaymentDto);
    IPage<ReceiptPaymentDto> bindInvoiceNoRegPage(Page page, @Param("req") ReceiptPaymentDto receiptPaymentDto);
    /**
     * å¼€ç¥¨å°è´¦è¯¦æƒ…
src/main/java/com/ruoyi/sales/mapper/SalesQuotationMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.sales.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.sales.dto.SalesQuotationDto;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.data.repository.query.Param;
@Mapper
public interface SalesQuotationMapper extends BaseMapper<SalesQuotation> {
    IPage<SalesQuotationDto> listPage(Page page,@Param("salesQuotationDto") SalesQuotationDto salesQuotationDto);
}
src/main/java/com/ruoyi/sales/mapper/SalesQuotationProductMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.sales.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.sales.pojo.SalesQuotationProduct;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SalesQuotationProductMapper extends BaseMapper<SalesQuotationProduct> {
//    List<SalesQuotationProduct> selectBySalesQuotationIds(List<Long> salesQuotationIds);
    List<SalesQuotationProduct> selectBySalesQuotationId(@Param("id") Long id);
}
src/main/java/com/ruoyi/sales/mapper/SalespersonManagementMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.ruoyi.sales.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.sales.pojo.SalespersonManagement;
import org.apache.ibatis.annotations.Param;
/**
 * @author :yys
 * @date : 2025/9/15 10:12
 */
public interface SalespersonManagementMapper extends BaseMapper<SalespersonManagement> {
    IPage<SalespersonManagement> listPage(Page page,@Param("req") SalespersonManagement salespersonManagement);
}
src/main/java/com/ruoyi/sales/mapper/ShippingInfoMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ruoyi.sales.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.sales.pojo.ShippingInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/10/22 9:32
 */
public interface ShippingInfoMapper extends BaseMapper<ShippingInfo> {
    IPage<ShippingInfo> listPage(Page page,@Param("req") ShippingInfo req);
    List<ShippingInfo> listAll();
}
src/main/java/com/ruoyi/sales/pojo/PaymentShipping.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
package com.ruoyi.sales.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/15 13:56
 */
@TableName(value = "payment_shipping")
@Data
@ApiModel
public class PaymentShipping {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "订单号")
    private String orderNo;
    @ApiModelProperty(value = "客户名称")
    private String customer;
    @ApiModelProperty(value = "订单金额")
    private String orderAmount;
    @ApiModelProperty(value = "已付款金额")
    private String paidAmount;
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
    @ApiModelProperty(value = "付款状态")
    private String paymentStatus;
    @ApiModelProperty(value = "发货状态")
    private String shippingStatus;
    @ApiModelProperty(value = "发货日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date shippingDate;
    @ApiModelProperty(value = "物流单号")
    private String trackingNo;
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -104,14 +104,22 @@
    @TableField(exist = false)
    @ApiModelProperty(value = "未开票金额(元)")
    private BigDecimal noInvoiceAmountTotal;
    private BigDecimal noInvoiceAmountTotal = BigDecimal.ZERO;
    @ApiModelProperty(value = "签订日期")
    private LocalDate executionDate;
    @TableField(exist = false)
    @ApiModelProperty(value = "已开票金额(元)")
    private BigDecimal invoiceTotal;
    private BigDecimal invoiceTotal = BigDecimal.ZERO;
    @TableField(exist = false)
    @ApiModelProperty(value = "回款金额")
    private BigDecimal receiptPaymentAmountTotal = BigDecimal.ZERO;
    @TableField(exist = false)
    @ApiModelProperty(value = "待回款金额")
    private BigDecimal noReceiptAmount = BigDecimal.ZERO;
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -58,7 +58,8 @@
     */
    @Excel(name = "数量")
    private BigDecimal quantity;
    @Excel(name = "最低库存数量")
    private BigDecimal minStock;
    /**
     * ç¨Žçއ
     */
src/main/java/com/ruoyi/sales/pojo/SalesQuotation.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.ruoyi.sales.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@TableName("sales_quotation")
public class SalesQuotation {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "报价单编号")
    private String quotationNo;
    @ApiModelProperty(value = "客户名称")
    private String customer;
    @ApiModelProperty(value = "业务员")
    private String salesperson;
    @ApiModelProperty(value = "报价日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate quotationDate;
    @ApiModelProperty(value = "有效期至")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate validDate;
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
    @ApiModelProperty(value = "交货周期天数")
    private String deliveryPeriod;
    @ApiModelProperty(value = "状态")
    private String status;
    @ApiModelProperty(value = "报价总金额")
    private Double totalAmount;
    @ApiModelProperty(value = "备注")
    private String remark;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/sales/pojo/SalesQuotationProduct.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
package com.ruoyi.sales.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("sales_quotation_product")
public class SalesQuotationProduct {
    @ApiModelProperty(value = "报价商品ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "销售报价单id")
    private Long salesQuotationId;
    @ApiModelProperty(value = "商品名称")
    private String product;
    @ApiModelProperty(value = "商品规格")
    private String specification;
    @ApiModelProperty(value = "单位")
    private String unit;
    @ApiModelProperty(value = "单价")
    private Double unitPrice;
    @ApiModelProperty(value = "数量")
    private Integer quantity;
    @ApiModelProperty(value = "金额")
    private Double amount;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/sales/pojo/SalespersonManagement.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
package com.ruoyi.sales.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/9/15 10:06
 */
@TableName(value = "salesperson_management")
@Data
@ApiModel
public class SalespersonManagement {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "姓名")
    private String name;
    @ApiModelProperty(value = "联系电话")
    private String phone;
    @ApiModelProperty(value = "邮箱")
    private String email;
    @ApiModelProperty(value = "部门")
    private String department;
    @ApiModelProperty(value = "职位")
    private String position;
    @ApiModelProperty(value = "入职日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date hireDate;
    @ApiModelProperty(value = "权限")
    private String permissions;
    @ApiModelProperty(value = "权限List")
    @TableField(exist = false)
    private List<String> permissionsList;
    @ApiModelProperty(value = "状态")
    private String status;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package com.ruoyi.sales.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * @author :yys
 * @date : 2025/10/22 9:29
 */
@Data
@TableName("shipping_info")
public class ShippingInfo {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "销售台账id")
    private Long salesLedgerId;
    @TableField(exist = false)
    @ApiModelProperty(value = "销售合同号")
    @Excel(name = "销售合同号")
    private String salesContractNo;
    @TableField(exist = false)
    @ApiModelProperty(value = "客户名称")
    @Excel(name = "客户名称")
    private String customerName;
    @ApiModelProperty(value = "发货日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "发货日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date shippingDate;
    @ApiModelProperty(value = "发货车牌号")
    @Excel(name = "发货车牌号")
    private String shippingCarNumber;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Integer createUser;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/sales/service/PaymentShippingService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.sales.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.sales.pojo.PaymentShipping;
/**
 * @author :yys
 * @date : 2025/9/15 14:01
 */
public interface PaymentShippingService extends IService<PaymentShipping> {
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param page
     * @param paymentShipping
     * @return
     */
    IPage<PaymentShipping> listPage(Page page, PaymentShipping paymentShipping);
}
src/main/java/com/ruoyi/sales/service/SalesQuotationProductService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.ruoyi.sales.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.sales.pojo.SalesQuotationProduct;
public interface SalesQuotationProductService extends IService<SalesQuotationProduct> {
}
src/main/java/com/ruoyi/sales/service/SalesQuotationService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.ruoyi.sales.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.sales.dto.SalesQuotationDto;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
public interface SalesQuotationService extends IService<SalesQuotation> {
    IPage listPage(Page page, SalesQuotationDto salesQuotationDto);
    boolean add(SalesQuotationDto salesQuotationDto);
    boolean delete(Long id);
    boolean edit(SalesQuotationDto salesQuotationDto);
}
src/main/java/com/ruoyi/sales/service/SalespersonManagementService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.sales.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.sales.pojo.SalespersonManagement;
/**
 * @author :yys
 * @date : 2025/9/15 10:14
 */
public interface SalespersonManagementService extends IService<SalespersonManagement> {
    /**
     * åˆ—表分页
     *
     * @param page
     * @param salespersonManagement
     * @return
     */
    IPage<SalespersonManagement> listPage(Page page, SalespersonManagement salespersonManagement);
}
src/main/java/com/ruoyi/sales/service/ShippingInfoService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.sales.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.sales.pojo.ShippingInfo;
/**
 * @author :yys
 * @date : 2025/10/22 9:33
 */
public interface ShippingInfoService extends IService<ShippingInfo>{
    IPage<ShippingInfo> listPage(Page page, ShippingInfo req);
}
src/main/java/com/ruoyi/sales/service/impl/PaymentShippingServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ruoyi.sales.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.sales.mapper.PaymentShippingMapper;
import com.ruoyi.sales.pojo.PaymentShipping;
import com.ruoyi.sales.service.PaymentShippingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author :yys
 * @date : 2025/9/15 14:01
 */
@Service
@Slf4j
public class PaymentShippingServiceImpl extends ServiceImpl<PaymentShippingMapper, PaymentShipping> implements PaymentShippingService {
    @Autowired
    private PaymentShippingMapper paymentShippingMapper;
    @Override
    public IPage<PaymentShipping> listPage(Page page, PaymentShipping paymentShipping) {
        IPage<PaymentShipping> listPage = paymentShippingMapper.listPage(page, paymentShipping);
        return listPage;
    }
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -8,6 +8,9 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.pojo.AccountExpense;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.common.enums.FileNameType;
@@ -62,6 +65,7 @@
@RequiredArgsConstructor
@Slf4j
public class SalesLedgerServiceImpl extends ServiceImpl<SalesLedgerMapper, SalesLedger> implements ISalesLedgerService {
    private final AccountIncomeService accountIncomeService;
    private final SalesLedgerMapper salesLedgerMapper;
@@ -376,13 +380,36 @@
            salesLedger.setCustomerName(customer.getCustomerName());
            salesLedger.setTenantId(customer.getTenantId());
            AccountIncome accountIncome = new AccountIncome();
            accountIncome.setIncomeDate(salesLedger.getEntryDate());
            accountIncome.setIncomeType("0");
            accountIncome.setCustomerName(customer.getCustomerName());
            accountIncome.setIncomeMoney(salesLedger.getContractAmount());
            accountIncome.setIncomeMethod("0");
            accountIncome.setInputTime(new Date());
            accountIncome.setInputUser(salesLedger.getEntryPerson());
            // 3. æ–°å¢žæˆ–更新主表
            if (salesLedger.getId() == null) {
                String contractNo = generateSalesContractNo();
                salesLedger.setSalesContractNo(contractNo);
                salesLedgerMapper.insert(salesLedger);
                accountIncome.setIncomeDescribed("销售合同:" + salesLedger.getSalesContractNo());
                accountIncome.setInvoiceNumber(salesLedger.getSalesContractNo());
                accountIncomeService.save(accountIncome);
            } else {
                salesLedgerMapper.updateById(salesLedger);
                SalesLedger salesLedgerDB = salesLedgerMapper.selectById(salesLedger.getId());
                AccountIncome accountIncomeDB = accountIncomeService.getByInvoiceNumber(salesLedger.getSalesContractNo());
                if (ObjectUtils.isEmpty(accountIncomeDB)) {
                    throw new BaseException("收入管理无该销售合同的收入记录");
                }
                accountIncomeDB.setCustomerName(salesLedgerDB.getCustomerName());
                accountIncomeDB.setIncomeMoney(salesLedgerDB.getContractAmount());
                accountIncomeDB.setIncomeDescribed("销售合同:" + salesLedgerDB.getSalesContractNo());
                accountIncomeDB.setInvoiceNumber(salesLedgerDB.getSalesContractNo());
                accountIncomeDB.setInputTime(new Date());
                accountIncomeDB.setInputUser(salesLedgerDB.getEntryPerson());
                accountIncomeService.updateById(accountIncomeDB);
            }
            // 4. å¤„理子表数据
src/main/java/com/ruoyi/sales/service/impl/SalesQuotationProductServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.sales.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.sales.mapper.SalesQuotationProductMapper;
import com.ruoyi.sales.pojo.SalesQuotationProduct;
import com.ruoyi.sales.service.SalesQuotationProductService;
import org.springframework.stereotype.Service;
@Service
public class SalesQuotationProductServiceImpl extends ServiceImpl<SalesQuotationProductMapper, SalesQuotationProduct> implements SalesQuotationProductService {
}
src/main/java/com/ruoyi/sales/service/impl/SalesQuotationServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
package com.ruoyi.sales.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.sales.dto.SalesQuotationDto;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
import com.ruoyi.sales.mapper.SalesQuotationProductMapper;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.pojo.SalesQuotationProduct;
import com.ruoyi.sales.service.SalesQuotationProductService;
import com.ruoyi.sales.service.SalesQuotationService;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class SalesQuotationServiceImpl extends ServiceImpl<SalesQuotationMapper, SalesQuotation> implements SalesQuotationService {
    @Autowired
    private SalesQuotationMapper salesQuotationMapper;
    @Autowired
    private SalesQuotationProductMapper salesQuotationProductMapper;
    @Autowired
    private SalesQuotationProductService salesQuotationProductService;
    @Override
    public IPage<SalesQuotationDto> listPage(Page page, SalesQuotationDto salesQuotationDto) {
        IPage<SalesQuotationDto> salesQuotationDtoIPage = salesQuotationMapper.listPage(page, salesQuotationDto);
        if(CollectionUtils.isEmpty(salesQuotationDtoIPage.getRecords())){
            return salesQuotationDtoIPage;
        }
        salesQuotationDtoIPage.getRecords().forEach(record -> {
            List<SalesQuotationProduct> products = salesQuotationProductMapper.selectBySalesQuotationId(record.getId());
            record.setProducts(products);
        });
        return salesQuotationDtoIPage;
    }
    @Override
    public boolean add(SalesQuotationDto salesQuotationDto) {
        SalesQuotation salesQuotation = new SalesQuotation();
        BeanUtils.copyProperties(salesQuotationDto, salesQuotation);
        String quotationNo = salesQuotation.getQuotationNo();
        salesQuotationMapper.insert(salesQuotation);
//        if(salesQuotationMapper.insert(salesQuotation)!=1){
//            return false;
//        }
        if(CollectionUtils.isEmpty(salesQuotationDto.getProducts())){
            return true;
        }
        List<SalesQuotationProduct> products = salesQuotationDto.getProducts().stream().map(product -> {
            SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct();
            BeanUtils.copyProperties(product, salesQuotationProduct);
            salesQuotationProduct.setSalesQuotationId(salesQuotationMapper.selectOne(new LambdaQueryWrapper<SalesQuotation>().eq(SalesQuotation::getQuotationNo, quotationNo)).getId());
            return salesQuotationProduct;
        }).collect(Collectors.toList());
        salesQuotationProductService.saveBatch(products);
        return true;
    }
    @Override
    public boolean edit(SalesQuotationDto salesQuotationDto) {
        SalesQuotation salesQuotation = new SalesQuotation();
        BeanUtils.copyProperties(salesQuotationDto, salesQuotation);
        if(salesQuotationMapper.updateById(salesQuotation)!=1){
            return false;
        }
        salesQuotationProductMapper.delete(new LambdaQueryWrapper<SalesQuotationProduct>().eq(SalesQuotationProduct::getSalesQuotationId, salesQuotationDto.getId()));
        if(CollectionUtils.isEmpty(salesQuotationDto.getProducts())){
            return true;
        }
        List<SalesQuotationProduct> products = salesQuotationDto.getProducts().stream().map(product -> {
            SalesQuotationProduct salesQuotationProduct = new SalesQuotationProduct();
            BeanUtils.copyProperties(product, salesQuotationProduct);
            salesQuotationProduct.setSalesQuotationId(salesQuotation.getId());
            return salesQuotationProduct;
        }).collect(Collectors.toList());
        salesQuotationProductService.saveBatch(products);
        return true;
    }
    @Override
    public boolean delete(Long id) {
        salesQuotationMapper.deleteById(id);
        salesQuotationProductMapper.delete(new LambdaQueryWrapper<SalesQuotationProduct>().eq(SalesQuotationProduct::getSalesQuotationId, id));
        return true;
    }
}
src/main/java/com/ruoyi/sales/service/impl/SalespersonManagementServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package com.ruoyi.sales.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.sales.mapper.SalespersonManagementMapper;
import com.ruoyi.sales.pojo.SalespersonManagement;
import com.ruoyi.sales.service.SalespersonManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
/**
 * @author :yys
 * @date : 2025/9/15 10:15
 */
@Service
@Slf4j
public class SalespersonManagementServiceImpl extends ServiceImpl<SalespersonManagementMapper, SalespersonManagement> implements SalespersonManagementService {
    @Autowired
    private SalespersonManagementMapper salespersonManagementMapper;
    @Override
    public IPage<SalespersonManagement> listPage(Page page, SalespersonManagement salespersonManagement) {
        IPage<SalespersonManagement> salespersonManagementIPage = salespersonManagementMapper.listPage(page, salespersonManagement);
        salespersonManagementIPage.getRecords().forEach(item -> {
            if(!StringUtils.isEmpty(item.getPermissions())){
                item.setPermissionsList(Arrays.asList(item.getPermissions().split(",")));
            }
        });
        return salespersonManagementIPage;
    }
}
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.ruoyi.sales.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ShippingInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author :yys
 * @date : 2025/10/22 9:33
 */
@Service
@Slf4j
public class ShippingInfoServiceImpl extends ServiceImpl<ShippingInfoMapper, ShippingInfo> implements ShippingInfoService {
    @Autowired
    private ShippingInfoMapper shippingInfoMapper;
    @Override
    public IPage<ShippingInfo> listPage(Page page, ShippingInfo req) {
        IPage<ShippingInfo> listPage = shippingInfoMapper.listPage(page, req);
        return listPage;
    }
}
src/main/java/com/ruoyi/staff/pojo/StaffJoinLeaveRecord.java
@@ -36,6 +36,14 @@
    private Integer staffState;
    /**
     * è¯•用期(月)
     */
    @Excel(name = "试用期(月)")
    private Integer probationPeriod;
    /**
     * å‘˜å·¥ç¼–号
     */
    @Excel(name = "员工编号")
src/main/java/com/ruoyi/warehouse/controller/DocumentationBorrowManagementController.java
@@ -54,6 +54,12 @@
    public AjaxResult listPageReturn(Page page, DocumentationReturnManagement documentationReturnManagement) {
        return AjaxResult.success(documentationReturnManagementMapper.listPage(page, documentationReturnManagement));
    }
    @GetMapping("/getByDocumentationId/{id}")
    @ApiOperation("根据书籍id查询借阅记录")
    @Log(title = "根据书籍id查询借阅记录", businessType = BusinessType.OTHER)
    public AjaxResult getByDocumentationId(@PathVariable Long id) {
        return AjaxResult.success(documentationBorrowManagementService.selectByDocumentationId(id));
    }
    @PostMapping("/add")
    @ApiOperation("文档借阅管理-借阅")
    @Log(title = "文档借阅管理-借阅", businessType = BusinessType.INSERT)
src/main/java/com/ruoyi/warehouse/service/DocumentationBorrowManagementService.java
@@ -33,4 +33,6 @@
    void exportrevent(HttpServletResponse response, DocumentationReturnManagement documentationReturnManagement);
    List<DocumentationBorrowManagementDto> listAll();
    List<DocumentationBorrowManagementDto> selectByDocumentationId(Long id);
}
src/main/java/com/ruoyi/warehouse/service/impl/DocumentationBorrowManagementServiceImpl.java
@@ -133,6 +133,17 @@
    }
    @Override
    public List<DocumentationBorrowManagementDto> selectByDocumentationId(Long id) {
        List<DocumentationBorrowManagementDto> list = documentationBorrowManagementMapper.list(new LambdaQueryWrapper<DocumentationBorrowManagementDto>()
                .eq(DocumentationBorrowManagementDto::getDocumentationId, id)
                .eq(DocumentationBorrowManagementDto::getBorrowStatus, "借阅"));
        if (list.isEmpty()){
            throw new RuntimeException("文档未被借阅");
        }
        return list;
    }
    @Override
    public boolean deleteByIds(List<Long> ids) {
        List<DocumentationBorrowManagement> list = documentationBorrowManagementMapper.selectList(new LambdaQueryWrapper<DocumentationBorrowManagement>().in(DocumentationBorrowManagement::getId, ids));
        for (DocumentationBorrowManagement documentationBorrowManagement : list) {
src/main/resources/application-bdsm.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9096
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-bdsm?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 15
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-bhmy.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9070
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: uploadPath
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-bhmy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 11
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-cmny.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9088
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: uploadPath
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-cmny?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 12
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-demo.yml
@@ -45,7 +45,7 @@
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: uploadPath
  default-bucket: demo-product
# ç”¨æˆ·é…ç½®
user:
  password:
src/main/resources/application-dhdc.yml
@@ -62,7 +62,7 @@
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.195:3306/product-inventory-management-dhdc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        url: jdbc:mysql://192.168.1.8:3306/product-inventory-management-dhdc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456
      # ä»Žåº“数据源
@@ -135,7 +135,7 @@
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.195
    host: 192.168.1.8
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
src/main/resources/application-hbkj.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9117
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-hbkj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6380
    # æ•°æ®åº“索引
    database: 3
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-hbxm.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9100
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-hbxm?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 13
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-hckx.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9090
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: uploadPath
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-hckx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 12
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-hcmy.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9103
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-hcmy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 15
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-hsmy.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9115
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-hsmy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6380
    # æ•°æ®åº“索引
    database: 2
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-hsxny.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9101
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: uploadPath
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-hsxny?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 12
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-hxgy.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9098
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-hxgy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 14
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-hxsj.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 8088
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-hxsj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: hxsj@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 172.17.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 15
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-hysn.yml
@@ -62,9 +62,9 @@
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.196:3306/product-inventory-management-hysn?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-hysn?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
@@ -135,7 +135,7 @@
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.196
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
src/main/resources/application-jjxm.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9107
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-jjxm?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6380
    # æ•°æ®åº“索引
    database: 0
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-jlsn.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9094
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: uploadPath
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-jlsn?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 13
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-jsyny.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9074
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: uploadPath
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-jsyny?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 12
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-mkzs.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9111
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-mkzs?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6380
    # æ•°æ®åº“索引
    database: 1
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-mqsp.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9123
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-lqmsp?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6380
    # æ•°æ®åº“索引
    database: 6
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-nydl.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9104
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.0.182:3306/product-inventory-management-nydl?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: HpencZdyK7WrtQvBUKnr
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.0.182
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 0
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-phmk.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9119
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-phmk?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6380
    # æ•°æ®åº“索引
    database: 4
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-prod.yml
@@ -135,6 +135,7 @@
  redis:
    # åœ°å€
    host: 127.0.0.1
#    host: localhost
#    host: 172.17.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
src/main/resources/application-qlmc.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 8090
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-qlmc?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: qlmc@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 172.17.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 15
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-tymk.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9121
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: bdsm-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.1.185:3306/product-inventory-management-tymk?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.1.185
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6380
    # æ•°æ®åº“索引
    database: 5
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/application-zyrq.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,219 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9030
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: demo-product
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://192.168.10.230:3306/product-inventory-management-zyrq?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: zyrq@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
#    host: 127.0.0.1
    host: 192.168.10.230
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 0
    # å¯†ç 
#    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/mapper/collaborativeApproval/StaffContactsPersonalMapper.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="com.ruoyi.collaborativeApproval.mapper.StaffContactsPersonalMapper">
    <select id="listPage" resultType="com.ruoyi.collaborativeApproval.dto.StaffContactsPersonalDTO">
        SELECT
            scp.id,
            scp.contact_id,
            sjlr.staff_no,
            sjlr.staff_name,
            sjlr.sex,
            sjlr.post_job,
            sjlr.adress,
            sjlr.profession,
            sjlr.identity_card,
            sjlr.phone,
            scp.create_time
        FROM staff_contacts_personal scp
            LEFT JOIN (select * from staff_join_leave_record WHERE staff_state = 1) sjlr ON scp.contact_id=sjlr.id
        where 1=1
        <if test="staffContactsPersonalDTO.staffName != null and staffContactsPersonalDTO.staffName != ''">
            and sjlr.staff_name like concat('%',#{staffContactsPersonalDTO.staffName},'%')
        </if>
    </select>
</mapper>
src/main/resources/mapper/device/DeviceDefectRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.device.mapper.DeviceDefectRecordMapper">
    <select id="listPage" resultType="com.ruoyi.device.dto.DeviceDefectRecordDto">
        select ddr.*,dl.device_name,dl.device_model
        from device_defect_record ddr
        left join device_ledger dl on ddr.device_ledger_id = dl.id
        <where>
            1=1
            <if test="deviceDefectRecordDto.deviceLedgerId != null">
                and ddr.device_ledger_id = #{deviceDefectRecordDto.deviceLedgerId}
            </if>
            <if test="deviceDefectRecordDto.deviceName != null and deviceDefectRecordDto.deviceName != ''">
                and dl.device_name like concat('%',#{deviceDefectRecordDto.deviceName},'%')
            </if>
            <if test="deviceDefectRecordDto.status != null">
                and ddr.status = #{deviceDefectRecordDto.status}
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/device/DeviceLedgerMapper.xml
@@ -13,6 +13,11 @@
        dl.supplier_name,
        dl.unit,
        dl.number,
        dl.status,
        dl.plan_runtime_time,
        dl.start_runtime_time,
        dl.end_runtime_time,
        dl.runtime_duration,
        dl.tax_including_price_unit,
        dl.tax_including_price_total,
        dl.tax_rate,
src/main/resources/mapper/inspectiontask/TimingTaskMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.inspectiontask.mapper.TimingTaskMapper">
    <select id="getTaskById" resultType="com.ruoyi.inspectiontask.pojo.TimingTask" useCache="false">
        SELECT * FROM timing_task WHERE id = #{id}
    </select>
</mapper>
src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper">
    <select id="listPage" resultType="com.ruoyi.measuringinstrumentledger.dto.SparePartsDto">
        select sp.*,sp1.name as parentName from spare_parts sp
        left join spare_parts sp1 on sp1.id = sp.parent_id
        <where>
            <if test="spareParts.name != null">
                and name like concat('%',#{spareParts.name},'%')
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/oA/OaProjectMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.oA.mapper.OaProjectMapper">
    <select id="listPage" resultType="com.ruoyi.oA.dto.OaProjectDto">
        select op.*,su.nick_name as managerName from oa_project op
        LEFT JOIN sys_user su ON op.manager_id=su.user_id
        <where>
        1=1
            <if test="req.projectName != null and req.projectName != ''">
                and op.project_name like concat('%',#{req.projectName},'%')
            </if>
            <if test="req.managerName != null and req.managerName != ''">
                and su.nick_name like concat('%',#{req.managerName},'%')
            </if>
            <if test="req.status != null and req.status != ''">
                and op.status = #{req.status}
            </if>
        </where>
    </select>
    <select id="selectByIds" resultType="com.ruoyi.oA.dto.OaProjectDto">
        select op.*,su.nick_name as managerName from oa_project op
        LEFT JOIN sys_user su ON op.manager_id=su.user_id
        where op.project_id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>
</mapper>
src/main/resources/mapper/oA/OaProjectPhaseMapper.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="com.ruoyi.oA.mapper.OaProjectPhaseMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.oA.pojo.OaProjectPhase">
            <id property="phaseId" column="phase_id" jdbcType="INTEGER"/>
            <result property="phaseName" column="phase_name" jdbcType="VARCHAR"/>
            <result property="oaProjectId" column="oa_project_id" jdbcType="INTEGER"/>
            <result property="startDate" column="start_date" jdbcType="TIMESTAMP"/>
            <result property="endDate" column="end_date" jdbcType="TIMESTAMP"/>
            <result property="status" column="status" jdbcType="VARCHAR"/>
            <result property="createUser" column="create_user" jdbcType="BIGINT"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateUser" column="update_user" jdbcType="BIGINT"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
            <result property="tenantId" column="tenant_id" jdbcType="BIGINT"/>
    </resultMap>
    <sql id="Base_Column_List">
        phase_id,phase_name,oa_project_id,
        start_date,end_date,status,
        create_user,create_time,update_user,
        update_time,tenant_id
    </sql>
</mapper>
src/main/resources/mapper/oA/OaProjectPhaseTaskMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.oA.mapper.OaProjectPhaseTaskMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.oA.pojo.OaProjectPhaseTask">
            <id property="taskId" column="task_id" jdbcType="INTEGER"/>
            <result property="taskName" column="task_name" jdbcType="VARCHAR"/>
            <result property="phaseId" column="phase_id" jdbcType="INTEGER"/>
            <result property="startDate" column="start_date" jdbcType="TIMESTAMP"/>
            <result property="endDate" column="end_date" jdbcType="TIMESTAMP"/>
            <result property="targetDate" column="target_date" jdbcType="TIMESTAMP"/>
            <result property="targetValue" column="target_value" jdbcType="INTEGER"/>
            <result property="currentValue" column="current_value" jdbcType="INTEGER"/>
            <result property="unit" column="unit" jdbcType="VARCHAR"/>
            <result property="status" column="status" jdbcType="VARCHAR"/>
            <result property="completionRate" column="completion_rate" jdbcType="INTEGER"/>
            <result property="createUser" column="create_user" jdbcType="BIGINT"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateUser" column="update_user" jdbcType="BIGINT"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
            <result property="tenantId" column="tenant_id" jdbcType="BIGINT"/>
    </resultMap>
    <sql id="Base_Column_List">
        task_id,task_name,phase_id,
        start_date,end_date,target_date,
        target_value,current_value,unit,
        status,completion_rate,create_user,
        create_time,update_user,update_time,
        tenant_id
    </sql>
</mapper>
src/main/resources/mapper/procurementrecord/InboundManagementMapper.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="com.ruoyi.procurementrecord.mapper.InboundManagementMapper">
    <select id="listPage" resultType="com.ruoyi.procurementrecord.pojo.InboundManagement">
        select * from inbound_management
        <where>
            <if test="req.orderNo != null and req.orderNo != ''">
                and order_no like concat('%',#{req.orderNo},'%')
            </if>
            <if test="req.supplierName != null and req.supplierName != ''">
                and supplier_name like concat('%',#{req.supplierName},'%')
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/procurementrecord/ProcurementPlanMapper.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="com.ruoyi.procurementrecord.mapper.ProcurementPlanMapper">
    <select id="listPage" resultType="com.ruoyi.procurementrecord.pojo.ProcurementPlan">
        SELECT * FROM procurement_plan
        <where>
            <if test="req.status != null and req.status != ''">
                AND status = #{req.status}
            </if>
            <if test="req.planName != null and req.planName != ''">
                AND plan_name LIKE CONCAT('%',#{req.planName},'%')
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/procurementrecord/ProcurementPriceManagementMapper.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="com.ruoyi.procurementrecord.mapper.ProcurementPriceManagementMapper">
    <select id="listPage" resultType="com.ruoyi.procurementrecord.pojo.ProcurementPriceManagement">
        SELECT * FROM procurement_price_management
        <where>
            <if test="req.productName != null and req.productName != ''">
                AND product_name like concat('%',#{req.productName},'%')
            </if>
            <if test="req.supplierName != null and req.supplierName != ''">
                AND supplier_name = #{req.supplierName}
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -11,6 +11,7 @@
            t2.specification_model,
            t2.unit,
            t2.quantity,
            t2.min_stock,
            t2.quantity as quantity0,
            t2.tax_rate,
            t2.tax_inclusive_unit_price,
@@ -89,6 +90,7 @@
        t1.create_user,
        t2.specification_model,
        t2.unit,
        t2.min_stock,
        t2.tax_rate,
        t2.tax_inclusive_unit_price,
        t2.tax_inclusive_total_price,
@@ -96,6 +98,7 @@
        t1.inbound_batches,
        t1.inbound_num,
        t1.inbound_num as inboundNum0,
        t1.inbound_num as totalInboundNum,
        t1.create_time,
        t1.update_time,
        t1.create_by
@@ -107,6 +110,21 @@
            <if test="req.supplierName != null and req.supplierName != ''">
                and t3.supplier_name like  concat('%',#{req.supplierName},'%')
            </if>
            <if test="req.reportDate != null">
                and t1.create_time >= #{req.reportDate} and t1.create_time &lt; DATE_ADD(#{req.reportDate}, INTERVAL 1 DAY)
            </if>
            <if test="req.startMonth != null">
                and t1.create_time >= #{req.startMonth}
            </if>
            <if test="req.endMonth != null">
                and t1.create_time &lt;= #{req.endMonth}
            </if>
            <if test="req.startDate != null">
                and t1.create_time >= #{req.startDate}
            </if>
            <if test="req.endDate != null">
                and t1.create_time &lt;= #{req.endDate}
            </if>
        </where>
    </select>
    <select id="listCopy" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy">
src/main/resources/mapper/procurementrecord/ReturnManagementMapper.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="com.ruoyi.procurementrecord.mapper.ReturnManagementMapper">
    <select id="listPage" resultType="com.ruoyi.procurementrecord.pojo.ReturnManagement">
        select * from return_management
        <where>
            <if test="req.returnNo != null and req.returnNo != ''">
                and return_no like concat('%',#{req.returnNo},'%')
            </if>
            <if test="req.returnType != null and req.returnType != ''">
                and return_type = #{req.returnType}
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/sales/InvoiceLedgerMapper.xml
@@ -114,7 +114,7 @@
            T4.id,T4.customer_name ,
            SUM(invoice_total) AS invoice_total,
            IFNULL( SUM(T5.receipt_payment_amount) , 0 ) AS receipt_payment_amount,
            IFNULL((SUM(invoice_total)  - SUM(T5.receipt_payment_amount)),0) AS unReceipt_payment_amount
            IFNULL((IFNULL(SUM(invoice_total),0)  - IFNULL(SUM(T5.receipt_payment_amount),0)),0) AS unReceipt_payment_amount
        FROM
            invoice_ledger T1
                LEFT JOIN invoice_registration_product T2 ON T1.invoice_registration_product_id = T2.id
src/main/resources/mapper/sales/PaymentShippingMapper.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="com.ruoyi.sales.mapper.PaymentShippingMapper">
    <select id="listPage" resultType="com.ruoyi.sales.pojo.PaymentShipping">
        select * from payment_shipping
        <where>
            <if test="req.orderNo != null and req.orderNo != ''">
                and order_no like concat('%',#{req.orderNo},'%')
            </if>
            <if test="req.paymentStatus != null and req.paymentStatus != ''">
                and payment_status = #{req.paymentStatus}
            </if>
            <if test="req.shippingStatus != null and req.shippingStatus != ''">
                and shipping_status = #{req.shippingStatus}
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/sales/ReceiptPaymentMapper.xml
@@ -95,17 +95,23 @@
        BY invoice_ledger_id
        ) T6 ON T1.id = T6.invoice_ledger_id
        <where>
            <if test="c.customerName != null and c.customerName !=''">
                AND T3.customer_name LIKE CONCAT('%',#{c.customerName},'%')
            <if test="req.customerName != null and req.customerName !=''">
                AND T3.customer_name LIKE CONCAT('%',#{req.customerName},'%')
            </if>
            <if test="c.invoiceLedgerId != null">
                AND T1.id = #{c.invoiceLedgerId}
            <if test="req.invoiceLedgerId != null">
                AND T1.id = #{req.invoiceLedgerId}
            </if>
            <if test="c.customerContractNo != null and c.customerContractNo !=''">
                AND T3.customer_contract_no LIKE CONCAT('%',#{c.customerContractNo},'%')
            <if test="req.customerContractNo != null and req.customerContractNo !=''">
                AND T3.customer_contract_no LIKE CONCAT('%',#{req.customerContractNo},'%')
            </if>
            <if test="c.projectName != null and c.projectName !=''">
                AND T3.project_name LIKE CONCAT('%',#{c.projectName},'%')
            <if test="req.projectName != null and req.projectName !=''">
                AND T3.project_name LIKE CONCAT('%',#{req.projectName},'%')
            </if>
            <if test="req.invoiceDateStart != null and req.invoiceDateStart != '' ">
                AND T1.invoice_date &gt;= DATE_FORMAT(#{req.invoiceDateStart},'%Y-%m-%d')
            </if>
            <if test="req.invoiceDateEnd != null and req.invoiceDateEnd != '' ">
                AND  T1.invoice_date &lt;= DATE_FORMAT(#{req.invoiceDateEnd},'%Y-%m-%d')
            </if>
        </where>
        ORDER BY T2.create_time DESC
src/main/resources/mapper/sales/SalesQuotationMapper.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="com.ruoyi.sales.mapper.SalesQuotationMapper">
    <select id="listPage" resultType="com.ruoyi.sales.dto.SalesQuotationDto">
        SELECT * FROM sales_quotation
        WHERE 1=1
        <if test="salesQuotationDto.quotationNo != null and salesQuotationDto.quotationNo != '' ">
            AND quotation_no LIKE CONCAT('%',#{salesQuotationDto.quotationNo},'%')
        </if>
        <if test="salesQuotationDto.customer != null and salesQuotationDto.customer != '' ">
            AND customer = #{salesQuotationDto.customer}
        </if>
        <if test="salesQuotationDto.status != null and salesQuotationDto.status != '' ">
            AND status = #{salesQuotationDto.status}
        </if>
    </select>
</mapper>
src/main/resources/mapper/sales/SalesQuotationProductMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sales.mapper.SalesQuotationProductMapper">
<!--    <select id="selectBySalesQuotationIds" resultType="com.ruoyi.sales.pojo.SalesQuotationProduct">-->
<!--        select * from sales_quotation_product where sales_quotation_id in-->
<!--        <foreach collection="salesQuotationIds" item="salesQuotationId" open="(" close=")" separator=",">-->
<!--            #{salesQuotationId}-->
<!--        </foreach>-->
<!--    </select>-->
    <select id="selectBySalesQuotationId" resultType="com.ruoyi.sales.pojo.SalesQuotationProduct">
        select * from sales_quotation_product where sales_quotation_id = #{id}
    </select>
</mapper>
src/main/resources/mapper/sales/SalespersonManagementMapper.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="com.ruoyi.sales.mapper.SalespersonManagementMapper">
    <select id="listPage" resultType="com.ruoyi.sales.pojo.SalespersonManagement">
        select * from salesperson_management
        <where>
            <if test="req.name != null and req.name != ''">
                and `name` like concat('%',#{req.name},'%')
            </if>
            <if test="req.department != null and req.department != ''">
                and department = #{req.department}
            </if>
            <if test="req.status != null and req.status != ''">
                and status = #{req.status}
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/sales/ShippingInfoMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sales.mapper.ShippingInfoMapper">
    <select id="listPage" resultType="com.ruoyi.sales.pojo.ShippingInfo">
        SELECT
        s.id,
        s.sales_ledger_id,
        s.shipping_date,
        s.shipping_car_number,
        s.create_time,
        s.update_time,
        s.create_user,
        s.update_user,
        s.tenant_id,
        sl.sales_contract_no,
        sl.customer_name
        FROM shipping_info s
        LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
        WHERE 1=1
        <if test="req.salesContractNo != null and req.salesContractNo != ''">
            AND sl.sales_contract_no LIKE CONCAT('%',#{req.salesContractNo},'%')
        </if>
        <if test="req.shippingCarNumber != null and req.shippingCarNumber != ''">
            AND s.shipping_car_number LIKE CONCAT('%',#{req.shippingCarNumber},'%')
        </if>
    </select>
    <select id="listAll" resultType="com.ruoyi.sales.pojo.ShippingInfo">
        SELECT
            s.id,
            s.sales_ledger_id,
            s.shipping_date,
            s.shipping_car_number,
            s.create_time,
            s.update_time,
            s.create_user,
            s.update_user,
            s.tenant_id,
            sl.sales_contract_no,
            sl.customer_name
        FROM shipping_info s
                 LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
    </select>
</mapper>
src/main/resources/mapper/system/SysUserMapper.xml
@@ -158,6 +158,28 @@
             #{item}
        </foreach>
    </select>
    <select id="selectList" resultType="com.ruoyi.project.system.domain.SysUser">
        SELECT user_id, nick_name FROM sys_user
        <where>
            <if test="list != null and list.size() > 0">
                user_id IN
                <foreach item="id" collection="list" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
            <if test="list == null or list.size() == 0">
                1=0  <!-- ç©ºåˆ—表时返回空结果 -->
            </if>
        </where>
    </select>
    <select id="selectUsersByIds" resultType="com.ruoyi.project.system.domain.SysUser">
        SELECT user_id, nick_name
        FROM sys_user
        WHERE user_id IN
        <foreach collection="userIds" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>
    <insert id="insertUser" parameterType="com.ruoyi.project.system.domain.SysUser" useGeneratedKeys="true" keyProperty="userId">
         insert into sys_user(