WXL
3 天以前 1a1df739a5f866de1014762167ac9ecb8e06595f
评估相关
已添加6个文件
1335 ■■■■■ 文件已修改
src/views/business/assess/assessInfo.vue 455 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/assessmentData.js 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/components/AttachmentPreview.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/components/OrganAssessmentForm.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/index.vue 501 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/mockAssessmentApi.js 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/assessInfo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,455 @@
<template>
  <div class="assessment-detail">
    <el-card class="basic-info-card">
      <div slot="header" class="clearfix">
        <span>案例基本信息</span>
        <el-button
          style="float: right; padding: 3px 0"
          type="text"
          @click="handleAttachmentPreview"
        >
          <i class="el-icon-folder-opened"></i> æŸ¥çœ‹é™„ä»¶
        </el-button>
      </div>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="案例编号">{{
          assessmentData.caseNo
        }}</el-descriptions-item>
        <el-descriptions-item label="潜在捐献者姓名">{{
          assessmentData.donorName
        }}</el-descriptions-item>
        <el-descriptions-item label="性别">
          <dict-tag :options="genderOptions" :value="assessmentData.gender" />
        </el-descriptions-item>
        <el-descriptions-item label="年龄"
          >{{ assessmentData.age }}岁</el-descriptions-item
        >
        <el-descriptions-item label="血型">
          <dict-tag
            :options="bloodTypeOptions"
            :value="assessmentData.bloodType"
          />
        </el-descriptions-item>
        <el-descriptions-item label="证件号码">{{
          assessmentData.idCardNo
        }}</el-descriptions-item>
        <el-descriptions-item label="疾病诊断">{{
          assessmentData.diagnosis
        }}</el-descriptions-item>
        <el-descriptions-item label="所在医疗机构">{{
          assessmentData.hospitalName
        }}</el-descriptions-item>
        <el-descriptions-item label="主治医生">{{
          assessmentData.doctorName
        }}</el-descriptions-item>
        <el-descriptions-item label="申请评估时间">{{
          assessmentData.applyTime
        }}</el-descriptions-item>
        <el-descriptions-item label="评估类型">
          <dict-tag
            :options="assessmentTypeOptions"
            :value="assessmentData.assessmentType"
          />
        </el-descriptions-item>
        <el-descriptions-item label="评估状态">
          <el-tag :type="statusFilter(assessmentData.assessmentStatus)">
            {{ statusTextFilter(assessmentData.assessmentStatus) }}
          </el-tag>
        </el-descriptions-item>
      </el-descriptions>
    </el-card>
    <el-card class="organ-assessment-card">
      <div slot="header" class="clearfix">
        <span>器官评估表</span>
        <el-button
          v-if="isCoordinator && allOrgansAssessed"
          style="float: right; margin-left: 10px"
          type="primary"
          size="mini"
          @click="handleCompleteAssessment"
        >
          ç¡®è®¤å®Œæˆè¯„ä¼°
        </el-button>
        <span v-if="!isCoordinator" class="jstitle">
          å½“前角色:{{ currentDepartment }}评估人员
        </span>
      </div>
      <el-table
        :data="organAssessmentList"
        v-loading="assessmentLoading"
        style="width: 100%"
        :row-class-name="getRowClassName"
      >
        <el-table-column
          label="器官类型"
          align="center"
          prop="organType"
          width="120"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="organTypeOptions"
              :value="scope.row.organType"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="评估科室"
          align="center"
          prop="department"
          width="120"
        />
        <el-table-column
          label="评估人员"
          align="center"
          prop="assessor"
          width="100"
        />
        <el-table-column label="评估状态" align="center" width="100">
          <template slot-scope="scope">
            <el-tag
              :type="scope.row.assessmentStatus === '1' ? 'success' : 'warning'"
              size="small"
            >
              {{ scope.row.assessmentStatus === "1" ? "已评估" : "待评估" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="功能状态" align="center" width="100">
          <template slot-scope="scope">
            <el-tag
              :type="getFunctionStatusType(scope.row.functionStatus)"
              size="small"
            >
              {{ getFunctionStatusText(scope.row.functionStatus) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          label="评估意见"
          align="center"
          prop="assessmentOpinion"
          min-width="150"
          show-overflow-tooltip
        />
        <el-table-column label="评估时间" align="center" width="120">
          <template slot-scope="scope">
            <span>{{ scope.row.assessmentTime || "-" }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          align="center"
          width="150"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
            <el-button
              v-if="canAssessOrgan(scope.row)"
              size="mini"
              type="text"
              @click="handleOrganAssess(scope.row)"
              >{{
                scope.row.assessmentStatus === "1" ? "查看/修改" : "评估"
              }}</el-button
            >
            <el-button v-else size="mini" type="text" disabled
              >无权限</el-button
            >
            <el-button
              v-if="isCoordinator"
              size="mini"
              type="text"
              @click="handleViewOrganDetail(scope.row)"
              >详情</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- å™¨å®˜è¯„估详情 -->
      <el-collapse
        v-model="activeOrgans"
        accordion
        class="organ-detail-collapse"
      >
        <el-collapse-item
          v-for="organ in organAssessmentList"
          :key="organ.organType"
          :name="organ.organType"
          :title="getOrganTitle(organ)"
        >
          <organ-assessment-form
            :organ-data="organ"
            :readonly="!canAssessOrgan(organ)"
            @save="handleSaveOrganAssessment"
          />
        </el-collapse-item>
      </el-collapse>
    </el-card>
    <!-- é™„件预览弹窗 -->
    <attachment-preview
      :visible="attachmentVisible"
      :attachment-list="attachmentList"
      @close="attachmentVisible = false"
    />
  </div>
</template>
<script>
// import { getAssessment, updateOrganAssessment, completeAssessment } from "@/api/case/assessment";
import {
  getAssessment,
  updateOrganAssessment,
  completeAssessment
} from "./mockAssessmentApi";
import OrganAssessmentForm from "./components/OrganAssessmentForm.vue";
import AttachmentPreview from "./components/AttachmentPreview.vue";
export default {
  name: "AssessmentDetail",
  components: { OrganAssessmentForm, AttachmentPreview },
  data() {
    return {
      // è¯„ä¼°ID
      assessmentId: undefined,
      // è¯„估数据
      assessmentData: {},
      // å™¨å®˜è¯„估列表
      organAssessmentList: [],
      // é™„件列表
      attachmentList: [],
      // åŠ è½½çŠ¶æ€
      assessmentLoading: false,
      // å½“前用户信息
      currentUser: {
        id: "001",
        name: "张医生",
        department: "心脏外科",
        role: "department" // coordinator: åè°ƒå‘˜, department: ç§‘室人员
      },
      // å±•开的器官
      activeOrgans: [],
      // é™„件预览可见性
      attachmentVisible: false,
      // å­—典选项
      genderOptions: [
        { value: "0", label: "男" },
        { value: "1", label: "女" }
      ],
      bloodTypeOptions: [
        { value: "A", label: "A型" },
        { value: "B", label: "B型" },
        { value: "O", label: "O型" },
        { value: "AB", label: "AB型" }
      ],
      assessmentTypeOptions: [
        { value: "1", label: "初次评估" },
        { value: "2", label: "最终评估" }
      ],
      organTypeOptions: [
        { value: "heart", label: "心脏" },
        { value: "liver", label: "肝脏" },
        { value: "kidney", label: "肾脏" },
        { value: "lung", label: "肺脏" },
        { value: "pancreas", label: "胰腺" },
        { value: "intestine", label: "肠道" },
        { value: "cornea", label: "角膜" },
        { value: "skin", label: "皮肤" }
      ]
    };
  },
  computed: {
    // æ˜¯å¦æ˜¯åè°ƒå‘˜
    isCoordinator() {
      return this.currentUser.role === "coordinator";
    },
    // å½“前科室
    currentDepartment() {
      return this.currentUser.department;
    },
    // æ‰€æœ‰å™¨å®˜æ˜¯å¦éƒ½å·²è¯„ä¼°
    allOrgansAssessed() {
      return this.organAssessmentList.every(
        organ => organ.assessmentStatus === "1"
      );
    }
  },
  created() {
    this.assessmentId = this.$route.query.id;
    this.getAssessmentDetail();
  },
  methods: {
    // èŽ·å–è¯„ä¼°è¯¦æƒ… - ä½¿ç”¨Mock数据
    getAssessmentDetail() {
      this.assessmentLoading = true;
      getAssessment(this.assessmentId)
        .then(response => {
          if (response.code === 200) {
            this.assessmentData = response.data.caseInfo;
            this.organAssessmentList = response.data.organAssessments || [];
            this.attachmentList = response.data.attachments || [];
          } else {
            this.$message.error("获取评估详情失败");
          }
          this.assessmentLoading = false;
        })
        .catch(error => {
          console.error("获取评估详情失败:", error);
          this.assessmentLoading = false;
          this.$message.error("获取评估详情失败");
        });
    },
    // çŠ¶æ€è¿‡æ»¤å™¨
    statusFilter(status) {
      const statusMap = {
        "0": "warning",
        "1": "primary",
        "2": "success",
        "3": "danger"
      };
      return statusMap[status] || "info";
    },
    statusTextFilter(status) {
      const statusMap = {
        "0": "待评估",
        "1": "评估中",
        "2": "已完成",
        "3": "已关闭"
      };
      return statusMap[status] || "未知";
    },
    // èŽ·å–åŠŸèƒ½çŠ¶æ€ç±»åž‹
    getFunctionStatusType(status) {
      const typeMap = {
        "1": "success", // æ­£å¸¸
        "2": "warning", // è½»åº¦å¼‚常
        "3": "danger", // é‡åº¦å¼‚常
        "4": "info" // æ— æ³•评估
      };
      return typeMap[status] || "info";
    },
    // èŽ·å–åŠŸèƒ½çŠ¶æ€æ–‡æœ¬
    getFunctionStatusText(status) {
      const textMap = {
        "1": "正常",
        "2": "轻度异常",
        "3": "重度异常",
        "4": "无法评估"
      };
      return textMap[status] || "未知";
    },
    // æ£€æŸ¥æ˜¯å¦æœ‰æƒé™è¯„估该器官
    canAssessOrgan(organ) {
      if (this.isCoordinator) return true;
      return organ.department === this.currentDepartment;
    },
    // èŽ·å–è¡Œç±»å
    getRowClassName({ row }) {
      return this.canAssessOrgan(row) ? "assessable-row" : "non-assessable-row";
    },
    // èŽ·å–å™¨å®˜æ ‡é¢˜
    getOrganTitle(organ) {
      const organName =
        this.organTypeOptions.find(opt => opt.value === organ.organType)
          ?.label || organ.organType;
      return `${organName}评估详情(${organ.department})`;
    },
    // å™¨å®˜è¯„ä¼°
    handleOrganAssess(organ) {
      this.activeOrgans = [organ.organType];
    },
    // æŸ¥çœ‹å™¨å®˜è¯¦æƒ…
    handleViewOrganDetail(organ) {
      this.activeOrgans = [organ.organType];
    },
    // ä¿å­˜å™¨å®˜è¯„ä¼° - ä½¿ç”¨Mock API
    handleSaveOrganAssessment(organData) {
      updateOrganAssessment(organData)
        .then(response => {
          if (response.code === 200) {
            this.$message.success("评估保存成功");
            // åˆ·æ–°æ•°æ®
            this.getAssessmentDetail();
          }
        })
        .catch(error => {
          console.error("保存评估失败:", error);
          this.$message.error("保存失败");
        });
    },
    // æŸ¥çœ‹é™„件预览
    handleAttachmentPreview() {
      this.attachmentVisible = true;
    },
    // å®Œæˆè¯„ä¼° - ä½¿ç”¨Mock API
    handleCompleteAssessment() {
      this.$confirm("确认完成所有器官评估吗?完成后将无法修改", "确认操作", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        completeAssessment(this.assessmentId)
          .then(response => {
            if (response.code === 200) {
              this.$message.success("评估完成确认成功");
              this.getAssessmentDetail();
            }
          })
          .catch(error => {
            console.error("完成评估失败:", error);
            this.$message.error("操作失败");
          });
      });
    }
  }
};
</script>
<style scoped>
.assessment-detail {
  padding: 20px;
}
.basic-info-card {
  margin-bottom: 20px;
}
.organ-assessment-card {
  margin-bottom: 20px;
}
.organ-detail-collapse {
  margin-top: 20px;
}
::v-deep .assessable-row {
  background-color: #f0f9ff;
}
::v-deep .non-assessable-row {
  background-color: #fafafa;
}
::v-deep .el-descriptions__label {
  width: 120px;
  background-color: #f5f7fa;
  font-weight: bold;
}
.fixed-width .el-button {
  margin: 0 2px;
}
.jstitle {
  float: right;
  font-size: 18px !important;
  font-weight: 600;
  color: #2645f7;
  font-size: 12px;
}
</style>
src/views/business/assess/assessmentData.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,156 @@
// src/mock/assessmentData.js
// æ¨¡æ‹Ÿè¯„估列表数据
export const assessmentListData = {
  code: 200,
  message: 'success',
  data: {
    total: 15,
    rows: [
      {
        id: '20241220001',
        caseNo: 'CASE20241220001',
        donorName: '张三',
        gender: '0',
        age: 45,
        diagnosis: '脑外伤导致脑死亡',
        hospitalName: '北京协和医院',
        applyTime: '2024-12-20 10:00:00',
        assessmentTime: '',
        assessmentStatus: '0',
        assignee: '李协调员',
        assessmentType: '1'
      },
      {
        id: '20241220002',
        caseNo: 'CASE20241220002',
        donorName: '李四',
        gender: '1',
        age: 32,
        diagnosis: '急性心肌梗死',
        hospitalName: '上海瑞金医院',
        applyTime: '2024-12-19 14:30:00',
        assessmentTime: '2024-12-20 09:00:00',
        assessmentStatus: '1',
        assignee: '王医生',
        assessmentType: '2'
      },
      {
        id: '20241220003',
        caseNo: 'CASE20241220003',
        donorName: '王五',
        gender: '0',
        age: 58,
        diagnosis: '脑出血',
        hospitalName: '广州中山医院',
        applyTime: '2024-12-18 09:15:00',
        assessmentTime: '2024-12-20 14:20:00',
        assessmentStatus: '2',
        assignee: '赵协调员',
        assessmentType: '1'
      }
    ]
  }
}
// æ¨¡æ‹Ÿè¯„估详情数据
export const assessmentDetailData = {
  code: 200,
  message: 'success',
  data: {
    caseInfo: {
      id: '20241220001',
      caseNo: 'CASE20241220001',
      donorName: '张三',
      gender: '0',
      age: 45,
      bloodType: 'A',
      idCardNo: '110101198001010011',
      diagnosis: '脑外伤导致脑死亡',
      hospitalName: '北京协和医院',
      doctorName: '刘主任',
      applyTime: '2024-12-20 10:00:00',
      assessmentType: '1',
      assessmentStatus: '0'
    },
    organAssessments: [
      {
        id: 1,
        organType: 'heart',
        department: '心脏外科',
        assessor: '王医生',
        assessmentStatus: '1',
        functionStatus: '1',
        assessmentOpinion: '心脏功能正常,射血分数65%,符合捐献条件',
        assessmentTime: '2024-12-20 10:30:00',
        details: {
          ejectionFraction: '65%',
          valveFunction: '正常',
          wallMotion: '正常',
          ecgResult: '窦性心律',
          specialNotes: '无特殊注意事项'
        }
      },
      {
        id: 2,
        organType: 'liver',
        department: '肝胆外科',
        assessor: '',
        assessmentStatus: '0',
        functionStatus: '',
        assessmentOpinion: '',
        assessmentTime: '',
        details: null
      },
      {
        id: 3,
        organType: 'kidney',
        department: '泌尿外科',
        assessor: '李医生',
        assessmentStatus: '1',
        functionStatus: '2',
        assessmentOpinion: '左肾功能正常,右肾轻度积水,需进一步评估',
        assessmentTime: '2024-12-20 11:15:00',
        details: {
          leftKidneyFunction: '正常',
          rightKidneyFunction: '轻度异常',
          creatinineLevel: '1.2mg/dL',
          urineOutput: '正常',
          specialNotes: '建议进行CT增强扫描'
        }
      },
      {
        id: 4,
        organType: 'lung',
        department: '胸外科',
        assessor: '',
        assessmentStatus: '0',
        functionStatus: '',
        assessmentOpinion: '',
        assessmentTime: '',
        details: null
      }
    ],
    attachments: [
      {
        id: 1,
        fileName: '捐献者身份证.jpg',
        fileType: 'jpg',
        fileSize: 1024000,
        uploadTime: '2024-12-19 10:30:00',
        fileUrl: '/mock/files/id_card.jpg'
      },
      {
        id: 2,
        fileName: '医疗诊断证明.pdf',
        fileType: 'pdf',
        fileSize: 2048000,
        uploadTime: '2024-12-19 11:20:00',
        fileUrl: '/mock/files/diagnosis.pdf'
      }
    ]
  }
}
// æ¨¡æ‹ŸAPI响应延迟
export const mockDelay = (ms = 500) => new Promise(resolve => setTimeout(resolve, ms))
src/views/business/assess/components/AttachmentPreview.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
<!-- src/views/case/assessment/components/AttachmentPreview.vue -->
<template>
  <el-dialog
    title="附件预览"
    :visible="visible"
    width="70%"
    @close="$emit('close')"
  >
    <el-table :data="attachmentList">
      <el-table-column label="文件名" prop="fileName" />
      <el-table-column label="类型" prop="fileType" width="100" />
      <el-table-column label="大小" width="100">
        <template slot-scope="scope">
          {{ (scope.row.fileSize / 1024 / 1024).toFixed(2) }} MB
        </template>
      </el-table-column>
      <el-table-column label="操作" width="150">
        <template slot-scope="scope">
          <el-button type="text" @click="handlePreview(scope.row)">预览</el-button>
          <el-button type="text" @click="handleDownload(scope.row)">下载</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
</template>
<script>
export default {
  name: "AttachmentPreview",
  props: {
    visible: Boolean,
    attachmentList: {
      type: Array,
      default: () => []
    }
  },
  methods: {
    handlePreview(file) {
      this.$message.info(`预览文件: ${file.fileName}`);
    },
    handleDownload(file) {
      this.$message.success(`开始下载: ${file.fileName}`);
    }
  }
}
</script>
src/views/business/assess/components/OrganAssessmentForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
<!-- src/views/case/assessment/components/OrganAssessmentForm.vue -->
<template>
  <div class="organ-assessment-form">
    <el-form :model="organData" label-width="120px">
      <el-form-item label="功能状态">
        <el-select v-model="organData.functionStatus" :disabled="readonly">
          <el-option label="正常" value="1" />
          <el-option label="轻度异常" value="2" />
          <el-option label="重度异常" value="3" />
          <el-option label="无法评估" value="4" />
        </el-select>
      </el-form-item>
      <el-form-item label="评估意见">
        <el-input
          type="textarea"
          v-model="organData.assessmentOpinion"
          :rows="4"
          :disabled="readonly"
          placeholder="请输入评估意见"
        />
      </el-form-item>
      <el-form-item v-if="!readonly">
        <el-button type="primary" @click="handleSave">保存评估</el-button>
        <el-button @click="handleCancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  name: "OrganAssessmentForm",
  props: {
    organData: {
      type: Object,
      default: () => ({})
    },
    readonly: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    handleSave() {
      this.$emit('save', {
        ...this.organData,
        assessmentTime: new Date().toISOString(),
        assessor: '当前用户'
      });
    },
    handleCancel() {
      this.$emit('cancel');
    }
  }
}
</script>
src/views/business/assess/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,501 @@
<template>
  <div class="assessment-list">
    <!-- æŸ¥è¯¢æ¡ä»¶ -->
    <el-card class="search-card">
      <el-form
        :model="queryParams"
        ref="queryForm"
        :inline="true"
        label-width="100px"
      >
        <el-form-item label="捐献者姓名" prop="donorName">
          <el-input
            v-model="queryParams.donorName"
            placeholder="请输入捐献者姓名"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="所在医疗机构" prop="hospitalName">
          <el-input
            v-model="queryParams.hospitalName"
            placeholder="请输入医疗机构"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="业务人员" prop="assignee">
          <el-input
            v-model="queryParams.assignee"
            placeholder="请输入业务人员"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="评估状态" prop="assessmentStatus">
          <el-select
            v-model="queryParams.assessmentStatus"
            placeholder="请选择评估状态"
            clearable
            style="width: 200px"
          >
            <el-option label="待评估" value="0" />
            <el-option label="评估中" value="1" />
            <el-option label="已完成" value="2" />
            <el-option label="已关闭" value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="申请时间" prop="applyTimeRange">
          <el-date-picker
            v-model="queryParams.applyTimeRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="yyyy-MM-dd"
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item label="评估时间" prop="assessmentTimeRange">
          <el-date-picker
            v-model="queryParams.assessmentTimeRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="yyyy-MM-dd"
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" @click="handleQuery"
            >搜索</el-button
          >
          <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- æ“ä½œæŒ‰é’® -->
    <el-card class="tool-card">
      <el-row :gutter="10">
        <el-col :span="16">
          <el-button type="primary" icon="el-icon-plus" @click="handleCreate"
            >新增评估</el-button
          >
          <el-button
            type="success"
            icon="el-icon-edit"
            :disabled="single"
            @click="handleUpdate"
            >修改</el-button
          >
          <el-button
            type="danger"
            icon="el-icon-delete"
            :disabled="multiple"
            @click="handleDelete"
            >删除</el-button
          >
          <el-button
            type="warning"
            icon="el-icon-download"
            @click="handleExport"
            >导出</el-button
          >
        </el-col>
        <el-col :span="8" style="text-align: right">
          <el-tooltip content="刷新" placement="top">
            <el-button icon="el-icon-refresh" circle @click="getList" />
          </el-tooltip>
        </el-col>
      </el-row>
    </el-card>
    <!-- æ•°æ®è¡¨æ ¼ -->
    <el-card>
      <el-table
        v-loading="loading"
        :data="assessmentList"
        @selection-change="handleSelectionChange"
        @row-click="handleRowClick"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column
          label="案例编号"
          align="center"
          prop="caseNo"
          width="120"
        />
        <el-table-column
          label="潜在捐献者姓名"
          align="center"
          prop="donorName"
          width="120"
        />
        <el-table-column label="性别" align="center" prop="gender" width="80">
          <template slot-scope="scope">
            <!-- <dict-tag :options="genderOptions" :value="scope.row.gender" /> -->
            <dict-tag
              :options="dict.type.sys_user_sex"
              :value="parseInt(scope.row.gender)"
            />
          </template>
        </el-table-column>
        <el-table-column label="年龄" align="center" prop="age" width="80" />
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosis"
          min-width="180"
          show-overflow-tooltip
        />
        <el-table-column
          label="所在医疗机构"
          align="center"
          prop="hospitalName"
          width="150"
          show-overflow-tooltip
        />
        <el-table-column
          label="申请评估时间"
          align="center"
          prop="applyTime"
          width="120"
        >
          <template slot-scope="scope">
            <span>{{ parseTime(scope.row.applyTime, "{y}-{m}-{d}") }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="评估时间"
          align="center"
          prop="assessmentTime"
          width="120"
        >
          <template slot-scope="scope">
            <span>{{
              scope.row.assessmentTime
                ? parseTime(scope.row.assessmentTime, "{y}-{m}-{d}")
                : "-"
            }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="评估状态"
          align="center"
          prop="assessmentStatus"
          width="100"
        >
          <template slot-scope="scope">
            <el-tag :type="statusFilter(scope.row.assessmentStatus)">
              {{ statusTextFilter(scope.row.assessmentStatus) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          label="业务人员"
          align="center"
          prop="assignee"
          width="100"
        />
        <el-table-column
          label="评估类型"
          align="center"
          prop="assessmentType"
          width="100"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.assessment_Type"
              :value="parseInt(scope.row.assessmentType)"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          align="center"
          width="200"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              icon="el-icon-view"
              @click.stop="handleView(scope.row)"
              >详情</el-button
            >
            <el-button
              v-if="
                scope.row.assessmentStatus === '0' ||
                  scope.row.assessmentStatus === '1'
              "
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click.stop="handleAssess(scope.row)"
              >评估</el-button
            >
            <el-button
              v-if="scope.row.assessmentStatus === '2'"
              size="mini"
              type="text"
              icon="el-icon-check"
              @click.stop="handleConfirm(scope.row)"
              >确认</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- åˆ†é¡µç»„ä»¶ -->
      <pagination
        v-show="total > 0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />
    </el-card>
  </div>
</template>
<script>
// import { listAssessment, delAssessment, exportAssessment } from "@/api/case/assessment";
import {
  listAssessment,
  delAssessment,
  exportAssessment
} from "./mockAssessmentApi";
import Pagination from "@/components/Pagination";
export default {
  name: "AssessmentList",
  components: { Pagination },
  dicts: ["sys_user_sex", "assessment_Type"],
  data() {
    return {
      // é®ç½©å±‚
      loading: true,
      // é€‰ä¸­æ•°ç»„
      ids: [],
      // éžå•个禁用
      single: true,
      // éžå¤šä¸ªç¦ç”¨
      multiple: true,
      // æ€»æ¡æ•°
      total: 0,
      // è¯„估表格数据
      assessmentList: [],
      // æŸ¥è¯¢å‚æ•°
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        donorName: undefined,
        hospitalName: undefined,
        assignee: undefined,
        assessmentStatus: undefined,
        applyTimeRange: [],
        assessmentTimeRange: []
      },
      // æ€§åˆ«é€‰é¡¹
      genderOptions: [
        { value: "0", label: "男" },
        { value: "1", label: "女" }
      ],
      // è¯„估类型选项
      assessmentTypeOptions: [
        { value: "1", label: "初次评估" },
        { value: "2", label: "最终评估" }
      ]
    };
  },
  created() {
    this.getList();
  },
  methods: {
    // çŠ¶æ€è¿‡æ»¤å™¨
    statusFilter(status) {
      const statusMap = {
        "0": "warning", // å¾…评估
        "1": "primary", // è¯„估中
        "2": "success", // å·²å®Œæˆ
        "3": "danger" // å·²å…³é—­
      };
      return statusMap[status] || "info";
    },
    statusTextFilter(status) {
      const statusMap = {
        "0": "待评估",
        "1": "评估中",
        "2": "已完成",
        "3": "已关闭"
      };
      return statusMap[status] || "未知";
    },
    // æŸ¥è¯¢è¯„估列表
    getList() {
      this.loading = true;
      listAssessment(this.queryParams)
        .then(response => {
          if (response.code === 200) {
            this.assessmentList = response.data.rows;
            this.total = response.data.total;
          } else {
            this.$message.error("获取数据失败");
          }
          this.loading = false;
        })
        .catch(error => {
          console.error("获取评估列表失败:", error);
          this.loading = false;
          this.$message.error("获取数据失败");
        });
    },
    // æœç´¢æŒ‰é’®æ“ä½œ
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    // é‡ç½®æŒ‰é’®æ“ä½œ
    resetQuery() {
      this.$refs.queryForm.resetFields();
      this.handleQuery();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    // è¡Œç‚¹å‡»äº‹ä»¶
    handleRowClick(row) {
      this.$router.push({
        path: "/case/assessment/detail",
        query: { id: row.id }
      });
    },
    // æŸ¥çœ‹è¯¦æƒ…
    handleView(row) {
      this.$router.push({ path: "/organ/assessInfo", query: { id: row.id } });
    },
    // è¿›è¡Œè¯„ä¼°
    handleAssess(row) {
      this.$router.push({
        path: "/case/assessment/detail",
        query: { id: row.id, assess: true }
      });
    },
    // ç¡®è®¤è¯„ä¼°
    handleConfirm(row) {
      this.$confirm("确认完成该案例的评估吗?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          // è°ƒç”¨Mock确认API
          this.$message.success("确认成功");
          // åˆ·æ–°åˆ—表
          this.getList();
        })
        .catch(() => {});
    },
    // æ–°å¢žæŒ‰é’®æ“ä½œ
    handleCreate() {
      this.$router.push("/case/assessment/add");
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œ
    handleUpdate() {
      const id = this.ids[0];
      this.$router.push({ path: "/case/assessment/edit", query: { id: id } });
    },
    // åˆ é™¤æŒ‰é’®æ“ä½œ - ä½¿ç”¨Mock API
    handleDelete() {
      const ids = this.ids;
      this.$confirm("是否确认删除选中的数据项?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          return delAssessment(ids);
        })
        .then(response => {
          if (response.code === 200) {
            this.$message.success("删除成功");
            this.getList();
          }
        })
        .catch(() => {});
    },
    // å¯¼å‡ºæŒ‰é’®æ“ä½œ - ä½¿ç”¨Mock API
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm("是否确认导出所有评估数据?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          this.loading = true;
          return exportAssessment(queryParams);
        })
        .then(response => {
          if (response.code === 200) {
            this.$message.success("导出成功,开始下载文件");
            // æ¨¡æ‹Ÿæ–‡ä»¶ä¸‹è½½
            const link = document.createElement("a");
            link.href = response.data.downloadUrl;
            link.download = "案例评估数据.xlsx";
            link.click();
          }
          this.loading = false;
        })
        .catch(() => {
          this.loading = false;
        });
    },
    // æ—¶é—´æ ¼å¼åŒ–
    parseTime(time, pattern) {
      if (!time) return "";
      // ä½¿ç”¨moment.js或简单格式化
      if (this.$moment) {
        return this.$moment(time).format(pattern || "{y}-{m}-{d} {h}:{i}:{s}");
      } else {
        // ç®€å•格式化
        const date = new Date(time);
        return `${date.getFullYear()}-${(date.getMonth() + 1)
          .toString()
          .padStart(2, "0")}-${date
          .getDate()
          .toString()
          .padStart(2, "0")}`;
      }
    }
  }
};
</script>
<style scoped>
.assessment-list {
  padding: 20px;
}
.search-card {
  margin-bottom: 20px;
}
.tool-card {
  margin-bottom: 20px;
}
.fixed-width .el-button {
  margin: 0 5px;
}
</style>
src/views/business/assess/mockAssessmentApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,121 @@
// src/api/mockAssessmentApi.js
import { assessmentListData, assessmentDetailData, mockDelay } from './assessmentData.js'
// æ¨¡æ‹Ÿè¯„估列表API
export const listAssessment = async (queryParams) => {
  await mockDelay(800)
  console.log('Mock API: èŽ·å–è¯„ä¼°åˆ—è¡¨', queryParams)
  // æ¨¡æ‹Ÿç­›é€‰é€»è¾‘
  let data = assessmentListData.data.rows
  if (queryParams.donorName) {
    data = data.filter(item => item.donorName.includes(queryParams.donorName))
  }
  if (queryParams.hospitalName) {
    data = data.filter(item => item.hospitalName.includes(queryParams.hospitalName))
  }
  if (queryParams.assessmentStatus) {
    data = data.filter(item => item.assessmentStatus === queryParams.assessmentStatus)
  }
  // æ¨¡æ‹Ÿåˆ†é¡µ
  const pageNum = queryParams.pageNum || 1
  const pageSize = queryParams.pageSize || 10
  const startIndex = (pageNum - 1) * pageSize
  const endIndex = startIndex + pageSize
  const pagedData = data.slice(startIndex, endIndex)
  return {
    code: 200,
    message: 'success',
    data: {
      total: data.length,
      rows: pagedData
    }
  }
}
// æ¨¡æ‹Ÿè¯„估详情API
export const getAssessment = async (id) => {
  await mockDelay(500)
  console.log('Mock API: èŽ·å–è¯„ä¼°è¯¦æƒ…', id)
  // æ ¹æ®ID返回不同的模拟数据
  const detailData = JSON.parse(JSON.stringify(assessmentDetailData))
  if (id === '20241220002') {
    detailData.data.caseInfo.donorName = '李四'
    detailData.data.caseInfo.caseNo = 'CASE20241220002'
    detailData.data.organAssessments[0].assessor = '张医生'
  } else if (id === '20241220003') {
    detailData.data.caseInfo.donorName = '王五'
    detailData.data.caseInfo.caseNo = 'CASE20241220003'
    detailData.data.organAssessments[0].assessor = '陈医生'
  }
  return detailData
}
// æ¨¡æ‹Ÿå™¨å®˜è¯„ä¼°æ›´æ–°API
export const updateOrganAssessment = async (organData) => {
  await mockDelay(300)
  console.log('Mock API: æ›´æ–°å™¨å®˜è¯„ä¼°', organData)
  return {
    code: 200,
    message: '器官评估更新成功',
    data: organData
  }
}
// æ¨¡æ‹Ÿå®Œæˆè¯„ä¼°API
export const completeAssessment = async (id) => {
  await mockDelay(500)
  console.log('Mock API: å®Œæˆè¯„ä¼°', id)
  return {
    code: 200,
    message: '评估完成确认成功',
    data: {
      assessmentId: id,
      completeTime: new Date().toISOString()
    }
  }
}
// æ¨¡æ‹Ÿåˆ é™¤è¯„ä¼°API
export const delAssessment = async (ids) => {
  await mockDelay(400)
  console.log('Mock API: åˆ é™¤è¯„ä¼°', ids)
  return {
    code: 200,
    message: '删除成功',
    data: ids
  }
}
// æ¨¡æ‹Ÿå¯¼å‡ºè¯„ä¼°API
export const exportAssessment = async (queryParams) => {
  await mockDelay(1000)
  console.log('Mock API: å¯¼å‡ºè¯„ä¼°', queryParams)
  // æ¨¡æ‹Ÿæ–‡ä»¶ä¸‹è½½
  return {
    code: 200,
    message: '导出成功',
    data: {
      downloadUrl: '/mock/export/assessment.xlsx',
      fileSize: '2.5MB'
    }
  }
}