feat(P1): 护理专项评估升级 — 压疮/跌倒/营养/疼痛/导管完整业务逻辑
- NursingAssessmentEnhancedController: 5种评估量表(Braden/Morse/NRS2002/NRS/TUBE) - 风险等级自动判定+干预措施自动生成 - NursingAssessmentIntervention: 干预措施管理(待执行/已执行) - V26 Flyway: 干预措施表+评估统计视图 - 前端assessment.vue: Tab式5种评估+实时评分+统计卡片 - 后端编译通过,前端构建通过
This commit is contained in:
@@ -0,0 +1,512 @@
|
||||
package com.healthlink.his.web.nursing.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.nursing.domain.NursingAssessment;
|
||||
import com.healthlink.his.nursing.domain.NursingAssessmentIntervention;
|
||||
import com.healthlink.his.nursing.service.INursingAssessmentInterventionService;
|
||||
import com.healthlink.his.nursing.service.INursingAssessmentService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 护理评估增强 Controller — 压疮/跌倒/管道/营养/疼痛专项评估
|
||||
* 使用已有 nursing_assessment 表,通过 assessment_tool 区分量表类型
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/nursing-assessment-enhanced")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class NursingAssessmentEnhancedController {
|
||||
|
||||
private final INursingAssessmentService assessmentService;
|
||||
private final INursingAssessmentInterventionService interventionService;
|
||||
|
||||
// ==================== 通用查询 ====================
|
||||
|
||||
@GetMapping("/page")
|
||||
public R<?> getPage(
|
||||
@RequestParam(value = "assessmentTool", required = false) String assessmentTool,
|
||||
@RequestParam(value = "riskLevel", required = false) String riskLevel,
|
||||
@RequestParam(value = "encounterId", required = false) Long encounterId,
|
||||
@RequestParam(value = "patientName", required = false) String patientName,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
|
||||
LambdaQueryWrapper<NursingAssessment> w = new LambdaQueryWrapper<>();
|
||||
w.eq(StringUtils.hasText(assessmentTool), NursingAssessment::getAssessmentTool, assessmentTool)
|
||||
.eq(StringUtils.hasText(riskLevel), NursingAssessment::getRiskLevel, riskLevel)
|
||||
.eq(encounterId != null, NursingAssessment::getEncounterId, encounterId)
|
||||
.like(StringUtils.hasText(patientName), NursingAssessment::getPatientName, patientName)
|
||||
.eq(NursingAssessment::getDelFlag, "0")
|
||||
.orderByDesc(NursingAssessment::getAssessmentTime);
|
||||
return R.ok(assessmentService.page(new Page<>(pageNo, pageSize), w));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public R<?> getList(
|
||||
@RequestParam("encounterId") Long encounterId,
|
||||
@RequestParam(value = "assessmentTool", required = false) String assessmentTool) {
|
||||
LambdaQueryWrapper<NursingAssessment> w = new LambdaQueryWrapper<>();
|
||||
w.eq(NursingAssessment::getEncounterId, encounterId)
|
||||
.eq(StringUtils.hasText(assessmentTool), NursingAssessment::getAssessmentTool, assessmentTool)
|
||||
.eq(NursingAssessment::getDelFlag, "0")
|
||||
.orderByDesc(NursingAssessment::getAssessmentTime);
|
||||
return R.ok(assessmentService.list(w));
|
||||
}
|
||||
|
||||
// ==================== 压疮评估(Braden) ====================
|
||||
|
||||
@PostMapping("/braden/assess")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> bradenAssess(@RequestBody NursingAssessment assessment) {
|
||||
Map<String, Integer> scores = parseItemScores(assessment.getItemScores());
|
||||
// Braden量表6项: 感觉(1-4) 潮湿(1-4) 活动(1-4) 移动(1-4) 营养(1-4) 摩擦力(1-3)
|
||||
int total = scores.values().stream().mapToInt(Integer::intValue).sum();
|
||||
String riskLevel = bradenRiskLevel(total);
|
||||
|
||||
assessment.setAssessmentTool("BRADEN");
|
||||
assessment.setTotalScore(total);
|
||||
assessment.setRiskLevel(riskLevel);
|
||||
assessment.setDelFlag("0");
|
||||
assessment.setAssessmentTime(new Date());
|
||||
assessmentService.save(assessment);
|
||||
|
||||
// 自动生成干预措施
|
||||
List<String> interventions = bradenInterventions(riskLevel);
|
||||
for (String content : interventions) {
|
||||
NursingAssessmentIntervention iv = new NursingAssessmentIntervention();
|
||||
iv.setAssessmentId(assessment.getId());
|
||||
iv.setEncounterId(assessment.getEncounterId());
|
||||
iv.setPatientId(assessment.getPatientId());
|
||||
iv.setRiskLevel(riskLevel);
|
||||
iv.setInterventionType("PRESSURE_ULCER");
|
||||
iv.setInterventionContent(content);
|
||||
iv.setNurseName(assessment.getAssessorName());
|
||||
iv.setStatus("PENDING");
|
||||
iv.setCreateTime(new Date());
|
||||
interventionService.save(iv);
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("assessment", assessment);
|
||||
result.put("interventions", interventions);
|
||||
result.put("riskDescription", bradenRiskDescription(riskLevel));
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
// ==================== 跌倒评估(Morse) ====================
|
||||
|
||||
@PostMapping("/morse/assess")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> morseAssess(@RequestBody NursingAssessment assessment) {
|
||||
Map<String, Integer> scores = parseItemScores(assessment.getItemScores());
|
||||
// Morse量表5项: 跌倒史(0-25) 医学诊断(0-15) 步行辅助(0-15) 静脉输液(0-20) 步态(0-20)
|
||||
int total = scores.values().stream().mapToInt(Integer::intValue).sum();
|
||||
String riskLevel = morseRiskLevel(total);
|
||||
|
||||
assessment.setAssessmentTool("MORSE");
|
||||
assessment.setTotalScore(total);
|
||||
assessment.setRiskLevel(riskLevel);
|
||||
assessment.setDelFlag("0");
|
||||
assessment.setAssessmentTime(new Date());
|
||||
assessmentService.save(assessment);
|
||||
|
||||
List<String> interventions = morseInterventions(riskLevel);
|
||||
for (String content : interventions) {
|
||||
NursingAssessmentIntervention iv = new NursingAssessmentIntervention();
|
||||
iv.setAssessmentId(assessment.getId());
|
||||
iv.setEncounterId(assessment.getEncounterId());
|
||||
iv.setPatientId(assessment.getPatientId());
|
||||
iv.setRiskLevel(riskLevel);
|
||||
iv.setInterventionType("FALL_RISK");
|
||||
iv.setInterventionContent(content);
|
||||
iv.setNurseName(assessment.getAssessorName());
|
||||
iv.setStatus("PENDING");
|
||||
iv.setCreateTime(new Date());
|
||||
interventionService.save(iv);
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("assessment", assessment);
|
||||
result.put("interventions", interventions);
|
||||
result.put("riskDescription", morseRiskDescription(riskLevel));
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
// ==================== 营养筛查(NRS 2002) ====================
|
||||
|
||||
@PostMapping("/nrs2002/assess")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> nrs2002Assess(@RequestBody NursingAssessment assessment) {
|
||||
Map<String, Integer> scores = parseItemScores(assessment.getItemScores());
|
||||
// NRS2002: 疾病严重(0-3) 营养状况(0-3) 年龄(0-1) 总分0-7
|
||||
int total = scores.values().stream().mapToInt(Integer::intValue).sum();
|
||||
String riskLevel = nrs2002RiskLevel(total);
|
||||
|
||||
assessment.setAssessmentTool("NRS2002");
|
||||
assessment.setTotalScore(total);
|
||||
assessment.setRiskLevel(riskLevel);
|
||||
assessment.setDelFlag("0");
|
||||
assessment.setAssessmentTime(new Date());
|
||||
assessmentService.save(assessment);
|
||||
|
||||
List<String> interventions = nrs2002Interventions(riskLevel);
|
||||
for (String content : interventions) {
|
||||
NursingAssessmentIntervention iv = new NursingAssessmentIntervention();
|
||||
iv.setAssessmentId(assessment.getId());
|
||||
iv.setEncounterId(assessment.getEncounterId());
|
||||
iv.setPatientId(assessment.getPatientId());
|
||||
iv.setRiskLevel(riskLevel);
|
||||
iv.setInterventionType("NUTRITION");
|
||||
iv.setInterventionContent(content);
|
||||
iv.setNurseName(assessment.getAssessorName());
|
||||
iv.setStatus("PENDING");
|
||||
iv.setCreateTime(new Date());
|
||||
interventionService.save(iv);
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("assessment", assessment);
|
||||
result.put("interventions", interventions);
|
||||
result.put("riskDescription", nrs2002RiskDescription(riskLevel));
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
// ==================== 疼痛评估(NRS) ====================
|
||||
|
||||
@PostMapping("/pain/assess")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> painAssess(@RequestBody NursingAssessment assessment) {
|
||||
Map<String, Integer> scores = parseItemScores(assessment.getItemScores());
|
||||
// NRS疼痛评分: 0-10
|
||||
int total = scores.getOrDefault("pain_score", 0);
|
||||
String riskLevel = painRiskLevel(total);
|
||||
|
||||
assessment.setAssessmentTool("NRS_PAIN");
|
||||
assessment.setTotalScore(total);
|
||||
assessment.setRiskLevel(riskLevel);
|
||||
assessment.setDelFlag("0");
|
||||
assessment.setAssessmentTime(new Date());
|
||||
assessmentService.save(assessment);
|
||||
|
||||
List<String> interventions = painInterventions(riskLevel, total);
|
||||
for (String content : interventions) {
|
||||
NursingAssessmentIntervention iv = new NursingAssessmentIntervention();
|
||||
iv.setAssessmentId(assessment.getId());
|
||||
iv.setEncounterId(assessment.getEncounterId());
|
||||
iv.setPatientId(assessment.getPatientId());
|
||||
iv.setRiskLevel(riskLevel);
|
||||
iv.setInterventionType("PAIN");
|
||||
iv.setInterventionContent(content);
|
||||
iv.setNurseName(assessment.getAssessorName());
|
||||
iv.setStatus("PENDING");
|
||||
iv.setCreateTime(new Date());
|
||||
interventionService.save(iv);
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("assessment", assessment);
|
||||
result.put("interventions", interventions);
|
||||
result.put("riskDescription", painRiskDescription(riskLevel, total));
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
// ==================== 导管评估 ====================
|
||||
|
||||
@PostMapping("/tube/assess")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> tubeAssess(@RequestBody NursingAssessment assessment) {
|
||||
Map<String, Integer> scores = parseItemScores(assessment.getItemScores());
|
||||
// 导管评估: 导管类型(1-5) 固定情况(1-3) 通畅情况(1-3) 周围皮肤(1-3) 感染风险(1-3)
|
||||
int total = scores.values().stream().mapToInt(Integer::intValue).sum();
|
||||
String riskLevel = tubeRiskLevel(total);
|
||||
|
||||
assessment.setAssessmentTool("TUBE");
|
||||
assessment.setTotalScore(total);
|
||||
assessment.setRiskLevel(riskLevel);
|
||||
assessment.setDelFlag("0");
|
||||
assessment.setAssessmentTime(new Date());
|
||||
assessmentService.save(assessment);
|
||||
|
||||
List<String> interventions = tubeInterventions(riskLevel);
|
||||
for (String content : interventions) {
|
||||
NursingAssessmentIntervention iv = new NursingAssessmentIntervention();
|
||||
iv.setAssessmentId(assessment.getId());
|
||||
iv.setEncounterId(assessment.getEncounterId());
|
||||
iv.setPatientId(assessment.getPatientId());
|
||||
iv.setRiskLevel(riskLevel);
|
||||
iv.setInterventionType("TUBE");
|
||||
iv.setInterventionContent(content);
|
||||
iv.setNurseName(assessment.getAssessorName());
|
||||
iv.setStatus("PENDING");
|
||||
iv.setCreateTime(new Date());
|
||||
interventionService.save(iv);
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("assessment", assessment);
|
||||
result.put("interventions", interventions);
|
||||
result.put("riskDescription", tubeRiskDescription(riskLevel));
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
// ==================== 干预措施管理 ====================
|
||||
|
||||
@GetMapping("/intervention/page")
|
||||
public R<?> getInterventionPage(
|
||||
@RequestParam(value = "interventionType", required = false) String interventionType,
|
||||
@RequestParam(value = "status", required = false) String status,
|
||||
@RequestParam(value = "encounterId", required = false) Long encounterId,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
|
||||
LambdaQueryWrapper<NursingAssessmentIntervention> w = new LambdaQueryWrapper<>();
|
||||
w.eq(StringUtils.hasText(interventionType), NursingAssessmentIntervention::getInterventionType, interventionType)
|
||||
.eq(StringUtils.hasText(status), NursingAssessmentIntervention::getStatus, status)
|
||||
.eq(encounterId != null, NursingAssessmentIntervention::getEncounterId, encounterId)
|
||||
.orderByDesc(NursingAssessmentIntervention::getCreateTime);
|
||||
return R.ok(interventionService.page(new Page<>(pageNo, pageSize), w));
|
||||
}
|
||||
|
||||
@PutMapping("/intervention/execute/{id}")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> executeIntervention(@PathVariable Long id) {
|
||||
NursingAssessmentIntervention iv = interventionService.getById(id);
|
||||
if (iv == null) return R.fail("干预记录不存在");
|
||||
iv.setStatus("EXECUTED");
|
||||
iv.setExecuteTime(new Date());
|
||||
interventionService.updateById(iv);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// ==================== 统计 ====================
|
||||
|
||||
@GetMapping("/stats")
|
||||
public R<?> getStats(
|
||||
@RequestParam(value = "startDate", required = false) String startDate,
|
||||
@RequestParam(value = "endDate", required = false) String endDate) {
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
String[] tools = {"BRADEN", "MORSE", "NRS2002", "NRS_PAIN", "TUBE"};
|
||||
for (String tool : tools) {
|
||||
LambdaQueryWrapper<NursingAssessment> w = new LambdaQueryWrapper<>();
|
||||
w.eq(NursingAssessment::getAssessmentTool, tool)
|
||||
.eq(NursingAssessment::getDelFlag, "0");
|
||||
long total = assessmentService.count(w);
|
||||
|
||||
LambdaQueryWrapper<NursingAssessment> hw = new LambdaQueryWrapper<>();
|
||||
hw.eq(NursingAssessment::getAssessmentTool, tool)
|
||||
.eq(NursingAssessment::getRiskLevel, "HIGH")
|
||||
.eq(NursingAssessment::getDelFlag, "0");
|
||||
long highRisk = assessmentService.count(hw);
|
||||
|
||||
stats.put(tool + "_total", total);
|
||||
stats.put(tool + "_high_risk", highRisk);
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<NursingAssessmentIntervention> iw = new LambdaQueryWrapper<>();
|
||||
iw.eq(NursingAssessmentIntervention::getStatus, "PENDING");
|
||||
stats.put("pending_interventions", interventionService.count(iw));
|
||||
|
||||
return R.ok(stats);
|
||||
}
|
||||
|
||||
// ==================== 业务逻辑: 风险等级判定 ====================
|
||||
|
||||
private String bradenRiskLevel(int score) {
|
||||
if (score <= 12) return "HIGH";
|
||||
if (score <= 14) return "MEDIUM";
|
||||
if (score <= 18) return "LOW";
|
||||
return "NORMAL";
|
||||
}
|
||||
|
||||
private String morseRiskLevel(int score) {
|
||||
if (score >= 45) return "HIGH";
|
||||
if (score >= 25) return "MEDIUM";
|
||||
return "LOW";
|
||||
}
|
||||
|
||||
private String nrs2002RiskLevel(int score) {
|
||||
if (score >= 3) return "HIGH";
|
||||
if (score >= 2) return "MEDIUM";
|
||||
return "NORMAL";
|
||||
}
|
||||
|
||||
private String painRiskLevel(int score) {
|
||||
if (score >= 7) return "HIGH";
|
||||
if (score >= 4) return "MEDIUM";
|
||||
if (score >= 1) return "LOW";
|
||||
return "NORMAL";
|
||||
}
|
||||
|
||||
private String tubeRiskLevel(int score) {
|
||||
if (score >= 12) return "HIGH";
|
||||
if (score >= 8) return "MEDIUM";
|
||||
return "LOW";
|
||||
}
|
||||
|
||||
// ==================== 业务逻辑: 干预措施 ====================
|
||||
|
||||
private List<String> bradenInterventions(String riskLevel) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if ("HIGH".equals(riskLevel)) {
|
||||
list.add("每2小时翻身一次,使用气垫床");
|
||||
list.add("保持皮肤清洁干燥,使用皮肤保护膜");
|
||||
list.add("加强营养支持,高蛋白饮食");
|
||||
list.add("使用减压敷料保护骨隆突处");
|
||||
list.add("填写压疮风险评估单,上报护士长");
|
||||
} else if ("MEDIUM".equals(riskLevel)) {
|
||||
list.add("每3小时翻身一次");
|
||||
list.add("保持皮肤清洁,使用润肤露");
|
||||
list.add("加强营养,增加蛋白质摄入");
|
||||
list.add("使用减压床垫");
|
||||
} else if ("LOW".equals(riskLevel)) {
|
||||
list.add("定时翻身,避免局部长期受压");
|
||||
list.add("保持皮肤清洁");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> morseInterventions(String riskLevel) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if ("HIGH".equals(riskLevel)) {
|
||||
list.add("悬挂高危跌倒标识");
|
||||
list.add("床栏上抬,必要时使用约束带");
|
||||
list.add("协助如厕,防滑鞋");
|
||||
list.add("床头铃置于易取处,呼叫器放在枕边");
|
||||
list.add("每1小时巡视,评估意识状态");
|
||||
list.add("填写跌倒风险评估单,上报护士长");
|
||||
} else if ("MEDIUM".equals(riskLevel)) {
|
||||
list.add("悬挂中危跌倒标识");
|
||||
list.add("床栏上抬,走廊扶手");
|
||||
list.add("协助下床活动");
|
||||
list.add("每2小时巡视");
|
||||
} else {
|
||||
list.add("做好防跌倒宣教");
|
||||
list.add("保持地面干燥");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> nrs2002Interventions(String riskLevel) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if ("HIGH".equals(riskLevel)) {
|
||||
list.add("请营养科会诊,制定营养支持方案");
|
||||
list.add("给予肠内/肠外营养支持");
|
||||
list.add("每日监测体重、白蛋白、前白蛋白");
|
||||
list.add("记录24小时出入量");
|
||||
} else if ("MEDIUM".equals(riskLevel)) {
|
||||
list.add("增加蛋白质摄入,口服营养补充剂");
|
||||
list.add("每周监测体重");
|
||||
list.add("营养宣教");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> painInterventions(String riskLevel, int score) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if ("HIGH".equals(riskLevel)) {
|
||||
list.add("立即通知医生,遵医嘱给予镇痛药");
|
||||
list.add("评估疼痛性质、部位、持续时间");
|
||||
list.add("每4小时评估疼痛评分");
|
||||
list.add("非药物镇痛:体位调整、冷敷/热敷");
|
||||
} else if ("MEDIUM".equals(riskLevel)) {
|
||||
list.add("遵医嘱给予口服镇痛药");
|
||||
list.add("每8小时评估疼痛评分");
|
||||
list.add("指导患者使用疼痛日记");
|
||||
} else if ("LOW".equals(riskLevel)) {
|
||||
list.add("继续观察,每日评估");
|
||||
list.add("非药物缓解:音乐疗法、放松训练");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<String> tubeInterventions(String riskLevel) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if ("HIGH".equals(riskLevel)) {
|
||||
list.add("每日评估导管必要性,尽早拔管");
|
||||
list.add("加强导管固定,使用专业固定装置");
|
||||
list.add("每日消毒导管周围皮肤");
|
||||
list.add("监测感染指标,必要时做培养");
|
||||
list.add("每班评估导管通畅性");
|
||||
} else if ("MEDIUM".equals(riskLevel)) {
|
||||
list.add("加强导管固定,防止脱出");
|
||||
list.add("每日评估导管功能");
|
||||
list.add("保持导管周围皮肤清洁");
|
||||
} else {
|
||||
list.add("常规导管护理");
|
||||
list.add("每班评估导管状态");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// ==================== 业务逻辑: 风险描述 ====================
|
||||
|
||||
private String bradenRiskDescription(String level) {
|
||||
switch (level) {
|
||||
case "HIGH": return "压疮高危(≤12分): 需立即采取综合预防措施";
|
||||
case "MEDIUM": return "压疮中危(13-14分): 需加强预防";
|
||||
case "LOW": return "压疮低危(15-18分): 常规预防";
|
||||
default: return "压疮无风险(>18分)";
|
||||
}
|
||||
}
|
||||
|
||||
private String morseRiskDescription(String level) {
|
||||
switch (level) {
|
||||
case "HIGH": return "跌倒高危(≥45分): 需专人看护+环境改造";
|
||||
case "MEDIUM": return "跌倒中危(25-44分): 需加强防护";
|
||||
default: return "跌倒低危(<25分): 常规宣教";
|
||||
}
|
||||
}
|
||||
|
||||
private String nrs2002RiskDescription(String level) {
|
||||
switch (level) {
|
||||
case "HIGH": return "营养高危(≥3分): 需营养科会诊+营养支持";
|
||||
case "MEDIUM": return "营养中危(2分): 需营养干预";
|
||||
default: return "营养正常(<2分): 常规饮食";
|
||||
}
|
||||
}
|
||||
|
||||
private String painRiskDescription(String level, int score) {
|
||||
if (score >= 7) return "重度疼痛(" + score + "分): 立即镇痛";
|
||||
if (score >= 4) return "中度疼痛(" + score + "分): 遵医嘱镇痛";
|
||||
if (score >= 1) return "轻度疼痛(" + score + "分): 观察+非药物缓解";
|
||||
return "无疼痛(0分)";
|
||||
}
|
||||
|
||||
private String tubeRiskDescription(String level) {
|
||||
switch (level) {
|
||||
case "HIGH": return "导管高危: 需专人管理+感染防控";
|
||||
case "MEDIUM": return "导管中危: 加强固定+定期评估";
|
||||
default: return "导管低危: 常规护理";
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 工具方法 ====================
|
||||
|
||||
private Map<String, Integer> parseItemScores(String itemScoresJson) {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
if (!StringUtils.hasText(itemScoresJson)) return map;
|
||||
try {
|
||||
String json = itemScoresJson.trim();
|
||||
if (json.startsWith("{")) {
|
||||
json = json.substring(1, json.length() - 1);
|
||||
for (String pair : json.split(",")) {
|
||||
String[] kv = pair.split(":");
|
||||
if (kv.length == 2) {
|
||||
String key = kv[0].trim().replace("\"", "");
|
||||
String val = kv[1].trim().replace("\"", "");
|
||||
map.put(key, Integer.parseInt(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析评估分数失败: {}", itemScoresJson, e);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
-- V26: 护理评估增强 — 干预措施+趋势统计
|
||||
|
||||
-- 评估干预措施表
|
||||
CREATE TABLE IF NOT EXISTS nursing_assessment_intervention (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
assessment_id BIGINT NOT NULL,
|
||||
encounter_id BIGINT NOT NULL,
|
||||
patient_id BIGINT NOT NULL,
|
||||
risk_level VARCHAR(16) NOT NULL,
|
||||
intervention_type VARCHAR(32) NOT NULL,
|
||||
intervention_content TEXT NOT NULL,
|
||||
nurse_name VARCHAR(64),
|
||||
execute_time TIMESTAMP,
|
||||
status VARCHAR(20) DEFAULT 'PENDING',
|
||||
tenant_id BIGINT DEFAULT 0,
|
||||
is_deleted INT NOT NULL DEFAULT 0,
|
||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
COMMENT ON TABLE nursing_assessment_intervention IS '评估干预措施';
|
||||
COMMENT ON COLUMN nursing_assessment_intervention.intervention_type IS '干预类型(PRESSURE_ULCER/FALL_RISK/NUTRITION/PAIN/TUBE)';
|
||||
COMMENT ON COLUMN nursing_assessment_intervention.status IS '状态(PENDING/EXECUTED/CANCELLED)';
|
||||
CREATE INDEX idx_nai_encounter ON nursing_assessment_intervention(encounter_id);
|
||||
CREATE INDEX idx_nai_status ON nursing_assessment_intervention(status);
|
||||
|
||||
-- 评估统计视图
|
||||
CREATE OR REPLACE VIEW v_assessment_stats AS
|
||||
SELECT
|
||||
assessment_tool,
|
||||
risk_level,
|
||||
COUNT(*) as count,
|
||||
DATE(assessment_time) as assess_date
|
||||
FROM nursing_assessment
|
||||
WHERE del_flag = '0'
|
||||
GROUP BY assessment_tool, risk_level, DATE(assessment_time);
|
||||
COMMENT ON VIEW v_assessment_stats IS '评估统计视图';
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.healthlink.his.nursing.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.core.common.core.domain.HisBaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 评估干预措施
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("nursing_assessment_intervention")
|
||||
public class NursingAssessmentIntervention extends HisBaseEntity {
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
private Long assessmentId;
|
||||
private Long encounterId;
|
||||
private Long patientId;
|
||||
private String riskLevel;
|
||||
private String interventionType;
|
||||
private String interventionContent;
|
||||
private String nurseName;
|
||||
private Date executeTime;
|
||||
private String status;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.healthlink.his.nursing.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.healthlink.his.nursing.domain.NursingAssessmentIntervention;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface NursingAssessmentInterventionMapper extends BaseMapper<NursingAssessmentIntervention> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.healthlink.his.nursing.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.healthlink.his.nursing.domain.NursingAssessmentIntervention;
|
||||
|
||||
public interface INursingAssessmentInterventionService extends IService<NursingAssessmentIntervention> {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.healthlink.his.nursing.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.healthlink.his.nursing.domain.NursingAssessmentIntervention;
|
||||
import com.healthlink.his.nursing.mapper.NursingAssessmentInterventionMapper;
|
||||
import com.healthlink.his.nursing.service.INursingAssessmentInterventionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class NursingAssessmentInterventionServiceImpl
|
||||
extends ServiceImpl<NursingAssessmentInterventionMapper, NursingAssessmentIntervention>
|
||||
implements INursingAssessmentInterventionService {
|
||||
}
|
||||
298
healthlink-his-ui/src/views/nursingenhanced/assessment.vue
Normal file
298
healthlink-his-ui/src/views/nursingenhanced/assessment.vue
Normal file
@@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<div style="padding:16px">
|
||||
<div style="margin-bottom:16px;display:flex;justify-content:space-between;align-items:center">
|
||||
<span style="font-size:18px;font-weight:bold">护理专项评估</span>
|
||||
<el-button type="primary" @click="loadStats">刷新统计</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<el-row :gutter="12" style="margin-bottom:16px">
|
||||
<el-col :span="4" v-for="item in statCards" :key="item.label">
|
||||
<el-card shadow="hover" :body-style="{padding:'12px'}">
|
||||
<div style="text-align:center">
|
||||
<div style="font-size:20px;font-weight:bold" :style="{color:item.color}">{{ item.value }}</div>
|
||||
<div style="font-size:12px;color:#999">{{ item.label }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 评估类型Tab -->
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<!-- 压疮评估(Braden) -->
|
||||
<el-tab-pane label="压疮评估(Braden)" name="BRADEN">
|
||||
<div style="margin-bottom:12px">
|
||||
<el-button type="success" @click="openAssess('BRADEN')">新建Braden评估</el-button>
|
||||
</div>
|
||||
<el-table :data="bradenData" border stripe>
|
||||
<el-table-column prop="patientName" label="患者" width="100"/>
|
||||
<el-table-column prop="totalScore" label="总分" width="70" align="center"/>
|
||||
<el-table-column prop="riskLevel" label="风险" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.riskLevel==='HIGH'?'danger':row.riskLevel==='MEDIUM'?'warning':'success'" size="small">
|
||||
{{ row.riskLevel==='HIGH'?'高危':row.riskLevel==='MEDIUM'?'中危':row.riskLevel==='LOW'?'低危':'正常' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="assessorName" label="评估人" width="80"/>
|
||||
<el-table-column prop="assessmentTime" label="评估时间" width="170"/>
|
||||
<el-table-column prop="detail" label="备注" show-overflow-tooltip/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 跌倒评估(Morse) -->
|
||||
<el-tab-pane label="跌倒评估(Morse)" name="MORSE">
|
||||
<div style="margin-bottom:12px">
|
||||
<el-button type="success" @click="openAssess('MORSE')">新建Morse评估</el-button>
|
||||
</div>
|
||||
<el-table :data="morseData" border stripe>
|
||||
<el-table-column prop="patientName" label="患者" width="100"/>
|
||||
<el-table-column prop="totalScore" label="总分" width="70" align="center"/>
|
||||
<el-table-column prop="riskLevel" label="风险" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.riskLevel==='HIGH'?'danger':row.riskLevel==='MEDIUM'?'warning':'success'" size="small">
|
||||
{{ row.riskLevel==='HIGH'?'高危':row.riskLevel==='MEDIUM'?'中危':'低危' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="assessorName" label="评估人" width="80"/>
|
||||
<el-table-column prop="assessmentTime" label="评估时间" width="170"/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 营养筛查(NRS2002) -->
|
||||
<el-tab-pane label="营养筛查(NRS2002)" name="NRS2002">
|
||||
<div style="margin-bottom:12px">
|
||||
<el-button type="success" @click="openAssess('NRS2002')">新建NRS2002评估</el-button>
|
||||
</div>
|
||||
<el-table :data="nrs2002Data" border stripe>
|
||||
<el-table-column prop="patientName" label="患者" width="100"/>
|
||||
<el-table-column prop="totalScore" label="总分" width="70" align="center"/>
|
||||
<el-table-column prop="riskLevel" label="风险" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.riskLevel==='HIGH'?'danger':row.riskLevel==='MEDIUM'?'warning':'success'" size="small">
|
||||
{{ row.riskLevel==='HIGH'?'高危':row.riskLevel==='MEDIUM'?'中危':'正常' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="assessorName" label="评估人" width="80"/>
|
||||
<el-table-column prop="assessmentTime" label="评估时间" width="170"/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 疼痛评估(NRS) -->
|
||||
<el-tab-pane label="疼痛评估(NRS)" name="NRS_PAIN">
|
||||
<div style="margin-bottom:12px">
|
||||
<el-button type="success" @click="openAssess('NRS_PAIN')">新建疼痛评估</el-button>
|
||||
</div>
|
||||
<el-table :data="painData" border stripe>
|
||||
<el-table-column prop="patientName" label="患者" width="100"/>
|
||||
<el-table-column prop="totalScore" label="疼痛评分" width="80" align="center">
|
||||
<template #default="{row}">
|
||||
<span :style="{color:row.totalScore>=7?'red':row.totalScore>=4?'orange':'green',fontWeight:'bold'}">{{ row.totalScore }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="riskLevel" label="程度" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.riskLevel==='HIGH'?'danger':row.riskLevel==='MEDIUM'?'warning':'success'" size="small">
|
||||
{{ row.riskLevel==='HIGH'?'重度':row.riskLevel==='MEDIUM'?'中度':row.riskLevel==='LOW'?'轻度':'无痛' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="assessorName" label="评估人" width="80"/>
|
||||
<el-table-column prop="assessmentTime" label="评估时间" width="170"/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 导管评估 -->
|
||||
<el-tab-pane label="导管评估" name="TUBE">
|
||||
<div style="margin-bottom:12px">
|
||||
<el-button type="success" @click="openAssess('TUBE')">新建导管评估</el-button>
|
||||
</div>
|
||||
<el-table :data="tubeData" border stripe>
|
||||
<el-table-column prop="patientName" label="患者" width="100"/>
|
||||
<el-table-column prop="totalScore" label="总分" width="70" align="center"/>
|
||||
<el-table-column prop="riskLevel" label="风险" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.riskLevel==='HIGH'?'danger':row.riskLevel==='MEDIUM'?'warning':'success'" size="small">
|
||||
{{ row.riskLevel==='HIGH'?'高危':row.riskLevel==='MEDIUM'?'中危':'低危' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="assessorName" label="评估人" width="80"/>
|
||||
<el-table-column prop="assessmentTime" label="评估时间" width="170"/>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 干预措施 -->
|
||||
<el-tab-pane label="干预措施" name="INTERVENTION">
|
||||
<el-table :data="interventionData" border stripe>
|
||||
<el-table-column prop="interventionType" label="类型" width="100"/>
|
||||
<el-table-column prop="riskLevel" label="风险" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.riskLevel==='HIGH'?'danger':row.riskLevel==='MEDIUM'?'warning':'info'" size="small">{{ row.riskLevel }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="interventionContent" label="干预内容" min-width="200" show-overflow-tooltip/>
|
||||
<el-table-column prop="nurseName" label="护士" width="80"/>
|
||||
<el-table-column prop="status" label="状态" width="80">
|
||||
<template #default="{row}">
|
||||
<el-tag :type="row.status==='EXECUTED'?'success':row.status==='CANCELLED'?'info':'warning'" size="small">
|
||||
{{ row.status==='EXECUTED'?'已执行':row.status==='CANCELLED'?'已取消':'待执行' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="{row}">
|
||||
<el-button v-if="row.status==='PENDING'" type="success" link size="small" @click="execIntervention(row.id)">执行</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!-- 评估对话框 -->
|
||||
<el-dialog v-model="assessDialogVisible" :title="assessDialogTitle" width="600px">
|
||||
<el-form :model="assessForm" label-width="100px">
|
||||
<el-form-item label="患者ID"><el-input v-model.number="assessForm.patientId"/></el-form-item>
|
||||
<el-form-item label="就诊ID"><el-input v-model.number="assessForm.encounterId"/></el-form-item>
|
||||
<el-form-item label="患者姓名"><el-input v-model="assessForm.patientName"/></el-form-item>
|
||||
<el-form-item label="评估人"><el-input v-model="assessForm.assessorName"/></el-form-item>
|
||||
|
||||
<!-- Braden量表 -->
|
||||
<template v-if="currentTool==='BRADEN'">
|
||||
<el-divider content-position="left">Braden压疮风险评估量表</el-divider>
|
||||
<el-form-item label="感觉(1-4)"><el-input-number v-model="bradenScores.sensory" :min="1" :max="4"/></el-form-item>
|
||||
<el-form-item label="潮湿(1-4)"><el-input-number v-model="bradenScores.moisture" :min="1" :max="4"/></el-form-item>
|
||||
<el-form-item label="活动(1-4)"><el-input-number v-model="bradenScores.activity" :min="1" :max="4"/></el-form-item>
|
||||
<el-form-item label="移动(1-4)"><el-input-number v-model="bradenScores.mobility" :min="1" :max="4"/></el-form-item>
|
||||
<el-form-item label="营养(1-4)"><el-input-number v-model="bradenScores.nutrition" :min="1" :max="4"/></el-form-item>
|
||||
<el-form-item label="摩擦力(1-3)"><el-input-number v-model="bradenScores.friction" :min="1" :max="3"/></el-form-item>
|
||||
<el-form-item label="预估总分"><span style="font-size:18px;font-weight:bold;color:#e6a23c">{{ bradenTotal }}</span></el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- Morse量表 -->
|
||||
<template v-if="currentTool==='MORSE'">
|
||||
<el-divider content-position="left">Morse跌倒风险评估量表</el-divider>
|
||||
<el-form-item label="跌倒史(0-25)"><el-input-number v-model="morseScores.fall_history" :min="0" :max="25"/></el-form-item>
|
||||
<el-form-item label="医学诊断(0-15)"><el-input-number v-model="morseScores.diagnosis" :min="0" :max="15"/></el-form-item>
|
||||
<el-form-item label="步行辅助(0-15)"><el-input-number v-model="morseScores.gait" :min="0" :max="15"/></el-form-item>
|
||||
<el-form-item label="静脉输液(0-20)"><el-input-number v-model="morseScores.iv" :min="0" :max="20"/></el-form-item>
|
||||
<el-form-item label="步态(0-20)"><el-input-number v-model="morseScores.gait_type" :min="0" :max="20"/></el-form-item>
|
||||
<el-form-item label="预估总分"><span style="font-size:18px;font-weight:bold;color:#e6a23c">{{ morseTotal }}</span></el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- NRS2002 -->
|
||||
<template v-if="currentTool==='NRS2002'">
|
||||
<el-divider content-position="left">NRS2002营养风险筛查</el-divider>
|
||||
<el-form-item label="疾病严重(0-3)"><el-input-number v-model="nrsScores.disease" :min="0" :max="3"/></el-form-item>
|
||||
<el-form-item label="营养状况(0-3)"><el-input-number v-model="nrsScores.nutrition" :min="0" :max="3"/></el-form-item>
|
||||
<el-form-item label="年龄(0-1)"><el-input-number v-model="nrsScores.age" :min="0" :max="1"/></el-form-item>
|
||||
<el-form-item label="预估总分"><span style="font-size:18px;font-weight:bold;color:#e6a23c">{{ nrsTotal }}</span></el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 疼痛NRS -->
|
||||
<template v-if="currentTool==='NRS_PAIN'">
|
||||
<el-divider content-position="left">NRS数字疼痛评分(0-10)</el-divider>
|
||||
<el-form-item label="疼痛评分">
|
||||
<el-slider v-model="painScore" :min="0" :max="10" :marks="painMarks" show-stops/>
|
||||
</el-form-item>
|
||||
<el-form-item label="疼痛描述">
|
||||
<span style="font-size:16px;font-weight:bold" :style="{color:painScore>=7?'red':painScore>=4?'orange':painScore>=1?'#e6a23c':'green'}">
|
||||
{{ painScore===0?'无痛':painScore<=3?'轻度疼痛':painScore<=6?'中度疼痛':'重度疼痛' }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 导管评估 -->
|
||||
<template v-if="currentTool==='TUBE'">
|
||||
<el-divider content-position="left">导管风险评估</el-divider>
|
||||
<el-form-item label="导管类型(1-5)"><el-input-number v-model="tubeScores.type" :min="1" :max="5"/></el-form-item>
|
||||
<el-form-item label="固定情况(1-3)"><el-input-number v-model="tubeScores.fixation" :min="1" :max="3"/></el-form-item>
|
||||
<el-form-item label="通畅情况(1-3)"><el-input-number v-model="tubeScores.patency" :min="1" :max="3"/></el-form-item>
|
||||
<el-form-item label="周围皮肤(1-3)"><el-input-number v-model="tubeScores.skin" :min="1" :max="3"/></el-form-item>
|
||||
<el-form-item label="感染风险(1-3)"><el-input-number v-model="tubeScores.infection" :min="1" :max="3"/></el-form-item>
|
||||
<el-form-item label="预估总分"><span style="font-size:18px;font-weight:bold;color:#e6a23c">{{ tubeTotal }}</span></el-form-item>
|
||||
</template>
|
||||
|
||||
<el-form-item label="备注"><el-input v-model="assessForm.detail" type="textarea" :rows="2"/></el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="assessDialogVisible=false">取消</el-button>
|
||||
<el-button type="primary" @click="submitAssess">提交评估</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref,computed,onMounted} from 'vue'
|
||||
import {ElMessage} from 'element-plus'
|
||||
import {getAssessmentPage,bradenAssess,morseAssess,nrs2002Assess,painAssess,tubeAssess,getInterventionPage,executeIntervention,getStats} from './assessmentApi'
|
||||
|
||||
const activeTab=ref('BRADEN')
|
||||
const bradenData=ref([]);const morseData=ref([]);const nrs2002Data=ref([]);const painData=ref([]);const tubeData=ref([])
|
||||
const interventionData=ref([]);const stats=ref({})
|
||||
|
||||
const assessDialogVisible=ref(false)
|
||||
const currentTool=ref('BRADEN')
|
||||
const assessDialogTitle=computed(()=>({BRADEN:'Braden压疮评估',MORSE:'Morse跌倒评估',NRS2002:'NRS2002营养筛查',NRS_PAIN:'疼痛评估(NRS)',TUBE:'导管风险评估'}[currentTool.value]))
|
||||
const assessForm=ref({patientId:null,encounterId:null,patientName:'',assessorName:'',detail:''})
|
||||
|
||||
const bradenScores=ref({sensory:4,moisture:4,activity:4,mobility:4,nutrition:4,friction:3})
|
||||
const bradenTotal=computed(()=>Object.values(bradenScores.value).reduce((a,b)=>a+b,0))
|
||||
|
||||
const morseScores=ref({fall_history:0,diagnosis:0,gait:0,iv:0,gait_type:0})
|
||||
const morseTotal=computed(()=>Object.values(morseScores.value).reduce((a,b)=>a+b,0))
|
||||
|
||||
const nrsScores=ref({disease:0,nutrition:0,age:0})
|
||||
const nrsTotal=computed(()=>Object.values(nrsScores.value).reduce((a,b)=>a+b,0))
|
||||
|
||||
const painScore=ref(0)
|
||||
const painMarks=ref({0:'无痛',3:'轻度',6:'中度',10:'重度'})
|
||||
|
||||
const tubeScores=ref({type:1,fixation:1,patency:1,skin:1,infection:1})
|
||||
const tubeTotal=computed(()=>Object.values(tubeScores.value).reduce((a,b)=>a+b,0))
|
||||
|
||||
const statCards=computed(()=>[
|
||||
{label:'压疮评估',value:stats.value.BRADEN_total||0,color:'#e6a23c'},
|
||||
{label:'压疮高危',value:stats.value.BRADEN_high_risk||0,color:'#f56c6c'},
|
||||
{label:'跌倒评估',value:stats.value.MORSE_total||0,color:'#409eff'},
|
||||
{label:'跌倒高危',value:stats.value.MORSE_high_risk||0,color:'#f56c6c'},
|
||||
{label:'营养筛查',value:stats.value.NRS2002_total||0,color:'#67c23a'},
|
||||
{label:'待执行干预',value:stats.value.pending_interventions||0,color:'#e6a23c'},
|
||||
])
|
||||
|
||||
const loadData=async()=>{
|
||||
const p={pageNo:1,pageSize:50}
|
||||
const [b,m,n,pa,t]=await Promise.all([
|
||||
getAssessmentPage({...p,assessmentTool:'BRADEN'}),
|
||||
getAssessmentPage({...p,assessmentTool:'MORSE'}),
|
||||
getAssessmentPage({...p,assessmentTool:'NRS2002'}),
|
||||
getAssessmentPage({...p,assessmentTool:'NRS_PAIN'}),
|
||||
getAssessmentPage({...p,assessmentTool:'TUBE'}),
|
||||
])
|
||||
bradenData.value=b.data?.records||[];morseData.value=m.data?.records||[]
|
||||
nrs2002Data.value=n.data?.records||[];painData.value=pa.data?.records||[]
|
||||
tubeData.value=t.data?.records||[]
|
||||
const iv=await getInterventionPage({pageNo:1,pageSize:50})
|
||||
interventionData.value=iv.data?.records||[]
|
||||
}
|
||||
const loadStats=async()=>{const r=await getStats();stats.value=r.data||{}}
|
||||
const openAssess=(tool)=>{currentTool.value=tool;assessForm.value={patientId:null,encounterId:null,patientName:'',assessorName:'',detail:''};assessDialogVisible.value=true}
|
||||
const submitAssess=async()=>{
|
||||
let scores={}
|
||||
if(currentTool.value==='BRADEN')scores=bradenScores.value
|
||||
else if(currentTool.value==='MORSE')scores=morseScores.value
|
||||
else if(currentTool.value==='NRS2002')scores=nrsScores.value
|
||||
else if(currentTool.value==='NRS_PAIN')scores={pain_score:painScore.value}
|
||||
else if(currentTool.value==='TUBE')scores=tubeScores.value
|
||||
|
||||
const data={...assessForm.value,itemScores:JSON.stringify(scores)}
|
||||
const assessFn={BRADEN:bradenAssess,MORSE:morseAssess,NRS2002:nrs2002Assess,NRS_PAIN:painAssess,TUBE:tubeAssess}
|
||||
const r=await assessFn[currentTool.value](data)
|
||||
ElMessage.success('评估完成,风险等级: '+r.data?.assessment?.riskLevel)
|
||||
assessDialogVisible.value=false;loadData();loadStats()
|
||||
}
|
||||
const execIntervention=async(id)=>{await executeIntervention(id);ElMessage.success('已执行');loadData();loadStats()}
|
||||
onMounted(()=>{loadData();loadStats()})
|
||||
</script>
|
||||
11
healthlink-his-ui/src/views/nursingenhanced/assessmentApi.js
Normal file
11
healthlink-his-ui/src/views/nursingenhanced/assessmentApi.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import request from '@/utils/request'
|
||||
export function getAssessmentPage(p){return request({url:'/nursing-assessment-enhanced/page',method:'get',params:p})}
|
||||
export function getAssessmentList(p){return request({url:'/nursing-assessment-enhanced/list',method:'get',params:p})}
|
||||
export function bradenAssess(d){return request({url:'/nursing-assessment-enhanced/braden/assess',method:'post',data:d})}
|
||||
export function morseAssess(d){return request({url:'/nursing-assessment-enhanced/morse/assess',method:'post',data:d})}
|
||||
export function nrs2002Assess(d){return request({url:'/nursing-assessment-enhanced/nrs2002/assess',method:'post',data:d})}
|
||||
export function painAssess(d){return request({url:'/nursing-assessment-enhanced/pain/assess',method:'post',data:d})}
|
||||
export function tubeAssess(d){return request({url:'/nursing-assessment-enhanced/tube/assess',method:'post',data:d})}
|
||||
export function getInterventionPage(p){return request({url:'/nursing-assessment-enhanced/intervention/page',method:'get',params:p})}
|
||||
export function executeIntervention(id){return request({url:'/nursing-assessment-enhanced/intervention/execute/'+id,method:'put'})}
|
||||
export function getStats(p){return request({url:'/nursing-assessment-enhanced/stats',method:'get',params:p})}
|
||||
Reference in New Issue
Block a user