diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/appservice/IRationalDrugAppService.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/appservice/IRationalDrugAppService.java
index 0e8aa9fd4..53e4cbb9b 100644
--- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/appservice/IRationalDrugAppService.java
+++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/appservice/IRationalDrugAppService.java
@@ -4,6 +4,7 @@ import com.healthlink.his.rationaldrug.domain.DrugInteractionRule;
import com.healthlink.his.rationaldrug.domain.DrugDosageRange;
import com.healthlink.his.rationaldrug.dto.AuditResultDto;
import com.healthlink.his.rationaldrug.dto.AuditStatisticsDto;
+import com.healthlink.his.rationaldrug.dto.DosageAdjustmentRequestDto;
import com.healthlink.his.rationaldrug.dto.InteractionCheckResultDto;
import com.healthlink.his.rationaldrug.dto.PrescriptionAuditDto;
@@ -74,4 +75,12 @@ public interface IRationalDrugAppService {
* @return 审核结果
*/
AuditResultDto checkDosage(String drugCode, BigDecimal dosage, String population);
+
+ /**
+ * 根据肝肾功能自动建议调量
+ *
+ * @param request 调量请求
+ * @return 调量建议结果
+ */
+ AuditResultDto adjustDosageByOrganFunction(DosageAdjustmentRequestDto request);
}
diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/appservice/impl/RationalDrugAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/appservice/impl/RationalDrugAppServiceImpl.java
index b30e1295c..4cab50864 100644
--- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/appservice/impl/RationalDrugAppServiceImpl.java
+++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/appservice/impl/RationalDrugAppServiceImpl.java
@@ -6,6 +6,7 @@ import com.healthlink.his.rationaldrug.domain.DrugInteractionRule;
import com.healthlink.his.rationaldrug.domain.PrescriptionAuditLog;
import com.healthlink.his.rationaldrug.dto.AuditResultDto;
import com.healthlink.his.rationaldrug.dto.AuditStatisticsDto;
+import com.healthlink.his.rationaldrug.dto.DosageAdjustmentRequestDto;
import com.healthlink.his.rationaldrug.dto.InteractionCheckResultDto;
import com.healthlink.his.rationaldrug.dto.PrescriptionAuditDto;
import com.healthlink.his.rationaldrug.service.IDrugDosageRangeService;
@@ -257,6 +258,218 @@ public class RationalDrugAppServiceImpl implements IRationalDrugAppService {
return buildResult("PASS", null, 0, "剂量在合理范围内", null);
}
+ /**
+ * 根据肝肾功能自动建议调量
+ *
+ * 流程:评估肝肾功能损害程度 → 匹配药品剂量规则 → 比较当前剂量 → 生成调量建议
+ *
+ */
+ @Override
+ public AuditResultDto adjustDosageByOrganFunction(DosageAdjustmentRequestDto request) {
+ String drugCode = request.getDrugCode();
+ String organType = request.getOrganFunctionType();
+ String population = request.getPopulation();
+
+ if (drugCode == null || organType == null) {
+ return buildResult("MANUAL", "INVALID_INPUT", 1,
+ "药品编码和肝肾功能类型不能为空",
+ "请提供完整的药品编码和肝肾功能类型");
+ }
+
+ // 1. 评估器官功能损害程度
+ String impairmentLevel = assessImpairmentLevel(request);
+ if ("NORMAL".equals(impairmentLevel)) {
+ return buildResult("PASS", null, 0,
+ "肝肾功能正常,当前剂量无需调整",
+ "无需调量");
+ }
+
+ // 2. 查询该药品的剂量规则
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(DrugDosageRange::getDrugCode, drugCode)
+ .eq(DrugDosageRange::getEnabled, "1")
+ .eq(DrugDosageRange::getDelFlag, "0");
+ if (population != null) {
+ wrapper.eq(DrugDosageRange::getPopulation, population);
+ }
+ List ranges = drugDosageRangeService.list(wrapper);
+
+ if (ranges.isEmpty()) {
+ return buildResult("MANUAL", "DOSAGE_RANGE_NOT_FOUND", 1,
+ "药品 " + drugCode + " 无剂量范围规则,请先维护剂量规则",
+ "建议人工确认剂量合理性");
+ }
+
+ // 3. 根据损害程度生成调量建议
+ BigDecimal currentDose = request.getCurrentDose();
+ DrugDosageRange matchedRange = ranges.get(0);
+
+ StringBuilder detail = new StringBuilder();
+ detail.append("肝肾功能评估: ").append(formatOrganType(organType));
+ detail.append(" — ").append(formatImpairmentLevel(impairmentLevel));
+
+ String suggestion;
+ String ruleHit;
+
+ if (currentDose == null) {
+ // 未提供当前剂量,仅给出通用建议
+ suggestion = "基于" + formatImpairmentLevel(impairmentLevel) + ","
+ + "建议参考剂量范围 " + matchedRange.getMinDose() + "-"
+ + matchedRange.getMaxDose() + matchedRange.getDoseUnit();
+ if (matchedRange.getAdjustmentNote() != null) {
+ suggestion += "。" + matchedRange.getAdjustmentNote();
+ }
+ ruleHit = "DOSE_NOT_PROVIDED";
+ detail.append("。未提供当前剂量,给出通用调量建议");
+ } else {
+ BigDecimal minDose = matchedRange.getMinDose();
+ BigDecimal maxDose = matchedRange.getMaxDose();
+
+ if (currentDose.compareTo(minDose) >= 0 && currentDose.compareTo(maxDose) <= 0) {
+ // 当前剂量在正常范围内,但器官功能受损,仍建议减量
+ if ("SEVERE".equals(impairmentLevel)) {
+ BigDecimal reducedDose = currentDose.multiply(BigDecimal.valueOf(0.5))
+ .setScale(1, RoundingMode.HALF_UP);
+ suggestion = "当前剂量 " + currentDose + matchedRange.getDoseUnit()
+ + " 虽在常规范围内,但" + formatImpairmentLevel(impairmentLevel)
+ + ",建议减量至 " + reducedDose + matchedRange.getDoseUnit();
+ if (matchedRange.getAdjustmentNote() != null) {
+ suggestion += "。" + matchedRange.getAdjustmentNote();
+ }
+ ruleHit = "SEVERE_IMPAIRMENT_REDUCE";
+ detail.append("。当前剂量在常规范围内,但重度损害需减量");
+ } else if ("MODERATE".equals(impairmentLevel)) {
+ BigDecimal reducedDose = currentDose.multiply(BigDecimal.valueOf(0.75))
+ .setScale(1, RoundingMode.HALF_UP);
+ suggestion = "当前剂量 " + currentDose + matchedRange.getDoseUnit()
+ + " 虽在常规范围内,但" + formatImpairmentLevel(impairmentLevel)
+ + ",建议减量至 " + reducedDose + matchedRange.getDoseUnit();
+ if (matchedRange.getAdjustmentNote() != null) {
+ suggestion += "。" + matchedRange.getAdjustmentNote();
+ }
+ ruleHit = "MODERATE_IMPAIRMENT_REDUCE";
+ detail.append("。当前剂量在常规范围内,中度损害建议适当减量");
+ } else {
+ suggestion = "当前剂量 " + currentDose + matchedRange.getDoseUnit()
+ + " 在常规范围内,轻度" + formatOrganType(organType) + "损害,暂无需调整,建议密切监测";
+ ruleHit = "MILD_IMPAIRMENT_MONITOR";
+ detail.append("。轻度损害,当前剂量可维持");
+ }
+ } else if (currentDose.compareTo(maxDose) > 0) {
+ // 当前剂量超出范围
+ suggestion = "当前剂量 " + currentDose + matchedRange.getDoseUnit()
+ + " 超过推荐范围 " + minDose + "-" + maxDose + matchedRange.getDoseUnit()
+ + ",且存在" + formatImpairmentLevel(impairmentLevel)
+ + ",强烈建议减量至 " + minDose + "-" + maxDose + matchedRange.getDoseUnit();
+ if (matchedRange.getAdjustmentNote() != null) {
+ suggestion += "。" + matchedRange.getAdjustmentNote();
+ }
+ ruleHit = "DOSAGE_EXCEEDS_RANGE_WITH_IMPAIRMENT";
+ detail.append("。当前剂量超出推荐范围,叠加器官损害风险更高");
+ } else {
+ // 当前剂量低于范围
+ suggestion = "当前剂量 " + currentDose + matchedRange.getDoseUnit()
+ + " 低于推荐范围 " + minDose + "-" + maxDose + matchedRange.getDoseUnit()
+ + ",结合" + formatImpairmentLevel(impairmentLevel)
+ + ",建议调整至 " + minDose + "-" + maxDose + matchedRange.getDoseUnit();
+ ruleHit = "DOSAGE_BELOW_RANGE_WITH_IMPAIRMENT";
+ detail.append("。当前剂量偏低,结合器官损害情况建议调整");
+ }
+ }
+
+ return buildResult("MANUAL", ruleHit, 1, detail.toString(), suggestion);
+ }
+
+ /**
+ * 评估器官功能损害程度
+ *
+ * @param request 调量请求
+ * @return 损害程度: NORMAL / MILD / MODERATE / SEVERE
+ */
+ private String assessImpairmentLevel(DosageAdjustmentRequestDto request) {
+ String organType = request.getOrganFunctionType();
+ String level = "NORMAL";
+
+ if ("KIDNEY".equals(organType) || "BOTH".equals(organType)) {
+ String kidneyLevel = assessKidneyFunction(request.getEgfr(), request.getCreatinine());
+ level = mergeLevel(level, kidneyLevel);
+ }
+ if ("LIVER".equals(organType) || "BOTH".equals(organType)) {
+ String liverLevel = assessLiverFunction(request.getAlt(), request.getAst());
+ level = mergeLevel(level, liverLevel);
+ }
+ return level;
+ }
+
+ private String assessKidneyFunction(java.math.BigDecimal egfr, java.math.BigDecimal creatinine) {
+ if (egfr != null) {
+ if (egfr.compareTo(java.math.BigDecimal.valueOf(90)) >= 0) return "NORMAL";
+ if (egfr.compareTo(java.math.BigDecimal.valueOf(60)) >= 0) return "MILD";
+ if (egfr.compareTo(java.math.BigDecimal.valueOf(30)) >= 0) return "MODERATE";
+ return "SEVERE";
+ }
+ if (creatinine != null) {
+ if (creatinine.compareTo(java.math.BigDecimal.valueOf(133)) < 0) return "NORMAL";
+ if (creatinine.compareTo(java.math.BigDecimal.valueOf(177)) < 0) return "MILD";
+ if (creatinine.compareTo(java.math.BigDecimal.valueOf(442)) < 0) return "MODERATE";
+ return "SEVERE";
+ }
+ return "NORMAL";
+ }
+
+ private String assessLiverFunction(java.math.BigDecimal alt, java.math.BigDecimal ast) {
+ int level = 0;
+ if (alt != null) {
+ if (alt.compareTo(java.math.BigDecimal.valueOf(40)) >= 0) level = Math.max(level, 1);
+ if (alt.compareTo(java.math.BigDecimal.valueOf(120)) >= 0) level = Math.max(level, 2);
+ if (alt.compareTo(java.math.BigDecimal.valueOf(400)) >= 0) level = Math.max(level, 3);
+ }
+ if (ast != null) {
+ if (ast.compareTo(java.math.BigDecimal.valueOf(40)) >= 0) level = Math.max(level, 1);
+ if (ast.compareTo(java.math.BigDecimal.valueOf(120)) >= 0) level = Math.max(level, 2);
+ if (ast.compareTo(java.math.BigDecimal.valueOf(400)) >= 0) level = Math.max(level, 3);
+ }
+ return switch (level) {
+ case 1 -> "MILD";
+ case 2 -> "MODERATE";
+ case 3 -> "SEVERE";
+ default -> "NORMAL";
+ };
+ }
+
+ private String mergeLevel(String current, String candidate) {
+ int currentLevel = impairmentLevelValue(current);
+ int candidateLevel = impairmentLevelValue(candidate);
+ return candidateLevel > currentLevel ? candidate : current;
+ }
+
+ private int impairmentLevelValue(String level) {
+ return switch (level) {
+ case "SEVERE" -> 3;
+ case "MODERATE" -> 2;
+ case "MILD" -> 1;
+ default -> 0;
+ };
+ }
+
+ private String formatOrganType(String organType) {
+ return switch (organType) {
+ case "LIVER" -> "肝功能";
+ case "KIDNEY" -> "肾功能";
+ case "BOTH" -> "肝肾功能";
+ default -> organType;
+ };
+ }
+
+ private String formatImpairmentLevel(String level) {
+ return switch (level) {
+ case "MILD" -> "轻度损害";
+ case "MODERATE" -> "中度损害";
+ case "SEVERE" -> "重度损害";
+ default -> "正常";
+ };
+ }
+
/**
* 保存审核日志
*/
diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/controller/RationalDrugController.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/controller/RationalDrugController.java
index 74d5e008c..bcc3a9bb7 100644
--- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/controller/RationalDrugController.java
+++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/rationaldrug/controller/RationalDrugController.java
@@ -5,6 +5,7 @@ import com.healthlink.his.rationaldrug.domain.DrugDosageRange;
import com.healthlink.his.rationaldrug.domain.DrugInteractionRule;
import com.healthlink.his.rationaldrug.dto.AuditResultDto;
import com.healthlink.his.rationaldrug.dto.AuditStatisticsDto;
+import com.healthlink.his.rationaldrug.dto.DosageAdjustmentRequestDto;
import com.healthlink.his.rationaldrug.dto.InteractionCheckResultDto;
import com.healthlink.his.rationaldrug.dto.PrescriptionAuditDto;
import com.healthlink.his.rationaldrug.service.IDrugDosageRangeService;
@@ -14,6 +15,7 @@ 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.math.BigDecimal;
@@ -127,4 +129,12 @@ public class RationalDrugController {
AuditResultDto result = rationalDrugAppService.checkDosage(drugCode, dosage, population);
return AjaxResult.success(result);
}
+
+ @PostMapping("/adjust-dosage")
+ @Operation(summary = "肝肾功能自动调量")
+ @PreAuthorize("hasAuthority('infection:rationaldrug:edit')")
+ public AjaxResult adjustDosageByOrganFunction(@RequestBody DosageAdjustmentRequestDto request) {
+ AuditResultDto result = rationalDrugAppService.adjustDosageByOrganFunction(request);
+ return AjaxResult.success(result);
+ }
}
diff --git a/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/rationaldrug/dto/DosageAdjustmentRequestDto.java b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/rationaldrug/dto/DosageAdjustmentRequestDto.java
new file mode 100644
index 000000000..bbdc4862b
--- /dev/null
+++ b/healthlink-his-server/healthlink-his-domain/src/main/java/com/healthlink/his/rationaldrug/dto/DosageAdjustmentRequestDto.java
@@ -0,0 +1,43 @@
+package com.healthlink.his.rationaldrug.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+
+/**
+ * 肝肾功能调量请求DTO
+ *
+ * @author system
+ */
+@Data
+@Accessors(chain = true)
+public class DosageAdjustmentRequestDto {
+
+ /** 药品编码 */
+ private String drugCode;
+
+ /** 当前剂量 */
+ private BigDecimal currentDose;
+
+ /** 剂量单位 */
+ private String doseUnit;
+
+ /** 肝肾功能类型: LIVER / KIDNEY / BOTH */
+ private String organFunctionType;
+
+ /** 肌酐 (μmol/L) — 肾功能 */
+ private BigDecimal creatinine;
+
+ /** 肾小球滤过率 eGFR (mL/min) — 肾功能 */
+ private BigDecimal egfr;
+
+ /** 谷丙转氨酶 ALT (U/L) — 肝功能 */
+ private BigDecimal alt;
+
+ /** 谷草转氨酶 AST (U/L) — 肝功能 */
+ private BigDecimal ast;
+
+ /** 人群类型: ADULT/CHILD/ELDERLY/PREGNANT */
+ private String population;
+}
diff --git a/healthlink-his-ui/src/api/rationaldrug.js b/healthlink-his-ui/src/api/rationaldrug.js
index e7a484ce2..abc3619f5 100644
--- a/healthlink-his-ui/src/api/rationaldrug.js
+++ b/healthlink-his-ui/src/api/rationaldrug.js
@@ -50,3 +50,8 @@ export function listDosageRules(params) {
export function checkDosage(drugCode, dosage, population) {
return request({ url: '/api/v1/rational-drug/check-dosage', method: 'get', params: { drugCode, dosage, population } })
}
+
+// ==================== 肝肾功能调量 ====================
+export function adjustDosageByOrganFunction(data) {
+ return request({ url: '/api/v1/rational-drug/adjust-dosage', method: 'post', data })
+}
diff --git a/healthlink-his-ui/src/views/rationaldrug/dosage-adjustment/index.vue b/healthlink-his-ui/src/views/rationaldrug/dosage-adjustment/index.vue
new file mode 100644
index 000000000..62ca8214f
--- /dev/null
+++ b/healthlink-his-ui/src/views/rationaldrug/dosage-adjustment/index.vue
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 肾功能指标
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 肝功能指标
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 生成调量建议
+
+
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ resultText(result.auditResult) }}
+
+
+
+ {{ result.ruleHit || '无' }}
+
+
+ {{ result.detail || '无' }}
+
+
+
+
+
+
+
+
+
+
+
+