diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/IInfectionScreeningAppService.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/IInfectionScreeningAppService.java new file mode 100644 index 000000000..165306938 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/IInfectionScreeningAppService.java @@ -0,0 +1,10 @@ +package com.healthlink.his.web.infection.appservice; + +import com.healthlink.his.infection.domain.HirInfectionCase; +import java.util.List; +import java.util.Map; + +public interface IInfectionScreeningAppService { + Map screenInfectionCases(Map params); + List getScreeningResults(Map params); +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionScreeningAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionScreeningAppServiceImpl.java new file mode 100644 index 000000000..7355cb880 --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionScreeningAppServiceImpl.java @@ -0,0 +1,126 @@ +package com.healthlink.his.web.infection.appservice.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.healthlink.his.infection.domain.HirInfectionCase; +import com.healthlink.his.infection.service.IHirInfectionCaseService; +import com.healthlink.his.web.infection.appservice.IInfectionScreeningAppService; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +@Slf4j +@AllArgsConstructor +public class InfectionScreeningAppServiceImpl implements IInfectionScreeningAppService { + + private final IHirInfectionCaseService infectionCaseService; + + @Override + public Map screenInfectionCases(Map params) { + log.info("开始院感病例自动筛查, 参数: {}", params); + Map result = new HashMap<>(); + int screenedCount = 0; + int suspectedCount = 0; + + String startDate = params.get("startDate") != null ? params.get("startDate").toString() : null; + String endDate = params.get("endDate") != null ? params.get("endDate").toString() : null; + String departmentName = params.get("departmentName") != null ? params.get("departmentName").toString() : null; + String infectionType = params.get("infectionType") != null ? params.get("infectionType").toString() : null; + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + if (startDate != null && !startDate.isEmpty()) { + wrapper.ge(HirInfectionCase::getReportTime, startDate); + } + if (endDate != null && !endDate.isEmpty()) { + wrapper.le(HirInfectionCase::getReportTime, endDate + " 23:59:59"); + } + if (infectionType != null && !infectionType.isEmpty()) { + wrapper.eq(HirInfectionCase::getInfectionType, infectionType); + } + wrapper.eq(HirInfectionCase::getDeleteFlag, "0"); + wrapper.orderByDesc(HirInfectionCase::getReportTime); + + List cases = infectionCaseService.list(wrapper); + screenedCount = cases.size(); + + List suspectedCases = new ArrayList<>(); + for (HirInfectionCase c : cases) { + if (isSuspectedInfection(c, params)) { + suspectedCases.add(c); + } + } + suspectedCount = suspectedCases.size(); + + result.put("screenedCount", screenedCount); + result.put("suspectedCount", suspectedCount); + result.put("suspectedCases", suspectedCases); + result.put("screenTime", new Date()); + result.put("rules", getScreeningRules(params)); + + log.info("筛查完成: 共筛查{}例, 疑似{}例", screenedCount, suspectedCount); + return result; + } + + @Override + public List getScreeningResults(Map params) { + String startDate = params.get("startDate") != null ? params.get("startDate").toString() : null; + String endDate = params.get("endDate") != null ? params.get("endDate").toString() : null; + String status = params.get("status") != null ? params.get("status").toString() : null; + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + if (startDate != null && !startDate.isEmpty()) { + wrapper.ge(HirInfectionCase::getReportTime, startDate); + } + if (endDate != null && !endDate.isEmpty()) { + wrapper.le(HirInfectionCase::getReportTime, endDate + " 23:59:59"); + } + if (status != null && !status.isEmpty()) { + wrapper.eq(HirInfectionCase::getStatus, status); + } + wrapper.eq(HirInfectionCase::getDeleteFlag, "0"); + wrapper.orderByDesc(HirInfectionCase::getReportTime); + + return infectionCaseService.list(wrapper); + } + + private boolean isSuspectedInfection(HirInfectionCase c, Map params) { + if (c.getInfectionType() != null && c.getInfectionType().contains("医院感染")) { + return true; + } + if (c.getPathogen() != null && !c.getPathogen().isEmpty()) { + return true; + } + if (c.getInfectionSite() != null) { + String site = c.getInfectionSite().toLowerCase(); + if (site.contains("血流") || site.contains("尿路") || site.contains("肺部") || site.contains("手术部位")) { + return true; + } + } + if (params.get("minDays") != null) { + try { + int minDays = Integer.parseInt(params.get("minDays").toString()); + if (c.getDiagnosisDate() != null) { + long days = (new Date().getTime() - c.getDiagnosisDate().getTime()) / (1000 * 60 * 60 * 24); + if (days >= minDays) { + return true; + } + } + } catch (NumberFormatException ignored) {} + } + return false; + } + + private List getScreeningRules(Map params) { + List rules = new ArrayList<>(); + rules.add("感染类型为'医院感染'"); + rules.add("已检出病原体"); + rules.add("感染部位为血流/尿路/肺部/手术部位"); + if (params.get("minDays") != null) { + rules.add("住院天数超过" + params.get("minDays") + "天"); + } + return rules; + } +} diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/controller/InfectionScreeningController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/controller/InfectionScreeningController.java new file mode 100644 index 000000000..0608034ca --- /dev/null +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/controller/InfectionScreeningController.java @@ -0,0 +1,44 @@ +package com.healthlink.his.web.infection.controller; + +import com.core.common.core.domain.R; +import com.healthlink.his.web.infection.appservice.IInfectionScreeningAppService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +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; + +@Tag(name = "院感病例自动筛查") +@RestController +@RequestMapping("/infection/screening") +@Slf4j +@AllArgsConstructor +public class InfectionScreeningController { + + private final IInfectionScreeningAppService screeningAppService; + + @Operation(summary = "执行院感病例自动筛查") + @PreAuthorize("@ss.hasPermi('infection:infection:edit')") + @PostMapping("/run") + public R runScreening(@RequestBody Map params) { + log.info("触发院感病例自动筛查"); + return R.ok(screeningAppService.screenInfectionCases(params)); + } + + @Operation(summary = "查询筛查结果") + @PreAuthorize("@ss.hasPermi('infection:infection:list')") + @GetMapping("/results") + public R getScreeningResults( + @RequestParam(value = "startDate", required = false) String startDate, + @RequestParam(value = "endDate", required = false) String endDate, + @RequestParam(value = "status", required = false) String status) { + Map params = new java.util.HashMap<>(); + params.put("startDate", startDate); + params.put("endDate", endDate); + params.put("status", status); + return R.ok(screeningAppService.getScreeningResults(params)); + } +} diff --git a/healthlink-his-ui/src/api/infection/screening.js b/healthlink-his-ui/src/api/infection/screening.js new file mode 100644 index 000000000..2c19d36c7 --- /dev/null +++ b/healthlink-his-ui/src/api/infection/screening.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +export function runScreening(params) { + return request({ url: '/infection/screening/run', method: 'post', data: params }) +} + +export function getScreeningResults(params) { + return request({ url: '/infection/screening/results', method: 'get', params }) +} diff --git a/healthlink-his-ui/src/views/infection/screening/index.vue b/healthlink-his-ui/src/views/infection/screening/index.vue new file mode 100644 index 000000000..e450bd1ae --- /dev/null +++ b/healthlink-his-ui/src/views/infection/screening/index.vue @@ -0,0 +1,171 @@ + + + + +