|
@@ -13,7 +13,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.validation.annotation.Validated;
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
import java.io.*;
|
|
import java.io.*;
|
|
-import java.nio.charset.StandardCharsets;
|
|
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Files;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
import java.util.zip.ZipEntry;
|
|
import java.util.zip.ZipEntry;
|
|
@@ -29,7 +28,6 @@ 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 cn.hutool.core.io.IoUtil;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* 标本管理 Service 实现类
|
|
* 标本管理 Service 实现类
|
|
@@ -151,13 +149,96 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
|
|
return imageName != null && imageName.matches(".*\\.(jpg|jpeg|png|gif)$"); // 检查格式
|
|
return imageName != null && imageName.matches(".*\\.(jpg|jpeg|png|gif)$"); // 检查格式
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// @Override
|
|
|
|
+// @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
|
|
|
+// public String importSpecimenImages(MultipartFile file) throws Exception {
|
|
|
|
+// // 校验文件类型
|
|
|
|
+// if (!file.getOriginalFilename().endsWith(".zip")) {
|
|
|
|
+// throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
|
|
|
|
+// }
|
|
|
|
+// // 创建临时目录存放解压后的文件
|
|
|
|
+// File tempDir = Files.createTempDirectory("specimen_images").toFile();
|
|
|
|
+// try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
|
|
|
|
+// ZipEntry entry;
|
|
|
|
+// while ((entry = zipInputStream.getNextEntry()) != null) {
|
|
|
|
+// if (!entry.isDirectory()) {
|
|
|
|
+// File newFile = new File(tempDir, entry.getName());
|
|
|
|
+// // 进行解压
|
|
|
|
+// try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
|
|
|
|
+// byte[] buffer = new byte[1024];
|
|
|
|
+// int len;
|
|
|
|
+// while ((len = zipInputStream.read(buffer)) > 0) {
|
|
|
|
+// bos.write(buffer, 0, len);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// // 处理每个图片文件
|
|
|
|
+// File[] imageFiles = tempDir.listFiles();
|
|
|
|
+// if (imageFiles != null) {
|
|
|
|
+// for (File imageFile : imageFiles) {
|
|
|
|
+// String imageName = imageFile.getName();
|
|
|
|
+// if (!isValidImageName(imageName)) {
|
|
|
|
+// // 如果不符合格式,抛出异常或记录日志
|
|
|
|
+// System.err.println("无效的图片格式: " + imageName);
|
|
|
|
+// continue; // 或者 throw new Exception("无效的图片格式: " + imageName);
|
|
|
|
+// }
|
|
|
|
+// // 根据图片名称查找对应的标本
|
|
|
|
+// SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageName(imageName);
|
|
|
|
+// if (specimenInfo != null) {
|
|
|
|
+// // 上传图片并获取URL
|
|
|
|
+// String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
|
|
|
|
+// // 更新标本信息中的图片路径
|
|
|
|
+// specimenInfo.setImagePath(imagePath);
|
|
|
|
+// specimenInfoMapper.updateById(specimenInfo);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 清理临时文件
|
|
|
|
+// FileUtils.deleteDirectory(tempDir);
|
|
|
|
+// return "标本图片导入成功";
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+// @Override
|
|
|
|
+// @Transactional(rollbackFor = Exception.class) // 事务管理
|
|
|
|
+// public void importSpecimenData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
|
|
|
|
+// // 1. 导入标本
|
|
|
|
+// List<SpecimenImportExcelVO> list = ExcelUtils.read(excelFile, SpecimenImportExcelVO.class);
|
|
|
|
+// SpecimenImportRespVO importRespVO = importSpecimenList(list, updateSupport);
|
|
|
|
+//
|
|
|
|
+// // 2. 导入图片
|
|
|
|
+// String imageImportResult = importSpecimenImages(imageFile);
|
|
|
|
+//
|
|
|
|
+// // 可以根据需要记录导入结果
|
|
|
|
+// System.out.println("标本导入结果: " + importRespVO);
|
|
|
|
+// System.out.println("标本图片导入结果: " + imageImportResult);
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+ //测试
|
|
|
|
+ @Override
|
|
|
|
+ @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
|
|
|
+ public void importSpecimenData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
|
|
|
|
+ // 1. 导入标本
|
|
|
|
+ List<SpecimenImportExcelVO> list = ExcelUtils.read(excelFile, SpecimenImportExcelVO.class);
|
|
|
|
+ SpecimenImportRespVO importRespVO = importSpecimenList(list, updateSupport);
|
|
|
|
+
|
|
|
|
+ // 2. 导入图片
|
|
|
|
+ importSpecimenImages(imageFile, importRespVO.getCreateSpecimenNumbers(), importRespVO.getUpdateSpecimenNumbers());
|
|
|
|
+
|
|
|
|
+ // 可以根据需要记录导入结果
|
|
|
|
+ System.out.println("标本导入结果: " + importRespVO);
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
|
@Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
|
|
- public String importSpecimenImages(MultipartFile file) throws Exception {
|
|
|
|
|
|
+ public void importSpecimenImages(MultipartFile file, List<String> createdSpecimens, List<String> updatedSpecimens) throws Exception {
|
|
// 校验文件类型
|
|
// 校验文件类型
|
|
if (!file.getOriginalFilename().endsWith(".zip")) {
|
|
if (!file.getOriginalFilename().endsWith(".zip")) {
|
|
throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
|
|
throw exception(UPLOADED_FOLDER_CANNOT_EMPTY);
|
|
}
|
|
}
|
|
|
|
+
|
|
// 创建临时目录存放解压后的文件
|
|
// 创建临时目录存放解压后的文件
|
|
File tempDir = Files.createTempDirectory("specimen_images").toFile();
|
|
File tempDir = Files.createTempDirectory("specimen_images").toFile();
|
|
try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
|
|
try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
|
|
@@ -176,15 +257,15 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
// 处理每个图片文件
|
|
// 处理每个图片文件
|
|
File[] imageFiles = tempDir.listFiles();
|
|
File[] imageFiles = tempDir.listFiles();
|
|
if (imageFiles != null) {
|
|
if (imageFiles != null) {
|
|
for (File imageFile : imageFiles) {
|
|
for (File imageFile : imageFiles) {
|
|
String imageName = imageFile.getName();
|
|
String imageName = imageFile.getName();
|
|
if (!isValidImageName(imageName)) {
|
|
if (!isValidImageName(imageName)) {
|
|
- // 如果不符合格式,抛出异常或记录日志
|
|
|
|
System.err.println("无效的图片格式: " + imageName);
|
|
System.err.println("无效的图片格式: " + imageName);
|
|
- continue; // 或者 throw new Exception("无效的图片格式: " + imageName);
|
|
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
// 根据图片名称查找对应的标本
|
|
// 根据图片名称查找对应的标本
|
|
SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageName(imageName);
|
|
SpecimenInfoDO specimenInfo = specimenInfoMapper.selectByImageName(imageName);
|
|
@@ -192,33 +273,28 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
|
|
// 上传图片并获取URL
|
|
// 上传图片并获取URL
|
|
String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
|
|
String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
|
|
// 更新标本信息中的图片路径
|
|
// 更新标本信息中的图片路径
|
|
- specimenInfo.setImagePath(imagePath);
|
|
|
|
- specimenInfoMapper.updateById(specimenInfo);
|
|
|
|
|
|
+ updateSpecimenImages(specimenInfo, imagePath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 清理临时文件
|
|
// 清理临时文件
|
|
FileUtils.deleteDirectory(tempDir);
|
|
FileUtils.deleteDirectory(tempDir);
|
|
- return "标本图片导入成功";
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
|
- @Transactional(rollbackFor = Exception.class) // 事务管理
|
|
|
|
- public void importSpecimenData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
|
|
|
|
- // 1. 导入标本
|
|
|
|
- List<SpecimenImportExcelVO> list = ExcelUtils.read(excelFile, SpecimenImportExcelVO.class);
|
|
|
|
- SpecimenImportRespVO importRespVO = importSpecimenList(list, updateSupport);
|
|
|
|
-
|
|
|
|
- // 2. 导入图片
|
|
|
|
- String imageImportResult = importSpecimenImages(imageFile);
|
|
|
|
-
|
|
|
|
- // 可以根据需要记录导入结果
|
|
|
|
- System.out.println("标本导入结果: " + importRespVO);
|
|
|
|
- System.out.println("标本图片导入结果: " + imageImportResult);
|
|
|
|
|
|
+ private void updateSpecimenImages(SpecimenInfoDO specimenInfo, String imagePath) {
|
|
|
|
+ // 假设 SpecimenInfoDO 有一个 List<String> 类型的 imagePaths 字段
|
|
|
|
+ List<String> imagePaths = specimenInfo.getImagePath(); // 获取现有的图片路径
|
|
|
|
+ if (imagePaths == null) {
|
|
|
|
+ imagePaths = new ArrayList<>();
|
|
|
|
+ }
|
|
|
|
+ imagePaths.add(imagePath); // 添加新图片路径
|
|
|
|
+ specimenInfo.setImagePath(imagePaths); // 更新标本对象
|
|
|
|
+ specimenInfoMapper.updateById(specimenInfo); // 更新数据库
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
//工作台
|
|
//工作台
|
|
//根据入库的登记情况统计本年标本入库信息
|
|
//根据入库的登记情况统计本年标本入库信息
|
|
@Override
|
|
@Override
|
|
@@ -238,16 +314,68 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
|
|
|
|
|
|
|
|
|
|
//根据出、回、入库登记统计标本历年增减情况
|
|
//根据出、回、入库登记统计标本历年增减情况
|
|
|
|
+// @Override
|
|
|
|
+// public Map<Integer, Map<String, Integer>> getYearlySpecimenStatistics() {
|
|
|
|
+// // 年份与标本统计信息的映射
|
|
|
|
+// Map<Integer, Map<String, Integer>> yearlyDataMap = new HashMap<>();
|
|
|
|
+//
|
|
|
|
+// // 获取入库记录
|
|
|
|
+// List<SpecimenInfoDO> inStockRecords = specimenInfoMapper.getInStockRecords();
|
|
|
|
+// if (inStockRecords == null) {
|
|
|
|
+// inStockRecords = new ArrayList<>(); // 初始化为空列表
|
|
|
|
+// }
|
|
|
|
+// for (SpecimenInfoDO record : inStockRecords) {
|
|
|
|
+// if (record.getCreateTime() != null) { // 检查时间字段
|
|
|
|
+// int year = record.getCreateTime().getYear(); // 获取年份
|
|
|
|
+// yearlyDataMap.putIfAbsent(year, new HashMap<>());
|
|
|
|
+// yearlyDataMap.get(year).put("inStockCount", yearlyDataMap.get(year).getOrDefault("inStockCount", 0) + 1);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 获取出库记录
|
|
|
|
+// List<SpecimenOutboundDO> outboundRecords = specimenOutboundMapper.getOutboundRecords();
|
|
|
|
+// if (outboundRecords == null) {
|
|
|
|
+// outboundRecords = new ArrayList<>(); // 初始化为空列表
|
|
|
|
+// }
|
|
|
|
+// for (SpecimenOutboundDO record : outboundRecords) {
|
|
|
|
+// if (record.getOutgoingTime() != null) { // 检查时间字段
|
|
|
|
+// int year = record.getOutgoingTime().getYear(); // 获取年份
|
|
|
|
+// yearlyDataMap.putIfAbsent(year, new HashMap<>());
|
|
|
|
+// yearlyDataMap.get(year).put("outStockCount", yearlyDataMap.get(year).getOrDefault("outStockCount", 0) + 1);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// // 获取回库记录
|
|
|
|
+// List<SpecimenOutboundDO> inboundRecords = specimenOutboundMapper.getOutboundRecords();
|
|
|
|
+// if (inboundRecords == null) {
|
|
|
|
+// inboundRecords = new ArrayList<>(); // 初始化为空列表
|
|
|
|
+// }
|
|
|
|
+// for (SpecimenOutboundDO record : inboundRecords) {
|
|
|
|
+// if (record.getReturnDate() != null) { // 检查时间字段
|
|
|
|
+// int year = record.getReturnDate().getYear(); // 获取年份
|
|
|
|
+// yearlyDataMap.putIfAbsent(year, new HashMap<>());
|
|
|
|
+// yearlyDataMap.get(year).put("returnCount", yearlyDataMap.get(year).getOrDefault("returnCount", 0) + 1);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return yearlyDataMap;
|
|
|
|
+// }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
- public Map<Integer, Map<String, Integer>> getYearlySpecimenStatistics() {
|
|
|
|
- // 年份与标本统计信息的映射
|
|
|
|
- Map<Integer, Map<String, Integer>> yearlyDataMap = new HashMap<>();
|
|
|
|
|
|
+ public Map<String, Object> getYearlySpecimenStatistics() {
|
|
|
|
+ // 创建一个列表来存放每年的统计数据
|
|
|
|
+ List<Map<String, Object>> yearlyStatisticsList = new ArrayList<>();
|
|
|
|
|
|
// 获取入库记录
|
|
// 获取入库记录
|
|
List<SpecimenInfoDO> inStockRecords = specimenInfoMapper.getInStockRecords();
|
|
List<SpecimenInfoDO> inStockRecords = specimenInfoMapper.getInStockRecords();
|
|
if (inStockRecords == null) {
|
|
if (inStockRecords == null) {
|
|
inStockRecords = new ArrayList<>(); // 初始化为空列表
|
|
inStockRecords = new ArrayList<>(); // 初始化为空列表
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 用于存储每年的统计数据
|
|
|
|
+ Map<Integer, Map<String, Integer>> yearlyDataMap = new HashMap<>();
|
|
|
|
+
|
|
|
|
+ // 统计入库数量
|
|
for (SpecimenInfoDO record : inStockRecords) {
|
|
for (SpecimenInfoDO record : inStockRecords) {
|
|
if (record.getCreateTime() != null) { // 检查时间字段
|
|
if (record.getCreateTime() != null) { // 检查时间字段
|
|
int year = record.getCreateTime().getYear(); // 获取年份
|
|
int year = record.getCreateTime().getYear(); // 获取年份
|
|
@@ -261,6 +389,8 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
|
|
if (outboundRecords == null) {
|
|
if (outboundRecords == null) {
|
|
outboundRecords = new ArrayList<>(); // 初始化为空列表
|
|
outboundRecords = new ArrayList<>(); // 初始化为空列表
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 统计出库数量
|
|
for (SpecimenOutboundDO record : outboundRecords) {
|
|
for (SpecimenOutboundDO record : outboundRecords) {
|
|
if (record.getOutgoingTime() != null) { // 检查时间字段
|
|
if (record.getOutgoingTime() != null) { // 检查时间字段
|
|
int year = record.getOutgoingTime().getYear(); // 获取年份
|
|
int year = record.getOutgoingTime().getYear(); // 获取年份
|
|
@@ -274,6 +404,8 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
|
|
if (inboundRecords == null) {
|
|
if (inboundRecords == null) {
|
|
inboundRecords = new ArrayList<>(); // 初始化为空列表
|
|
inboundRecords = new ArrayList<>(); // 初始化为空列表
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 统计回库数量
|
|
for (SpecimenOutboundDO record : inboundRecords) {
|
|
for (SpecimenOutboundDO record : inboundRecords) {
|
|
if (record.getReturnDate() != null) { // 检查时间字段
|
|
if (record.getReturnDate() != null) { // 检查时间字段
|
|
int year = record.getReturnDate().getYear(); // 获取年份
|
|
int year = record.getReturnDate().getYear(); // 获取年份
|
|
@@ -282,9 +414,24 @@ public class SpecimenInfoServiceImpl implements SpecimenInfoService {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return yearlyDataMap;
|
|
|
|
|
|
+ // 将统计结果转化为列表格式
|
|
|
|
+ for (Map.Entry<Integer, Map<String, Integer>> entry : yearlyDataMap.entrySet()) {
|
|
|
|
+ Map<String, Object> yearData = new HashMap<>();
|
|
|
|
+ yearData.put("year", entry.getKey().toString());
|
|
|
|
+ yearData.putAll(entry.getValue()); // 添加对应的数量
|
|
|
|
+ yearlyStatisticsList.add(yearData);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 构建最终的返回结果
|
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
|
+ resultMap.put("code", 200);
|
|
|
|
+ resultMap.put("data", yearlyStatisticsList);
|
|
|
|
+ resultMap.put("msg", "各年入库出库回库标本数");
|
|
|
|
+
|
|
|
|
+ return resultMap;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public Map<Integer, Map<String, Integer>> getYearlySpecimenSourceStatistics() {
|
|
public Map<Integer, Map<String, Integer>> getYearlySpecimenSourceStatistics() {
|
|
// 年份与标本来源统计信息的映射
|
|
// 年份与标本来源统计信息的映射
|