WXL
2026-01-23 8192b75a1b1e46fd962485d26690b5ecc7e2af06
青岛维护
已修改2个文件
553 ■■■■ 文件已修改
src/views/business/assess/assessInfo.vue 545 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/transfer/transportDetail.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/assessInfo.vue
@@ -106,9 +106,31 @@
          label="评估人员"
          align="center"
          prop="assessor"
          width="100"
        />
        <el-table-column label="评估状态" align="center" width="100">
        <!-- 新增:第一次评估状态 -->
        <el-table-column label="第一次评估" align="center" >
          <template slot-scope="scope">
            <el-tag
              :type="getAssessmentTagType(scope.row.firstAssessment.status)"
              size="small"
            >
              {{ getAssessmentStatusText(scope.row.firstAssessment.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <!-- 新增:第二次评估状态 -->
        <el-table-column label="第二次评估" align="center" >
          <template slot-scope="scope">
            <el-tag
              :type="getAssessmentTagType(scope.row.secondAssessment.status)"
              size="small"
            >
              {{ getAssessmentStatusText(scope.row.secondAssessment.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="整体状态" align="center" >
          <template slot-scope="scope">
            <el-tag
              :type="scope.row.assessmentStatus === '1' ? 'success' : 'warning'"
@@ -118,32 +140,10 @@
            </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"
          width="180"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
@@ -152,93 +152,166 @@
              size="mini"
              type="text"
              @click="handleOrganAssess(scope.row)"
              >{{
                scope.row.assessmentStatus === "1" ? "查看/修改" : "评估"
              }}</el-button
            >
              评估
            </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
            >
              详情
            </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)"
        >
          <div class="organ-detail-header">
            <span class="organ-name">{{ getOrganName(organ.organType) }}评估详情</span>
            <span class="attachment-count" v-if="organ.attachments && organ.attachments.length > 0">
              附件数量: {{ organ.attachments.length }}
            </span>
          </div>
          <organ-assessment-form
            :organ-data="organ"
            :readonly="!canAssessOrgan(organ)"
            @save="handleSaveOrganAssessment"
          />
        </el-collapse-item>
      </el-collapse>
      <!-- 器官评估详情 - 改为Tab页形式 -->
      <el-dialog
        :title="`${currentOrgan.organName}评估详情`"
        :visible.sync="organDetailVisible"
        width="90%"
        top="5vh"
        class="organ-detail-dialog"
      >
        <el-tabs v-model="activeAssessmentTab" type="card">
          <!-- 第一次评估Tab -->
          <el-tab-pane label="第一次评估" name="first">
            <organ-assessment-form
              :organ-data="currentOrgan"
              :assessment-data="currentOrgan.firstAssessment"
              assessment-type="first"
              :readonly="!canAssessOrgan(currentOrgan)"
              @save="handleSaveOrganAssessment"
            />
          </el-tab-pane>
          <!-- 第二次评估Tab -->
          <el-tab-pane label="第二次评估" name="second">
            <organ-assessment-form
              :organ-data="currentOrgan"
              :assessment-data="currentOrgan.secondAssessment"
              assessment-type="second"
              :readonly="!canAssessOrgan(currentOrgan)"
              @save="handleSaveOrganAssessment"
            />
          </el-tab-pane>
          <!-- 评估汇总Tab -->
          <el-tab-pane label="评估汇总" name="summary">
            <div class="assessment-summary">
              <el-descriptions title="评估结果汇总" :column="2" border>
                <el-descriptions-item label="器官类型">
                  {{ currentOrgan.organName }}
                </el-descriptions-item>
                <el-descriptions-item label="评估科室">
                  {{ currentOrgan.department }}
                </el-descriptions-item>
                <el-descriptions-item label="第一次评估状态">
                  <el-tag :type="getAssessmentTagType(currentOrgan.firstAssessment.status)">
                    {{ getAssessmentStatusText(currentOrgan.firstAssessment.status) }}
                  </el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="第二次评估状态">
                  <el-tag :type="getAssessmentTagType(currentOrgan.secondAssessment.status)">
                    {{ getAssessmentStatusText(currentOrgan.secondAssessment.status) }}
                  </el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="第一次评估时间" :span="2">
                  {{ currentOrgan.firstAssessment.assessmentTime || '-' }}
                </el-descriptions-item>
                <el-descriptions-item label="第二次评估时间" :span="2">
                  {{ currentOrgan.secondAssessment.assessmentTime || '-' }}
                </el-descriptions-item>
              </el-descriptions>
              <!-- 附件汇总 -->
              <el-card header="评估附件" style="margin-top: 20px;">
                <el-table :data="getAllAttachments(currentOrgan)" size="small">
                  <el-table-column label="附件名称" prop="fileName" />
                  <el-table-column label="评估阶段" >
                    <template slot-scope="{row}">
                      {{ row.assessmentType === 'first' ? '第一次评估' : '第二次评估' }}
                    </template>
                  </el-table-column>
                  <el-table-column label="上传时间" prop="uploadTime" width="180" />
                  <el-table-column label="操作" width="120">
                    <template slot-scope="{row}">
                      <el-button type="text" @click="handlePreviewAttachment(row)">预览</el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </el-card>
            </div>
          </el-tab-pane>
        </el-tabs>
        <div slot="footer" class="dialog-footer">
          <el-button @click="organDetailVisible = false">关闭</el-button>
          <el-button
            v-if="canAssessOrgan(currentOrgan)"
            type="primary"
            @click="handleSaveAllAssessments"
          >
            保存所有评估
          </el-button>
        </div>
      </el-dialog>
    </el-card>
    <!-- 附件预览弹窗 -->
    <attachment-preview
    <!-- <attachment-preview
      :visible="attachmentVisible"
      :attachment-list="attachmentList"
      @close="attachmentVisible = false"
    /> -->
    <FilePreviewDialog
      :visible="attachmentVisible"
      :file="attachmentList"
      @close="attachmentVisible = false"
    />
  </div>
</template>
<script>
// import { getAssessment, updateOrganAssessment, completeAssessment } from "@/api/case/assessment";
import {
  getAssessment,
  updateOrganAssessment,
  completeAssessment
} from "./mockAssessmentApi";
import { getAssessment, updateOrganAssessment, completeAssessment } from "./mockAssessmentApi";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import OrganAssessmentForm from "./components/OrganAssessmentForm.vue";
import AttachmentPreview from "./components/AttachmentPreview.vue";
export default {
  name: "AssessmentDetail",
  components: { OrganAssessmentForm, AttachmentPreview },
  components: { OrganAssessmentForm, FilePreviewDialog },
  data() {
    return {
      // 评估ID
      assessmentId: undefined,
      // 评估数据
      assessmentData: {},
      // 器官评估列表
      organAssessmentList: [],
      // 附件列表
      attachmentList: [],
      // 加载状态
      assessmentLoading: false,
      // 当前用户信息
      // 器官详情相关数据
      organDetailVisible: false,
      currentOrgan: {
        organType: '',
        organName: '',
        department: '',
        firstAssessment: this.getDefaultAssessment(),
        secondAssessment: this.getDefaultAssessment()
      },
      activeAssessmentTab: 'first',
      currentUser: {
        id: "001",
        name: "张医生",
        department: "心脏外科",
        role: "department" // coordinator: 协调员, department: 科室人员
        role: "department"
      },
      // 展开的器官
      activeOrgans: [],
      // 附件预览可见性
      attachmentVisible: false,
      // 字典选项
      genderOptions: [
        { value: "0", label: "男" },
@@ -267,42 +340,46 @@
    };
  },
  computed: {
    // 是否是协调员
    isCoordinator() {
      return this.currentUser.role === "coordinator";
    },
    // 当前科室
    currentDepartment() {
      return this.currentUser.department;
    },
    // 所有器官是否都已评估
    allOrgansAssessed() {
      return this.organAssessmentList.every(
        organ => organ.assessmentStatus === "1"
      return this.organAssessmentList.every(organ =>
        organ.firstAssessment.status === 'assessed' &&
        organ.secondAssessment.status === 'assessed'
      );
    }
  },
  created() {
    this.assessmentId = this.$route.query.id;
    this.getAssessmentDetail();
  },
  methods: {
    // 获取评估详情 - 使用Mock数据
    // 获取默认评估数据结构
    getDefaultAssessment() {
      return {
        status: 'pending', // pending, assessing, assessed
        assessmentTime: '',
        assessor: '',
        functionStatus: '',
        assessmentOpinion: '',
        attachments: [],
        clinicalData: {},
        labResults: {}
      };
    },
    // 获取评估详情
    getAssessmentDetail() {
      this.assessmentLoading = true;
      getAssessment(this.assessmentId)
        .then(response => {
          if (response.code === 200) {
            this.assessmentData = response.data.caseInfo;
            this.organAssessmentList = response.data.organAssessments || [];
            // 确保每个器官评估数据都有attachments数组
            this.organAssessmentList.forEach(organ => {
              if (!organ.attachments) {
                organ.attachments = [];
              }
            });
            this.organAssessmentList = this.transformOrganData(response.data.organAssessments || []);
          }
          this.assessmentLoading = false;
        })
@@ -312,30 +389,59 @@
        });
    },
    // 新增方法:获取器官名称
    getOrganName(organType) {
      const organ = this.organTypeOptions.find(opt => opt.value === organType);
      return organ ? organ.label : organType;
    // 转换器官数据格式,支持两次评估
    transformOrganData(organList) {
      return organList.map(organ => {
        const organName = this.getOrganName(organ.organType);
        // 确保有两次评估的数据结构
        if (!organ.firstAssessment) {
          organ.firstAssessment = this.getDefaultAssessment();
        }
        if (!organ.secondAssessment) {
          organ.secondAssessment = this.getDefaultAssessment();
        }
        // 设置器官名称
        organ.organName = organName;
        // 计算整体评估状态
        organ.assessmentStatus = this.calculateOverallStatus(organ);
        return organ;
      });
    },
    // 状态过滤器
    statusFilter(status) {
      const statusMap = {
        "0": "warning",
        "1": "primary",
        "2": "success",
        "3": "danger"
    // 计算整体评估状态
    calculateOverallStatus(organ) {
      const firstDone = organ.firstAssessment.status === 'assessed';
      const secondDone = organ.secondAssessment.status === 'assessed';
      if (firstDone && secondDone) return '1'; // 已完成
      if (firstDone || secondDone) return '2'; // 部分完成
      return '0'; // 未开始
    },
    // 获取评估状态标签类型
    getAssessmentTagType(status) {
      const typeMap = {
        'pending': 'info',
        'assessing': 'warning',
        'assessed': 'success'
      };
      return statusMap[status] || "info";
      return typeMap[status] || 'info';
    },
    statusTextFilter(status) {
      const statusMap = {
        "0": "待评估",
        "1": "评估中",
        "2": "已完成",
        "3": "已关闭"
    // 获取评估状态文本
    getAssessmentStatusText(status) {
      const textMap = {
        'pending': '待评估',
        'assessing': '评估中',
        'assessed': '已评估'
      };
      return statusMap[status] || "未知";
      return textMap[status] || '未知';
    },
    // 获取功能状态类型
    getFunctionStatusType(status) {
      const typeMap = {
@@ -346,6 +452,7 @@
      };
      return typeMap[status] || "info";
    },
    // 获取功能状态文本
    getFunctionStatusText(status) {
      const textMap = {
@@ -356,37 +463,66 @@
      };
      return textMap[status] || "未知";
    },
    // 检查是否有权限评估该器官
    // 获取器官名称
    getOrganName(organType) {
      const organ = this.organTypeOptions.find(opt => opt.value === organType);
      return organ ? organ.label : organType;
    },
    // 检查评估权限
    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.getOrganName(organ.organType);
      const attachmentCount = organ.attachments ? organ.attachments.length : 0;
      return `${organName}评估详情(${organ.department})${attachmentCount > 0 ? ` · ${attachmentCount}个附件` : ''}`;
    // 格式化时间
    formatTime(time) {
      if (!time) return '';
      return new Date(time).toLocaleString();
    },
    // 器官评估
    handleOrganAssess(organ) {
      this.activeOrgans = [organ.organType];
    },
    // 查看器官详情
    handleViewOrganDetail(organ) {
      this.activeOrgans = [organ.organType];
      this.currentOrgan = JSON.parse(JSON.stringify(organ));
      this.activeAssessmentTab = 'first';
      this.organDetailVisible = true;
    },
    // 保存器官评估 - 使用Mock API
    handleSaveOrganAssessment(organData) {
      updateOrganAssessment(organData)
    // 器官评估
    handleOrganAssess(organ) {
      this.currentOrgan = JSON.parse(JSON.stringify(organ));
      this.activeAssessmentTab = 'first';
      this.organDetailVisible = true;
    },
    // 保存单个评估
    handleSaveOrganAssessment(assessmentData, assessmentType) {
      const organToUpdate = {
        ...this.currentOrgan,
        [assessmentType === 'first' ? 'firstAssessment' : 'secondAssessment']: {
          ...assessmentData,
          status: 'assessed',
          assessmentTime: new Date().toISOString(),
          assessor: this.currentUser.name
        }
      };
      // 更新整体状态
      organToUpdate.assessmentStatus = this.calculateOverallStatus(organToUpdate);
      updateOrganAssessment(organToUpdate)
        .then(response => {
          if (response.code === 200) {
            this.$message.success("评估保存成功");
            // 刷新数据
            this.$message.success(`${assessmentType === 'first' ? '第一次' : '第二次'}评估保存成功`);
            this.getAssessmentDetail();
            // 自动切换到下一个未完成的评估或汇总页
            this.autoSwitchTab(assessmentType);
          }
        })
        .catch(error => {
@@ -394,11 +530,101 @@
          this.$message.error("保存失败");
        });
    },
    // 查看附件预览
    // 自动切换Tab页
    autoSwitchTab(currentType) {
      if (currentType === 'first' && this.currentOrgan.secondAssessment.status === 'pending') {
        this.activeAssessmentTab = 'second';
      } else if (currentType === 'second' ||
                (currentType === 'first' && this.currentOrgan.secondAssessment.status === 'assessed')) {
        this.activeAssessmentTab = 'summary';
      }
    },
    // 保存所有评估
    handleSaveAllAssessments() {
      this.$confirm("确认保存所有评估数据吗?", "确认保存", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        const organToUpdate = JSON.parse(JSON.stringify(this.currentOrgan));
        // 更新整体状态
        organToUpdate.assessmentStatus = this.calculateOverallStatus(organToUpdate);
        updateOrganAssessment(organToUpdate)
          .then(response => {
            if (response.code === 200) {
              this.$message.success("所有评估数据保存成功");
              this.getAssessmentDetail();
              this.organDetailVisible = false;
            }
          })
          .catch(error => {
            console.error("保存评估失败:", error);
            this.$message.error("保存失败");
          });
      });
    },
    // 获取所有附件
    getAllAttachments(organ) {
      const attachments = [];
      if (organ.firstAssessment.attachments) {
        organ.firstAssessment.attachments.forEach(att => {
          attachments.push({
            ...att,
            assessmentType: 'first'
          });
        });
      }
      if (organ.secondAssessment.attachments) {
        organ.secondAssessment.attachments.forEach(att => {
          attachments.push({
            ...att,
            assessmentType: 'second'
          });
        });
      }
      return attachments;
    },
    // 预览附件
    handlePreviewAttachment(attachment) {
      // 实现附件预览逻辑
      console.log('预览附件:', attachment);
      this.$message.info('附件预览功能待实现');
    },
    // 状态过滤器
    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] || "未知";
    },
    handleAttachmentPreview() {
      this.attachmentVisible = true;
    },
    // 完成评估 - 使用Mock API
    handleCompleteAssessment() {
      this.$confirm("确认完成所有器官评估吗?完成后将无法修改", "确认操作", {
        confirmButtonText: "确定",
@@ -435,31 +661,45 @@
  margin-bottom: 20px;
}
.organ-detail-collapse {
  margin-top: 20px;
}
.organ-detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
.assessment-time {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}
.organ-name {
  font-size: 16px;
  font-weight: bold;
  color: #303133;
/* Tab页样式优化 */
.organ-detail-dialog ::v-deep .el-dialog__body {
  padding: 20px;
  max-height: 70vh;
  overflow-y: auto;
}
.attachment-count {
  font-size: 14px;
  color: #409EFF;
  background-color: #ecf5ff;
  padding: 4px 8px;
  border-radius: 4px;
.organ-detail-dialog ::v-deep .el-tabs__content {
  padding: 20px 0;
  min-height: 400px;
}
.assessment-summary {
  padding: 10px;
}
.dialog-footer {
  text-align: right;
  padding-top: 20px;
  border-top: 1px solid #ebeef5;
}
/* 响应式设计 */
@media (max-width: 768px) {
  .organ-detail-dialog {
    width: 95% !important;
  }
  .assessment-detail {
    padding: 10px;
  }
}
::v-deep .assessable-row {
  background-color: #f0f9ff;
}
@@ -477,6 +717,7 @@
.fixed-width .el-button {
  margin: 0 2px;
}
.jstitle {
  float: right;
  font-size: 18px !important;
@@ -484,4 +725,22 @@
  color: #2645f7;
  font-size: 12px;
}
/* Tab页激活状态样式 */
::v-deep .el-tabs__item.is-active {
  color: #409EFF;
  font-weight: bold;
}
/* 评估表单样式 */
.assessment-form-section {
  margin-bottom: 20px;
}
.assessment-form-section h3 {
  margin-bottom: 15px;
  color: #303133;
  border-left: 4px solid #409EFF;
  padding-left: 10px;
}
</style>
src/views/business/transfer/transportDetail.vue
@@ -199,7 +199,7 @@
      class="pdf-preview-dialog"
      @close="handlePdfDialogClose"
    >
      <div class="pdf-preview-container" v-loading="pdfLoading">
      <div class="pdf-preview-container" >
        <div class="pdf-toolbar">
          <el-button-group>
            <el-button
@@ -246,7 +246,7 @@
          </el-button>
        </div>
        <div class="pdf-viewport">
        <div class="pdf-viewport" v-loading="pdfLoading">
          <pdf
            ref="pdf"
            :src="pdfUrl"
@@ -315,9 +315,7 @@
export default {
  name: "TransportDetail",
  components: {
    pdf
  },
  components: {
    pdf,
    UploadAttachment
  },
  dicts: ["sys_user_sex"],