20250220 更新

1.毒品统计饼图接口实现
master
陈江保 2 days ago
parent 7ec5b615cc
commit 0b9c724c73
  1. 13
      src/main/java/digital/laboratory/platform/imr/controller/DrugHandingOverStatisticController.java
  2. 43
      src/main/java/digital/laboratory/platform/imr/convert/DrugLiteConvert.java
  3. 10
      src/main/java/digital/laboratory/platform/imr/service/DrugHandingOverStatisticService.java
  4. 4
      src/main/java/digital/laboratory/platform/imr/service/impl/CommonFeignServiceImpl.java
  5. 88
      src/main/java/digital/laboratory/platform/imr/service/impl/DrugHandingOverStatisticServiceImpl.java
  6. 2
      src/main/resources/mapper/DrugMaterialInfoMapper.xml

@ -5,14 +5,13 @@ import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.imr.query.DrugStatisticQuery;
import digital.laboratory.platform.imr.service.DrugHandingOverStatisticService;
import digital.laboratory.platform.imr.vo.DrugStatisticVO;
import digital.laboratory.platform.sys.entity.DrugLite;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/drugStatistic")
@ -29,4 +28,10 @@ public class DrugHandingOverStatisticController {
return R.ok(vo);
}
@ApiOperation("获取统计图中可以根据毒品进行分类统计的选项")
@GetMapping("/getDrugNameList")
public R getDrugNameList() {
List<DrugLite> list = drugHandingOverStatisticService.getDrugNameList();
return R.ok(list);
}
}

@ -0,0 +1,43 @@
package digital.laboratory.platform.imr.convert;
import com.alibaba.fastjson.JSONArray;
import digital.laboratory.platform.sys.entity.DrugLite;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* 毒品概要实体 转换类
*
*/
public class DrugLiteConvert {
/**
* 因为从数据库取出来的字段属性实际是一个JSONObject数组没有对应的getset方法所以需要转换
* @param drugLitesJson
* @return
*/
public static List<DrugLite> convertDirtyLiteByJSON(List<DrugLite> drugLitesJson) {
if (drugLitesJson == null) {
return Collections.emptyList();
}
String drugToString = JSONArray.toJSONString(drugLitesJson);
List<DrugLite> drugLiteList = JSONArray.parseArray(drugToString, DrugLite.class).stream().sorted(Comparator.comparing(DrugLite::getName)).collect(Collectors.toList());;
return drugLiteList;
}
/**
* 将药物列表名称连接成字符串
*
* @param drugLitesJson 药物列表JSON格式
* @param delimiter 分隔符
* @return 连接后的字符串
*/
public static String joiningDrugListNameToStr(List<DrugLite> drugLitesJson, String delimiter) {
return convertDirtyLiteByJSON(drugLitesJson)
.stream()
.map(DrugLite::getName)
.collect(Collectors.joining(delimiter));
}
}

@ -2,6 +2,9 @@ package digital.laboratory.platform.imr.service;
import digital.laboratory.platform.imr.query.DrugStatisticQuery;
import digital.laboratory.platform.imr.vo.DrugStatisticVO;
import digital.laboratory.platform.sys.entity.DrugLite;
import java.util.List;
/**
* 毒品库送缴量统计 服务处接口
@ -13,4 +16,11 @@ public interface DrugHandingOverStatisticService {
* @return
*/
DrugStatisticVO statistic(DrugStatisticQuery query);
/**
* 获取统计图中可以根据毒品进行分类统计的选项
* @return
*/
List<DrugLite> getDrugNameList();
}

