添加了一些统计的功能,例如检出率

master
杨海航 2 months ago
parent 92bce1a11f
commit e3badb0457
  1. 20
      src/main/java/digital/laboratory/platform/entrustment/controller/EntrustMaterialCheckoutResultController.java
  2. 8
      src/main/java/digital/laboratory/platform/entrustment/controller/EntrustmentController.java
  3. 5
      src/main/java/digital/laboratory/platform/entrustment/service/EntrustMaterialCheckoutResultService.java
  4. 538
      src/main/java/digital/laboratory/platform/entrustment/service/impl/EntrustMaterialCheckoutResultServiceImpl.java
  5. 13
      src/main/java/digital/laboratory/platform/entrustment/vo/EntrustmentIdentificationMaterialVO.java

@ -16,10 +16,12 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
@ -85,20 +87,26 @@ public class EntrustMaterialCheckoutResultController {
@ApiOperation("查询所有检出检材的毒品种类清单,并按名称进行排序") @ApiOperation("查询所有检出检材的毒品种类清单,并按名称进行排序")
@GetMapping("/getResultType") @GetMapping("/getResultType")
public R getResultType(Integer year, String orgId){ public R getResultType(Integer year, String orgId) {
return R.ok(entrustMaterialCheckoutResultService.getResultType(year, orgId),"查询成功!"); return R.ok(entrustMaterialCheckoutResultService.getResultType(year, orgId), "查询成功!");
} }
@ApiOperation("查询所有毒品的检出率") @ApiOperation("查询所有毒品的检出率")
@GetMapping("/getDetectionRate") @GetMapping("/getDetectionRate")
public R getDetectionRateByMaterial(Integer year, String orgId){ public R getDetectionRateByMaterial(Integer year, String orgId) {
return R.ok(entrustMaterialCheckoutResultService.getDetectionRateByMaterial(year, orgId),"查询成功!"); return R.ok(entrustMaterialCheckoutResultService.getDetectionRateByMaterial(year, orgId), "查询成功!");
} }
@ApiOperation("根据毒品名称来查询所有检出该毒品的检材列表") @ApiOperation("根据毒品名称来查询所有检出该毒品的检材列表")
@GetMapping("/getMaterialByDetection") @GetMapping("/getMaterialByDetection")
public R<IPage> getMaterialByDetection(String drugName, Integer year, Page page){ public R<IPage> getMaterialByDetection(String drugName, Integer year, Page page) {
return R.ok(entrustMaterialCheckoutResultService.getMaterialByDetection(drugName,year,page)); return R.ok(entrustMaterialCheckoutResultService.getMaterialByDetection(drugName, year, page));
}
@ApiOperation("导出Excel")
@GetMapping("/getExcelByResult")
public void getResultData(HttpServletResponse response, Integer entrustType, String oldResult, LocalDateTime startTime, LocalDateTime endTime) throws IOException {
entrustMaterialCheckoutResultService.getExcelByResult(response, entrustType, oldResult, startTime, endTime);
} }
} }

@ -16,6 +16,7 @@ import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.log.annotation.SysLog; import digital.laboratory.platform.common.log.annotation.SysLog;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser; import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.common.oss.service.OssFile; import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.common.security.annotation.Inner;
import digital.laboratory.platform.common.security.util.SecurityUtils; import digital.laboratory.platform.common.security.util.SecurityUtils;
import digital.laboratory.platform.entrustment.dto.EntrustmentDTO; import digital.laboratory.platform.entrustment.dto.EntrustmentDTO;
import digital.laboratory.platform.entrustment.entity.CaseEvent; import digital.laboratory.platform.entrustment.entity.CaseEvent;
@ -2387,4 +2388,11 @@ public class EntrustmentController {
return R.ok(entrustmentService.getDelivererList(dlpUser), "数据查询成功!"); return R.ok(entrustmentService.getDelivererList(dlpUser), "数据查询成功!");
} }
@GetMapping("/getById")
@Inner(value = false)
public R getEntrustById(String id) {
Entrustment entrustment = entrustmentService.getById(id);
return R.ok(entrustment);
}
} }

@ -12,6 +12,7 @@ import digital.laboratory.platform.entrustment.vo.EntrustmentIdentificationMater
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
@ -69,4 +70,8 @@ public interface EntrustMaterialCheckoutResultService extends IService<EntrustMa
* @return * @return
*/ */
DetectionRateVO getDetectionRateByMaterial(Integer year, String orgId); DetectionRateVO getDetectionRateByMaterial(Integer year, String orgId);
List<EntrustmentIdentificationMaterialVO> getResultData(Integer entrustType, String oldResult, LocalDateTime startTime, LocalDateTime endTime);
void getExcelByResult(HttpServletResponse response, Integer entrustType, String oldResult, LocalDateTime startTime, LocalDateTime endTime) throws IOException;
} }

