WXL
3 天以前 4c9fdc87987140e8b2c3f0dfc2f6608cdb6be774
src/views/business/appear/caseDetail.vue
@@ -29,11 +29,15 @@
        </el-descriptions-item>
        <el-descriptions-item label="Rh阴性">
          {{
            caseData.rhYin === "1" ? "是" : caseData.rhYin === "0" ? "否" : "-"
            caseData.rhYin == "1" ? "是" : caseData.rhYin == "0" ? "否" : "-"
          }}
        </el-descriptions-item>
        <el-descriptions-item label="证件类型">
          {{ getIdCardTypeText(caseData.idcardtype) }}
          <dict-tag
            :options="dict.type.sys_IDType"
            :value="caseData.idcardtype"
          />
        </el-descriptions-item>
        <el-descriptions-item label="证件号码">{{
          caseData.idcardno || "-"
@@ -47,12 +51,16 @@
        <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="学历">
          <dict-tag
            :options="dict.type.sys_education"
            :value="String(caseData.education)"
        /></el-descriptions-item>
        <el-descriptions-item label="职业">
          <dict-tag
            :options="dict.type.sys_occupation"
            :value="caseData.occupation"
        /></el-descriptions-item>
        <el-descriptions-item label="出生日期">{{
          formatDate(caseData.birthday)
        }}</el-descriptions-item>
@@ -86,25 +94,33 @@
        <el-descriptions-item label="疾病诊断名称">{{
          caseData.diagnosisname || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="病情概况">{{
        <!-- <el-descriptions-item label="病情概况">{{
          caseData.illnessoverview || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="病人状况">{{
          caseData.patientstate || "-"
        }}</el-descriptions-item>
        }}</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="传染病情况"
          >{{
            getLabelsFromString(caseData.infectious, dict.type.sys_Infectious)
          }}
        </el-descriptions-item>
        <el-descriptions-item
          label="传染病其他说明"
          v-if="caseData.infectiousOther"
          >{{ caseData.infectiousOther }}</el-descriptions-item
        >
        <el-descriptions-item label="是否需要转运">
          {{ caseData.isTransport === "2" ? "需要" : "不需要" }}
          {{
            caseData.isTransport == "1"
              ? "不需要"
              : caseData.isTransport == "2"
              ? "需要"
              : "待定"
          }}
        </el-descriptions-item>
      </el-descriptions>
    </el-card>
@@ -115,24 +131,27 @@
        <span class="section-title">医院信息</span>
      </div>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="治疗医院名称">{{
        <el-descriptions-item label="ICU评估医生">{{
          caseData.icuDoctor || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="ICU医生电话">{{
          caseData.icuDoctorPhone || "-"
        }}</el-descriptions-item
        ><el-descriptions-item label="治疗医院名称">{{
          caseData.treatmenthospitalname || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="治疗科室名称">{{
        <!-- <el-descriptions-item label="治疗科室名称">{{
          caseData.treatmentdeptname || "-"
        }}</el-descriptions-item>
        }}</el-descriptions-item> -->
        <el-descriptions-item label="住院号">{{
          caseData.inpatientno || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="部门名称">{{
          caseData.deptName || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="部门编号">{{
        <!-- <el-descriptions-item label="部门编号">{{
          caseData.deptNo || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="上报医院">{{
          caseData.toHospital || "-"
        }}</el-descriptions-item>
        }}</el-descriptions-item> -->
      </el-descriptions>
    </el-card>
@@ -142,14 +161,15 @@
        <span class="section-title">上报信息</span>
      </div>
      <el-descriptions :column="2" border>
        <el-descriptions-item label="上报医院">{{
          caseData.toHospital || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="报告者姓名">{{
          caseData.infoName || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="报告者编号">{{
          caseData.infoNo || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="报告者联系电话">{{
          caseData.reporterphone || "-"
          caseData.phone || "-"
        }}</el-descriptions-item>
        <el-descriptions-item label="协调员姓名">{{
          caseData.coordinatorName || "-"
@@ -166,7 +186,7 @@
          formatDateTime(caseData.createTime)
        }}</el-descriptions-item>
        <el-descriptions-item label="是否终止案例">
          {{ caseData.terminationCase === "1" ? "已终止" : "进行中" }}
          {{ caseData.terminationCase == "1" ? "已终止" : "进行中" }}
        </el-descriptions-item>
      </el-descriptions>
    </el-card>
@@ -180,91 +200,98 @@
        <span class="section-title">附件信息</span>
      </div>
      <div class="detail-attachments">
        <div class="attachment-grid">
          <div
            v-for="file in caseData.annexfilesList"
            :key="file.id || file.fileName"
            class="attachment-card"
          >
            <template v-if="isImageFile(file.fileName || file.path)">
              <!-- 图片使用 el-image 预览 -->
              <el-image
                class="image-attachment"
                :src="getFileUrl(file)"
                :preview-src-list="getImagePreviewList(file)"
                fit="cover"
                :style="{ width: '120px', height: '120px' }"
                lazy
              >
                <div slot="error" class="image-error">
                  <i class="el-icon-picture-outline"></i>
                  <span>加载失败</span>
                </div>
                <div slot="placeholder" class="image-loading">
                  <i class="el-icon-loading"></i>
                </div>
              </el-image>
              <div class="image-info">
                <div class="file-name" :title="file.fileName">
                  {{ file.fileName }}
                </div>
                <div class="file-actions">
                  <el-button
                    type="text"
                    size="mini"
                    @click="handleDownload(file)"
                    icon="el-icon-download"
                    title="下载"
                  />
                  <el-button
                    type="text"
                    size="mini"
                    @click="handlePreview(file)"
                    icon="el-icon-view"
                    title="预览"
                  />
                </div>
              </div>
            </template>
            <template v-else>
              <!-- 非图片文件使用卡片样式 -->
              <el-card shadow="hover" class="file-card">
                <div class="file-content">
                  <i :class="getFileIcon(file.fileName)" class="file-icon"></i>
                  <div class="file-info">
                    <div class="file-name" :title="file.fileName">
                      {{ file.fileName }}
                    </div>
                    <div class="file-meta">
                      <span class="file-type">{{
                        getFileTypeText(file.fileName)
                      }}</span>
                      <span v-if="file.createTime" class="file-time">
                        {{ formatDateTime(file.createTime) }}
                      </span>
                    </div>
        <div
          v-for="group in attachmentGroups"
          :key="group.label"
          class="attachment-group"
        >
          <div class="attachment-group-title">{{ group.label }}</div>
          <div class="attachment-grid">
            <div
              v-for="file in group.files"
              :key="file.id || file.fileName"
              class="attachment-card"
            >
              <template v-if="isImageFile(file.fileName || file.path)">
                <!-- 图片使用 el-image 预览 -->
                <el-image
                  class="image-attachment"
                  :src="getFileUrl(file)"
                  :preview-src-list="getImagePreviewList(file)"
                  fit="cover"
                  :style="{ width: '120px', height: '120px' }"
                  lazy
                >
                  <div slot="error" class="image-error">
                    <i class="el-icon-picture-outline"></i>
                    <span>加载失败</span>
                  </div>
                  <div slot="placeholder" class="image-loading">
                    <i class="el-icon-loading"></i>
                  </div>
                </el-image>
                <div class="image-info">
                  <div class="file-name" :title="file.fileName">
                    {{ file.fileName }}
                  </div>
                  <div class="file-actions">
                    <el-button
                      type="text"
                      size="mini"
                      @click="handleDownload(file)"
                      icon="el-icon-download"
                      title="下载"
                    />
                    <el-button
                      type="text"
                      size="mini"
                      @click="handlePreview(file)"
                      icon="el-icon-view"
                      title="预览"
                    />
                  </div>
                </div>
                <div class="file-actions">
                  <el-button
                    type="text"
                    size="mini"
                    @click="handleDownload(file)"
                  >
                    下载
                  </el-button>
                  <el-button
                    v-if="canPreview(file.fileName)"
                    type="text"
                    size="mini"
                    @click="handlePreview(file)"
                  >
                    预览
                  </el-button>
                </div>
              </el-card>
            </template>
              </template>
              <template v-else>
                <!-- 非图片文件使用卡片样式 -->
                <el-card shadow="hover" class="file-card">
                  <div class="file-content">
                    <i :class="getFileIcon(file.fileName)" class="file-icon"></i>
                    <div class="file-info">
                      <div class="file-name" :title="file.fileName">
                        {{ file.fileName }}
                      </div>
                      <div class="file-meta">
                        <span class="file-type">{{
                          getFileTypeText(file.fileName)
                        }}</span>
                        <span v-if="file.createTime" class="file-time">
                          {{ formatDateTime(file.createTime) }}
                        </span>
                      </div>
                    </div>
                  </div>
                  <div class="file-actions">
                    <el-button
                      type="text"
                      size="mini"
                      @click="handleDownload(file)"
                    >
                      下载
                    </el-button>
                    <el-button
                      v-if="canPreview(file.fileName)"
                      type="text"
                      size="mini"
                      @click="handlePreview(file)"
                    >
                      预览
                    </el-button>
                  </div>
                </el-card>
              </template>
            </div>
          </div>
        </div>
      </div>
@@ -283,16 +310,25 @@
    <!-- 审批信息模块(状态为已同意或已驳回时显示) -->
    <el-card
      class="detail-section"
      v-if="caseData.reportStatus === '3' || caseData.reportStatus === '4'"
      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 :type="caseData.reportStatus == '3' ? 'success' : 'danger'">
            {{ caseData.reportStatus == "3" ? "已同意" : "已驳回" }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item
          label="驳回原因"
          v-if="caseData.reportStatus == 4"
        >
          <dict-tag
            :options="dict.type.reject_type"
            :value="caseData.rejectType"
          />
        </el-descriptions-item>
        <el-descriptions-item label="审批人">{{
          caseData.updateBy || "-"
@@ -301,7 +337,7 @@
          formatDateTime(caseData.updateTime)
        }}</el-descriptions-item>
        <el-descriptions-item label="审批意见">{{
          caseData.remark || "无"
          caseData.confirmResult || "无"
        }}</el-descriptions-item>
      </el-descriptions>
    </el-card>
@@ -316,7 +352,7 @@
      <div slot="header" class="section-header">
        <span class="section-title">转运信息</span>
        <el-button
          v-if="caseData.reportStatus === '3'"
          v-if="caseData.reportStatus == '3'"
          type="primary"
          size="small"
          icon="el-icon-truck"
@@ -367,7 +403,7 @@
    <!-- 无转运信息但需要转运的提示 -->
    <el-card
      class="detail-section"
      v-else-if="caseData.isTransport === '2' && caseData.reportStatus === '3'"
      v-else-if="caseData.isTransport == '2' && caseData.reportStatus == '3'"
    >
      <div slot="header" class="section-header">
        <span class="section-title">转运信息</span>
@@ -413,6 +449,15 @@
    pdf,
    FilePreviewDialog
  },
  dicts: [
    "sys_user_sex",
    "sys_BloodType",
    "sys_Infectious",
    "sys_IDType",
    "sys_education",
    "sys_occupation",
    "reject_type"
  ],
  props: {
    caseData: {
      type: Object,
@@ -423,15 +468,22 @@
      default: true
    }
  },
  dicts: ["sys_user_sex", "sys_BloodType"],
  data() {
    return {
      // 预览相关
      previewVisible: false,
      currentPreviewFile: null,
      // 动态计算的 baseUrlHt
      baseUrlHt: "",
      // 图片预览相关
      imagePreviewUrls: []
      imagePreviewUrls: [],
      rejectOptions: [
        { label: "好转", value: "1" },
        { label: "死亡", value: "2" },
        { label: "不符合捐献标准", value: "3" },
        { label: "家属放弃捐献", value: "4" },
        { label: "其他", value: "5" }
      ]
    };
  },
  computed: {
@@ -447,13 +499,59 @@
        .filter(file => this.isImageFile(file.fileName || file.path))
        .map(file => this.getFileUrl(file))
        .filter(url => url);
    },
    // 按分类分组附件(捐献者登记阶段:登记表附件/证件照/疾病诊断治疗)
    attachmentGroups() {
      const list = this.caseData.annexfilesList;
      if (!Array.isArray(list) || list.length === 0) return [];
      const categories = [
        { value: "登记表附件", label: "人体器官潜在捐献者登记表附件" },
        { value: "证件照", label: "证件照" },
        { value: "疾病诊断治疗", label: "疾病诊断治疗" }
      ];
      const groups = categories
        .map(cat => ({
          label: cat.label,
          files: list.filter(f => (f.fileType || "").trim() === cat.value)
        }))
        .filter(group => group.files.length > 0);
      // 未分类附件兜底,避免丢失旧数据
      const classifiedValues = categories.map(c => c.value);
      const unclassified = list.filter(f => {
        const t = (f.fileType || "").trim();
        return !t || !classifiedValues.includes(t);
      });
      if (unclassified.length > 0) {
        groups.push({ label: "未分类", files: unclassified });
      }
      return groups;
    }
  },
  created() {
    this.calculateBaseUrl();
  },
  methods: {
    handleClose() {
      this.$emit("close");
    },
    /** 计算 baseUrlHt */
    calculateBaseUrl() {
      const currentUrl = window.location.href;
      try {
        const urlObj = new URL(currentUrl);
        const hostname = urlObj.hostname;
        this.baseUrlHt = `http://${hostname}:9095`;
      } catch (error) {
        console.error("解析URL失败:", error);
        const match = currentUrl.match(/https?:\/\/([^:\/]+)/);
        if (match) {
          this.baseUrlHt = `http://${match[1]}:9095`;
        } else {
          this.baseUrlHt = "http://localhost:9095";
        }
      }
    },
    // 格式化日期时间
    formatDateTime(dateTime) {
      if (!dateTime) return "-";
@@ -522,8 +620,9 @@
    /** 创建转运单 */
    handleCreateTransport() {
      this.$router.push({
        path: "/business/transport/create",
        path: "/report/transfer",
        query: {
          autoCreate: "true",
          caseId: this.caseData.id,
          caseNo: this.caseData.caseNo,
          patName: this.caseData.name,
@@ -634,7 +733,30 @@
    },
    getFileUrl(file) {
      return file.path || file.fileUrl || "";
      if (!file) return "";
      const url = file.path || file.fileUrl || file.url || "";
      return this.processFileUrl(url);
    },
    // URL处理函数 - 将完整URL替换为baseUrlHt
    processFileUrl(url) {
      if (!url) return "";
      // 如果已经是完整的http或https链接
      if (url.startsWith("http://") || url.startsWith("https://")) {
        // 找到第三个斜杠后的位置,提取路径部分
        const thirdSlashIndex = url.indexOf("/", 8);
        if (thirdSlashIndex !== -1) {
          return `${this.baseUrlHt}${url.substring(thirdSlashIndex)}`;
        }
        return this.baseUrlHt;
      }
      // 相对路径处理
      if (url.startsWith("/")) {
        return `${this.baseUrlHt}${url}`;
      }
      return `${this.baseUrlHt}/${url}`;
    },
    getImagePreviewList(file) {
@@ -696,7 +818,7 @@
    handlePreview(file) {
      this.currentPreviewFile = {
        fileName: file.fileName,
        fileUrl: this.getFileUrl(file),
        fileUrl: this.getFileUrl(file), // 已经处理过URL
        fileType: this.getFileType(file.fileName)
      };
      this.previewVisible = true;
@@ -720,7 +842,7 @@
    // 文件下载
    handleDownload(file) {
      const fileUrl = this.getFileUrl(file);
      const fileUrl = this.getFileUrl(file); // 使用处理过的URL
      const fileName = file.fileName;
      if (fileUrl) {
@@ -766,6 +888,19 @@
  padding: 10px 0;
}
.attachment-group {
  margin-bottom: 20px;
}
.attachment-group-title {
  font-size: 14px;
  font-weight: bold;
  color: #409eff;
  margin-bottom: 12px;
  padding-left: 10px;
  border-left: 3px solid #409eff;
}
.attachment-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));