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.github.xiaoymin.knife4j.core.util.CollectionUtils; import com.ruoyi.basic.enums.RecordTypeEnum; import com.ruoyi.basic.utils.FileUtil; import com.ruoyi.common.utils.DictUtils; 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.DeviceRepairMapper; 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.device.vo.DeviceRepairVo; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper; import com.ruoyi.measuringinstrumentledger.pojo.SpareParts; import com.ruoyi.approve.pojo.KnowledgeBase; import com.ruoyi.approve.service.KnowledgeBaseService; import com.ruoyi.device.pojo.DeviceRepairSparePart; import com.ruoyi.device.service.IDeviceRepairSparePartService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.ruoyi.measuringinstrumentledger.pojo.SparePartsRequisitionRecord; import com.ruoyi.measuringinstrumentledger.service.SparePartsRequisitionRecordService; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @Service @RequiredArgsConstructor @Slf4j public class DeviceRepairServiceImpl extends ServiceImpl implements IDeviceRepairService { private final DeviceDefectRecordService deviceDefectRecordService; private final DeviceRepairMapper deviceRepairMapper; private final IDeviceLedgerService deviceLedgerService; private final SparePartsMapper sparePartsMapper; private final SparePartsRequisitionRecordService sparePartsRequisitionRecordService; private final IDeviceRepairSparePartService deviceRepairSparePartService; private final KnowledgeBaseService knowledgeBaseService; private final FileUtil fileUtil; private static final int STATUS_PENDING_REPAIR = 0; private static final int STATUS_COMPLETED = 1; private static final int STATUS_FAILED = 2; private static final int STATUS_PENDING_ACCEPTANCE = 3; @Override public IPage queryPage(Page page, DeviceRepairDto deviceRepairDto) { IPage pageDto = deviceRepairMapper.queryPage(page, deviceRepairDto); for (DeviceRepairVo vo : pageDto.getRecords()) { vo.setStorageBlobVOs(fileUtil.getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum.DEVICE_REPAIR, vo.getId())); } return pageDto; } @Override @Transactional(rollbackFor = Exception.class) public AjaxResult saveDeviceRepair(DeviceRepairDto deviceRepairDto) { DeviceLedger byId = deviceLedgerService.getById(deviceRepairDto.getDeviceLedgerId()); deviceRepairDto.setDeviceName(byId.getDeviceName()); deviceRepairDto.setDeviceModel(byId.getDeviceModel()); if (deviceRepairDto.getStatus() == null) { deviceRepairDto.setStatus(STATUS_PENDING_REPAIR); } boolean save = this.save(deviceRepairDto); if (save) { // 处理图片上传 fileUtil.saveStorageAttachmentByRecordTypeAndRecordId("file", RecordTypeEnum.DEVICE_REPAIR, deviceRepairDto.getId(), deviceRepairDto.getStorageBlobDTOs()); return AjaxResult.success(); } return AjaxResult.error("保存失败"); } @Override @Transactional(rollbackFor = Exception.class) public AjaxResult updateDeviceRepair(DeviceRepairDto deviceRepairDto) { DeviceRepair oldDeviceRepair = this.getById(deviceRepairDto.getId()); if (oldDeviceRepair == null) { return AjaxResult.error("报修记录不存在"); } if (deviceRepairDto.getStatus() != null && deviceRepairDto.getStatus() == STATUS_COMPLETED && (oldDeviceRepair.getStatus() == null || oldDeviceRepair.getStatus() != STATUS_COMPLETED)) { return AjaxResult.error("请先提交验收审批,验收通过后才可完结"); } // 清理旧的备件使用记录,防止重复累计 deviceRepairSparePartService.remove(new QueryWrapper() .eq("source_id", deviceRepairDto.getId()) .eq("source_type", 1)); // 处理备件使用情况 if (CollectionUtils.isNotEmpty(deviceRepairDto.getSparePartsUseList())) { List sparePartIds = new ArrayList<>(); for (DeviceRepairDto.SparePartUse sparePartUse : deviceRepairDto.getSparePartsUseList()) { // 获取备件信息 SpareParts spareParts = sparePartsMapper.selectById(sparePartUse.getId()); if (spareParts != null) { // 检查数量是否足够 if (spareParts.getQuantity().compareTo(new BigDecimal(sparePartUse.getQuantity())) >= 0) { // 更新数量 spareParts.setQuantity(spareParts.getQuantity().subtract(new BigDecimal(sparePartUse.getQuantity()))); sparePartsMapper.updateById(spareParts); sparePartIds.add(sparePartUse.getId()); // 创建备件领用记录 SparePartsRequisitionRecord record = new SparePartsRequisitionRecord(); record.setSourceType(0); // 0 维修 record.setSourceId(deviceRepairDto.getId()); record.setDeviceLedgerId(oldDeviceRepair.getDeviceLedgerId()); record.setSparePartsId(sparePartUse.getId()); record.setQuantity(sparePartUse.getQuantity()); sparePartsRequisitionRecordService.save(record); // 插入记录到 device_repair_spare_part DeviceRepairSparePart partRecord = new DeviceRepairSparePart(); partRecord.setSourceId(deviceRepairDto.getId()); partRecord.setSourceType(1); // 1 报修 partRecord.setSparePartId(sparePartUse.getId()); partRecord.setQuantity(sparePartUse.getQuantity()); deviceRepairSparePartService.save(partRecord); } else { return AjaxResult.error("备件 " + spareParts.getName() + " 数量不足"); } } } // 更新备件IDs字段 if (!sparePartIds.isEmpty()) { deviceRepairDto.setSparePartsIds(StringUtils.join(sparePartIds, ",")); } } if (this.updateById(deviceRepairDto)) { Long id = deviceRepairDto.getId(); // DeviceDefectRecordDto deviceDefectRecordDto = new DeviceDefectRecordDto(); deviceDefectRecordDto.setDeviceLedgerId(id); deviceDefectRecordDto.setStatus("严重缺陷"); List records = deviceDefectRecordService.listPage(new Page<>(1, -1), deviceDefectRecordDto).getRecords(); if (!records.isEmpty()){ records.forEach(deviceDefectRecord -> { deviceDefectRecord.setStatus("正常"); deviceDefectRecordService.updateByDDR(deviceDefectRecord); }); } // 处理图片上传 if (deviceRepairDto.getStorageBlobDTOs() != null) { fileUtil.saveStorageAttachmentByRecordTypeAndRecordId("file", RecordTypeEnum.DEVICE_REPAIR, id, deviceRepairDto.getStorageBlobDTOs()); } return AjaxResult.success(); } return AjaxResult.error(); } @Override @Transactional(rollbackFor = Exception.class) public AjaxResult confirmRepair(DeviceRepairDto deviceRepairDto) { DeviceRepair oldDeviceRepair = this.getById(deviceRepairDto.getId()); if (oldDeviceRepair == null) { return AjaxResult.error("报修记录不存在"); } if (oldDeviceRepair.getStatus() != null && oldDeviceRepair.getStatus() == STATUS_COMPLETED) { return AjaxResult.error("该报修已完结,不能重复确认维修"); } if (oldDeviceRepair.getStatus() != null && oldDeviceRepair.getStatus() == STATUS_PENDING_ACCEPTANCE) { return AjaxResult.error("该报修已提交验收审批"); } deviceRepairDto.setStatus(STATUS_PENDING_ACCEPTANCE); return updateDeviceRepair(deviceRepairDto); } @Override @Transactional(rollbackFor = Exception.class) public AjaxResult approveRepairAcceptance(DeviceRepairDto deviceRepairDto) { if (deviceRepairDto.getId() == null) { return AjaxResult.error("报修记录id不能为空"); } DeviceRepair oldDeviceRepair = this.getById(deviceRepairDto.getId()); if (oldDeviceRepair == null) { return AjaxResult.error("报修记录不存在"); } if (oldDeviceRepair.getStatus() == null || oldDeviceRepair.getStatus() != STATUS_PENDING_ACCEPTANCE) { return AjaxResult.error("该报修未进入待验收状态,不能审批"); } if (StringUtils.isBlank(deviceRepairDto.getAcceptanceName())) { return AjaxResult.error("验收人不能为空"); } if (deviceRepairDto.getAcceptanceTime() == null) { return AjaxResult.error("验收时间不能为空"); } if (StringUtils.isBlank(deviceRepairDto.getAcceptanceRemark())) { return AjaxResult.error("验收备注不能为空"); } DeviceRepair update = new DeviceRepair(); update.setId(deviceRepairDto.getId()); update.setAcceptanceName(deviceRepairDto.getAcceptanceName()); update.setAcceptanceTime(deviceRepairDto.getAcceptanceTime()); update.setAcceptanceRemark(deviceRepairDto.getAcceptanceRemark()); update.setStatus(STATUS_COMPLETED); if (this.updateById(update)) { try { DeviceLedger deviceLedger = deviceLedgerService.getById(oldDeviceRepair.getDeviceLedgerId()); List parts = deviceRepairSparePartService.getListWithPartName(deviceRepairDto.getId(), 1); String sparePartsInfo = ""; if (CollectionUtils.isNotEmpty(parts)) { StringBuilder sb = new StringBuilder(); for (DeviceRepairSparePart p : parts) { sb.append(p.getSparePartName()).append("(").append(p.getQuantity()).append("个) "); } sparePartsInfo = " 配件使用情况: " + sb.toString(); } KnowledgeBase kb = new KnowledgeBase(); String typeName = deviceLedger.getType(); String deviceModel = deviceLedger.getDeviceModel(); String repairTypeStr = oldDeviceRepair.getRepairType(); String repairTypeLabel = DictUtils.getDictLabel("device_repair_type", repairTypeStr); if (StringUtils.isBlank(repairTypeLabel)) { repairTypeLabel = "维修"; } kb.setTitle((typeName != null ? typeName : "设备") + "_" + (deviceModel != null ? deviceModel : "") + " 的 " + repairTypeLabel + "记录"); kb.setScenario("设备维修"); kb.setType("解决方案"); String remarkStr = oldDeviceRepair.getRemark() == null ? "" : oldDeviceRepair.getRemark(); kb.setProblem(String.format("设备号: %s, 设备名称: %s, 故障描述: %s", deviceLedger.getUniqueCode(), deviceLedger.getDeviceName(), remarkStr)); String reasonStr = oldDeviceRepair.getReasonAnalysis() == null ? "" : oldDeviceRepair.getReasonAnalysis(); String handlingStr = oldDeviceRepair.getHandlingMeasures() == null ? "" : oldDeviceRepair.getHandlingMeasures(); kb.setSolution(String.format("原因分析: %s. 处理措施: %s.%s", reasonStr, handlingStr, sparePartsInfo)); kb.setCreator(oldDeviceRepair.getMaintenanceName()); knowledgeBaseService.save(kb); } catch(Exception e) { log.error("保存知识库失败", e); } return AjaxResult.success(); } return AjaxResult.error("验收审批失败"); } @Override public void export(HttpServletResponse response, Long[] ids) { if (ids == null || ids.length == 0) { List supplierManageList = this.list(); ArrayList deviceLedgerExeclDtos = new ArrayList<>(); supplierManageList.stream().forEach(deviceRepair -> { DeviceRepairExeclDto deviceRepairExeclDto = new DeviceRepairExeclDto(); BeanUtils.copyProperties(deviceRepair,deviceRepairExeclDto); deviceRepairExeclDto.setStatusStr(resolveStatusText(deviceRepair.getStatus())); deviceLedgerExeclDtos.add(deviceRepairExeclDto); }); ExcelUtil util = new ExcelUtil(DeviceRepairExeclDto.class); util.exportExcel(response, deviceLedgerExeclDtos, "设备报修导出"); }else { ArrayList arrayList = new ArrayList<>(Arrays.asList(ids)); List supplierManageList = deviceRepairMapper.selectBatchIds(arrayList); ArrayList deviceLedgerExeclDtos = new ArrayList<>(); supplierManageList.stream().forEach(deviceRepair -> { DeviceRepairExeclDto deviceRepairExeclDto = new DeviceRepairExeclDto(); BeanUtils.copyProperties(deviceRepair,deviceRepairExeclDto); deviceRepairExeclDto.setStatusStr(resolveStatusText(deviceRepair.getStatus())); deviceLedgerExeclDtos.add(deviceRepairExeclDto); }); ExcelUtil util = new ExcelUtil(DeviceRepairExeclDto.class); util.exportExcel(response, deviceLedgerExeclDtos, "设备报修导出"); } } private String resolveStatusText(Integer status) { if (status == null) { return ""; } if (status == STATUS_PENDING_REPAIR) { return "待维修"; } if (status == STATUS_COMPLETED) { return "完结"; } if (status == STATUS_FAILED) { return "失败"; } if (status == STATUS_PENDING_ACCEPTANCE) { return "待验收"; } return "未知"; } @Override public DeviceRepairVo detailById(Long id) { DeviceRepairVo vo = deviceRepairMapper.detailById(id); vo.setStorageBlobVOs(fileUtil.getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum.DEVICE_REPAIR, id)); List parts = deviceRepairSparePartService.getListWithPartName(id, 1); vo.setSparePartsUseListDetails(parts); return vo; } }