@ -2,7 +2,10 @@ package digital.laboratory.platform.entrustment.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -29,6 +32,7 @@ import digital.laboratory.platform.sys.entity.Area;
import digital.laboratory.platform.sys.entity.DrugLite; import digital.laboratory.platform.sys.entity.DrugLite;
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -43,13 +47,13 @@ import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* @author ChenJiangBao * @author ChenJiangBao
* @description 针对表b_entrust_material_checkout_result(委托检材--检出定性定量结果信息)的数据库操作Service实现 * @description 针对表b_entrust_material_checkout_result(委托检材--检出定性定量结果信息)的数据库操作Service实现
* @createDate 2024-12-30 16:16:25 * @createDate 2024-12-30 16:16:25
*/ */
@Service @Service
public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<EntrustMaterialCheckoutResultMapper, EntrustMaterialCheckoutResult> public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<EntrustMaterialCheckoutResultMapper, EntrustMaterialCheckoutResult>
implements EntrustMaterialCheckoutResultService { implements EntrustMaterialCheckoutResultService {
@Resource @Resource
private EntrustmentService entrustmentService; private EntrustmentService entrustmentService;
@ -106,6 +110,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
/** /**
* 根据DTO保存检材得检出结果信息 * 根据DTO保存检材得检出结果信息
*
* @param dto 检出DTO * @param dto 检出DTO
* @return * @return
*/ */
@ -144,7 +149,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
* 根据委托id导出检出结果excel文件 * 根据委托id导出检出结果excel文件
* *
* @param entrustIds 委托id列表包含需要导出的委托的id * @param entrustIds 委托id列表包含需要导出的委托的id
* @param response HttpServletResponse对象用于将生成的excel文件写入响应中 * @param response HttpServletResponse对象用于将生成的excel文件写入响应中
*/ */
@Override @Override
public void exportExcel(List<String> entrustIds, HttpServletResponse response) throws IOException { public void exportExcel(List<String> entrustIds, HttpServletResponse response) throws IOException {
@ -196,6 +201,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
/** /**
* vo 分页对象 * vo 分页对象
*
* @param query * @param query
* @return * @return
*/ */
@ -223,7 +229,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
return baseMapper.getEntrustMaterialCheckoutResultVOPage( return baseMapper.getEntrustMaterialCheckoutResultVOPage(
new Page<>(query.getCurrent(), query.getSize()), new Page<>(query.getCurrent(), query.getSize()),
Wrappers.<EntrustMaterialCheckoutResultVO>query() Wrappers.<EntrustMaterialCheckoutResultVO>query()
.eq(StrUtil.isNotBlank(query.getEntrustId()), "emr.entrust_id", query.getEntrustId()) .eq(StrUtil.isNotBlank(query.getEntrustId()), "emr.entrust_id", query.getEntrustId())
.orderByAsc("em.order_no") .orderByAsc("em.order_no")
); );
} }
@ -231,15 +237,15 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
/** /**
* 构建并输出Excel文件 * 构建并输出Excel文件
* *
* @param response HttpServletResponse对象用于输出Excel文件 * @param response HttpServletResponse对象用于输出Excel文件
* @param checkoutResultExcelDTOS 需要写入Excel的数据列表 * @param checkoutResultExcelDTOS 需要写入Excel的数据列表
* @throws IOException 如果在写入Excel文件时发生IO异常 * @throws IOException 如果在写入Excel文件时发生IO异常
* * <p>
* 此方法用于将给定的checkoutResultExcelDTOS列表数据写入Excel文件并输出到HttpServletResponse对象中 * 此方法用于将给定的checkoutResultExcelDTOS列表数据写入Excel文件并输出到HttpServletResponse对象中
* 方法首先创建一个新的XSSFWorkbook对象作为Excel工作簿并为其创建一个名为当前日期时间的工作表 * 方法首先创建一个新的XSSFWorkbook对象作为Excel工作簿并为其创建一个名为当前日期时间的工作表
* 接着根据buildExcelHead方法返回的表头信息构建Excel的表头行 * 接着根据buildExcelHead方法返回的表头信息构建Excel的表头行
* 然后遍历checkoutResultExcelDTOS列表将每个元素的数据写入Excel的对应行中 * 然后遍历checkoutResultExcelDTOS列表将每个元素的数据写入Excel的对应行中
* 最后使用response.getOutputStream()获取输出流将构建好的Excel工作簿写入该输出流中实现文件的下载 * 最后使用response.getOutputStream()获取输出流将构建好的Excel工作簿写入该输出流中实现文件的下载
*/ */
private void buildExcel(HttpServletResponse response, List<CheckoutResultExcelDTO> checkoutResultExcelDTOS) throws IOException { private void buildExcel(HttpServletResponse response, List<CheckoutResultExcelDTO> checkoutResultExcelDTOS) throws IOException {
Workbook workbook = new XSSFWorkbook(); Workbook workbook = new XSSFWorkbook();
@ -301,9 +307,9 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
/** /**
* 根据委托列表材料映射和检验结果映射生成导出Excel的DTO列表 * 根据委托列表材料映射和检验结果映射生成导出Excel的DTO列表
* *
* @param entrustList 委托列表 * @param entrustList 委托列表
* @param materialMap 材料映射键为委托ID值为对应的材料列表 * @param materialMap 材料映射键为委托ID值为对应的材料列表
* @param checkoutResultMap 检验结果映射键为委托ID值为对应的检验结果 * @param checkoutResultMap 检验结果映射键为委托ID值为对应的检验结果
* @return 导出Excel的DTO列表但此方法实际返回空列表因为最后返回的是Collections.emptyList() * @return 导出Excel的DTO列表但此方法实际返回空列表因为最后返回的是Collections.emptyList()
*/ */
private List<CheckoutResultExcelDTO> fetchCheckoutResultExcelDTOList(List<Entrustment> entrustList, Map<String, List<EntrustmentIdentificationMaterial>> materialMap, Map<String, EntrustMaterialCheckoutResult> checkoutResultMap) { private List<CheckoutResultExcelDTO> fetchCheckoutResultExcelDTOList(List<Entrustment> entrustList, Map<String, List<EntrustmentIdentificationMaterial>> materialMap, Map<String, EntrustMaterialCheckoutResult> checkoutResultMap) {
@ -385,10 +391,10 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
// 查询所有非空且不为空的定性结果,且创建时间大于等于起始时间 // 查询所有非空且不为空的定性结果,且创建时间大于等于起始时间
List<EntrustMaterialCheckoutResult> list = this.list(Wrappers.<EntrustMaterialCheckoutResult>lambdaQuery() List<EntrustMaterialCheckoutResult> list = this.list(Wrappers.<EntrustMaterialCheckoutResult>lambdaQuery()
.in(CollUtil.isNotEmpty(entrustIdList), EntrustMaterialCheckoutResult::getEntrustId, entrustIdList) .in(CollUtil.isNotEmpty(entrustIdList), EntrustMaterialCheckoutResult::getEntrustId, entrustIdList)
.ne(EntrustMaterialCheckoutResult::getQualitativeResult, "") // 排除空字符串 .ne(EntrustMaterialCheckoutResult::getQualitativeResult, "") // 排除空字符串
.isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult) // 排除空值 .isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult) // 排除空值
.ge(EntrustMaterialCheckoutResult::getCreateTime, startTime)); // 创建时间大于等于起始时间 .ge(EntrustMaterialCheckoutResult::getCreateTime, startTime)); // 创建时间大于等于起始时间
// 用于存储去重后的毒品类型列表 // 用于存储去重后的毒品类型列表
ArrayList<String> typeList = new ArrayList<>(); ArrayList<String> typeList = new ArrayList<>();
@ -452,9 +458,9 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
// 查询所有非空且不为空的定性结果,且创建时间大于等于起始时间 // 查询所有非空且不为空的定性结果,且创建时间大于等于起始时间
List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery() List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
.in(CollUtil.isNotEmpty(entrustIdList), EntrustmentIdentificationMaterial::getEntrustmentId, entrustIdList) .in(CollUtil.isNotEmpty(entrustIdList), EntrustmentIdentificationMaterial::getEntrustmentId, entrustIdList)
.ge(EntrustmentIdentificationMaterial::getAcceptTime, startTime) .ge(EntrustmentIdentificationMaterial::getAcceptTime, startTime)
.eq(EntrustmentIdentificationMaterial::getAcceptPassed, 1)); .eq(EntrustmentIdentificationMaterial::getAcceptPassed, 1));
// 如果查询结果为空,直接返回 null // 如果查询结果为空,直接返回 null
@ -481,17 +487,17 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
.multiply(new BigDecimal(100)) .multiply(new BigDecimal(100))
.doubleValue(); .doubleValue();
nameList.add(drugName); nameList.add(drugName);
percentList.add(String.format("%.2f%%",percentage)); percentList.add(String.format("%.2f%%", percentage));
} }
} }
vo.setNameList(nameList); vo.setNameList(nameList);
vo.setPercentList(percentList); vo.setPercentList(percentList);
// 返回包含毒品名称及其检出占比的映射表 // 返回包含毒品名称及其检出占比的映射表
return vo ; return vo;
} }
@Override @Override
public IPage<EntrustmentIdentificationMaterialVO> getMaterialByDetection(String drugName, Integer year, Page page){ public IPage<EntrustmentIdentificationMaterialVO> getMaterialByDetection(String drugName, Integer year, Page page) {
List<EntrustMaterialCheckoutResult> list = this.list(Wrappers.<EntrustMaterialCheckoutResult>lambdaQuery() List<EntrustMaterialCheckoutResult> list = this.list(Wrappers.<EntrustMaterialCheckoutResult>lambdaQuery()
.like(EntrustMaterialCheckoutResult::getQualitativeResult, drugName)); .like(EntrustMaterialCheckoutResult::getQualitativeResult, drugName));
@ -511,6 +517,484 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus
return materialPage; return materialPage;
} }
public List<EntrustmentIdentificationMaterialVO> getResultData(Integer entrustType, String oldResult, LocalDateTime startTime, LocalDateTime endTime) {
LambdaQueryWrapper<EntrustMaterialCheckoutResult> qw = new LambdaQueryWrapper<>();
if (startTime != null && endTime != null) {
qw.ge(startTime != null, EntrustMaterialCheckoutResult::getCreateTime, startTime)
.le(endTime != null, EntrustMaterialCheckoutResult::getCreateTime, endTime);
} else {
qw.ge(EntrustMaterialCheckoutResult::getCreateTime, this.getStartTime(null));
}
// 查询所有符合时间条件的检测结果
List<EntrustMaterialCheckoutResult> resultList = this.list(qw
.isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult)
.ne(EntrustMaterialCheckoutResult::getQualitativeResult, ""));
// 如果没有查询到数据,则直接返回空列表
if (CollUtil.isEmpty(resultList)) {
return Collections.emptyList();
}
// 按委托 ID 进行分组
Map<String, List<EntrustMaterialCheckoutResult>> resultMap = resultList.stream()
.collect(Collectors.groupingBy(EntrustMaterialCheckoutResult::getEntrustId));
// 获取所有的委托 ID
Set<String> entrustIdList = resultMap.keySet();
LambdaQueryWrapper<Entrustment> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(oldResult)) {
if (oldResult.equals("委托")) {
String types[] = {"首次鉴定", "补充鉴定", "重新鉴定"};
wrapper.in(Entrustment::getOldIdentificationResult, types);
} else {
wrapper.eq(Entrustment::getOldIdentificationResult, oldResult);
}
}
// 批量查询符合条件的委托信息,避免多次查询数据库
List<Entrustment> entrustmentList = entrustmentService.list(wrapper
.in(Entrustment::getId, entrustIdList)
.eq(entrustType != null, Entrustment::getEntrustmentType, entrustType));
if (CollUtil.isEmpty(entrustmentList)) {
return Collections.emptyList();
}
// 获取所有符合条件的委托 ID
Set<String> filteredEntrustIds = entrustmentList.stream()
.map(Entrustment::getId)
.collect(Collectors.toSet());
// 获取所有符合条件的委托map
Map<String, Entrustment> entrustMap = entrustmentList.stream()
.collect(Collectors.toMap(Entrustment::getId, Function.identity()));
// 过滤出符合条件的检测结果
List<EntrustMaterialCheckoutResult> newResultList = resultList.stream()
.filter(result -> filteredEntrustIds.contains(result.getEntrustId()))
.collect(Collectors.toList());
// 提取所有 resultId 批量查询 EntrustmentIdentificationMaterial,避免循环查询数据库
Set<String> resultIds = newResultList.stream()
.map(EntrustMaterialCheckoutResult::getId)
.collect(Collectors.toSet());
// 批量查询所有相关的材料信息
List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.list(Wrappers
.<EntrustmentIdentificationMaterial>lambdaQuery()
.in(EntrustmentIdentificationMaterial::getId, resultIds)
.last("ORDER BY " +
"CAST(SUBSTRING_INDEX(accept_no, '-', 1) AS UNSIGNED) ASC, " + // 年份排序
"CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(accept_no, '-', -2), '-', 1) AS UNSIGNED) ASC, " + // 流水号排序
"CAST(SUBSTRING_INDEX(accept_no, '-', -1) AS UNSIGNED) ASC")); // 子流水号排序
// 将材料信息转换为 Map 以便快速查找
Map<String, EntrustmentIdentificationMaterial> materialMap = materialList.stream()
.collect(Collectors.toMap(EntrustmentIdentificationMaterial::getId, Function.identity()));
// 构建返回的 VO 对象列表
List<EntrustmentIdentificationMaterialVO> voList = newResultList.stream()
.map(result -> {
EntrustmentIdentificationMaterial material = materialMap.get(result.getId());
if (material == null) {
return null;
}
EntrustmentIdentificationMaterialVO vo = new EntrustmentIdentificationMaterialVO();
BeanUtils.copyProperties(material, vo);
vo.setDrugLites(DrugLiteConvert.getDrugLites(result.getQualitativeResult()));
Entrustment entrust = entrustMap.get(vo.getEntrustmentId());
String oldIdentificationResult = entrust.getOldIdentificationResult();
if (oldIdentificationResult.equals("首次鉴定") || oldIdentificationResult.equals("补充鉴定") || oldIdentificationResult.equals("重新鉴定")) {
vo.setOldIdentificationResult("委托");
} else {
vo.setOldIdentificationResult(oldIdentificationResult);
}
vo.setOrgName(entrust.getClientOrgName());
return vo;
})
.filter(Objects::nonNull) // 过滤掉可能为空的数据
.collect(Collectors.toList());
// 按 acceptNo 进行排序
voList.sort(Comparator.comparing((EntrustmentIdentificationMaterial m) -> {
String[] parts = m.getAcceptNo().split("-");
return new int[]{Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2])};
}, Comparator.comparingInt((int[] arr) -> arr[0]) // 按年份排序
.thenComparingInt(arr -> arr[1]) // 按流水号排序
.thenComparingInt(arr -> arr[2]))); // 按子流水号排序
return voList;
}
public Map<String, List<EntrustmentIdentificationMaterialVO>> getResultDataMap(
Integer entrustType, String oldResult, LocalDateTime startTime, LocalDateTime endTime) {
try {
// 1. 构建查询条件
LambdaQueryWrapper<Entrustment> qw = new LambdaQueryWrapper<>();
// 时间过滤条件
if (startTime != null && endTime != null) {
qw.ge(Entrustment::getAcceptTime, startTime).le(Entrustment::getCreateTime, endTime);
} else {
qw.ge(Entrustment::getAcceptTime, this.getStartTime(null));
}
if (StringUtils.isNotBlank(oldResult)) {
if (oldResult.equals("委托")) {
String types[] = {"首次鉴定", "补充鉴定", "重新鉴定"};
qw.in(Entrustment::getOldIdentificationResult, types);
} else {
qw.eq(Entrustment::getOldIdentificationResult, oldResult);
}
}
// 2. 查询委托数据
List<Entrustment> entrusts = entrustmentService.list(qw
.eq(Entrustment::getEntrustmentType, entrustType)
.ge(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED.getStatus()));
if (entrusts.isEmpty()) {
return Collections.emptyMap();
}
// 将 Entrustment 转换为 Map,以 ID 为 Key,减少后续查询数据库的次数
Map<String, Entrustment> entrustMap = entrusts.stream()
.collect(Collectors.toMap(Entrustment::getId, Function.identity()));
Set<String> entrustIdList = entrustMap.keySet();
// 3. 查询符合条件的检验结果
List<EntrustMaterialCheckoutResult> newResultList = this.list(Wrappers.<EntrustMaterialCheckoutResult>lambdaQuery()
.in(EntrustMaterialCheckoutResult::getEntrustId, entrustIdList)
.isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult)
.ne(EntrustMaterialCheckoutResult::getQualitativeResult, ""));
if (newResultList.isEmpty()) {
return Collections.emptyMap();
}
// 4. 提取所有涉及的毒品名称(去重)
Set<String> drugNames = new HashSet<>();
for (EntrustMaterialCheckoutResult result : newResultList) {
List<DrugLite> drugLites = DrugLiteConvert.getDrugLites(result.getQualitativeResult());
for (DrugLite drugLite : drugLites) {
drugNames.add(drugLite.getName());
}
}
// 5. 处理不同毒品名称的数据
Map<String, List<EntrustmentIdentificationMaterialVO>> resultMap = new HashMap<>();
for (String drugName : drugNames) {
// 5.1 查询所有含有该毒品的检验结果
List<EntrustMaterialCheckoutResult> resultList = this.list(Wrappers.<EntrustMaterialCheckoutResult>lambdaQuery()
.like(EntrustMaterialCheckoutResult::getQualitativeResult, drugName)
.in(EntrustMaterialCheckoutResult::getEntrustId, entrustIdList));
if (resultList.isEmpty()) {
continue;
}
// 转换为 Map,方便后续查找
Map<String, EntrustMaterialCheckoutResult> checkoutResultMap = resultList.stream()
.collect(Collectors.toMap(EntrustMaterialCheckoutResult::getId, Function.identity()));
// 5.2 获取相关的鉴定材料
Set<String> materialIdSet = checkoutResultMap.keySet();
List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
.in(EntrustmentIdentificationMaterial::getId, materialIdSet));
if (materialList.isEmpty()) {
continue;
}
// 5.3 组装 VO 数据
List<EntrustmentIdentificationMaterialVO> voList = new ArrayList<>();
for (EntrustmentIdentificationMaterial material : materialList) {
Entrustment entrust = entrustMap.get(material.getEntrustmentId());
if (entrust == null) continue;
EntrustmentIdentificationMaterialVO vo = new EntrustmentIdentificationMaterialVO();
BeanUtils.copyProperties(material, vo);
vo.setOrgName(entrust.getClientOrgName());
String oldIdentificationResult = entrust.getOldIdentificationResult();
if (oldIdentificationResult.equals("首次鉴定") || oldIdentificationResult.equals("补充鉴定") || oldIdentificationResult.equals("重新鉴定")) {
vo.setOldIdentificationResult("委托");
} else {
vo.setOldIdentificationResult(oldIdentificationResult);
}
EntrustMaterialCheckoutResult checkoutResult = checkoutResultMap.get(vo.getId());
if (checkoutResult != null) {
vo.setDrugLites(DrugLiteConvert.getDrugLites(checkoutResult.getQualitativeResult()));
}
voList.add(vo);
}
// 5.4 按受理编号排序
voList.sort(Comparator.comparing(EntrustmentIdentificationMaterialVO::getAcceptNo, (a, b) -> {
try {
String[] partsA = a.split("-");
String[] partsB = b.split("-");
if (partsA.length != 3 || partsB.length != 3) return 0;
int yearA = Integer.parseInt(partsA[0]), serialA = Integer.parseInt(partsA[1]), subSerialA = Integer.parseInt(partsA[2]);
int yearB = Integer.parseInt(partsB[0]), serialB = Integer.parseInt(partsB[1]), subSerialB = Integer.parseInt(partsB[2]);
return Comparator.comparingInt((int[] arr) -> arr[0])
.thenComparingInt(arr -> arr[1])
.thenComparingInt(arr -> arr[2])
.compare(new int[]{yearA, serialA, subSerialA}, new int[]{yearB, serialB, subSerialB});
} catch (Exception e) {
return 0; // 防止解析错误导致异常
}
}));
resultMap.put(drugName, voList);
}
return resultMap;
} catch (Exception e) {
log.error("获取结果数据失败: ", e);
return Collections.emptyMap();
}
}
@Override
public void getExcelByResult(HttpServletResponse response, Integer entrustType, String oldResult, LocalDateTime
startTime, LocalDateTime endTime) throws IOException {
List<EntrustmentIdentificationMaterialVO> resultData = this.getResultData(entrustType, oldResult, startTime, endTime);
Map<String, List<EntrustmentIdentificationMaterialVO>> resultDataMap = this.getResultDataMap(entrustType, oldResult, startTime, endTime);
if (resultData.isEmpty() || resultDataMap.isEmpty()) {
throw new RuntimeException("没有符合条件的数据!");
}
Workbook workbook = new XSSFWorkbook();
Sheet sheet = null;
if (entrustType == 0) {
sheet = workbook.createSheet("常规毒品");
} else {
if (StringUtils.isNotBlank(oldResult)) {
sheet = workbook.createSheet("生物样本-" + oldResult);
} else {
sheet = workbook.createSheet("生物样本");
}
}
String[] InVivoHeadList = new String[]{"检材类型", "检材编号", "检材名称", "检材性状", "检材质量", "年龄", "性别", "委托单位", "受理日期", "检出结果"};
String[] InVitroHeadList = new String[]{"检材类型", "检材编号", "检材名称", "检材性状", "检材质量", "委托单位", "受理日期", "检出结果"};
String[] headList;
if (entrustType == 0) {
headList = InVitroHeadList;
} else {
headList = InVivoHeadList;
}
Row row = sheet.createRow(0);
for (int i = 0; i < headList.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(headList[i]);
}
for (int i = 0; i < resultData.size(); i++) {
EntrustmentIdentificationMaterialVO vo = resultData.get(i);
Row contentRow = sheet.createRow(i + 1);
contentRow.createCell(0).setCellValue(vo.getOldIdentificationResult());
contentRow.createCell(1).setCellValue(vo.getAcceptNo());
contentRow.createCell(2).setCellValue(vo.getName());
contentRow.createCell(3).setCellValue(vo.getFormName());
contentRow.createCell(4).setCellValue(vo.getQuantity() + vo.getUnit());
if (entrustType == 1) {
contentRow.createCell(5).setCellValue(vo.getMaterialAge());
contentRow.createCell(6).setCellValue(vo.getBiologyGender());
contentRow.createCell(7).setCellValue(vo.getOrgName());
contentRow.createCell(8).setCellValue(vo.getAcceptTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
List<DrugLite> drugLites = vo.getDrugLites();
if (CollUtil.isNotEmpty(drugLites)) {
StringBuilder drugName = new StringBuilder();
for (DrugLite drugLite : drugLites) {
drugName.append(drugLite.getName()).append(",");
}
contentRow.createCell(9).setCellValue(drugName.substring(0, drugName.length() - 1));
} else {
contentRow.createCell(9).setCellValue("");
}
} else {
contentRow.createCell(5).setCellValue(vo.getOrgName());
contentRow.createCell(6).setCellValue(vo.getAcceptTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
List<DrugLite> drugLites = vo.getDrugLites();
if (CollUtil.isNotEmpty(drugLites)) {
StringBuilder drugName = new StringBuilder();
for (DrugLite drugLite : drugLites) {
drugName.append(drugLite.getName()).append(",");
}
contentRow.createCell(7).setCellValue(drugName.substring(0, drugName.length() - 1));
} else {
contentRow.createCell(7).setCellValue("");
}
}
}
Sheet statisticsSheet = workbook.createSheet("统计");
Row statisticsSheetRow = statisticsSheet.createRow(0);
String[] statisticsHeadList = new String[]{"化合物种类", "类型", "检出数量", "总数量", "检出率"};
for (int i = 0; i < statisticsHeadList.length; i++) {
Cell cell = statisticsSheetRow.createCell(i);
cell.setCellValue(statisticsHeadList[i]);
}
Set<String> drugSet = resultDataMap.keySet();
int materialSize = 0;
for (String s : drugSet) {
materialSize += resultDataMap.get(s).size();
}
Map<String, Integer> sizeMap = this.getSizeMap(entrustType, oldResult, startTime, endTime);
System.out.println(sizeMap);
for (String drugName : drugSet) {
List<EntrustmentIdentificationMaterialVO> materialVOList = resultDataMap.get(drugName);
if (StringUtils.isNotBlank(oldResult)) {
Row sheetRow = statisticsSheet.createRow(statisticsSheet.getLastRowNum() + 1);
sheetRow.createCell(0).setCellValue(drugName);
sheetRow.createCell(1).setCellValue(oldResult);
sheetRow.createCell(2).setCellValue(materialVOList.size());
sheetRow.createCell(3).setCellValue(sizeMap.get(oldResult));
sheetRow.createCell(4).setCellValue(String.format("%.2f", materialVOList.size() * 1.0 / sizeMap.get(oldResult) * 100) + "%");
} else {
Map<String, List<EntrustmentIdentificationMaterialVO>> map = materialVOList.stream().collect(Collectors.groupingBy(EntrustmentIdentificationMaterialVO::getOldIdentificationResult));
Set<String> keySet = map.keySet();
for (String key : keySet) {
System.out.println(key);
int size = map.get(key).size();
Row sheetRow = statisticsSheet.createRow(statisticsSheet.getLastRowNum() + 1);
sheetRow.createCell(0).setCellValue(drugName);
sheetRow.createCell(1).setCellValue(key);
sheetRow.createCell(2).setCellValue(size);
sheetRow.createCell(3).setCellValue(Integer.valueOf(sizeMap.get(key)));
sheetRow.createCell(4).setCellValue(String.format("%.2f", size * 1.0 / sizeMap.get(key) * 100) + "%");
}
}
}
for (String drugName : drugSet) {
List<EntrustmentIdentificationMaterialVO> materialVOList = resultDataMap.get(drugName);
String title = drugName.replaceAll("[^\\u4e00-\\u9fa5a-zA-Z0-9]", "");
sheet = workbook.createSheet(title);
Row row0 = sheet.createRow(0);
for (int i = 0; i < headList.length; i++) {
Cell cell = row0.createCell(i);
cell.setCellValue(headList[i]);
}
for (int i = 0; i < materialVOList.size(); i++) {
EntrustmentIdentificationMaterialVO vo = materialVOList.get(i);
Row contentRow = sheet.createRow(i + 1);
contentRow.createCell(0).setCellValue(vo.getOldIdentificationResult());
contentRow.createCell(1).setCellValue(vo.getAcceptNo());
contentRow.createCell(2).setCellValue(vo.getName());
contentRow.createCell(3).setCellValue(vo.getFormName());
contentRow.createCell(4).setCellValue(vo.getQuantity() + vo.getUnit());
if (entrustType == 1) {
contentRow.createCell(5).setCellValue(vo.getMaterialAge());
contentRow.createCell(6).setCellValue(vo.getBiologyGender());
contentRow.createCell(7).setCellValue(vo.getOrgName());
contentRow.createCell(8).setCellValue(vo.getAcceptTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
contentRow.createCell(9).setCellValue(drugName);
} else {
contentRow.createCell(5).setCellValue(vo.getOrgName());
contentRow.createCell(6).setCellValue(vo.getAcceptTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
contentRow.createCell(7).setCellValue(drugName);
}
}
}
workbook.write(response.getOutputStream());
}
public Map<String, Integer> getSizeMap(Integer entrustType, String oldResult, LocalDateTime startTime, LocalDateTime endTime) {
// 构造查询条件,查询 EntrustmentIdentificationMaterial 数据
LambdaQueryWrapper<EntrustmentIdentificationMaterial> qw = new LambdaQueryWrapper<>();
LocalDateTime queryStartTime = Optional.ofNullable(startTime).orElseGet(() -> this.getStartTime(null));
if (endTime != null) {
qw.between(EntrustmentIdentificationMaterial::getAcceptTime, queryStartTime, endTime);
} else {
qw.ge(EntrustmentIdentificationMaterial::getAcceptTime, queryStartTime);
}
// 统计各类委托的数量
int entrustSize = 0;
int preliminaryScreeningSize = 0;
int myanmarRelatedSize = 0;
int voluntaryRehabilitationSize = 0;
// 构造查询条件,查询 Entrustment 数据
LambdaQueryWrapper<Entrustment> wrapper = new LambdaQueryWrapper<>();
if (endTime != null) {
wrapper.between(Entrustment::getAcceptTime, queryStartTime, endTime);
} else {
wrapper.ge(Entrustment::getAcceptTime, queryStartTime);
}
// 查询符合条件的 Entrustment 记录
List<Entrustment> entrusts = entrustmentService.list(wrapper
.eq(Entrustment::getEntrustmentType, entrustType)
.eq(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED.getStatus())
);
// 按照 oldIdentificationResult 进行分组
Map<String, List<Entrustment>> entrustMap = entrusts.stream()
.collect(Collectors.groupingBy(Entrustment::getOldIdentificationResult));
// 遍历分组数据,计算各类 EntrustmentIdentificationMaterial 的数量
for (Map.Entry<String, List<Entrustment>> entry : entrustMap.entrySet()) {
String oldIdentificationResult = entry.getKey();
List<Entrustment> entrustList = entry.getValue();
// 获取 Entrustment ID 列表
List<String> entIdList = entrustList.stream()
.map(Entrustment::getId)
.collect(Collectors.toList());
// 查询与这些 Entrustment 关联的 EntrustmentIdentificationMaterial 数量
int size = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
.in(EntrustmentIdentificationMaterial::getEntrustmentId, entIdList)).size();
// 根据 oldIdentificationResult 分类累加数量
switch (oldIdentificationResult) {
case "初筛":
preliminaryScreeningSize += size;
break;
case "涉缅人员":
myanmarRelatedSize += size;
break;
case "自愿戒治人员":
voluntaryRehabilitationSize += size;
break;
default:
entrustSize += size;
break;
}
}
// 组装返回结果
Map<String, Integer> sizeMap = new HashMap<>();
sizeMap.put("委托", entrustSize);
sizeMap.put("初筛", preliminaryScreeningSize);
sizeMap.put("涉缅人员", myanmarRelatedSize);
sizeMap.put("自愿戒治人员", voluntaryRehabilitationSize);
return sizeMap;
}
} }

@ -1,12 +1,17 @@
package digital.laboratory.platform.entrustment.vo; package digital.laboratory.platform.entrustment.vo;
import digital.laboratory.platform.entrustment.entity.EntrustmentIdentificationMaterial; import digital.laboratory.platform.entrustment.entity.EntrustmentIdentificationMaterial;
import digital.laboratory.platform.sys.entity.DrugLite;
import lombok.Data; import lombok.Data;
import java.util.List;
@Data @Data
public class EntrustmentIdentificationMaterialVO extends EntrustmentIdentificationMaterial { public class EntrustmentIdentificationMaterialVO extends EntrustmentIdentificationMaterial {
String formName; // 检材性状 String formName; // 检材性状
String sample1Type; // 样本1的类型:A/B, 根据盒子的 sampleType 而得 String sample1Type; // 样本1的类型:A/B, 根据盒子的 sampleType 而得
String sample2Type; // 样本2的类型:A/B, 根据盒子的 sampleType 而得 String sample2Type; // 样本2的类型:A/B, 根据盒子的 sampleType 而得
List<DrugLite> drugLites;
String oldIdentificationResult;
String orgName;// 原鉴定情况 用来区分是初筛还是委托 或者其他。。。
} }

Loading…
Cancel
Save