WXL (wul)
5 天以前 39c8b288ec8294e026459dfb1955f0bbc49ebb52
src/views/patient/archives/maternalHealth/KuppermanScoreTable.vue
@@ -1,50 +1,144 @@
<template>
  <div>
    <el-table :data="items" border size="small">
      <el-table-column prop="symptom" label="症状" width="160" />
      <el-table-column label="程度" align="center" width="120">
        <template slot-scope="scope">
          <el-select v-if="editing" v-model="scope.row.degree" size="small">
            <el-option v-for="o in degrees" :key="o.v" :label="o.l" :value="o.v" />
          </el-select>
          <span v-else>{{ degLabel(scope.row.degree) }}</span>
        </template>
  <div class="scale-wrap">
    <div class="scale-title">改良 Kupperman 评分标准</div>
    <!-- 纸质表表头:患者基本信息 -->
    <el-descriptions :column="3" border size="small" class="scale-head">
      <el-descriptions-item label="姓名">{{ patient.name || "-" }}</el-descriptions-item>
      <el-descriptions-item label="性别">{{ patient.sex || "-" }}</el-descriptions-item>
      <el-descriptions-item label="年龄">{{ patient.age || "-" }}</el-descriptions-item>
      <el-descriptions-item label="科室">{{ patient.dept || "-" }}</el-descriptions-item>
      <el-descriptions-item label="临床诊断">{{ patient.diagnosis || "-" }}</el-descriptions-item>
      <el-descriptions-item label="评估日期">
        <el-date-picker v-if="editing" v-model="local.date" value-format="yyyy-MM-dd" size="mini" style="width:160px" placeholder="选择日期" />
        <span v-else>{{ local.date || "-" }}</span>
      </el-descriptions-item>
    </el-descriptions>
    <div class="scale-tip">指导语:症状程度按 0=无、1=轻、2=中、3=重 评分,各项得分 = 程度 × 系数。</div>
    <!-- 纸质表主体:症状 + 系数 + 0~3 程度 + 评分 -->
    <el-table :data="items" border size="small" class="kup-table">
      <el-table-column type="index" label="序号" width="60" align="center" />
      <el-table-column prop="symptom" label="症状" min-width="160" />
      <el-table-column prop="factorLabel" label="系数" width="70" align="center" />
      <el-table-column label="0 无" align="center" width="80">
        <template slot-scope="scope"><el-radio v-if="editing" v-model="local[scope.row.key]" :label="0">&nbsp;</el-radio><span v-else>{{ local[scope.row.key] === 0 ? "✓" : "" }}</span></template>
      </el-table-column>
      <el-table-column prop="score" label="评分" align="center" width="100" />
      <el-table-column label="1 轻" align="center" width="80">
        <template slot-scope="scope"><el-radio v-if="editing" v-model="local[scope.row.key]" :label="1">&nbsp;</el-radio><span v-else>{{ local[scope.row.key] === 1 ? "✓" : "" }}</span></template>
      </el-table-column>
      <el-table-column label="2 中" align="center" width="80">
        <template slot-scope="scope"><el-radio v-if="editing" v-model="local[scope.row.key]" :label="2">&nbsp;</el-radio><span v-else>{{ local[scope.row.key] === 2 ? "✓" : "" }}</span></template>
      </el-table-column>
      <el-table-column label="3 重" align="center" width="80">
        <template slot-scope="scope"><el-radio v-if="editing" v-model="local[scope.row.key]" :label="3">&nbsp;</el-radio><span v-else>{{ local[scope.row.key] === 3 ? "✓" : "" }}</span></template>
      </el-table-column>
      <el-table-column label="评分" align="center" width="80">
        <template slot-scope="scope">{{ (Number(local[scope.row.key]) || 0) * scope.row.factor }}</template>
      </el-table-column>
    </el-table>
    <div style="margin-top:10px;font-size:14px">总分:{{ totalScore }} &nbsp;&nbsp; 程度:{{ severity }}</div>
    <!-- 结果 -->
    <el-descriptions :column="3" border size="small" class="scale-result">
      <el-descriptions-item label="Kupperman 总分"><b :class="levelClass">{{ totalScore }}</b> 分</el-descriptions-item>
      <el-descriptions-item label="程度">{{ severity }}</el-descriptions-item>
      <el-descriptions-item label="评分人员">
        <el-input v-if="editing" v-model="local.evaluator" size="mini" style="width:160px" placeholder="请输入" />
        <span v-else>{{ local.evaluator || "-" }}</span>
      </el-descriptions-item>
    </el-descriptions>
    <div class="kup-range">程度分级:≤6 正常,7~15 轻度,16~30 中度,&gt;30 重度;各项得分 = 程度 × 系数</div>
  </div>
