| | |
| | | import com.ruoyi.common.utils.WxCpUtils; |
| | | import com.ruoyi.device.dto.DeviceMaintenancePlanDetailsDto; |
| | | import com.ruoyi.device.dto.DeviceMaintenancePlanDto; |
| | | import com.ruoyi.device.mapper.DeviceMaintenanceAttachmentMapper; |
| | | import com.ruoyi.device.mapper.DeviceMaintenanceMapper; |
| | | import com.ruoyi.device.mapper.DeviceMaintenancePlanDetailsMapper; |
| | | import com.ruoyi.device.mapper.DeviceMaintenancePlanMapper; |
| | | import com.ruoyi.device.mapper.DeviceMapper; |
| | | import com.ruoyi.device.pojo.Device; |
| | | import com.ruoyi.device.pojo.DeviceMaintenance; |
| | | import com.ruoyi.device.pojo.DeviceMaintenanceAttachment; |
| | | import com.ruoyi.device.pojo.DeviceMaintenancePlan; |
| | | import com.ruoyi.device.pojo.DeviceMaintenancePlanDetails; |
| | | import com.ruoyi.device.service.DeviceMaintenancePlanDetailsService; |
| | |
| | | import com.ruoyi.system.service.InformationNotificationService; |
| | | import org.apache.commons.collections4.CollectionUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.net.URLEncoder; |
| | |
| | | import java.time.YearMonth; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.time.temporal.ChronoUnit; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | |
| | | private DeviceMapper deviceMapper; |
| | | @Resource |
| | | private DeviceMaintenanceMapper deviceMaintenanceMapper; |
| | | @Resource |
| | | private DeviceMaintenanceAttachmentMapper deviceMaintenanceAttachmentMapper; |
| | | |
| | | @Value("${file.path}") |
| | | private String filePath; |
| | | |
| | | @Value("${wordUrl}") |
| | | private String wordUrl; |
| | | |
| | | /** |
| | | * 分页查询设备保养计划 |
| | |
| | | } |
| | | this.saveOrUpdate(deviceMaintenancePlanDto); |
| | | |
| | | // 删除原本的详情 |
| | | // 删除原本的详情;明细重建后仍保留原明细id的附件不清理,id丢失的才清理 |
| | | List<DeviceMaintenancePlanDetails> oldDetails = deviceMaintenancePlanDetailsService.list( |
| | | Wrappers.<DeviceMaintenancePlanDetails>lambdaQuery() |
| | | .eq(DeviceMaintenancePlanDetails::getMaintenancePlanId, deviceMaintenancePlanDto.getMaintenancePlanId())); |
| | | deviceMaintenancePlanDetailsService.remove(Wrappers.<DeviceMaintenancePlanDetails>lambdaQuery().eq(DeviceMaintenancePlanDetails::getMaintenancePlanId, deviceMaintenancePlanDto.getMaintenancePlanId())); |
| | | List<Integer> lostDetailIds = oldDetails.stream().map(DeviceMaintenancePlanDetails::getMaintenancePlanDetailId) |
| | | .collect(Collectors.toList()); |
| | | // 详情赋值并保存 |
| | | List<DeviceMaintenancePlanDetailsDto> deviceMaintenancePlanDetails = deviceMaintenancePlanDto.getDeviceMaintenancePlanDetails(); |
| | | if (CollectionUtils.isNotEmpty(deviceMaintenancePlanDetails)) { // 详情不为空 |
| | | List<Integer> keptDetailIds = deviceMaintenancePlanDetails.stream() |
| | | .map(DeviceMaintenancePlanDetails::getMaintenancePlanDetailId) |
| | | .filter(id -> id != null) |
| | | .collect(Collectors.toList()); |
| | | lostDetailIds.removeAll(keptDetailIds); |
| | | List<DeviceMaintenancePlanDetails> collect = deviceMaintenancePlanDetails.stream().map(deviceMaintenancePlanDetail -> { // 遍历详情 |
| | | deviceMaintenancePlanDetail.setDeviceId(deviceMaintenancePlanDto.getDeviceId()); // 设备ID |
| | | deviceMaintenancePlanDetail.setMaintenancePlanId(deviceMaintenancePlanDto.getMaintenancePlanId()); // 保养计划ID |
| | | DeviceMaintenancePlanDetails planDetails = new DeviceMaintenancePlanDetails(); |
| | | BeanUtils.copyProperties(deviceMaintenancePlanDetail, planDetails); |
| | |
| | | }).collect(Collectors.toList()); |
| | | deviceMaintenancePlanDetailsService.saveBatch(collect); |
| | | } |
| | | removeAttachmentsByDetailIds(lostDetailIds); |
| | | return Result.success(); |
| | | } |
| | | |
| | |
| | | */ |
| | | @Override |
| | | public Result deleteMaintenancePlan(DeviceMaintenancePlanDto deviceMaintenancePlanDto) { |
| | | List<DeviceMaintenancePlanDetails> details = deviceMaintenancePlanDetailsService.list( |
| | | Wrappers.<DeviceMaintenancePlanDetails>lambdaQuery() |
| | | .eq(DeviceMaintenancePlanDetails::getMaintenancePlanId, deviceMaintenancePlanDto.getMaintenancePlanId())); |
| | | this.removeById(deviceMaintenancePlanDto); |
| | | deviceMaintenancePlanDetailsService.remove(Wrappers.<DeviceMaintenancePlanDetails>lambdaQuery().eq(DeviceMaintenancePlanDetails::getMaintenancePlanId, deviceMaintenancePlanDto.getMaintenancePlanId())); |
| | | removeAttachmentsByDetailIds(details.stream().map(DeviceMaintenancePlanDetails::getMaintenancePlanDetailId).collect(Collectors.toList())); |
| | | return Result.success(); |
| | | } |
| | | |
| | |
| | | // 查询设备保养计划 |
| | | DeviceMaintenancePlanDto deviceMaintenancePlan = baseMapper.selectMaintenancePlanById(maintenancePlanId); |
| | | |
| | | // 查询设备保养计划详情 |
| | | List<DeviceMaintenancePlanDetailsDto> deviceMaintenancePlanDetailsDtoList = deviceMaintenancePlanDetailsMapper.deviceInspectionRecordDetailsList(maintenancePlanId); |
| | | // 查询设备保养计划详情,按“设备 + 保养月份”兜底去重 |
| | | List<DeviceMaintenancePlanDetailsDto> deviceMaintenancePlanDetailsDtoList = dedupeMaintenanceDetails( |
| | | deviceMaintenancePlanDetailsMapper.deviceInspectionRecordDetailsList(maintenancePlanId)); |
| | | // 设置序号 |
| | | deviceMaintenancePlanDetailsDtoList.forEach(deviceInspectionRecordDetails -> { |
| | | deviceInspectionRecordDetails.setIndex(deviceMaintenancePlanDetailsDtoList.indexOf(deviceInspectionRecordDetails) + 1); |
| | | }); |
| | | for (int i = 0; i < deviceMaintenancePlanDetailsDtoList.size(); i++) { |
| | | deviceMaintenancePlanDetailsDtoList.get(i).setIndex(i + 1); |
| | | } |
| | | |
| | | // 获取路径 |
| | | InputStream inputStream = this.getClass().getResourceAsStream("/static/word/maintenance-plan.docx"); |
| | | Configure configure = Configure.builder() |
| | | .bind("deviceMaintenancePlanDetailsDtoList", new HackLoopTableRenderPolicy()) |
| | | .build(); |
| | | XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render( |
| | | new HashMap<String, Object>() {{ |
| | | put("deviceMaintenancePlan", deviceMaintenancePlan); |
| | | put("deviceMaintenancePlanDetailsDtoList", deviceMaintenancePlanDetailsDtoList); |
| | | // 编制人签名地址 |
| | | put("compilerUrl", UserUtils.getFinalUserSignatureOrTransparent(deviceMaintenancePlan.getCompilerId())); |
| | | // 审核人签名地址 |
| | | put("auditUrl", UserUtils.getFinalUserSignatureOrTransparent(deviceMaintenancePlan.getAuditId())); |
| | | }}); |
| | | Map<String, Object> renderData = new HashMap<>(); |
| | | renderData.put("deviceMaintenancePlan", deviceMaintenancePlan); |
| | | renderData.put("deviceMaintenancePlanDetailsDtoList", deviceMaintenancePlanDetailsDtoList); |
| | | // 编制人签名地址 |
| | | renderData.put("compilerUrl", UserUtils.getFinalUserSignatureOrTransparent(deviceMaintenancePlan.getCompilerId())); |
| | | // 审核人签名地址 |
| | | renderData.put("auditUrl", UserUtils.getFinalUserSignatureOrTransparent(deviceMaintenancePlan.getAuditId())); |
| | | XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(renderData); |
| | | |
| | | try { |
| | | response.setContentType("application/msword"); |
| | |
| | | // 查询详情 |
| | | DeviceMaintenancePlanDto deviceMaintenancePlanDto = new DeviceMaintenancePlanDto(); |
| | | BeanUtils.copyProperties(deviceMaintenancePlan, deviceMaintenancePlanDto); |
| | | deviceMaintenancePlanDto.setDeviceMaintenancePlanDetails(deviceMaintenancePlanDetailsMapper.deviceInspectionRecordDetailsList(maintenancePlanId)); |
| | | deviceMaintenancePlanDto.setDeviceMaintenancePlanDetails(dedupeMaintenanceDetails( |
| | | deviceMaintenancePlanDetailsMapper.deviceInspectionRecordDetailsList(maintenancePlanId))); |
| | | return Result.success(deviceMaintenancePlanDto); |
| | | } |
| | | |
| | |
| | | List<Integer> recordIds = records.stream().map(DeviceMaintenance::getId).collect(Collectors.toList()); |
| | | deviceMaintenanceMapper.deleteBatchIds(recordIds); |
| | | } |
| | | removeAttachmentsByDetailIds(List.of(maintenancePlanDetailId)); |
| | | return deviceMaintenancePlanDetailsMapper.deleteById(maintenancePlanDetailId) > 0; |
| | | } |
| | | |
| | | @Override |
| | | public List<DeviceMaintenanceAttachment> selectAttachments(Integer maintenancePlanDetailId) { |
| | | if (maintenancePlanDetailId == null) { |
| | | return new ArrayList<>(); |
| | | } |
| | | return deviceMaintenanceAttachmentMapper.selectList(Wrappers.<DeviceMaintenanceAttachment>lambdaQuery() |
| | | .eq(DeviceMaintenanceAttachment::getMaintenancePlanDetailId, maintenancePlanDetailId) |
| | | .orderByAsc(DeviceMaintenanceAttachment::getSort, DeviceMaintenanceAttachment::getId)); |
| | | } |
| | | |
| | | @Override |
| | | public DeviceMaintenanceAttachment uploadAttachment(Integer maintenancePlanDetailId, MultipartFile file) { |
| | | if (maintenancePlanDetailId == null) { |
| | | throw new ErrorException("缺少保养计划明细id"); |
| | | } |
| | | if (deviceMaintenancePlanDetailsMapper.selectById(maintenancePlanDetailId) == null) { |
| | | throw new ErrorException("保养计划明细不存在"); |
| | | } |
| | | if (file == null || file.isEmpty()) { |
| | | throw new ErrorException("附件不能为空"); |
| | | } |
| | | // 系统全局上传上限为200MB,这里提前给出友好提示 |
| | | if (file.getSize() > 200L * 1024 * 1024) { |
| | | throw new ErrorException("附件不能超过200MB"); |
| | | } |
| | | String originalName = file.getOriginalFilename(); |
| | | if (originalName == null || originalName.trim().isEmpty()) { |
| | | originalName = "未命名文件"; |
| | | } |
| | | // 个别浏览器可能带上路径前缀,只保留文件名本身 |
| | | originalName = originalName.replaceAll(".*[/\\\\]", ""); |
| | | try { |
| | | // 图片放图片目录(/img 静态路径),其余任意格式放 word 目录(/word 静态路径) |
| | | boolean image = originalName.matches("(?i).+\\.(jpg|jpeg|png|gif)$"); |
| | | File directory = new File(image ? filePath : wordUrl); |
| | | if (!directory.exists()) { |
| | | directory.mkdirs(); |
| | | } |
| | | String fileUrl = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmssSSS")) + "-" + originalName; |
| | | file.transferTo(new File(directory, fileUrl)); |
| | | DeviceMaintenanceAttachment attachment = new DeviceMaintenanceAttachment(); |
| | | attachment.setMaintenancePlanDetailId(maintenancePlanDetailId); |
| | | attachment.setFileName(originalName); |
| | | attachment.setFileUrl(fileUrl); |
| | | attachment.setSort(selectAttachments(maintenancePlanDetailId).size()); |
| | | deviceMaintenanceAttachmentMapper.insert(attachment); |
| | | return attachment; |
| | | } catch (IOException e) { |
| | | throw new ErrorException("附件上传失败"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public boolean deleteAttachment(Long id) { |
| | | return deviceMaintenanceAttachmentMapper.deleteById(id) > 0; |
| | | } |
| | | |
| | | /** |
| | | * 删除计划明细对应的附件记录 |
| | | */ |
| | | private void removeAttachmentsByDetailIds(List<Integer> maintenancePlanDetailIds) { |
| | | if (CollectionUtils.isEmpty(maintenancePlanDetailIds)) { |
| | | return; |
| | | } |
| | | deviceMaintenanceAttachmentMapper.delete(Wrappers.<DeviceMaintenanceAttachment>lambdaQuery() |
| | | .in(DeviceMaintenanceAttachment::getMaintenancePlanDetailId, maintenancePlanDetailIds)); |
| | | } |
| | | |
| | | /** |
| | | * 同一计划、同一设备只保留一条;SQL 已按“已有保养记录优先、审核通过优先、最新优先”排序,这里取首条 |
| | | */ |
| | | private List<DeviceMaintenancePlanDetailsDto> dedupeMaintenanceDetails(List<DeviceMaintenancePlanDetailsDto> details) { |
| | | if (CollectionUtils.isEmpty(details)) { |
| | | return details; |
| | | } |
| | | Map<String, DeviceMaintenancePlanDetailsDto> unique = new LinkedHashMap<>(); |
| | | for (DeviceMaintenancePlanDetailsDto detail : details) { |
| | | String key = detail.getDeviceId() != null ? String.valueOf(detail.getDeviceId()) |
| | | : "name:" + detail.getDeviceName(); |
| | | unique.putIfAbsent(key, detail); |
| | | } |
| | | return new ArrayList<>(unique.values()); |
| | | } |
| | | |
| | | /** |
| | | * 两个保养日期之间相差的月数 |
| | | */ |