diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/IDrgAnalysisAppService.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/IDrgAnalysisAppService.java new file mode 100644 index 000000000..76a700487 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/IDrgAnalysisAppService.java @@ -0,0 +1,9 @@ +package com.healthlink.his.web.reportmanage.appservice; + +import com.core.common.core.domain.R; +import java.util.Map; + +public interface IDrgAnalysisAppService { + R analyzeDrg(Map params); + R getDrgStats(String startDate, String endDate); +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/impl/DrgAnalysisAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/impl/DrgAnalysisAppServiceImpl.java new file mode 100644 index 000000000..589892060 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/impl/DrgAnalysisAppServiceImpl.java @@ -0,0 +1,135 @@ +package com.healthlink.his.web.reportmanage.appservice.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.core.common.core.domain.R; +import com.healthlink.his.crossmodule.domain.DrgPerformance; +import com.healthlink.his.crossmodule.service.IDrgPerformanceService; +import com.healthlink.his.mrhomepage.domain.MrDrgGrouping; +import com.healthlink.his.mrhomepage.service.IMrDrgGroupingService; +import com.healthlink.his.web.reportmanage.appservice.IDrgAnalysisAppService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.stream.Collectors; + +@Service +@AllArgsConstructor +public class DrgAnalysisAppServiceImpl implements IDrgAnalysisAppService { + + private final IMrDrgGroupingService drgGroupingService; + private final IDrgPerformanceService drgPerformanceService; + + @Override + public R analyzeDrg(Map params) { + String startDate = (String) params.get("startDate"); + String endDate = (String) params.get("endDate"); + String groupingType = (String) params.get("groupingType"); + + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + w.eq(StringUtils.hasText(groupingType), MrDrgGrouping::getGroupingType, groupingType) + .eq(MrDrgGrouping::getIsValid, true); + if (StringUtils.hasText(startDate)) { + w.ge(MrDrgGrouping::getDischargeDate, startDate); + } + if (StringUtils.hasText(endDate)) { + w.le(MrDrgGrouping::getDischargeDate, endDate); + } + + List list = drgGroupingService.list(w); + + Map result = new HashMap<>(); + result.put("totalCases", list.size()); + + BigDecimal totalCost = BigDecimal.ZERO; + BigDecimal totalInsurance = BigDecimal.ZERO; + int totalLos = 0; + for (MrDrgGrouping g : list) { + if (g.getTotalCost() != null) totalCost = totalCost.add(g.getTotalCost()); + if (g.getInsurancePayment() != null) totalInsurance = totalInsurance.add(g.getInsurancePayment()); + if (g.getLosDays() != null) totalLos += g.getLosDays(); + } + int count = list.size(); + result.put("totalCost", totalCost); + result.put("totalInsurance", totalInsurance); + result.put("avgCost", count > 0 ? totalCost.divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP) : BigDecimal.ZERO); + result.put("avgLos", count > 0 ? BigDecimal.valueOf(totalLos).divide(BigDecimal.valueOf(count), 1, RoundingMode.HALF_UP) : BigDecimal.ZERO); + result.put("insuranceRate", totalCost.compareTo(BigDecimal.ZERO) > 0 + ? totalInsurance.multiply(BigDecimal.valueOf(100)).divide(totalCost, 2, RoundingMode.HALF_UP) : BigDecimal.ZERO); + + Map typeCount = list.stream() + .collect(Collectors.groupingBy( + g -> g.getGroupingType() != null ? g.getGroupingType() : "UNKNOWN", + Collectors.summingInt(g -> 1))); + result.put("typeDistribution", typeCount); + + Map drgCostMap = new LinkedHashMap<>(); + Map drgCountMap = new LinkedHashMap<>(); + for (MrDrgGrouping g : list) { + String code = g.getDrgCode(); + if (StringUtils.hasText(code)) { + drgCostMap.merge(code, g.getTotalCost() != null ? g.getTotalCost() : BigDecimal.ZERO, BigDecimal::add); + drgCountMap.merge(code, 1, Integer::sum); + } + } + List> topDrg = drgCostMap.entrySet().stream() + .sorted(Map.Entry.comparingByValue().reversed()) + .limit(10) + .map(e -> { + Map item = new HashMap<>(); + item.put("drgCode", e.getKey()); + item.put("count", drgCountMap.getOrDefault(e.getKey(), 0)); + item.put("totalCost", e.getValue()); + return item; + }) + .collect(Collectors.toList()); + result.put("topDrgByCost", topDrg); + + return R.ok(result); + } + + @Override + public R getDrgStats(String startDate, String endDate) { + LambdaQueryWrapper w = new LambdaQueryWrapper<>(); + if (StringUtils.hasText(startDate)) { + w.ge(DrgPerformance::getStatMonth, startDate); + } + if (StringUtils.hasText(endDate)) { + w.le(DrgPerformance::getStatMonth, endDate); + } + w.orderByDesc(DrgPerformance::getStatMonth); + List perfList = drgPerformanceService.list(w); + + Map result = new HashMap<>(); + result.put("totalRecords", perfList.size()); + + if (!perfList.isEmpty()) { + DrgPerformance latest = perfList.get(0); + result.put("latestMonth", latest.getStatMonth()); + result.put("latestTotalCases", latest.getTotalCases()); + result.put("latestDrgCoveredRate", latest.getDrgCoveredRate()); + result.put("latestAvgWeight", latest.getAvgWeight()); + result.put("latestAvgCost", latest.getAvgCost()); + result.put("latestCostControlRate", latest.getCostControlRate()); + result.put("latestCmiValue", latest.getCmiValue()); + } + + BigDecimal totalCases = BigDecimal.ZERO; + BigDecimal totalWeight = BigDecimal.ZERO; + BigDecimal totalCostControl = BigDecimal.ZERO; + for (DrgPerformance p : perfList) { + if (p.getTotalCases() != null) totalCases = totalCases.add(BigDecimal.valueOf(p.getTotalCases())); + if (p.getAvgWeight() != null) totalWeight = totalWeight.add(p.getAvgWeight()); + if (p.getCostControlRate() != null) totalCostControl = totalCostControl.add(p.getCostControlRate()); + } + int size = perfList.size(); + result.put("periodTotalCases", totalCases); + result.put("avgWeight", size > 0 ? totalWeight.divide(BigDecimal.valueOf(size), 4, RoundingMode.HALF_UP) : BigDecimal.ZERO); + result.put("avgCostControlRate", size > 0 ? totalCostControl.divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP) : BigDecimal.ZERO); + + return R.ok(result); + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/controller/DrgAnalysisController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/controller/DrgAnalysisController.java new file mode 100644 index 000000000..d84bf8f2c --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/controller/DrgAnalysisController.java @@ -0,0 +1,33 @@ +package com.healthlink.his.web.reportmanage.controller; + +import com.core.common.core.domain.R; +import com.healthlink.his.web.reportmanage.appservice.IDrgAnalysisAppService; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequestMapping("/report/drg") +@Slf4j +@AllArgsConstructor +public class DrgAnalysisController { + + private final IDrgAnalysisAppService drgAnalysisAppService; + + @PostMapping("/analyze") + @PreAuthorize("hasAuthority('infection:report:edit')") + public R analyzeDrg(@RequestBody Map params) { + return drgAnalysisAppService.analyzeDrg(params); + } + + @GetMapping("/stats") + @PreAuthorize("hasAuthority('infection:report:list')") + public R getDrgStats( + @RequestParam(required = false) String startDate, + @RequestParam(required = false) String endDate) { + return drgAnalysisAppService.getDrgStats(startDate, endDate); + } +} diff --git a/healthlink-his-ui/src/views/drganalysis/api.js b/healthlink-his-ui/src/views/drganalysis/api.js new file mode 100644 index 000000000..b17ab6c57 --- /dev/null +++ b/healthlink-his-ui/src/views/drganalysis/api.js @@ -0,0 +1,3 @@ +import request from '@/utils/request' +export function analyzeDrg(d){return request({url:'/report/drg/analyze',method:'post',data:d})} +export function getDrgStats(p){return request({url:'/report/drg/stats',method:'get',params:p})} diff --git a/healthlink-his-ui/src/views/drganalysis/index.vue b/healthlink-his-ui/src/views/drganalysis/index.vue new file mode 100644 index 000000000..dde657b3a --- /dev/null +++ b/healthlink-his-ui/src/views/drganalysis/index.vue @@ -0,0 +1,191 @@ + + +