</template>
<script>
const KUP_ITEMS = [
  { key: "kup_0", symptom: "潮热出汗", factor: 4 },
  { key: "kup_1", symptom: "感觉异常", factor: 2 },
  { key: "kup_2", symptom: "失眠", factor: 2 },
  { key: "kup_3", symptom: "情绪波动", factor: 2 },
  { key: "kup_4", symptom: "抑郁疑心", factor: 1 },
  { key: "kup_5", symptom: "眩晕", factor: 1 },
  { key: "kup_6", symptom: "疲乏", factor: 1 },
  { key: "kup_7", symptom: "骨关节痛", factor: 1 },
  { key: "kup_8", symptom: "头痛", factor: 1 },
  { key: "kup_9", symptom: "心悸", factor: 1 },
  { key: "kup_10", symptom: "皮肤蚁走感", factor: 1 },
  { key: "kup_11", symptom: "性生活", factor: 2 },
  { key: "kup_12", symptom: "泌尿系症状", factor: 2 },
];
const KEYS = KUP_ITEMS.map((i) => i.key);
export default {
  name:"KuppermanScoreTable",
  props:{ value:{ type:Object, default:()=>({}) }, editing:Boolean },
  data(){ return { degrees:[{v:0,l:"无"},{v:1,l:"轻"},{v:2,l:"中"},{v:3,l:"重"}] }; },
  computed:{
    items(){
      const list = [
        { symptom:"潮热出汗",factor:4 },{ symptom:"感觉异常",factor:2 },{ symptom:"失眠",factor:2 },
        { symptom:"情绪波动",factor:2 },{ symptom:"抑郁",factor:1 },{ symptom:"眩晕",factor:1 },
        { symptom:"疲乏",factor:1 },{ symptom:"关节痛",factor:1 },{ symptom:"头痛",factor:1 },
        { symptom:"心悸",factor:1 },{ symptom:"皮肤蚁走感",factor:1 },{ symptom:"性生活",factor:2 },{ symptom:"泌尿系感染",factor:2 },
      ];
      return list.map(item => {
        const v = this.value[item.symptom]||0;
        return { ...item, degree:v, score:item.factor * v };
      });
  props: {
    value: { type: Object, default: () => ({}) },
    patient: { type: Object, default: () => ({}) },
    editing: Boolean,
    },
    totalScore(){ return this.items.reduce((s,i)=>s+i.score,0); },
    severity(){ const t=this.totalScore; return t<=6?"正常":t<=15?"轻度":t<=30?"中度":"重度"; },
  data() {
    return {
      items: KUP_ITEMS.map((i) => Object.assign({}, i, { factorLabel: "×" + i.factor })),
      local: this.normalize(this.value),
    };
  },
  computed: {
    totalScore() {
      return KUP_ITEMS.reduce((s, i) => s + (Number(this.local[i.key]) || 0) * i.factor, 0);
    },
    severity() {
      const t = this.totalScore;
      if (t <= 6) return "正常";
      if (t <= 15) return "轻度";
      if (t <= 30) return "中度";
      return "重度";
    },
    levelClass() {
      const t = this.totalScore;
      return t <= 6 ? "lv-good" : t <= 15 ? "lv-mid" : t <= 30 ? "lv-warn" : "lv-bad";
    },
  },
  watch:{
    items:{ deep:true, handler(v){
      const obj = { ...this.value, kuppermanTotal:this.totalScore, kuppermanSeverity:this.severity };
      v.forEach(i=>{ obj[i.symptom]=i.degree; });
      this.$emit('input',obj);
    }},
    value: {
      deep: true,
      handler(v) {
        const n = this.normalize(v);
        if (JSON.stringify(n) !== JSON.stringify(this.local)) this.local = n;
      },
    },
    local: {
      deep: true,
      handler(v) {
        const out = this.buildOut(v);
        if (JSON.stringify(out) !== JSON.stringify(this.value)) this.$emit("input", out);
      },
    },
  },
  methods:{
    degLabel(v){ const r=this.degrees.find(d=>d.v===v); return r?r.l:"-"; },
    normalize(v) {
      const src = v || {};
      const out = { date: src.date || "", evaluator: src.evaluator || "" };
      KEYS.forEach((k) => { out[k] = Number(src[k]) || 0; });
      return out;
    },
    buildOut(v) {
      return Object.assign({}, v, { kuppermanTotal: this.totalScore, kuppermanSeverity: this.severity });
    },
  },
};
</script>
<style scoped>
.scale-title { margin-bottom: 10px; font-size: 16px; font-weight: 700; text-align: center; color: #303133; }
.scale-head { margin-bottom: 10px; }
.scale-tip { margin-bottom: 10px; padding: 6px 10px; font-size: 13px; color: #606266; line-height: 1.6; background: #f8f9fb; border-left: 3px solid #c0c4cc; }
.kup-table { margin-bottom: 12px; }
.scale-result { margin-top: 6px; }
.kup-range { margin-top: 8px; font-size: 12px; color: #909399; }
.lv-good { color: #67c23a; }
.lv-mid { color: #409eff; }
.lv-warn { color: #e6a23c; }
.lv-bad { color: #f56c6c; }
</style>