Image使用字符串格式
- 清理任务记录Service中示例图ID到URL的转换逻辑,改为直接使用refactor(pdi-statusURL - 修改Controller中异常抛出类型,统一抛Exception --item 引入文件上传服务和): 修改inspectionImage字段类型为字符串并更新相关处理逻辑 -相关工具类处理图片上传与路径生成 将QmsPdiDetectionRulesStatusItem及相关DTO中inspectionImage字段由Long改为String类型 - 修改导出及导入逻辑以适应inspectionImage为URL字符串的变化 - 优化导入流程,支持识别Excel中图片公式并上传图片获取URL - 清理旧有根据ID查询文件记录并转换为URL的逻辑,直接使用inspectionImage字段的URL - 调整接口和服务层异常及参数类型,提升导入文件安全性和灵活性 - 更新Excel导出模板示例中的inspectionImage示例数据为字符串格式
This commit is contained in:
parent
179322612b
commit
5b24459bcb
|
|
@ -88,7 +88,7 @@ public class QmsPdiStatusItemController extends BaseController {
|
||||||
@PostMapping("/import")
|
@PostMapping("/import")
|
||||||
public ApiResult<?> importData(@RequestParam("file") MultipartFile file,
|
public ApiResult<?> importData(@RequestParam("file") MultipartFile file,
|
||||||
@NotNull(message = "PDI检测规则ID不能为空") @RequestParam Long detectionRulesId,
|
@NotNull(message = "PDI检测规则ID不能为空") @RequestParam Long detectionRulesId,
|
||||||
@NotNull(message = "状态不能为空") @RequestParam Integer status) throws IOException {
|
@NotNull(message = "状态不能为空") @RequestParam Integer status) throws Exception {
|
||||||
statusItemControllerService.importFromExcel(file, detectionRulesId, status);
|
statusItemControllerService.importFromExcel(file, detectionRulesId, status);
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.nflg.qms.admin.service;
|
package com.nflg.qms.admin.service;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.nflg.wms.common.exception.NflgException;
|
import com.nflg.wms.common.exception.NflgException;
|
||||||
|
|
@ -13,20 +14,28 @@ import com.nflg.wms.common.pojo.qo.QmsPdiStatusItemAddQO;
|
||||||
import com.nflg.wms.common.pojo.qo.QmsPdiStatusItemSearchQO;
|
import com.nflg.wms.common.pojo.qo.QmsPdiStatusItemSearchQO;
|
||||||
import com.nflg.wms.common.pojo.qo.QmsPdiStatusItemUpdateQO;
|
import com.nflg.wms.common.pojo.qo.QmsPdiStatusItemUpdateQO;
|
||||||
import com.nflg.wms.common.pojo.vo.QmsPdiStatusItemGroupVO;
|
import com.nflg.wms.common.pojo.vo.QmsPdiStatusItemGroupVO;
|
||||||
|
import com.nflg.wms.common.util.DateTimeUtil;
|
||||||
import com.nflg.wms.common.util.EecExcelUtil;
|
import com.nflg.wms.common.util.EecExcelUtil;
|
||||||
import com.nflg.wms.common.util.UserUtil;
|
import com.nflg.wms.common.util.UserUtil;
|
||||||
|
import com.nflg.wms.repository.entity.FileUploadRecord;
|
||||||
import com.nflg.wms.repository.entity.QmsPdiDetectionRulesStatusItem;
|
import com.nflg.wms.repository.entity.QmsPdiDetectionRulesStatusItem;
|
||||||
import com.nflg.wms.repository.entity.QmsPdiDetectionRules;
|
import com.nflg.wms.repository.entity.QmsPdiDetectionRules;
|
||||||
import com.nflg.wms.repository.mapper.QmsPdiDetectionRulesStatusItemMapper;
|
import com.nflg.wms.repository.mapper.QmsPdiDetectionRulesStatusItemMapper;
|
||||||
|
import com.nflg.wms.repository.service.IFileUploadRecordService;
|
||||||
import com.nflg.wms.repository.service.IQmsPdiDetectionRulesStatusItemService;
|
import com.nflg.wms.repository.service.IQmsPdiDetectionRulesStatusItemService;
|
||||||
import com.nflg.wms.repository.service.IQmsPdiDetectionRulesService;
|
import com.nflg.wms.repository.service.IQmsPdiDetectionRulesService;
|
||||||
|
import com.nflg.wms.starter.service.FileUploadService;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.ttzero.excel.reader.Drawings;
|
||||||
|
import org.ttzero.excel.reader.ExcelReader;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -42,6 +51,8 @@ public class QmsPdiStatusItemControllerService {
|
||||||
private final IQmsPdiDetectionRulesStatusItemService statusItemService;
|
private final IQmsPdiDetectionRulesStatusItemService statusItemService;
|
||||||
private final QmsPdiDetectionRulesStatusItemMapper statusItemMapper;
|
private final QmsPdiDetectionRulesStatusItemMapper statusItemMapper;
|
||||||
private final IQmsPdiDetectionRulesService pdiDetectionRulesService;
|
private final IQmsPdiDetectionRulesService pdiDetectionRulesService;
|
||||||
|
private final FileUploadService fileUploadService;
|
||||||
|
private final IFileUploadRecordService fileUploadRecordService;
|
||||||
|
|
||||||
// ========================= 新增 =========================
|
// ========================= 新增 =========================
|
||||||
|
|
||||||
|
|
@ -169,7 +180,7 @@ public class QmsPdiStatusItemControllerService {
|
||||||
QmsPdiStatusItemImportDTO example = new QmsPdiStatusItemImportDTO()
|
QmsPdiStatusItemImportDTO example = new QmsPdiStatusItemImportDTO()
|
||||||
.setComponentsDes("示例部件描述")
|
.setComponentsDes("示例部件描述")
|
||||||
.setInspectionContent("示例检查核实内容")
|
.setInspectionContent("示例检查核实内容")
|
||||||
.setInspectionImage(123456L);
|
.setInspectionImage("123456");
|
||||||
EecExcelUtil.export("PDI检测项导入模板", "PDI检测项导入模板", List.of(example), response);
|
EecExcelUtil.export("PDI检测项导入模板", "PDI检测项导入模板", List.of(example), response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,11 +190,42 @@ public class QmsPdiStatusItemControllerService {
|
||||||
* 导入PDI检测项
|
* 导入PDI检测项
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public void importFromExcel(MultipartFile file, Long detectionRulesId, Integer status) throws IOException {
|
public void importFromExcel(MultipartFile file, Long detectionRulesId, Integer status) throws Exception {
|
||||||
List<QmsPdiStatusItemImportDTO> data = EecExcelUtil.readTo(file.getInputStream(), QmsPdiStatusItemImportDTO.class);
|
// 先将文件内容缓存为字节数组,避免流只能读一次
|
||||||
|
byte[] fileBytes = file.getBytes();
|
||||||
|
|
||||||
|
List<QmsPdiStatusItemImportDTO> data = EecExcelUtil.readTo(new java.io.ByteArrayInputStream(fileBytes), QmsPdiStatusItemImportDTO.class);
|
||||||
if (CollectionUtil.isEmpty(data)) {
|
if (CollectionUtil.isEmpty(data)) {
|
||||||
throw new NflgException(STATE.BusinessError, "导入文件内容为空");
|
throw new NflgException(STATE.BusinessError, "导入文件内容为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 读取 Excel 里的所有图片
|
||||||
|
List<Drawings.Picture> pictures = new ExcelReader(new java.io.ByteArrayInputStream(fileBytes)).listPictures();
|
||||||
|
|
||||||
|
// 遍历 DTO,遇到 DISPIMG 就上传图片并替换地址
|
||||||
|
for (int i = 0; i < data.size(); i++) {
|
||||||
|
QmsPdiStatusItemImportDTO dto = data.get(i);
|
||||||
|
String inspectionImage = dto.getInspectionImage();
|
||||||
|
|
||||||
|
// 如果是图片公式,就取图片上传,把地址填回去
|
||||||
|
if (StrUtil.isNotBlank(inspectionImage) && inspectionImage.startsWith("=DISPIMG(")) {
|
||||||
|
if (i < pictures.size()) {
|
||||||
|
Drawings.Picture pic = pictures.get(i);
|
||||||
|
try (FileInputStream fis = new FileInputStream(pic.getLocalPath().toFile())) {
|
||||||
|
// 上传图片 → 获取地址
|
||||||
|
String imageUrl = fileUploadService.upload(
|
||||||
|
"image/" + DateTimeUtil.format(LocalDate.now(), "yyyyMMdd") + "/" + IdUtil.fastUUID() + ".png",
|
||||||
|
fis,
|
||||||
|
"image/png"
|
||||||
|
);
|
||||||
|
dto.setInspectionImage(imageUrl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dto.setInspectionImage(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String operator = UserUtil.getUserName();
|
String operator = UserUtil.getUserName();
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
List<QmsPdiDetectionRulesStatusItem> entities = data.stream()
|
List<QmsPdiDetectionRulesStatusItem> entities = data.stream()
|
||||||
|
|
|
||||||
|
|
@ -154,21 +154,8 @@ public class QmsPdiTaskRecordControllerService {
|
||||||
.collect(Collectors.toMap(QmsPdiDetectionRulesStatusItem::getId, si -> si, (a, b) -> a));
|
.collect(Collectors.toMap(QmsPdiDetectionRulesStatusItem::getId, si -> si, (a, b) -> a));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收集所有示例图ID,批量查询file_upload_record
|
|
||||||
Set<Long> exampleImageIds = statusItemMap.values().stream()
|
|
||||||
.map(QmsPdiDetectionRulesStatusItem::getInspectionImage)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
Map<Long, String> exampleImageUrlMap = Map.of();
|
|
||||||
if (!exampleImageIds.isEmpty()) {
|
|
||||||
List<FileUploadRecord> files = fileUploadRecordService.listByIds(exampleImageIds);
|
|
||||||
exampleImageUrlMap = files.stream()
|
|
||||||
.collect(Collectors.toMap(FileUploadRecord::getId, FileUploadRecord::getUrl, (a, b) -> a));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 映射
|
// 映射
|
||||||
Map<Long, QmsPdiDetectionRulesStatusItem> finalStatusMap = statusItemMap;
|
Map<Long, QmsPdiDetectionRulesStatusItem> finalStatusMap = statusItemMap;
|
||||||
Map<Long, String> finalExampleImageUrlMap = exampleImageUrlMap;
|
|
||||||
List<QmsPdiTaskRecordDetailVO.StatusItemVO> voList = records.stream().map(r -> {
|
List<QmsPdiTaskRecordDetailVO.StatusItemVO> voList = records.stream().map(r -> {
|
||||||
QmsPdiTaskRecordDetailVO.StatusItemVO vo = new QmsPdiTaskRecordDetailVO.StatusItemVO();
|
QmsPdiTaskRecordDetailVO.StatusItemVO vo = new QmsPdiTaskRecordDetailVO.StatusItemVO();
|
||||||
vo.setId(r.getId());
|
vo.setId(r.getId());
|
||||||
|
|
@ -176,10 +163,8 @@ public class QmsPdiTaskRecordControllerService {
|
||||||
if (si != null) {
|
if (si != null) {
|
||||||
vo.setComponentsDes(si.getComponentsDes());
|
vo.setComponentsDes(si.getComponentsDes());
|
||||||
vo.setInspectionContent(si.getInspectionContent());
|
vo.setInspectionContent(si.getInspectionContent());
|
||||||
// 示例图ID转URL
|
// inspectionImage 已经是URL,直接使用
|
||||||
if (si.getInspectionImage() != null) {
|
vo.setInspectionImage(si.getInspectionImage());
|
||||||
vo.setInspectionImage(finalExampleImageUrlMap.get(si.getInspectionImage()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 现场图已经是List<FileDetailVO>,无需转换(在下一步处理)
|
// 现场图已经是List<FileDetailVO>,无需转换(在下一步处理)
|
||||||
vo.setInspectionItemImage(convertImageIdsToVO(r.getInspectionItemImage()));
|
vo.setInspectionItemImage(convertImageIdsToVO(r.getInspectionItemImage()));
|
||||||
|
|
@ -223,21 +208,8 @@ public class QmsPdiTaskRecordControllerService {
|
||||||
.collect(Collectors.toMap(QmsPdiDetectionRulesStatusItem::getId, si -> si, (a, b) -> a));
|
.collect(Collectors.toMap(QmsPdiDetectionRulesStatusItem::getId, si -> si, (a, b) -> a));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收集所有示例图ID,批量查询file_upload_record
|
|
||||||
Set<Long> exampleImageIds = statusItemMap.values().stream()
|
|
||||||
.map(QmsPdiDetectionRulesStatusItem::getInspectionImage)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
Map<Long, String> exampleImageUrlMap = Map.of();
|
|
||||||
if (!exampleImageIds.isEmpty()) {
|
|
||||||
List<FileUploadRecord> files = fileUploadRecordService.listByIds(exampleImageIds);
|
|
||||||
exampleImageUrlMap = files.stream()
|
|
||||||
.collect(Collectors.toMap(FileUploadRecord::getId, FileUploadRecord::getUrl, (a, b) -> a));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 映射
|
// 映射
|
||||||
Map<Long, QmsPdiDetectionRulesStatusItem> finalStatusMap = statusItemMap;
|
Map<Long, QmsPdiDetectionRulesStatusItem> finalStatusMap = statusItemMap;
|
||||||
Map<Long, String> finalExampleImageUrlMap = exampleImageUrlMap;
|
|
||||||
return records.stream().map(r -> {
|
return records.stream().map(r -> {
|
||||||
QmsPdiTaskRecordDetailVO.StatusItemVO vo = new QmsPdiTaskRecordDetailVO.StatusItemVO();
|
QmsPdiTaskRecordDetailVO.StatusItemVO vo = new QmsPdiTaskRecordDetailVO.StatusItemVO();
|
||||||
vo.setId(r.getId());
|
vo.setId(r.getId());
|
||||||
|
|
@ -245,9 +217,8 @@ public class QmsPdiTaskRecordControllerService {
|
||||||
if (si != null) {
|
if (si != null) {
|
||||||
vo.setComponentsDes(si.getComponentsDes());
|
vo.setComponentsDes(si.getComponentsDes());
|
||||||
vo.setInspectionContent(si.getInspectionContent());
|
vo.setInspectionContent(si.getInspectionContent());
|
||||||
if (si.getInspectionImage() != null) {
|
// inspectionImage 已经是URL,直接使用
|
||||||
vo.setInspectionImage(finalExampleImageUrlMap.get(si.getInspectionImage()));
|
vo.setInspectionImage(si.getInspectionImage());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
vo.setInspectionItemImage(convertImageIdsToVO(r.getInspectionItemImage()));
|
vo.setInspectionItemImage(convertImageIdsToVO(r.getInspectionItemImage()));
|
||||||
vo.setInspectionBy(r.getInspectionBy());
|
vo.setInspectionBy(r.getInspectionBy());
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ public class QmsPdiStatusItemExportDTO {
|
||||||
@ExcelColumn("检查核实内容")
|
@ExcelColumn("检查核实内容")
|
||||||
private String inspectionContent;
|
private String inspectionContent;
|
||||||
|
|
||||||
@ExcelColumn("检测示例图(文件ID)")
|
@ExcelColumn("检测示例图")
|
||||||
private Long inspectionImage;
|
private String inspectionImage;
|
||||||
|
|
||||||
@ExcelColumn("状态")
|
@ExcelColumn("状态")
|
||||||
private String statusName;
|
private String statusName;
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ public class QmsPdiStatusItemImportDTO {
|
||||||
private String inspectionContent;
|
private String inspectionContent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测示例图(文件记录ID)
|
* 检测示例图(URL)
|
||||||
*/
|
*/
|
||||||
@ExcelColumn("检测示例图(文件ID)")
|
@ExcelColumn("检测示例图")
|
||||||
private Long inspectionImage;
|
private String inspectionImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ public class QmsPdiStatusItemAddQO {
|
||||||
* 检测示例图(文件记录ID,必传)
|
* 检测示例图(文件记录ID,必传)
|
||||||
*/
|
*/
|
||||||
@NotNull(message = "检测示例图不能为空")
|
@NotNull(message = "检测示例图不能为空")
|
||||||
private Long inspectionImage;
|
private String inspectionImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态:0为静态,1为动态,2为特殊(必传)
|
* 状态:0为静态,1为动态,2为特殊(必传)
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ public class QmsPdiStatusItemGroupVO {
|
||||||
/**
|
/**
|
||||||
* 检测示例图(文件记录ID)
|
* 检测示例图(文件记录ID)
|
||||||
*/
|
*/
|
||||||
private Long inspectionImage;
|
private String inspectionImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态:0为静态,1为动态,2为特殊
|
* 状态:0为静态,1为动态,2为特殊
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public class QmsPdiDetectionRulesStatusItem implements Serializable {
|
||||||
/**
|
/**
|
||||||
* 检测示例图(文件记录ID)
|
* 检测示例图(文件记录ID)
|
||||||
*/
|
*/
|
||||||
private Long inspectionImage;
|
private String inspectionImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态:0为静态,1为动态,2为特殊
|
* 状态:0为静态,1为动态,2为特殊
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,11 @@ public interface QmsPdiDetectionRulesStatusItemMapper extends BaseMapper<QmsPdiD
|
||||||
List<QmsPdiStatusItemExportDTO> listForExport(@Param("ids") List<Long> ids,
|
List<QmsPdiStatusItemExportDTO> listForExport(@Param("ids") List<Long> ids,
|
||||||
@Param("detectionRulesId") Long detectionRulesId,
|
@Param("detectionRulesId") Long detectionRulesId,
|
||||||
@Param("status") List<Integer> status);
|
@Param("status") List<Integer> status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出检测项(返回实体对象)
|
||||||
|
*/
|
||||||
|
List<QmsPdiDetectionRulesStatusItem> listForExportRaw(@Param("ids") List<Long> ids,
|
||||||
|
@Param("detectionRulesId") Long detectionRulesId,
|
||||||
|
@Param("status") List<Integer> status);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,4 +26,31 @@
|
||||||
ORDER BY s.id ASC
|
ORDER BY s.id ASC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 导出检测项(返回实体对象) -->
|
||||||
|
<select id="listForExportRaw" resultType="com.nflg.wms.repository.entity.QmsPdiDetectionRulesStatusItem">
|
||||||
|
SELECT
|
||||||
|
s.id,
|
||||||
|
s.detection_rules_id,
|
||||||
|
s.components_des,
|
||||||
|
s.inspection_content,
|
||||||
|
s.inspection_image,
|
||||||
|
s.status,
|
||||||
|
s.sort,
|
||||||
|
s.create_by,
|
||||||
|
s.create_time
|
||||||
|
FROM qms_pdi_detection_rules_status_item s
|
||||||
|
WHERE s.detection_rules_id = #{detectionRulesId}
|
||||||
|
AND s.status IN
|
||||||
|
<foreach collection="status" item="st" open="(" separator="," close=")">
|
||||||
|
#{st}
|
||||||
|
</foreach>
|
||||||
|
<if test="ids != null and ids.size() > 0">
|
||||||
|
AND s.id IN
|
||||||
|
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
ORDER BY s.id ASC
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue