|
|
|
@ -8,15 +8,18 @@ import com.baomidou.mybatisplus.core.metadata.IPage; |
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils; |
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
|
|
|
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; |
|
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|
|
|
|
import digital.laboratory.platform.common.core.exception.CheckedException; |
|
|
|
|
import digital.laboratory.platform.common.core.util.R; |
|
|
|
|
import digital.laboratory.platform.common.mybatis.security.service.DLPUser; |
|
|
|
|
import digital.laboratory.platform.common.oss.service.OssFile; |
|
|
|
|
import digital.laboratory.platform.entrustment.convert.DrugLiteConvert; |
|
|
|
|
import digital.laboratory.platform.entrustment.convert.EntrustMaterialCheckoutResultConvert; |
|
|
|
|
import digital.laboratory.platform.entrustment.dto.CheckoutResultExcelDTO; |
|
|
|
|
import digital.laboratory.platform.entrustment.dto.EntrustMaterialCheckoutResultDTO; |
|
|
|
|
import digital.laboratory.platform.entrustment.dto.GenerateQuarterlyReportDTO; |
|
|
|
|
import digital.laboratory.platform.entrustment.dto.ResultExcelDTO; |
|
|
|
|
import digital.laboratory.platform.entrustment.entity.*; |
|
|
|
|
import digital.laboratory.platform.entrustment.enums.EntrustStatusConstants; |
|
|
|
@ -30,10 +33,9 @@ import digital.laboratory.platform.entrustment.vo.EntrustmentIdentificationMater |
|
|
|
|
import digital.laboratory.platform.entrustment.vo.SuspectDetectionVO; |
|
|
|
|
import digital.laboratory.platform.sys.entity.Area; |
|
|
|
|
import digital.laboratory.platform.sys.entity.DrugLite; |
|
|
|
|
import org.apache.poi.ss.usermodel.Row; |
|
|
|
|
import org.apache.poi.ss.usermodel.Sheet; |
|
|
|
|
import org.apache.poi.ss.usermodel.Workbook; |
|
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|
|
|
|
import org.apache.poi.ss.usermodel.*; |
|
|
|
|
import org.apache.poi.ss.util.CellRangeAddress; |
|
|
|
|
import org.apache.poi.xssf.usermodel.*; |
|
|
|
|
import org.springframework.beans.BeanUtils; |
|
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
|
@ -44,8 +46,12 @@ import java.math.BigDecimal; |
|
|
|
|
import java.math.RoundingMode; |
|
|
|
|
import java.net.URLEncoder; |
|
|
|
|
import java.sql.*; |
|
|
|
|
import java.time.LocalDate; |
|
|
|
|
import java.time.LocalDateTime; |
|
|
|
|
import java.time.LocalTime; |
|
|
|
|
import java.time.Month; |
|
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
|
import java.time.temporal.TemporalAdjusters; |
|
|
|
|
import java.util.*; |
|
|
|
|
import java.util.function.Function; |
|
|
|
|
import java.util.stream.Collectors; |
|
|
|
@ -77,6 +83,9 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
@Resource |
|
|
|
|
private CaseEventService caseEventService; |
|
|
|
|
|
|
|
|
|
@Resource |
|
|
|
|
private OssFile ossFile; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 构建委托材料检验结果字符串 |
|
|
|
|
* |
|
|
|
@ -642,6 +651,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
LocalDateTime endTime = excelDTO.getEndTime(); |
|
|
|
|
List<String> oldResults = excelDTO.getOldResult(); |
|
|
|
|
Integer entrustType = excelDTO.getEntrustType(); |
|
|
|
|
boolean metabolite = excelDTO.isMetabolite(); |
|
|
|
|
try { |
|
|
|
|
// 1. 构建查询条件
|
|
|
|
|
LambdaQueryWrapper<Entrustment> qw = new LambdaQueryWrapper<>(); |
|
|
|
@ -1047,8 +1057,8 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
.isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult) |
|
|
|
|
.list(); |
|
|
|
|
|
|
|
|
|
if (CollectionUtils.isEmpty(results)){ |
|
|
|
|
throw new IllegalArgumentException("没有阳性的检验结果:" + entrustmentId+",无需进行推送!"); |
|
|
|
|
if (CollectionUtils.isEmpty(results)) { |
|
|
|
|
throw new IllegalArgumentException("没有阳性的检验结果:" + entrustmentId + ",无需进行推送!"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 获取嫌疑人信息
|
|
|
|
@ -1056,8 +1066,8 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
.eq(Suspect::getEntrustId, entrustmentId) |
|
|
|
|
.list(); |
|
|
|
|
|
|
|
|
|
if (CollectionUtils.isEmpty(suspects)){ |
|
|
|
|
throw new IllegalArgumentException("未找到嫌疑人信息:" + entrustmentId+",请先添加嫌疑人信息!"); |
|
|
|
|
if (CollectionUtils.isEmpty(suspects)) { |
|
|
|
|
throw new IllegalArgumentException("未找到嫌疑人信息:" + entrustmentId + ",请先添加嫌疑人信息!"); |
|
|
|
|
} |
|
|
|
|
// 构造物证材料映射
|
|
|
|
|
Map<String, EntrustmentIdentificationMaterial> materialMap = entrustmentIdentificationMaterialService.lambdaQuery() |
|
|
|
@ -1092,7 +1102,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
vo.setAcceptNo(material.getAcceptNo()); |
|
|
|
|
} |
|
|
|
|
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); |
|
|
|
|
System.out.println("结果的毒品列表:"+result.getQualitativeResult()); |
|
|
|
|
System.out.println("结果的毒品列表:" + result.getQualitativeResult()); |
|
|
|
|
|
|
|
|
|
vo.setQualitativeResult( |
|
|
|
|
DrugLiteConvert.getDrugLites(result.getQualitativeResult()) |
|
|
|
@ -1194,6 +1204,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
entrustment.setPlatformFlag(true); |
|
|
|
|
entrustmentService.updateById(entrustment); |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -1217,8 +1228,8 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
List<Entrustment> entrusts = entrustmentService.lambdaQuery() |
|
|
|
|
.in(Entrustment::getId, entrustSet) |
|
|
|
|
.ge(Entrustment::getStatus, EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()) // status >= 9
|
|
|
|
|
.and(qw ->qw |
|
|
|
|
.eq(Entrustment::getPlatformFlag,false) |
|
|
|
|
.and(qw -> qw |
|
|
|
|
.eq(Entrustment::getPlatformFlag, false) |
|
|
|
|
.or() |
|
|
|
|
.isNull(Entrustment::getPlatformFlag)) |
|
|
|
|
.list(); |
|
|
|
@ -1228,7 +1239,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
.map(Entrustment::getId) |
|
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
|
|
|
|
|
// 查询案件信息,并构造以案件ID为键的映射
|
|
|
|
|
// 查询案件信息,并构造以案件ID为键 的映射
|
|
|
|
|
Map<String, CaseEvent> caseMap = caseEventService.lambdaQuery() |
|
|
|
|
.in(CaseEvent::getId, entrusts.stream().map(Entrustment::getCaseId).collect(Collectors.toList())) |
|
|
|
|
.list() |
|
|
|
@ -1258,7 +1269,7 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
.stream() |
|
|
|
|
.collect(Collectors.toMap(EntrustmentIdentificationMaterial::getId, Function.identity())); |
|
|
|
|
|
|
|
|
|
if (materialMap.isEmpty()){ |
|
|
|
|
if (materialMap.isEmpty()) { |
|
|
|
|
return R.failed("未查询到有检材信息!"); |
|
|
|
|
} |
|
|
|
|
// 构造结果VO列表
|
|
|
|
@ -1284,10 +1295,487 @@ public class EntrustMaterialCheckoutResultServiceImpl extends ServiceImpl<Entrus |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return R.ok("推送成功"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 生成指定年份和季度列表的季度统计数据 |
|
|
|
|
* |
|
|
|
|
* @param year 统计年份 |
|
|
|
|
* @param quarterlyList 季度列表(1~4) |
|
|
|
|
* @return Map,key为季度号,value为该季度对应的统计数据 |
|
|
|
|
*/ |
|
|
|
|
public HashMap<Integer, Map<String, List<Integer>>> generateQuarterlyReportData(int year, List<Integer> quarterlyList) { |
|
|
|
|
// 先对季度排序,保证顺序一致
|
|
|
|
|
quarterlyList.sort(Comparator.naturalOrder()); |
|
|
|
|
|
|
|
|
|
HashMap<Integer, Map<String, List<Integer>>> resultMap = new HashMap<>(); |
|
|
|
|
|
|
|
|
|
for (Integer quarter : quarterlyList) { |
|
|
|
|
// 计算季度起止时间
|
|
|
|
|
LocalDateTime startDateTime = getQuarterStartDateTime(year, quarter); |
|
|
|
|
LocalDateTime endDateTime = getQuarterEndDateTime(year, quarter); |
|
|
|
|
|
|
|
|
|
System.out.println("开始时间:" + startDateTime); |
|
|
|
|
System.out.println("结束时间:" + endDateTime); |
|
|
|
|
|
|
|
|
|
// 获取该季度所有委托数据(首次鉴定、补充鉴定、重新鉴定)
|
|
|
|
|
List<Entrustment> entrusts = queryEntrustments(startDateTime, endDateTime, 0, |
|
|
|
|
Arrays.asList("首次鉴定", "补充鉴定", "重新鉴定")); |
|
|
|
|
|
|
|
|
|
if (entrusts == null || entrusts.isEmpty()) { |
|
|
|
|
// 如果无委托则跳过该季度
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 统计该季度普通材料检测情况
|
|
|
|
|
Map<String, List<Integer>> quarterMap = calculateMaterialStats(entrusts); |
|
|
|
|
|
|
|
|
|
// 统计生物样本检测情况(委托类型为1)
|
|
|
|
|
List<Entrustment> inVivoEntrusts = queryEntrustments(startDateTime, endDateTime, 1, null); |
|
|
|
|
if (inVivoEntrusts != null && !inVivoEntrusts.isEmpty()) { |
|
|
|
|
quarterMap.put("生物样本", calculateEntrustmentStats(inVivoEntrusts)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 统计初筛检测情况(委托类型0,鉴定结果为“初筛”)
|
|
|
|
|
List<Entrustment> initialScreeningEntrusts = queryEntrustments(startDateTime, endDateTime, 0, Collections.singletonList("初筛")); |
|
|
|
|
if (initialScreeningEntrusts != null && !initialScreeningEntrusts.isEmpty()) { |
|
|
|
|
quarterMap.put("初筛", calculateEntrustmentStats(initialScreeningEntrusts)); |
|
|
|
|
} |
|
|
|
|
List<Entrustment> entrustments = entrustmentService.lambdaQuery() |
|
|
|
|
.between(Entrustment::getAcceptTime, startDateTime, endDateTime) |
|
|
|
|
.ge(Entrustment::getStatus, EntrustStatusConstants.ENTRUST_STATUS_WAITING_CHECK_CLAIM.getStatus()) |
|
|
|
|
.orderByAsc(Entrustment::getAcceptTime) |
|
|
|
|
.list(); |
|
|
|
|
ArrayList<Integer> integers = new ArrayList<>(); |
|
|
|
|
integers.add(Integer.valueOf(entrustments.get(0).getAcceptNo().split("-")[1])); |
|
|
|
|
integers.add(Integer.valueOf(entrustments.get(entrustments.size() - 1).getAcceptNo().split("-")[1])); |
|
|
|
|
quarterMap.put("entrustCount", integers); |
|
|
|
|
resultMap.put(quarter, quarterMap); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
System.out.println(resultMap); |
|
|
|
|
return resultMap; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 获取指定年份季度开始时间 |
|
|
|
|
*/ |
|
|
|
|
private LocalDateTime getQuarterStartDateTime(int year, int quarter) { |
|
|
|
|
Month startMonth = Month.of((quarter - 1) * 3 + 1); |
|
|
|
|
return LocalDateTime.of(LocalDate.of(year, startMonth, 1), LocalTime.MIN); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 获取指定年份季度结束时间 |
|
|
|
|
*/ |
|
|
|
|
private LocalDateTime getQuarterEndDateTime(int year, int quarter) { |
|
|
|
|
Month startMonth = Month.of((quarter - 1) * 3 + 1); |
|
|
|
|
Month endMonth = startMonth.plus(2); |
|
|
|
|
LocalDate endDate = LocalDate.of(year, endMonth, 1).with(TemporalAdjusters.lastDayOfMonth()); |
|
|
|
|
return LocalDateTime.of(endDate, LocalTime.MAX); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 根据条件查询委托 |
|
|
|
|
* |
|
|
|
|
* @param start 开始时间(包含) |
|
|
|
|
* @param end 结束时间(包含) |
|
|
|
|
* @param entrustmentType 委托类型,0或1 |
|
|
|
|
* @param oldIdentificationResults 鉴定结果列表,null表示不筛选此条件 |
|
|
|
|
* @return 符合条件的委托列表 |
|
|
|
|
*/ |
|
|
|
|
private List<Entrustment> queryEntrustments(LocalDateTime start, LocalDateTime end, int entrustmentType, List<String> oldIdentificationResults) { |
|
|
|
|
LambdaQueryChainWrapper<Entrustment> query = entrustmentService.lambdaQuery() |
|
|
|
|
.between(Entrustment::getAcceptTime, start, end) |
|
|
|
|
.ge(Entrustment::getStatus, EntrustStatusConstants.ENTRUST_STATUS_ACCEPTED.getStatus()) |
|
|
|
|
.eq(Entrustment::getEntrustmentType, entrustmentType); |
|
|
|
|
|
|
|
|
|
if (oldIdentificationResults != null && !oldIdentificationResults.isEmpty()) { |
|
|
|
|
query.in(Entrustment::getOldIdentificationResult, oldIdentificationResults); |
|
|
|
|
} |
|
|
|
|
return query.list(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 根据委托列表,计算普通材料的统计数据 |
|
|
|
|
* |
|
|
|
|
* @param entrusts 委托列表 |
|
|
|
|
* @return key为药品名称字符串,value为对应统计值列表(案件总数、检出数、未检出数等) |
|
|
|
|
*/ |
|
|
|
|
private Map<String, List<Integer>> calculateMaterialStats(List<Entrustment> entrusts) { |
|
|
|
|
Map<String, List<Integer>> quarterMap = new HashMap<>(); |
|
|
|
|
|
|
|
|
|
if (entrusts == null || entrusts.isEmpty()) return quarterMap; |
|
|
|
|
|
|
|
|
|
// 获取所有委托ID
|
|
|
|
|
Set<String> entrustIds = entrusts.stream() |
|
|
|
|
.map(Entrustment::getId) |
|
|
|
|
.collect(Collectors.toSet()); |
|
|
|
|
|
|
|
|
|
if (entrustIds.isEmpty()) return quarterMap; |
|
|
|
|
|
|
|
|
|
// 查询材料列表
|
|
|
|
|
List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.lambdaQuery() |
|
|
|
|
.in(EntrustmentIdentificationMaterial::getEntrustmentId, entrustIds) |
|
|
|
|
.list(); |
|
|
|
|
if (materialList == null || materialList.isEmpty()) return quarterMap; |
|
|
|
|
|
|
|
|
|
// 获取材料ID集合
|
|
|
|
|
Set<String> materialIds = materialList.stream() |
|
|
|
|
.map(EntrustmentIdentificationMaterial::getId) |
|
|
|
|
.collect(Collectors.toSet()); |
|
|
|
|
if (materialIds.isEmpty()) return quarterMap; |
|
|
|
|
|
|
|
|
|
// 查询检测结果列表,排除空或null结果
|
|
|
|
|
List<EntrustMaterialCheckoutResult> resultList = this.lambdaQuery() |
|
|
|
|
.in(EntrustMaterialCheckoutResult::getId, materialIds) |
|
|
|
|
.notLike(EntrustMaterialCheckoutResult::getQualitativeResult, "null") |
|
|
|
|
.isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult) |
|
|
|
|
.list(); |
|
|
|
|
|
|
|
|
|
if (resultList == null) resultList = Collections.emptyList(); |
|
|
|
|
|
|
|
|
|
// 按材料ID分组检测结果,方便判断是否检测
|
|
|
|
|
Map<String, List<EntrustMaterialCheckoutResult>> resultMap = resultList.stream() |
|
|
|
|
.collect(Collectors.groupingBy(EntrustMaterialCheckoutResult::getId)); |
|
|
|
|
|
|
|
|
|
// 按候选药品名称分组材料(名称排序后拼接)
|
|
|
|
|
Map<String, List<EntrustmentIdentificationMaterial>> drugGroupMap = materialList.stream() |
|
|
|
|
.collect(Collectors.groupingBy(item -> { |
|
|
|
|
List<String> drugNames = DrugLiteConvert.convertDirtyLiteByJSON(item.getCandidateDrugs()) |
|
|
|
|
.stream() |
|
|
|
|
.map(DrugLite::getName) |
|
|
|
|
.sorted() |
|
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
return String.join("、", drugNames); |
|
|
|
|
})); |
|
|
|
|
|
|
|
|
|
// 遍历药品分组,统计数据
|
|
|
|
|
for (Map.Entry<String, List<EntrustmentIdentificationMaterial>> entry : drugGroupMap.entrySet()) { |
|
|
|
|
String drugNames = entry.getKey(); |
|
|
|
|
List<EntrustmentIdentificationMaterial> drugMaterials = entry.getValue(); |
|
|
|
|
|
|
|
|
|
// 按委托ID分组材料
|
|
|
|
|
Map<String, List<EntrustmentIdentificationMaterial>> entrustToMaterials = drugMaterials.stream() |
|
|
|
|
.collect(Collectors.groupingBy(EntrustmentIdentificationMaterial::getEntrustmentId)); |
|
|
|
|
|
|
|
|
|
int caseCount = entrustToMaterials.size(); // 案件总数
|
|
|
|
|
int checked = 0, notChecked = 0, partChecked = 0, materialCount = drugMaterials.size(), resultCount = 0; |
|
|
|
|
|
|
|
|
|
// 遍历每个委托的材料,判断检测情况
|
|
|
|
|
for (Map.Entry<String, List<EntrustmentIdentificationMaterial>> e : entrustToMaterials.entrySet()) { |
|
|
|
|
List<EntrustmentIdentificationMaterial> materials = e.getValue(); |
|
|
|
|
int mCount = materials.size(); |
|
|
|
|
|
|
|
|
|
// 材料中有检测结果的数量
|
|
|
|
|
int rCount = (int) materials.stream() |
|
|
|
|
.filter(m -> resultMap.containsKey(m.getId())) |
|
|
|
|
.count(); |
|
|
|
|
|
|
|
|
|
resultCount += rCount; |
|
|
|
|
|
|
|
|
|
if (rCount == 0) { |
|
|
|
|
notChecked++; |
|
|
|
|
} else if (rCount == mCount) { |
|
|
|
|
checked++; |
|
|
|
|
} else { |
|
|
|
|
partChecked++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int materialNotChecked = materialCount - resultCount; |
|
|
|
|
|
|
|
|
|
// 按顺序添加统计值
|
|
|
|
|
ArrayList<Integer> integers = new ArrayList<>(); |
|
|
|
|
integers.add(caseCount); // 案件总数
|
|
|
|
|
integers.add(checked); // 检出数(案件数)
|
|
|
|
|
integers.add(notChecked); // 未检出数(案件数)
|
|
|
|
|
integers.add(partChecked); // 部分检出数(案件数)
|
|
|
|
|
integers.add(materialCount); // 材料总数
|
|
|
|
|
integers.add(resultCount); // 材料检出数
|
|
|
|
|
integers.add(materialNotChecked);// 材料未检出数
|
|
|
|
|
|
|
|
|
|
quarterMap.put(drugNames, integers); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return quarterMap; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 根据委托列表计算生物样本或初筛的统计数据 |
|
|
|
|
* 该统计逻辑和材料统计类似,但针对委托整体 |
|
|
|
|
* |
|
|
|
|
* @param entrusts 委托列表 |
|
|
|
|
* @return 统计数据列表,顺序同材料统计 |
|
|
|
|
*/ |
|
|
|
|
private List<Integer> calculateEntrustmentStats(List<Entrustment> entrusts) { |
|
|
|
|
if (entrusts == null || entrusts.isEmpty()) return Collections.emptyList(); |
|
|
|
|
|
|
|
|
|
Set<String> entrustIds = entrusts.stream() |
|
|
|
|
.map(Entrustment::getId) |
|
|
|
|
.collect(Collectors.toSet()); |
|
|
|
|
|
|
|
|
|
if (entrustIds.isEmpty()) return Collections.emptyList(); |
|
|
|
|
|
|
|
|
|
// 查询所有相关材料
|
|
|
|
|
List<EntrustmentIdentificationMaterial> materials = entrustmentIdentificationMaterialService.lambdaQuery() |
|
|
|
|
.in(EntrustmentIdentificationMaterial::getEntrustmentId, entrustIds) |
|
|
|
|
.list(); |
|
|
|
|
if (materials == null) materials = Collections.emptyList(); |
|
|
|
|
|
|
|
|
|
Set<String> materialIds = materials.stream() |
|
|
|
|
.map(EntrustmentIdentificationMaterial::getId) |
|
|
|
|
.collect(Collectors.toSet()); |
|
|
|
|
|
|
|
|
|
if (materialIds.isEmpty()) return Collections.emptyList(); |
|
|
|
|
|
|
|
|
|
// 查询所有检测结果
|
|
|
|
|
List<EntrustMaterialCheckoutResult> results = this.lambdaQuery() |
|
|
|
|
.in(EntrustMaterialCheckoutResult::getId, materialIds) |
|
|
|
|
.notLike(EntrustMaterialCheckoutResult::getQualitativeResult, "null") |
|
|
|
|
.isNotNull(EntrustMaterialCheckoutResult::getQualitativeResult) |
|
|
|
|
.list(); |
|
|
|
|
|
|
|
|
|
if (results == null) results = Collections.emptyList(); |
|
|
|
|
|
|
|
|
|
// 按材料ID分组结果
|
|
|
|
|
Map<String, List<EntrustMaterialCheckoutResult>> resultMap = results.stream() |
|
|
|
|
.collect(Collectors.groupingBy(EntrustMaterialCheckoutResult::getId)); |
|
|
|
|
|
|
|
|
|
int caseCount = entrusts.size(); |
|
|
|
|
int materialCount = materials.size(); |
|
|
|
|
int resultCount = results.size(); |
|
|
|
|
|
|
|
|
|
int checked = 0, notChecked = 0, partChecked = 0; |
|
|
|
|
|
|
|
|
|
// 按委托ID分组材料,判断检测状态
|
|
|
|
|
Map<String, List<EntrustmentIdentificationMaterial>> entrustToMaterials = materials.stream() |
|
|
|
|
.collect(Collectors.groupingBy(EntrustmentIdentificationMaterial::getEntrustmentId)); |
|
|
|
|
|
|
|
|
|
for (List<EntrustmentIdentificationMaterial> matList : entrustToMaterials.values()) { |
|
|
|
|
int totalM = matList.size(); |
|
|
|
|
int detected = (int) matList.stream() |
|
|
|
|
.filter(m -> resultMap.containsKey(m.getId())) |
|
|
|
|
.count(); |
|
|
|
|
|
|
|
|
|
if (detected == 0) notChecked++; |
|
|
|
|
else if (detected == totalM) checked++; |
|
|
|
|
else partChecked++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ArrayList<Integer> statistics = new ArrayList<>(); |
|
|
|
|
statistics.add(caseCount); // 案件总数
|
|
|
|
|
statistics.add(checked); // 检出数(案件数)
|
|
|
|
|
statistics.add(notChecked); // 未检出数(案件数)
|
|
|
|
|
statistics.add(partChecked); // 部分检出数(案件数)
|
|
|
|
|
statistics.add(materialCount); // 材料总数
|
|
|
|
|
statistics.add(resultCount); // 材料检出数
|
|
|
|
|
statistics.add(materialCount - resultCount);// 材料未检出数
|
|
|
|
|
|
|
|
|
|
return statistics; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
public void generateQuarterlyReportExcel(GenerateQuarterlyReportDTO dto, HttpServletResponse response) throws IOException { |
|
|
|
|
HashMap<Integer, Map<String, List<Integer>>> map = this.generateQuarterlyReportData(dto.getYear(), dto.getQuarterlyList()); |
|
|
|
|
XSSFWorkbook workbook = new XSSFWorkbook(); |
|
|
|
|
Set<Integer> quarterlySet = map.keySet(); |
|
|
|
|
quarterlySet.stream().sorted(new Comparator<Integer>() { |
|
|
|
|
@Override |
|
|
|
|
public int compare(Integer o1, Integer o2) { |
|
|
|
|
return o1 - o2; |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
for (Integer quarterly : quarterlySet) { |
|
|
|
|
this.generateQuarterlyReportSheet(workbook, dto.getYear(), quarterly, map.get(quarterly)); |
|
|
|
|
} |
|
|
|
|
workbook.write(response.getOutputStream()); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void generateQuarterlyReportSheet(XSSFWorkbook workbook, Integer year, Integer quarterly, Map<String, List<Integer>> map) { |
|
|
|
|
String quarterlyName = ""; |
|
|
|
|
switch (quarterly) { |
|
|
|
|
case 1: |
|
|
|
|
quarterlyName = "一"; |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
quarterlyName = "二"; |
|
|
|
|
break; |
|
|
|
|
case 3: |
|
|
|
|
quarterlyName = "三"; |
|
|
|
|
break; |
|
|
|
|
case 4: |
|
|
|
|
quarterlyName = "四"; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
XSSFSheet sheet = workbook.createSheet(year + "年第" + quarterlyName + "季度统计"); |
|
|
|
|
int rowIndex = 0; |
|
|
|
|
|
|
|
|
|
// 表头样式(大号黑色字体,居中)
|
|
|
|
|
XSSFCellStyle headStyle = workbook.createCellStyle(); |
|
|
|
|
headStyle.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
|
headStyle.setVerticalAlignment(VerticalAlignment.CENTER); |
|
|
|
|
XSSFFont headFont = workbook.createFont(); |
|
|
|
|
headFont.setFontHeightInPoints((short) 16); |
|
|
|
|
headFont.setFontName("宋体"); |
|
|
|
|
headFont.setColor(IndexedColors.BLACK.getIndex()); |
|
|
|
|
headStyle.setFont(headFont); |
|
|
|
|
|
|
|
|
|
// 创建边框居中样式基础
|
|
|
|
|
XSSFCellStyle baseStyle = workbook.createCellStyle(); |
|
|
|
|
baseStyle.setAlignment(HorizontalAlignment.CENTER); |
|
|
|
|
baseStyle.setVerticalAlignment(VerticalAlignment.CENTER); |
|
|
|
|
baseStyle.setBorderTop(BorderStyle.THIN); |
|
|
|
|
baseStyle.setBorderBottom(BorderStyle.THIN); |
|
|
|
|
baseStyle.setBorderLeft(BorderStyle.THIN); |
|
|
|
|
baseStyle.setBorderRight(BorderStyle.THIN); |
|
|
|
|
baseStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); |
|
|
|
|
baseStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); |
|
|
|
|
baseStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); |
|
|
|
|
baseStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); |
|
|
|
|
|
|
|
|
|
// 黑色字体样式
|
|
|
|
|
XSSFCellStyle blackStyle = workbook.createCellStyle(); |
|
|
|
|
blackStyle.cloneStyleFrom(baseStyle); |
|
|
|
|
XSSFFont blackFont = workbook.createFont(); |
|
|
|
|
blackFont.setFontHeightInPoints((short) 12); |
|
|
|
|
blackFont.setFontName("宋体"); |
|
|
|
|
blackFont.setColor(IndexedColors.BLACK.getIndex()); |
|
|
|
|
blackStyle.setFont(blackFont); |
|
|
|
|
|
|
|
|
|
// 红色字体样式
|
|
|
|
|
XSSFCellStyle redStyle = workbook.createCellStyle(); |
|
|
|
|
redStyle.cloneStyleFrom(baseStyle); |
|
|
|
|
XSSFFont redFont = workbook.createFont(); |
|
|
|
|
redFont.setFontHeightInPoints((short) 12); |
|
|
|
|
redFont.setFontName("宋体"); |
|
|
|
|
redFont.setColor(IndexedColors.RED.getIndex()); |
|
|
|
|
redStyle.setFont(redFont); |
|
|
|
|
|
|
|
|
|
List<Integer> integers = map.get("entrustCount"); |
|
|
|
|
|
|
|
|
|
String entrustCount = year + "年" + integers.get(0) + "-" + integers.get(1) + "号种类"; |
|
|
|
|
String[] nameRows = {entrustCount, "案件送检登记数", "案件检出数", "案件未检出数", "案件检出及未检出数", "检材送检登记数", "检材检出数", "检材未检出数"}; |
|
|
|
|
map.remove("entrustCount"); |
|
|
|
|
|
|
|
|
|
int[] wides = {25, 16, 12, 12, 19, 15, 12, 13}; |
|
|
|
|
|
|
|
|
|
// 第一行(合并单元格)
|
|
|
|
|
XSSFRow headRow = sheet.createRow(rowIndex); |
|
|
|
|
headRow.setHeight((short) (20.25 * 20)); |
|
|
|
|
Cell headCell = headRow.createCell(0); |
|
|
|
|
headCell.setCellValue(year + "年第" + quarterlyName + "季度"); |
|
|
|
|
headCell.setCellStyle(headStyle); |
|
|
|
|
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, nameRows.length - 1)); |
|
|
|
|
|
|
|
|
|
// 第二行 表头列名
|
|
|
|
|
XSSFRow nameRow = sheet.createRow(rowIndex + 1); |
|
|
|
|
nameRow.setHeight((short) (14.25 * 20)); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < nameRows.length; i++) { |
|
|
|
|
sheet.setColumnWidth(i, wides[i] * 256); |
|
|
|
|
Cell cell = nameRow.createCell(i); |
|
|
|
|
cell.setCellValue(nameRows[i]); |
|
|
|
|
// 第1列(索引1)和第5列(索引5)用红色字体样式,其他用黑色
|
|
|
|
|
if (i == 1 || i == 5) { |
|
|
|
|
cell.setCellStyle(redStyle); |
|
|
|
|
} else { |
|
|
|
|
cell.setCellStyle(blackStyle); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 第三行 空白行
|
|
|
|
|
XSSFRow gapRow = sheet.createRow(rowIndex + 2); |
|
|
|
|
gapRow.setHeight((short) (14.25 * 20)); |
|
|
|
|
for (int i = 0; i < nameRows.length; i++) { |
|
|
|
|
Cell cell = gapRow.createCell(i); |
|
|
|
|
cell.setCellStyle(blackStyle); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rowIndex = 3; |
|
|
|
|
|
|
|
|
|
// 拆分 entry 顺序
|
|
|
|
|
List<Map.Entry<String, List<Integer>>> normalEntries = new ArrayList<>(); |
|
|
|
|
List<Map.Entry<String, List<Integer>>> specialEntries = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, List<Integer>> entry : map.entrySet()) { |
|
|
|
|
String key = entry.getKey(); |
|
|
|
|
if ("生物样本".equals(key) || "初筛".equals(key)) { |
|
|
|
|
specialEntries.add(entry); |
|
|
|
|
} else { |
|
|
|
|
normalEntries.add(entry); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 合并成最终顺序:普通的在前,特殊的在后
|
|
|
|
|
List<Map.Entry<String, List<Integer>>> orderedEntries = new ArrayList<>(); |
|
|
|
|
orderedEntries.addAll(normalEntries); |
|
|
|
|
orderedEntries.addAll(specialEntries); |
|
|
|
|
|
|
|
|
|
Integer va1 = 0, va2 = 0, va3 = 0, va4 = 0, va5 = 0, va6 = 0, va7 = 0; |
|
|
|
|
Integer[] ints = {va1, va2, va3, va4, va5, va6, va7}; |
|
|
|
|
|
|
|
|
|
for (Map.Entry<String, List<Integer>> entry : orderedEntries) { |
|
|
|
|
XSSFRow dataRow = sheet.createRow(rowIndex); |
|
|
|
|
dataRow.setHeight((short) (14.25 * 20)); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < nameRows.length; i++) { |
|
|
|
|
Cell cell = dataRow.createCell(i); |
|
|
|
|
|
|
|
|
|
if (i == 0) { |
|
|
|
|
cell.setCellValue(entry.getKey()); |
|
|
|
|
} else { |
|
|
|
|
Integer val = entry.getValue().get(i - 1); |
|
|
|
|
if (val != null && val != 0) { |
|
|
|
|
cell.setCellValue(val); |
|
|
|
|
ints[i-1] += entry.getValue().get(i - 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (i == 1 || i == 5) { |
|
|
|
|
cell.setCellStyle(redStyle); |
|
|
|
|
} else { |
|
|
|
|
cell.setCellStyle(blackStyle); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 空白行
|
|
|
|
|
XSSFRow emptyRow = sheet.createRow(rowIndex + 1); |
|
|
|
|
emptyRow.setHeight((short) (14.25 * 20)); |
|
|
|
|
for (int i = 0; i < nameRows.length; i++) { |
|
|
|
|
Cell cell = emptyRow.createCell(i); |
|
|
|
|
cell.setCellStyle(blackStyle); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rowIndex += 2; |
|
|
|
|
} |
|
|
|
|
XSSFRow lastRow = sheet.createRow(rowIndex-1); |
|
|
|
|
lastRow.setHeight((short) (14.25 * 20)); |
|
|
|
|
for (int i = 0; i < nameRows.length; i++) { |
|
|
|
|
if (i == 0){ |
|
|
|
|
Cell cell = lastRow.createCell(i); |
|
|
|
|
cell.setCellStyle(blackStyle); |
|
|
|
|
} |
|
|
|
|
if (i != 0) { |
|
|
|
|
Cell cell = lastRow.createCell(i); |
|
|
|
|
cell.setCellValue(ints[i - 1]); |
|
|
|
|
if (i == 1 || i == 5) { |
|
|
|
|
cell.setCellStyle(redStyle); |
|
|
|
|
} else { |
|
|
|
|
cell.setCellStyle(blackStyle); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|