From 632d0828b449dac3ee6831f2526d359def3e465c Mon Sep 17 00:00:00 2001 From: chenqi Date: Thu, 18 Jun 2026 15:11:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(reportmanage):=20T11.3=20=E5=8F=AF?= =?UTF-8?q?=E8=A7=86=E5=8C=96=E4=BB=AA=E8=A1=A8=E7=9B=98=20-=20AppService?= =?UTF-8?q?=20+=20Controller=20+=20Frontend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../appservice/IDashboardAppService.java | 9 ++ .../impl/DashboardAppServiceImpl.java | 129 ++++++++++++++++++ .../controller/DashboardDataController.java | 35 +++++ healthlink-his-ui/src/views/dashboard/api.js | 2 + .../src/views/dashboard/index.vue | 47 ++++++- 5 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/IDashboardAppService.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/impl/DashboardAppServiceImpl.java create mode 100644 healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/controller/DashboardDataController.java diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/IDashboardAppService.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/IDashboardAppService.java new file mode 100644 index 000000000..f7bcc9064 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/IDashboardAppService.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 IDashboardAppService { + R getDashboardData(Map params); + R getCharts(Map params); +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/impl/DashboardAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/impl/DashboardAppServiceImpl.java new file mode 100644 index 000000000..22d85b696 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/appservice/impl/DashboardAppServiceImpl.java @@ -0,0 +1,129 @@ +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.basicmanage.domain.DashboardConfig; +import com.healthlink.his.basicmanage.service.IDashboardConfigService; +import com.healthlink.his.quality.domain.BusinessAnalytics; +import com.healthlink.his.quality.service.IBusinessAnalyticsService; +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.IDashboardAppService; +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 DashboardAppServiceImpl implements IDashboardAppService { + + private final IDashboardConfigService dashboardConfigService; + private final IBusinessAnalyticsService analyticsService; + private final IDrgPerformanceService drgPerformanceService; + private final IMrDrgGroupingService drgGroupingService; + + @Override + public R getDashboardData(Map params) { + Map data = new HashMap<>(); + + List analyticsList = analyticsService.list(); + BigDecimal totalRevenue = BigDecimal.ZERO; + BigDecimal totalCost = BigDecimal.ZERO; + int totalPatients = 0; + for (BusinessAnalytics ba : analyticsList) { + if (ba.getRevenue() != null) totalRevenue = totalRevenue.add(ba.getRevenue()); + if (ba.getCost() != null) totalCost = totalCost.add(ba.getCost()); + if (ba.getPatientCount() != null) totalPatients += ba.getPatientCount(); + } + data.put("totalRevenue", totalRevenue); + data.put("totalCost", totalCost); + data.put("totalProfit", totalRevenue.subtract(totalCost)); + data.put("totalPatients", totalPatients); + data.put("totalRecords", analyticsList.size()); + + LambdaQueryWrapper configW = new LambdaQueryWrapper<>(); + configW.eq(DashboardConfig::getIsDefault, true); + List defaultConfigs = dashboardConfigService.list(configW); + data.put("defaultDashboard", defaultConfigs.isEmpty() ? null : defaultConfigs.get(0)); + + LambdaQueryWrapper perfW = new LambdaQueryWrapper<>(); + perfW.orderByDesc(DrgPerformance::getStatMonth).last("LIMIT 1"); + List latestPerf = drgPerformanceService.list(perfW); + if (!latestPerf.isEmpty()) { + DrgPerformance p = latestPerf.get(0); + data.put("latestDrgCases", p.getTotalCases()); + data.put("latestCmiValue", p.getCmiValue()); + data.put("latestCostControlRate", p.getCostControlRate()); + } + + long totalDrgCases = drgGroupingService.count(); + data.put("totalDrgCases", totalDrgCases); + + return R.ok(data); + } + + @Override + public R getCharts(Map params) { + Map charts = new HashMap<>(); + + List analyticsList = analyticsService.list(); + Map monthlyRevenue = new LinkedHashMap<>(); + Map monthlyCost = new LinkedHashMap<>(); + for (BusinessAnalytics ba : analyticsList) { + String month = ba.getStatDate(); + if (StringUtils.hasText(month) && month.length() >= 7) { + month = month.substring(0, 7); + } else { + month = "未知"; + } + monthlyRevenue.merge(month, ba.getRevenue() != null ? ba.getRevenue() : BigDecimal.ZERO, BigDecimal::add); + monthlyCost.merge(month, ba.getCost() != null ? ba.getCost() : BigDecimal.ZERO, BigDecimal::add); + } + List> revenueChart = new ArrayList<>(); + monthlyRevenue.forEach((k, v) -> { + Map item = new HashMap<>(); + item.put("month", k); + item.put("revenue", v); + item.put("cost", monthlyCost.getOrDefault(k, BigDecimal.ZERO)); + revenueChart.add(item); + }); + charts.put("revenueChart", revenueChart); + + Map deptRevenue = analyticsList.stream() + .filter(ba -> StringUtils.hasText(ba.getDepartmentName())) + .collect(Collectors.groupingBy( + BusinessAnalytics::getDepartmentName, + Collectors.reducing(BigDecimal.ZERO, ba -> ba.getRevenue() != null ? ba.getRevenue() : BigDecimal.ZERO, BigDecimal::add))); + List> deptChart = new ArrayList<>(); + deptRevenue.forEach((k, v) -> { + Map item = new HashMap<>(); + item.put("department", k); + item.put("revenue", v); + deptChart.add(item); + }); + charts.put("departmentChart", deptChart); + + LambdaQueryWrapper perfW = new LambdaQueryWrapper<>(); + perfW.orderByAsc(DrgPerformance::getStatMonth); + List perfList = drgPerformanceService.list(perfW); + List> cmiChart = new ArrayList<>(); + for (DrgPerformance p : perfList) { + Map item = new HashMap<>(); + item.put("month", p.getStatMonth()); + item.put("cmiValue", p.getCmiValue()); + item.put("costControlRate", p.getCostControlRate()); + item.put("totalCases", p.getTotalCases()); + cmiChart.add(item); + } + charts.put("cmiChart", cmiChart); + + return R.ok(charts); + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/controller/DashboardDataController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/controller/DashboardDataController.java new file mode 100644 index 000000000..54c40cb28 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/reportmanage/controller/DashboardDataController.java @@ -0,0 +1,35 @@ +package com.healthlink.his.web.reportmanage.controller; + +import com.core.common.core.domain.R; +import com.healthlink.his.web.reportmanage.appservice.IDashboardAppService; +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("/dashboard") +@Slf4j +@AllArgsConstructor +public class DashboardDataController { + + private final IDashboardAppService dashboardAppService; + + @GetMapping("/data") + @PreAuthorize("hasAuthority('infection:report:list')") + public R getDashboardData(@RequestParam(required = false) String dashboardType) { + Map params = new java.util.HashMap<>(); + params.put("dashboardType", dashboardType); + return dashboardAppService.getDashboardData(params); + } + + @GetMapping("/charts") + @PreAuthorize("hasAuthority('infection:report:list')") + public R getCharts(@RequestParam(required = false) String dashboardType) { + Map params = new java.util.HashMap<>(); + params.put("dashboardType", dashboardType); + return dashboardAppService.getCharts(params); + } +} diff --git a/healthlink-his-ui/src/views/dashboard/api.js b/healthlink-his-ui/src/views/dashboard/api.js index b771a1033..9bd8c6123 100644 --- a/healthlink-his-ui/src/views/dashboard/api.js +++ b/healthlink-his-ui/src/views/dashboard/api.js @@ -1,3 +1,5 @@ import request from '@/utils/request' export function getDashboardOverview(){return request({url:'/dashboard/overview',method:'get'})} export function getDashboardList(p){return request({url:'/dashboard/list',method:'get',params:p})} +export function getDashboardData(p){return request({url:'/dashboard/data',method:'get',params:p})} +export function getDashboardCharts(p){return request({url:'/dashboard/charts',method:'get',params:p})} diff --git a/healthlink-his-ui/src/views/dashboard/index.vue b/healthlink-his-ui/src/views/dashboard/index.vue index 349727ec1..e8cd29451 100644 --- a/healthlink-his-ui/src/views/dashboard/index.vue +++ b/healthlink-his-ui/src/views/dashboard/index.vue @@ -62,6 +62,42 @@ + + + + +
+
{{ formatMoney(dashData.totalRevenue) }}
+
总收入(万)
+
+
+
+ + +
+
{{ formatMoney(dashData.totalProfit) }}
+
总利润(万)
+
+
+
+ + +
+
{{ dashData.totalPatients || 0 }}
+
总患者数
+
+
+
+ + +
+
{{ dashData.totalDrgCases || 0 }}
+
DRG病例数
+
+
+
+
+ import {ref, onMounted} from 'vue' import {ElMessage} from 'element-plus' -import {getDashboardOverview} from './api' +import {getDashboardOverview, getDashboardData, getDashboardCharts} from './api' const overview = ref({}) +const dashData = ref({}) const showSystemInfo = ref(false) const statCards = ref([ @@ -231,10 +268,16 @@ const recentLogs = ref([ {content:'危急值处理完成', time:'20分钟前', type:'danger'} ]) +function formatMoney(val) { + if (!val) return '0.00' + return (val / 10000).toFixed(2) +} + async function loadData() { try { - const r = await getDashboardOverview() + const [r, d] = await Promise.all([getDashboardOverview(), getDashboardData()]) overview.value = r.data || {} + dashData.value = d.data || {} statCards.value[0].value = overview.value.totalTables || 0 statCards.value[1].value = overview.value.totalApis || 0 statCards.value[2].value = modules.value.length