WXL
2025-12-29 3b7fcf5ea471f6cb388f86d0732b8ece47a3cefc
src/views/business/course/components/MedicalAssessmentStage.vue
@@ -1,208 +1,397 @@
<template>
  <base-stage :stage-data="stageData" :case-info="caseInfo">
    <template #header>
      <el-alert
        :title="alertTitle"
        :type="alertType"
        :description="alertDescription"
        show-icon
        :closable="false"
      />
    </template>
  <div class="assessment-detail">
    <el-row :gutter="20" style="margin-top: 20px;">
      <el-col :span="8">
        <el-card>
          <div slot="header" class="card-header">
            <span>评估概况</span>
          </div>
          <div class="assessment-stats">
            <div class="stat-item">
              <span class="stat-label">评估状态:</span>
              <el-tag :type="getStatusTag(stageData.status)">
                {{ getStatusText(stageData.status) }}
              </el-tag>
            </div>
            <div class="stat-item">
              <span class="stat-label">评估医生:</span>
              <span>{{ stageData.operator || '待分配' }}</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">开始时间:</span>
              <span>{{ formatTime(stageData.updateTime) }}</span>
            </div>
            <div class="stat-item">
              <span class="stat-label">完成时间:</span>
              <span>{{ formatTime(stageData.completeTime) || '-' }}</span>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="16">
        <el-card>
          <div slot="header" class="card-header">
            <span>评估项目进度</span>
          </div>
          <div class="progress-list">
            <div v-for="item in assessmentItems" :key="item.name" class="progress-item">
              <div class="progress-info">
                <span class="item-name">{{ item.name }}</span>
                <span class="item-status">
                  <el-tag :type="item.status === 'completed' ? 'success' : 'warning'" size="small">
                    {{ item.status === 'completed' ? '已完成' : '待评估' }}
                  </el-tag>
                </span>
              </div>
              <el-progress
                :percentage="item.status === 'completed' ? 100 : 0"
                :show-text="false"
                :status="item.status === 'completed' ? 'success' : 'exception'"
              />
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
    <el-card style="margin-top: 20px;">
      <div slot="header" class="card-header">
        <span>评估详情记录</span>
        <el-button type="primary" size="small" @click="handleViewReport">
          查看评估报告
        </el-button>
    <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-descriptions :column="2" border>
        <el-descriptions-item label="生理指标评估">
          {{ assessmentDetails.physiological || '待评估' }}
        </el-descriptions-item>
        <el-descriptions-item label="器官功能评估">
          {{ assessmentDetails.organFunction || '待评估' }}
        </el-descriptions-item>
        <el-descriptions-item label="感染性疾病筛查">
          {{ assessmentDetails.infectionScreening || '待筛查' }}
        </el-descriptions-item>
        <el-descriptions-item label="恶性肿瘤筛查">
          {{ assessmentDetails.cancerScreening || '待筛查' }}
        </el-descriptions-item>
        <el-descriptions-item label="评估结论">
          <el-tag :type="assessmentDetails.conclusion ? 'success' : 'warning'">
            {{ assessmentDetails.conclusion || '评估中' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="评估医生意见">
          {{ assessmentDetails.doctorOpinion || '待填写' }}
        </el-descriptions-item>
      </el-descriptions>
      <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>
  </base-stage>
    <!-- 附件预览弹窗 -->
    <attachment-preview
      :visible="attachmentVisible"
      :attachment-list="attachmentList"
      @close="attachmentVisible = false"
    />
  </div>
</template>
<script>
import BaseStage from './BaseStage.vue';
// import { getAssessment, updateOrganAssessment, completeAssessment } from "@/api/case/assessment";
import {
  getAssessment,
  updateOrganAssessment,
  completeAssessment
} from "./api/mockAssessmentApi";
import OrganAssessmentForm from "./components/OrganAssessmentForm.vue";
import AttachmentPreview from "./components/AttachmentPreview.vue";
export default {
  name: 'MedicalAssessmentStage',
  components: { BaseStage },
  props: {
    stageData: {
      type: Object,
      default: () => ({})
    },
    caseInfo: {
      type: Object,
      default: () => ({})
    }
  },
  computed: {
    alertTitle() {
      const status = this.stageData.status;
      return status === 'completed' ? '医学评估完成' :
             status === 'in_progress' ? '医学评估进行中' : '待开始医学评估';
    },
    alertType() {
      const status = this.stageData.status;
      return status === 'completed' ? 'success' :
             status === 'in_progress' ? 'warning' : 'info';
    },
    alertDescription() {
      const status = this.stageData.status;
      return status === 'completed' ? '所有医学评估项目已完成,供者符合捐献条件' :
             status === 'in_progress' ? '医学评估正在进行中,请关注评估进度' : '等待开始医学评估流程';
    }
  },
  name: "AssessmentDetail",
  components: { OrganAssessmentForm, AttachmentPreview },
  data() {
    return {
      assessmentItems: [
        { name: '生理指标评估', status: 'completed' },
        { name: '器官功能评估', status: 'completed' },
        { name: '感染性疾病筛查', status: 'completed' },
        { name: '恶性肿瘤筛查', status: 'completed' },
        { name: '遗传性疾病筛查', status: 'completed' },
        { name: '心理状态评估', status: 'completed' }
      // 评估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: "女" }
      ],
      assessmentDetails: {
        physiological: '各项生理指标正常,符合捐献要求',
        organFunction: '主要器官功能良好,无禁忌症',
        infectionScreening: '传染病筛查均为阴性',
        cancerScreening: '无恶性肿瘤迹象',
        conclusion: '适合器官捐献',
        doctorOpinion: '供者身体状况良好,符合捐献医学标准'
      }
      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: "皮肤" }
      ]
    };
  },
  methods: {
    getStatusText(status) {
      const map = {
        'completed': '已完成',
        'in_progress': '进行中',
        'pending': '未开始'
      };
      return map[status] || '未知';
  computed: {
    // 是否是协调员
    isCoordinator() {
      return this.currentUser.role === "coordinator";
    },
    handleViewReport() {
      this.$message.info('查看医学评估报告功能');
    // 当前科室
    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-stats {
  padding: 10px 0;
.assessment-detail {
  padding: 20px;
}
.stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
.basic-info-card {
  margin-bottom: 20px;
}
.stat-label {
  color: #606266;
  font-weight: 500;
.organ-assessment-card {
  margin-bottom: 20px;
}
.progress-list {
  padding: 10px 0;
.organ-detail-collapse {
  margin-top: 20px;
}
.progress-item {
  margin-bottom: 15px;
::v-deep .assessable-row {
  background-color: #f0f9ff;
}
.progress-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
::v-deep .non-assessable-row {
  background-color: #fafafa;
}
.item-name {
  color: #606266;
  font-size: 14px;
::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>