@ -83,7 +83,9 @@ public class CommonFeignServiceImpl implements CommonFeignService {
sysOrg.setParentId(orgId);
R<List<SysOrg>> r = remoteOrgService.innerGetOrgList(sysOrg);
if (r != null && r.getCode() == CommonConstants.SUCCESS) {
return r.getData();
List<SysOrg> data = r.getData();
data.add(remoteGetSysOrg(orgId));
return data;
} else {
throw new RuntimeException(String.format("没有找到 orgId 为 %s 的机构, 请确认用户所属机构的正确性!", orgId));
}

@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import digital.laboratory.platform.imr.component.DateUtils;
import digital.laboratory.platform.imr.convert.DrugLiteConvert;
import digital.laboratory.platform.imr.entity.DrugCaseInfo;
import digital.laboratory.platform.imr.entity.DrugHandingOverApply;
import digital.laboratory.platform.imr.entity.DrugMaterialInfo;
@ -16,6 +17,7 @@ import digital.laboratory.platform.imr.service.DrugHandingOverApplyService;
import digital.laboratory.platform.imr.service.DrugHandingOverStatisticService;
import digital.laboratory.platform.imr.vo.DrugMaterialInfoVO;
import digital.laboratory.platform.imr.vo.DrugStatisticVO;
import digital.laboratory.platform.sys.entity.DrugLite;
import digital.laboratory.platform.sys.entity.SysOrg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -25,13 +27,12 @@ import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@ -51,8 +52,6 @@ public class DrugHandingOverStatisticServiceImpl implements DrugHandingOverStati
@Resource
private CommonFeignService commonFeignService;
@Autowired
private DrugHandingOverApplyMapper drugHandingOverApplyMapper;
/**
* 获取统计图的数据 根据时间范围, 送缴单位毒品种类返回数据
@ -65,9 +64,9 @@ public class DrugHandingOverStatisticServiceImpl implements DrugHandingOverStati
// 创建 CompletableFuture 用于异步执行 buildLineChartData 和 buildBarChartData
CompletableFuture<Void> lineChartFuture = CompletableFuture.runAsync(() -> buildLineChartData(query, drugStatisticVO));
CompletableFuture<Void> barChartFuture = CompletableFuture.runAsync(() -> buildBarChartData(query, drugStatisticVO));
CompletableFuture<Void> pieChartFuture = CompletableFuture.runAsync(() -> buildPieChartData(query, drugStatisticVO));
// 等待两个任务完成
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(lineChartFuture, barChartFuture);
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(lineChartFuture, barChartFuture, pieChartFuture);
try {
// 等待所有异步任务执行完成
@ -81,6 +80,55 @@ public class DrugHandingOverStatisticServiceImpl implements DrugHandingOverStati
return drugStatisticVO;
}
/**
* 获取统计图中可以根据毒品进行分类统计的选项
* @return
*/
@Override
public List<DrugLite> getDrugNameList() {
List<DrugMaterialInfo> drugMaterialInfoVOS = drugMaterialInfoMapper.selectList(Wrappers.<DrugMaterialInfo>lambdaQuery().groupBy(DrugMaterialInfo::getType));// 获取所有的检材
List<DrugLite> drugLiteListJson = drugMaterialInfoVOS.stream().flatMap(item -> item.getType().stream()).collect(Collectors.toList());
return DrugLiteConvert.convertDirtyLiteByJSON(drugLiteListJson).stream().filter(distinctByKey(DrugLite::getName)).collect(Collectors.toList());
}
private void buildPieChartData(DrugStatisticQuery query, DrugStatisticVO drugStatisticVO) {
List<List<Object>> pieChartData = new ArrayList<>();
List<Object> drugNameList = new ArrayList<>();
List<Object> dataList = new ArrayList<>();
// 获取检材列表
List<DrugMaterialInfoVO> drugMaterialInfoVOS = drugMaterialInfoMapper.getDrugMaterialVO(Wrappers.<DrugMaterialInfo>query()
.eq(StrUtil.isNotBlank(query.getOrgId()), "dhoa.handing_over_org", query.getOrgId())
.ge(query.getStartDate() != null, "dhoa.handing_over_date", query.getStartDate())
.le(query.getEndDate() != null, "dhoa.handing_over_date", query.getEndDate())
);
Map<String, List<DrugMaterialInfoVO>> drugGroupType = drugMaterialInfoVOS.stream().collect(Collectors.groupingBy(vo -> DrugLiteConvert.joiningDrugListNameToStr(vo.getType(), ",")));
// 创建 以毒品名称为键,数量为值的map
Map<String, Integer> countMap = new HashMap<>();
drugGroupType.forEach((key, value) -> {
List<String> drugNameSplits = StrUtil.split(key, ",");
for (String drugName : drugNameSplits) {
if (countMap.containsKey(drugName)) {
countMap.put(drugName, countMap.get(drugName) + value.size());
} else {
countMap.put(drugName, value.size());
}
}
});
countMap.forEach((key, value) -> {
drugNameList.add(key);
dataList.add(value);
});
pieChartData.add(drugNameList);
pieChartData.add(dataList);
drugStatisticVO.setPieChartDataList(pieChartData);
drugStatisticVO.setPieChartDataSum(drugMaterialInfoVOS.size());
}
/**
* 构建柱状图的数据
*
@ -112,8 +160,8 @@ public class DrugHandingOverStatisticServiceImpl implements DrugHandingOverStati
// 根据时间点获取检材
List<DrugMaterialInfoVO> drugMaterialInfoVOList = drugMaterialInfoMapper.getDrugMaterialVO(
Wrappers.<DrugMaterialInfo>query()
.ge(query.getStartDate() != null, "dc.handing_over_date", query.getStartDate())
.le(query.getEndDate() != null, "dc.handing_over_date", query.getEndDate())
.ge(query.getStartDate() != null, "dhoa.handing_over_date", query.getStartDate())
.le(query.getEndDate() != null, "dhoa.handing_over_date", query.getEndDate())
);
Map<String, List<DrugMaterialInfoVO>> groupByHandingOverOrgMap = drugMaterialInfoVOList.stream().collect(Collectors.groupingBy(DrugMaterialInfoVO::getHandingOverOrg));
sysOrgMap.forEach((orgId, sysOrg) -> {
@ -157,8 +205,12 @@ public class DrugHandingOverStatisticServiceImpl implements DrugHandingOverStati
} else if (startDate != null && endDate != null) {
// 计算查询开始时间和接受时间相差的月份数量
long between = ChronoUnit.MONTHS.between(startDate, endDate);
for (int i = (int) (between -1); i >= 0; i--) {
fillLineChartData(monthsList, dataList, dateTimeFormatter, startDate, query.getOrgId(), i);
if (between == 0) {
fillLineChartData(monthsList, dataList, dateTimeFormatter, endDate, query.getOrgId(), 0);
} else {
for (int i = (int) (between - 1); i >= 0; i--) {
fillLineChartData(monthsList, dataList, dateTimeFormatter, endDate, query.getOrgId(), i);
}
}
} else if (startDate == null && endDate != null) {
// 只返回1年内的数据
@ -200,4 +252,16 @@ public class DrugHandingOverStatisticServiceImpl implements DrugHandingOverStati
);
monthsList.add(localDate.format(dateTimeFormatter));
}
/**
* 根据指定的键提取器生成一个Predicate用于判断对象是否唯一
*
* @param <T> 对象类型
* @param keyExtractor 键提取器用于从对象中提取唯一键
* @return 一个Predicate用于判断对象是否唯一
*/
private <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(keyExtractor.apply(t));
}
}

@ -113,7 +113,7 @@
ORDER BY dm.update_time DESC
</select>
<select id="getDrugMaterialVO" resultType="digital.laboratory.platform.imr.vo.DrugMaterialInfoVO">
<select id="getDrugMaterialVO" resultType="digital.laboratory.platform.imr.vo.DrugMaterialInfoVO" resultMap="voMap">
<include refid="queryVOSQL"/>
${ew.customSqlSegment}
</select>

Loading…
Cancel
Save