WXL
6 天以前 631c8f37b449b09d19345b76400a39abdb7800f6
src/views/business/appear/caseDetail.vue
@@ -1,163 +1,241 @@
<template>
  <div class="case-detail">
    <el-tabs v-model="activeTab">
      <el-tab-pane label="基本信息" name="basic">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="捐献编号">{{
            caseData.donorNo
          }}</el-descriptions-item>
          <el-descriptions-item label="捐献者姓名">{{
            caseData.donorName
          }}</el-descriptions-item>
          <el-descriptions-item label="性别">
            <dict-tag :options="genderOptions" :value="caseData.gender" />
          </el-descriptions-item>
          <el-descriptions-item label="年龄"
            >{{ caseData.age }}岁</el-descriptions-item
          >
          <el-descriptions-item label="血型">
            <dict-tag :options="bloodTypeOptions" :value="caseData.bloodType" />
          </el-descriptions-item>
          <el-descriptions-item label="证件号码">{{
            caseData.idCardNo
          }}</el-descriptions-item>
          <el-descriptions-item label="民族">{{
            caseData.nation
          }}</el-descriptions-item>
          <el-descriptions-item label="联系电话">{{
            caseData.phone
          }}</el-descriptions-item>
          <el-descriptions-item label="住址" :span="2">{{
            caseData.address
          }}</el-descriptions-item>
        </el-descriptions>
      </el-tab-pane>
    <!-- 基本信息模块 -->
    <el-card class="detail-section">
      <div slot="header" class="section-header">
        <span class="section-title">基本信息</span>
      </div>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="案例编号">{{
          caseData.caseNo || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="捐献者姓名">{{
          caseData.name || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="性别">
          <dict-tag
            :options="dict.type.sys_user_sex"
            :value="caseData.sex ? parseInt(caseData.sex) : ''"
          />
        </el-descriptions-item>
        <el-descriptions-item label="年龄">
          {{ caseData.age || "-"
          }}{{
            caseData.ageunit ? `(${getAgeUnitText(caseData.ageunit)})` : ""
          }}
        </el-descriptions-item>
        <el-descriptions-item label="血型">
          <dict-tag
            :options="dict.type.sys_BloodType"
            :value="caseData.bloodType"
          />
        </el-descriptions-item>
        <el-descriptions-item label="Rh阴性">
          {{
            caseData.rhYin === "1" ? "是" : caseData.rhYin === "0" ? "否" : "-"
          }}
        </el-descriptions-item>
        <el-descriptions-item label="证件类型">
          {{ getIdCardTypeText(caseData.idcardtype) }}
        </el-descriptions-item>
        <el-descriptions-item label="证件号码">{{
          caseData.idcardno || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="民族">{{
          caseData.nation || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="国籍">{{
          caseData.nationality || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="籍贯">{{
          caseData.nativeplace || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="学历">{{
          caseData.education || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="职业">{{
          caseData.occupation || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="出生日期">{{
          formatDate(caseData.birthday)
        }}</el-descriptions-item>
        <el-descriptions-item label="联系电话">{{
          caseData.phone || "-"
        }}</el-descriptions-item>
      </el-descriptions>
    </el-card>
      <el-tab-pane label="医疗信息" name="medical">
        <el-descriptions :column="1" border>
          <el-descriptions-item label="疾病诊断">{{
            caseData.diagnosis
          }}</el-descriptions-item>
          <el-descriptions-item label="住院号">{{
            caseData.inpatientNo
          }}</el-descriptions-item>
          <el-descriptions-item label="所在科室">{{
            caseData.departmentName
          }}</el-descriptions-item>
          <el-descriptions-item label="主治医生">{{
            caseData.doctorName
          }}</el-descriptions-item>
          <el-descriptions-item label="传染病情况">{{
            caseData.infectiousDisease || "无"
          }}</el-descriptions-item>
          <el-descriptions-item label="医疗记录">{{
            caseData.medicalRecord
          }}</el-descriptions-item>
        </el-descriptions>
      </el-tab-pane>
    <!-- 地址信息模块 -->
    <el-card class="detail-section">
      <div slot="header" class="section-header">
        <span class="section-title">地址信息</span>
      </div>
      <el-descriptions :column="1" border>
        <el-descriptions-item label="户籍地址">
          {{ getFullRegisterAddress() }}
        </el-descriptions-item>
        <el-descriptions-item label="现住地址">
          {{ getFullResidenceAddress() }}
        </el-descriptions-item>
      </el-descriptions>
    </el-card>
      <el-tab-pane label="医院信息" name="hospital">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="医院名称">{{
            caseData.hospitalName
          }}</el-descriptions-item>
          <el-descriptions-item label="医院级别">{{
            caseData.hospitalLevel
          }}</el-descriptions-item>
          <el-descriptions-item label="联系人">{{
            caseData.contactPerson
          }}</el-descriptions-item>
          <el-descriptions-item label="联系电话">{{
            caseData.contactPhone
          }}</el-descriptions-item>
          <el-descriptions-item label="医院地址" :span="2">{{
            caseData.hospitalAddress
          }}</el-descriptions-item>
        </el-descriptions>
      </el-tab-pane>
    <!-- 医疗信息模块 -->
    <el-card class="detail-section">
      <div slot="header" class="section-header">
        <span class="section-title">医疗信息</span>
      </div>
      <el-descriptions :column="1" border>
        <el-descriptions-item label="疾病诊断名称">{{
          caseData.diagnosisname || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="病情概况">{{
          caseData.illnessoverview || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="病人状况">{{
          caseData.patientstate || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="GCS评分">{{
          caseData.gcsScore || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="传染病情况">{{
          caseData.infectious || "无"
        }}</el-descriptions-item>
        <el-descriptions-item
          label="传染病其他说明"
          v-if="caseData.infectiousOther"
          >{{ caseData.infectiousOther }}</el-descriptions-item
        >
        <el-descriptions-item label="是否需要转运">
          {{ caseData.isTransport === "2" ? "需要" : "不需要" }}
        </el-descriptions-item>
      </el-descriptions>
    </el-card>
      <!-- 新增附件信息标签页 -->
      <el-tab-pane label="附件信息" name="attachments">
        <el-card class="attachment-card">
          <div slot="header" class="clearfix">
            <span>附件列表</span>
            <el-button
              style="float: right; padding: 3px 0"
              type="text"
              @click="handleUpload"
    <!-- 医院信息模块 -->
    <el-card class="detail-section">
      <div slot="header" class="section-header">
        <span class="section-title">医院信息</span>
      </div>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="治疗医院名称">{{
          caseData.treatmenthospitalname || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="治疗科室名称">{{
          caseData.treatmentdeptname || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="住院号">{{
          caseData.inpatientno || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="部门名称">{{
          caseData.deptName || "-"
        }}</el-descriptions-item>
      </el-descriptions>
    </el-card>
    <!-- 上报信息模块 -->
    <el-card class="detail-section">
      <div slot="header" class="section-header">
        <span class="section-title">上报信息</span>
      </div>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="报告者姓名">{{
          caseData.infoName || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="报告者编号">{{
          caseData.infoNo || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="报告者联系电话">{{
          caseData.reporterphone || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="协调员姓名">{{
          caseData.coordinatorName || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="协调员编号">{{
          caseData.coordinatorNo || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="上报状态">
          <el-tag :type="getStatusType(caseData.reportStatus)">
            {{ getStatusText(caseData.reportStatus) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="报告时间">{{
          formatDateTime(caseData.reporttime)
        }}</el-descriptions-item>
        <el-descriptions-item label="是否终止案例">
          {{ caseData.terminationCase === "1" ? "已终止" : "进行中" }}
        </el-descriptions-item>
      </el-descriptions>
    </el-card>
    <!-- 附件信息模块 -->
    <el-card class="detail-section" v-if="attachmentList.length > 0">
      <div slot="header" class="section-header">
        <span class="section-title">附件信息</span>
      </div>
      <el-table :data="attachmentList" style="width: 100%">
        <el-table-column label="文件名" width="300">
          <template slot-scope="scope">
            <i class="el-icon-document" style="margin-right: 8px;"></i>
            <span>{{ scope.row.fileName }}</span>
          </template>
        </el-table-column>
        <el-table-column label="文件类型" width="120">
          <template slot-scope="scope">
            <el-tag size="small">{{ scope.row.fileType }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="大小" width="100">
          <template slot-scope="scope">
            <span>{{ formatFileSize(scope.row.fileSize) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="上传时间" width="180">
          <template slot-scope="scope">
            <span>{{ scope.row.uploadTime }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button size="mini" @click="handlePreview(scope.row)"
              >预览</el-button
            >
              上传附件
            </el-button>
          </div>
            <el-button
              size="mini"
              type="success"
              @click="handleDownload(scope.row)"
              >下载</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </el-card>
          <el-table :data="attachmentList" style="width: 100%">
            <el-table-column label="文件名" width="300">
              <template slot-scope="scope">
                <i class="el-icon-document" style="margin-right: 8px;"></i>
                <span>{{ scope.row.fileName }}</span>
              </template>
            </el-table-column>
            <el-table-column label="文件类型" width="120">
              <template slot-scope="scope">
                <el-tag size="small">{{ scope.row.fileType }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="大小" width="100">
              <template slot-scope="scope">
                <span>{{ formatFileSize(scope.row.fileSize) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="上传时间" width="180">
              <template slot-scope="scope">
                <span>{{ scope.row.uploadTime }}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template slot-scope="scope">
                <el-button size="mini" @click="handlePreview(scope.row)"
                  >预览</el-button
                >
                <el-button
                  size="mini"
                  type="success"
                  @click="handleDownload(scope.row)"
                  >下载</el-button
                >
                <el-button
                  size="mini"
                  type="danger"
                  @click="handleDelete(scope.row)"
                  >删除</el-button
                >
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-tab-pane>
      <el-tab-pane
        label="审批信息"
        name="approval"
        v-if="caseData.status !== '0'"
      >
        <el-descriptions :column="1" border>
          <el-descriptions-item label="审批结果">
            <el-tag :type="caseData.status | statusFilter">
              {{ caseData.status | statusTextFilter }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="审批时间">{{
            caseData.approveTime
          }}</el-descriptions-item>
          <el-descriptions-item label="审批人">{{
            caseData.approverName
          }}</el-descriptions-item>
          <el-descriptions-item label="审批意见">{{
            caseData.approveOpinion
          }}</el-descriptions-item>
        </el-descriptions>
      </el-tab-pane>
    </el-tabs>
    <!-- 审批信息模块(状态为已同意或已驳回时显示) -->
    <el-card
      class="detail-section"
      v-if="caseData.reportStatus === '3' || caseData.reportStatus === '4'"
    >
      <div slot="header" class="section-header">
        <span class="section-title">审批信息</span>
      </div>
      <el-descriptions :column="1" border>
        <el-descriptions-item label="审批结果">
          <el-tag :type="caseData.reportStatus === '3' ? 'success' : 'danger'">
            {{ caseData.reportStatus === "3" ? "已同意" : "已驳回" }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="审批时间">{{
          formatDateTime(caseData.updateTime)
        }}</el-descriptions-item>
        <el-descriptions-item label="审批人">{{
          caseData.updateBy || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="审批意见">{{
          caseData.remark || "无"
        }}</el-descriptions-item>
      </el-descriptions>
    </el-card>
    <!-- PDF预览弹窗 -->
    <el-dialog
@@ -275,7 +353,7 @@
      </div>
    </el-dialog>
    <div class="detail-footer">
    <div class="detail-footer" v-if="showtitle">
      <el-button @click="handleClose">关闭</el-button>
    </div>
  </div>
@@ -293,8 +371,13 @@
    caseData: {
      type: Object,
      default: () => ({})
    },
    showtitle: {
      type: Boolean,
      default: true
    }
  },
  dicts: ["sys_user_sex", "sys_BloodType"],
  filters: {
    statusFilter(status) {
      const statusMap = {
@@ -315,74 +398,159 @@
  },
  data() {
    return {
      activeTab: "basic",
      genderOptions: [
        { value: "0", label: "男" },
        { value: "1", label: "女" }
      ],
      bloodTypeOptions: [
        { value: "A", label: "A型" },
        { value: "B", label: "B型" },
        { value: "O", label: "O型" },
        { value: "AB", label: "AB型" }
      ],
      // 附件相关数据
      attachmentList: [
        {
          id: 1,
          fileName: "捐献者身份证.jpg",
          fileType: "jpg",
          fileSize: 1024000,
          uploadTime: "2024-12-19 10:30:00",
          fileUrl: "https://img95.699pic.com/photo/40142/8262.jpg_wh860.jpg"
        },
        {
          id: 2,
          fileName: "医疗诊断证明.pdf",
          fileType: "pdf",
          fileSize: 2048000,
          uploadTime: "2024-12-19 11:20:00",
          fileUrl:
            "http://192.168.100.10:8080/profile/upload/2025/12/19/(吴龙8.7)每日工作总结1766131266142.pdf"
        },
        {
          id: 3,
          fileName: "检验报告单.jpg",
          fileType: "docx",
          fileSize: 512000,
          uploadTime: "2024-12-19 14:15:00",
          fileUrl: "https://img95.699pic.com/photo/40019/3490.jpg_wh860.jpg"
        }
      ],
      // PDF预览相关数据
      // 预览相关数据(保持原有代码)
      pdfPreviewVisible: false,
      imagePreviewVisible: false,
      unsupportedPreviewVisible: false,
      pdfLoading: false,
      pdfUrl: "",
      currentPage: 1,
      pageCount: 0,
      scale: 100,
      pageRotate: 0,
      // 图片预览相关
      imagePreviewVisible: false,
      // 不支持预览相关
      unsupportedPreviewVisible: false,
      // 通用预览数据
      previewTitle: "",
      previewUrl: "",
      currentFile: null
      currentFile: null,
      // 附件列表
      attachmentList: []
    };
  },
  watch: {
    caseData: {
      immediate: true,
      handler(newVal) {
        if (newVal && newVal.annexfilesList) {
          this.loadAttachments(newVal.annexfilesList);
        }
      }
    }
  },
  methods: {
    handleClose() {
      this.$emit("close");
    },
    // 获取文件类型
    // 加载附件
    loadAttachments(annexfilesList) {
      if (!annexfilesList || !Array.isArray(annexfilesList)) {
        this.attachmentList = [];
        return;
      }
      this.attachmentList = annexfilesList.map((file, index) => ({
        id: index + 1,
        fileName: file.fileName || `附件${index + 1}`,
        fileType: this.getFileExtension(file.fileUrl || ""),
        fileSize: file.fileSize || 0,
        uploadTime: file.uploadTime || this.formatDateTime(new Date()),
        fileUrl: file.fileUrl || ""
      }));
    },
    // 获取文件扩展名
    getFileExtension(filename) {
      return (
        filename
          .split(".")
          .pop()
          ?.toLowerCase() || "unknown"
      );
    },
    // 格式化日期时间
    formatDateTime(dateString) {
      if (!dateString) return "-";
      return dateString.replace("T", " ").substring(0, 19);
    },
    // 格式化日期
    formatDate(dateString) {
      if (!dateString) return "-";
      return dateString.split("T")[0];
    },
    // 获取完整户籍地址
    getFullRegisterAddress() {
      const {
        registerprovincename,
        registercityname,
        registertownname,
        registercommunityname,
        registeraddress
      } = this.caseData;
      const addressParts = [
        registerprovincename,
        registercityname,
        registertownname,
        registercommunityname,
        registeraddress
      ];
      return addressParts.filter(part => part).join("") || "-";
    },
    // 获取完整现住地址
    getFullResidenceAddress() {
      const {
        residenceprovincename,
        residencecountyname,
        residencetownname,
        residencecommunityname,
        residenceaddress
      } = this.caseData;
      const addressParts = [
        residenceprovincename,
        residencecountyname,
        residencetownname,
        residencecommunityname,
        residenceaddress
      ];
      return addressParts.filter(part => part).join("") || "-";
    },
    // 获取状态文本
    getStatusText(status) {
      const statusMap = {
        "1": "已上报",
        "2": "已阅读",
        "3": "已同意",
        "4": "已驳回"
      };
      return statusMap[status] || "未知状态";
    },
    // 获取状态类型
    getStatusType(status) {
      const statusMap = {
        "1": "info",
        "2": "warning",
        "3": "success",
        "4": "danger"
      };
      return statusMap[status] || "info";
    },
    // 获取年龄单位文本
    getAgeUnitText(unit) {
      const unitMap = {
        year: "岁",
        month: "月",
        day: "天"
      };
      return unitMap[unit] || unit;
    },
    // 获取证件类型文本
    getIdCardTypeText(type) {
      const typeMap = {
        "1": "身份证",
        "2": "护照",
        "3": "军官证"
      };
      return typeMap[type] || type || "-";
    },
    // 文件预览相关方法(保持原有代码)
    getFileType(fileName) {
      const extension = fileName
        .split(".")
@@ -390,13 +558,11 @@
        .toLowerCase();
      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
      const pdfTypes = ["pdf"];
      if (imageTypes.includes(extension)) return "image";
      if (pdfTypes.includes(extension)) return "pdf";
      return "other";
    },
    // 文件预览主入口
    handlePreview(file) {
      this.currentFile = file;
      this.previewTitle = `预览 - ${file.fileName}`;
@@ -416,7 +582,6 @@
      }
    },
    // PDF预览方法
    previewPdf(file) {
      this.pdfPreviewVisible = true;
      this.pdfLoading = true;
@@ -426,13 +591,11 @@
      this.pdfUrl = file.fileUrl;
    },
    // PDF加载完成回调
    loadPdfHandler() {
      this.pdfLoading = false;
      this.currentPage = 1;
    },
    // PDF加载错误处理
    pdfErrorHandler(error) {
      console.error("PDF加载失败:", error);
      this.pdfLoading = false;
@@ -440,26 +603,18 @@
      this.pdfPreviewVisible = false;
    },
    // 翻页功能
    changePage(newPage) {
      if (newPage < 1 || newPage > this.pageCount) return;
      this.currentPage = newPage;
    },
    // 缩放功能
    zoomIn() {
      if (this.scale >= 200) {
        this.$message.info("已放大到最大比例");
        return;
      }
      if (this.scale >= 200) return;
      this.scale += 10;
    },
    zoomOut() {
      if (this.scale <= 50) {
        this.$message.info("已缩小到最小比例");
        return;
      }
      if (this.scale <= 50) return;
      this.scale -= 10;
    },
@@ -467,24 +622,20 @@
      this.scale = 100;
    },
    // 图片预览方法
    previewImage(file) {
      this.imagePreviewVisible = true;
    },
    // 不支持预览的文件类型
    previewUnsupported(file) {
      this.unsupportedPreviewVisible = true;
    },
    // PDF对话框关闭处理
    handlePdfDialogClose() {
      this.pdfUrl = "";
      this.currentPage = 1;
      this.pageCount = 0;
    },
    // 文件下载
    handleDownload(file) {
      const link = document.createElement("a");
      link.href = file.fileUrl;
@@ -496,31 +647,10 @@
      this.$message.success("开始下载文件");
    },
    // 专用PDF下载方法
    downloadPdf(file) {
      this.handleDownload(file);
    },
    // 文件删除
    handleDelete(file) {
      this.$confirm("确定要删除这个附件吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.attachmentList = this.attachmentList.filter(
          item => item.id !== file.id
        );
        this.$message.success("删除成功");
      });
    },
    // 上传附件
    handleUpload() {
      this.$message.info("上传功能待实现");
    },
    // 格式化文件大小
    formatFileSize(bytes) {
      if (bytes === 0) return "0 B";
      const k = 1024;