|
@@ -31,7 +31,12 @@ import org.springframework.web.multipart.MultipartFile;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
import static cn.iocoder.yudao.module.museums.enums.ErrorCodeConstants.*;
|
|
import static cn.iocoder.yudao.module.museums.enums.ErrorCodeConstants.*;
|
|
import static cn.iocoder.yudao.module.museums.enums.social.LogRecordConstants.*;
|
|
import static cn.iocoder.yudao.module.museums.enums.social.LogRecordConstants.*;
|
|
-
|
|
|
|
|
|
+import org.apache.tomcat.util.http.fileupload.FileUtils;
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.FileOutputStream;
|
|
|
|
+import java.nio.file.Files;
|
|
|
|
+import java.util.zip.ZipEntry;
|
|
|
|
+import java.util.zip.ZipInputStream;
|
|
/**
|
|
/**
|
|
* 标本管理 Service 实现类
|
|
* 标本管理 Service 实现类
|
|
*
|
|
*
|
|
@@ -297,6 +302,188 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
|
|
return respVO;
|
|
return respVO;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public SpecimenImportRespVO importSpecimenListAndImages(List<SpecimenImportExcelVO> importSpecimens,
|
|
|
|
+ MultipartFile file, Integer updateType, boolean isUpdateSupport) {
|
|
|
|
+
|
|
|
|
+ File tempDir;
|
|
|
|
+ try {
|
|
|
|
+ tempDir = Files.createTempDirectory("specimen_images").toFile();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new RuntimeException("创建临时目录失败", e);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(file != null && !file.isEmpty()) {
|
|
|
|
+ if (!file.getOriginalFilename().endsWith(".zip")) {
|
|
|
|
+ throw exception(PHOTO_GROUP_MUST_BE_COMPRESSED_PACKAGE);
|
|
|
|
+ }
|
|
|
|
+ try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
|
|
|
|
+ ZipEntry entry;
|
|
|
|
+ while ((entry = zipInputStream.getNextEntry()) != null) {
|
|
|
|
+ if (!entry.isDirectory()) {
|
|
|
|
+ String fileName = entry.getName().toLowerCase();
|
|
|
|
+ if (isSupportedImage(fileName)) {
|
|
|
|
+ File newFile = new File(tempDir, fileName);
|
|
|
|
+ try (FileOutputStream fos = new FileOutputStream(newFile);
|
|
|
|
+ BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
|
|
|
+ byte[] buffer = new byte[4096];
|
|
|
|
+ int length;
|
|
|
|
+ while ((length = zipInputStream.read(buffer)) != -1) {
|
|
|
|
+ bos.write(buffer, 0, length);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw exception(PHOTO_GROUP_PACKAGE_FAILED_DECOMPRESS);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 1.1 参数校验
|
|
|
|
+ if (CollUtil.isEmpty(importSpecimens)) {
|
|
|
|
+ throw exception(SPECIMEN_INFO_LIST_IS_EMPTY);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 2. 遍历,逐个创建或更新
|
|
|
|
+ SpecimenImportRespVO respVO = SpecimenImportRespVO.builder()
|
|
|
|
+ .createSpecimenNumbers(new ArrayList<>())
|
|
|
|
+ .updateSpecimenNumbers(new ArrayList<>())
|
|
|
|
+ .failureSpecimenNumbers(new LinkedHashMap<>())
|
|
|
|
+ .createdSpecimenIds(new ArrayList<>())
|
|
|
|
+ .createSpecimenImages(new ArrayList<>()) // 成功导入的图片
|
|
|
|
+ .failureSpecimenImages(new LinkedHashMap<>()) // 失败的图片及错误信息
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ List<Long> successfulSpecimenIds = new ArrayList<>(); // 用于存储成功导入的标本ID
|
|
|
|
+ List<Long> updatedSpecimenIds = new ArrayList<>(); // 用于存储成功更新的标本ID
|
|
|
|
+
|
|
|
|
+ importSpecimens.forEach(importSpecimen -> {
|
|
|
|
+ // 2.1. 判断是否存在
|
|
|
|
+ SpecimenInfoDO existSpecimen = specimenInfoMapper.selectBySpecimenNumber(importSpecimen.getSpecimenNumber());
|
|
|
|
+
|
|
|
|
+ if (!isValidImageName(importSpecimen.getImageName())) {
|
|
|
|
+ respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "图片名称格式不正确");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String[] names = importSpecimen.getImageName().split("、");
|
|
|
|
+ List<String> imagePathSet = new ArrayList<>();
|
|
|
|
+ for (String importName : names) {
|
|
|
|
+ File imageFile = findImageInTempDir(tempDir, importName);
|
|
|
|
+ if (imageFile != null) {
|
|
|
|
+ try {
|
|
|
|
+ byte[] imageBytes = Files.readAllBytes(imageFile.toPath());
|
|
|
|
+ String imagePath = fileApi.createFile(imageBytes);
|
|
|
|
+ imagePathSet.add(imagePath);
|
|
|
|
+ respVO.getCreateSpecimenImages().add(importName);
|
|
|
|
+ // 处理上传后的路径,如存储到数据库或更新状态等
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ respVO.getFailureSpecimenImages().put(importName, "图片上传失败");
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ respVO.getFailureSpecimenImages().put(importSpecimen.getSpecimenNumber(), "图片不存在压缩包中");
|
|
|
|
+ }
|
|
|
|
+ if (existSpecimen != null && imagePathSet.isEmpty()) {
|
|
|
|
+ imagePathSet = BeanUtils.toBean(existSpecimen, SpecimenInfoRespVO.class).getImagePath();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 处理文献资料字段,如果为空就赋值 <br>
|
|
|
|
+ if (importSpecimen.getDescription() == null || importSpecimen.getDescription().trim().isEmpty()) {
|
|
|
|
+ importSpecimen.setDescription("<p><br></p>");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (existSpecimen == null) {
|
|
|
|
+ // 2.2.1 不存在则插入
|
|
|
|
+ SpecimenInfoDO newSpecimen = BeanUtils.toBean(importSpecimen, SpecimenInfoDO.class);
|
|
|
|
+ newSpecimen.setImagePath(imagePathSet.toString());
|
|
|
|
+ if (updateType != -1) {
|
|
|
|
+ newSpecimen.setSpecimenType(updateType);
|
|
|
|
+ }
|
|
|
|
+ specimenInfoMapper.insert(newSpecimen);
|
|
|
|
+ respVO.getCreateSpecimenNumbers().add(importSpecimen.getSpecimenNumber());
|
|
|
|
+ respVO.getCreatedSpecimenIds().add(newSpecimen.getId()); // 添加新标本 ID
|
|
|
|
+ successfulSpecimenIds.add(newSpecimen.getId()); // 记录成功导入的ID
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 2.2.2 如果存在,判断是否允许更新
|
|
|
|
+ if (!isUpdateSupport) {
|
|
|
|
+ respVO.getFailureSpecimenNumbers().put(importSpecimen.getSpecimenNumber(), "标本编号已存在,且不支持更新");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ // 更新逻辑
|
|
|
|
+ SpecimenInfoDO updateSpecimen = BeanUtils.toBean(importSpecimen, SpecimenInfoDO.class);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ updateSpecimen.setImagePath(imagePathSet.toString());
|
|
|
|
+ if (updateType != -1) {
|
|
|
|
+ updateSpecimen.setSpecimenType(updateType);
|
|
|
|
+ }
|
|
|
|
+ updateSpecimen.setId(existSpecimen.getId()); // 设置 ID 进行更新
|
|
|
|
+ specimenInfoMapper.updateById(updateSpecimen);
|
|
|
|
+ respVO.getUpdateSpecimenNumbers().add(importSpecimen.getSpecimenNumber());
|
|
|
|
+ updatedSpecimenIds.add(updateSpecimen.getId()); // 记录成功更新的ID
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 合并成功导入和更新的标本ID
|
|
|
|
+ successfulSpecimenIds.addAll(updatedSpecimenIds);
|
|
|
|
+
|
|
|
|
+ // 记录成功导入和更新的标本ID到日志上下文
|
|
|
|
+ LogRecordContext.putVariable("extra", successfulSpecimenIds);
|
|
|
|
+
|
|
|
|
+ return respVO;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ private boolean isSupportedImage(String fileName) {
|
|
|
|
+ return fileName.endsWith(".jpg") || fileName.endsWith(".png") || fileName.endsWith(".gif") ||
|
|
|
|
+ fileName.endsWith(".bmp") || fileName.endsWith(".tiff") || fileName.endsWith(".jpeg") ||
|
|
|
|
+ fileName.endsWith(".psd") || fileName.endsWith(".raw") || fileName.endsWith(".svg");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private File findImageInTempDir(File tempDir, String imageName) {
|
|
|
|
+ File[] files = tempDir.listFiles((dir, name) -> name.equalsIgnoreCase(imageName));
|
|
|
|
+ return files != null && files.length > 0 ? files[0] : null;
|
|
|
|
+ }
|
|
|
|
+ //公共方法
|
|
|
|
+// public List<Integer> processZipFile(ZipInputStream zipInputStream, Integer groupId) throws Exception {
|
|
|
|
+// List<Integer> photoIds = new ArrayList<>();
|
|
|
|
+// ZipEntry entry;
|
|
|
|
+// while ((entry = zipInputStream.getNextEntry()) != null) {
|
|
|
|
+// if (!entry.isDirectory()) {
|
|
|
|
+// String fileName = entry.getName().toLowerCase(); // 转为小写
|
|
|
|
+// // 检查文件类型,只处理图片(转换为小写后进行检查)
|
|
|
|
+// if (fileName.endsWith(".jpg") || fileName.endsWith(".png") || fileName.endsWith(".gif")
|
|
|
|
+// || fileName.endsWith(".bmp") || fileName.endsWith(".tiff")|| fileName.endsWith(".jpeg")
|
|
|
|
+// || fileName.endsWith(".psd") || fileName.endsWith(".raw") || fileName.endsWith(".svg")) {
|
|
|
|
+//
|
|
|
|
+// // 使用 ByteArrayOutputStream 读取文件内容
|
|
|
|
+// ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
|
|
+// byte[] buffer = new byte[1024];
|
|
|
|
+// int length;
|
|
|
|
+// while ((length = zipInputStream.read(buffer)) != -1) {
|
|
|
|
+// bos.write(buffer, 0, length);
|
|
|
|
+// }
|
|
|
|
+// byte[] imageBytes = bos.toByteArray();
|
|
|
|
+//
|
|
|
|
+// // 上传图片并获取 URL
|
|
|
|
+// String imagePath = fileApi.createFile(imageBytes);
|
|
|
|
+//
|
|
|
|
+// // 创建照片信息记录
|
|
|
|
+// PhotosDO photoRecord = new PhotosDO();
|
|
|
|
+// photoRecord.setGroupId(groupId);
|
|
|
|
+// photoRecord.setPhotoUrl(imagePath);
|
|
|
|
+// photosMapper.insert(photoRecord);
|
|
|
|
+//
|
|
|
|
+// // 获取并存储新插入的照片 ID
|
|
|
|
+// photoIds.add(photoRecord.getId());
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// return photoIds;
|
|
|
|
+// }
|
|
//工作台
|
|
//工作台
|
|
//根据入库的登记情况统计本年标本入库信息
|
|
//根据入库的登记情况统计本年标本入库信息
|
|
@Override
|
|
@Override
|