From 8ad863082097ffdcab4a8e7f426d344a1fe6f892 Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期六, 07 十一月 2026 00:27:02 +0800
Subject: [PATCH] 修复人员管理接口校验与导出,完善设备保养计划与文件受控功能
---
cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java | 150 ++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 133 insertions(+), 17 deletions(-)
diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java
index 1b680fb..64e266f 100644
--- a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java
@@ -17,12 +17,14 @@
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;
@@ -34,12 +36,16 @@
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;
@@ -48,7 +54,9 @@
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;
@@ -79,6 +87,14 @@
private DeviceMapper deviceMapper;
@Resource
private DeviceMaintenanceMapper deviceMaintenanceMapper;
+ @Resource
+ private DeviceMaintenanceAttachmentMapper deviceMaintenanceAttachmentMapper;
+
+ @Value("${file.path}")
+ private String filePath;
+
+ @Value("${wordUrl}")
+ private String wordUrl;
/**
* 鍒嗛〉鏌ヨ璁惧淇濆吇璁″垝
@@ -141,13 +157,22 @@
}
this.saveOrUpdate(deviceMaintenancePlanDto);
- // 鍒犻櫎鍘熸湰鐨勮鎯�
+ // 鍒犻櫎鍘熸湰鐨勮鎯咃紱鏄庣粏閲嶅缓鍚庝粛淇濈暀鍘熸槑缁唅d鐨勯檮浠朵笉娓呯悊锛宨d涓㈠け鐨勬墠娓呯悊
+ 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);
@@ -155,6 +180,7 @@
}).collect(Collectors.toList());
deviceMaintenancePlanDetailsService.saveBatch(collect);
}
+ removeAttachmentsByDetailIds(lostDetailIds);
return Result.success();
}
@@ -165,8 +191,12 @@
*/
@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();
}
@@ -181,27 +211,27 @@
// 鏌ヨ璁惧淇濆吇璁″垝
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");
@@ -233,7 +263,8 @@
// 鏌ヨ璇︽儏
DeviceMaintenancePlanDto deviceMaintenancePlanDto = new DeviceMaintenancePlanDto();
BeanUtils.copyProperties(deviceMaintenancePlan, deviceMaintenancePlanDto);
- deviceMaintenancePlanDto.setDeviceMaintenancePlanDetails(deviceMaintenancePlanDetailsMapper.deviceInspectionRecordDetailsList(maintenancePlanId));
+ deviceMaintenancePlanDto.setDeviceMaintenancePlanDetails(dedupeMaintenanceDetails(
+ deviceMaintenancePlanDetailsMapper.deviceInspectionRecordDetailsList(maintenancePlanId)));
return Result.success(deviceMaintenancePlanDto);
}
@@ -659,9 +690,94 @@
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());
+ }
+
/**
* 涓や釜淇濆吇鏃ユ湡涔嬮棿鐩稿樊鐨勬湀鏁�
*/
--
Gitblit v1.9.3