feat(rationaldrug): T11.4 肝肾功能自动调量
- 新增 DosageAdjustmentRequestDto 请求DTO - IRationalDrugAppService 新增 adjustDosageByOrganFunction 方法 - RationalDrugAppServiceImpl 实现肝肾功能评估 + 剂量匹配逻辑 - RationalDrugController 新增 POST /adjust-dosage 端点 - rationaldrug.js 新增前端 API 函数 - 新建 DosageAdjustment.vue 肝肾功能输入 + 调量建议展示
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据肝肾功能自动建议调量
|
||||
* <p>
|
||||
* 流程:评估肝肾功能损害程度 → 匹配药品剂量规则 → 比较当前剂量 → 生成调量建议
|
||||
* </p>
|
||||
*/
|
||||
@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<DrugDosageRange> 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<DrugDosageRange> 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 -> "正常";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存审核日志
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>肝肾功能自动调量</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
label="药品编码"
|
||||
prop="drugCode"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.drugCode"
|
||||
placeholder="请输入药品编码"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
label="人群类型"
|
||||
prop="population"
|
||||
>
|
||||
<el-select
|
||||
v-model="form.population"
|
||||
placeholder="请选择人群类型"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in populationOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item
|
||||
label="当前剂量"
|
||||
prop="currentDose"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.currentDose"
|
||||
:min="0"
|
||||
:precision="1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item
|
||||
label="剂量单位"
|
||||
prop="doseUnit"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.doseUnit"
|
||||
placeholder="如 mg、ml"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item
|
||||
label="肝肾功能类型"
|
||||
prop="organFunctionType"
|
||||
>
|
||||
<el-select
|
||||
v-model="form.organFunctionType"
|
||||
placeholder="请选择"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in organTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider content-position="left">
|
||||
肾功能指标
|
||||
</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="肌酐 (μmol/L)">
|
||||
<el-input-number
|
||||
v-model="form.creatinine"
|
||||
:min="0"
|
||||
:precision="1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="eGFR (mL/min)">
|
||||
<el-input-number
|
||||
v-model="form.egfr"
|
||||
:min="0"
|
||||
:precision="1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider content-position="left">
|
||||
肝功能指标
|
||||
</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="ALT (U/L)">
|
||||
<el-input-number
|
||||
v-model="form.alt"
|
||||
:min="0"
|
||||
:precision="1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="AST (U/L)">
|
||||
<el-input-number
|
||||
v-model="form.ast"
|
||||
:min="0"
|
||||
:precision="1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="loading"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
生成调量建议
|
||||
</el-button>
|
||||
<el-button @click="handleReset">
|
||||
重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card
|
||||
v-if="result"
|
||||
shadow="never"
|
||||
class="mt20"
|
||||
>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>调量建议结果</span>
|
||||
<el-tag :type="resultTagType(result.auditResult)">
|
||||
{{ resultText(result.auditResult) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-descriptions
|
||||
:column="1"
|
||||
border
|
||||
>
|
||||
<el-descriptions-item label="审核结果">
|
||||
<el-tag :type="resultTagType(result.auditResult)">
|
||||
{{ resultText(result.auditResult) }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="规则命中">
|
||||
{{ result.ruleHit || '无' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="详细评估">
|
||||
{{ result.detail || '无' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="调量建议">
|
||||
<el-alert
|
||||
:title="result.suggestion || '无需调整'"
|
||||
:type="result.auditResult === 'PASS' ? 'success' : 'warning'"
|
||||
show-icon
|
||||
:closable="false"
|
||||
/>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="DosageAdjustment" lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { adjustDosageByOrganFunction } from '@/api/rationaldrug'
|
||||
|
||||
const formRef = ref(null)
|
||||
const loading = ref(false)
|
||||
const result = ref(null)
|
||||
|
||||
const form = reactive({
|
||||
drugCode: '',
|
||||
population: 'ADULT',
|
||||
currentDose: null,
|
||||
doseUnit: 'mg',
|
||||
organFunctionType: 'KIDNEY',
|
||||
creatinine: null,
|
||||
egfr: null,
|
||||
alt: null,
|
||||
ast: null
|
||||
})
|
||||
|
||||
const rules = reactive({
|
||||
drugCode: [{ required: true, message: '药品编码不能为空', trigger: 'blur' }],
|
||||
organFunctionType: [{ required: true, message: '请选择肝肾功能类型', trigger: 'change' }]
|
||||
})
|
||||
|
||||
const populationOptions = [
|
||||
{ label: '成人', value: 'ADULT' },
|
||||
{ label: '儿童', value: 'CHILD' },
|
||||
{ label: '老年', value: 'ELDERLY' },
|
||||
{ label: '孕妇', value: 'PREGNANT' }
|
||||
]
|
||||
|
||||
const organTypeOptions = [
|
||||
{ label: '肾功能', value: 'KIDNEY' },
|
||||
{ label: '肝功能', value: 'LIVER' },
|
||||
{ label: '肝肾功能', value: 'BOTH' }
|
||||
]
|
||||
|
||||
function resultTagType(auditResult) {
|
||||
const map = { PASS: 'success', REJECT: 'danger', MANUAL: 'warning' }
|
||||
return map[auditResult] || 'info'
|
||||
}
|
||||
|
||||
function resultText(auditResult) {
|
||||
const map = { PASS: '通过', REJECT: '拒绝', MANUAL: '需人工复核' }
|
||||
return map[auditResult] || '未知'
|
||||
}
|
||||
|
||||
function handleSubmit() {
|
||||
formRef.value?.validate(valid => {
|
||||
if (!valid) return
|
||||
loading.value = true
|
||||
adjustDosageByOrganFunction(form).then(res => {
|
||||
result.value = res.data
|
||||
ElMessage.success('调量评估完成')
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
formRef.value?.resetFields()
|
||||
Object.assign(form, {
|
||||
drugCode: '',
|
||||
population: 'ADULT',
|
||||
currentDose: null,
|
||||
doseUnit: 'mg',
|
||||
organFunctionType: 'KIDNEY',
|
||||
creatinine: null,
|
||||
egfr: null,
|
||||
alt: null,
|
||||
ast: null
|
||||
})
|
||||
result.value = null
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
}
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user