From 0c03027d7f238bf5beb98e85463f53f0bd92bbaa Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期一, 20 四月 2026 17:56:01 +0800
Subject: [PATCH] 青岛维护

---
 src/views/business/appear/caseDetail.vue | 1215 +++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 746 insertions(+), 469 deletions(-)

diff --git a/src/views/business/appear/caseDetail.vue b/src/views/business/appear/caseDetail.vue
index db0dc01..362085c 100644
--- a/src/views/business/appear/caseDetail.vue
+++ b/src/views/business/appear/caseDetail.vue
@@ -6,33 +6,74 @@
         <span class="section-title">鍩烘湰淇℃伅</span>
       </div>
       <el-descriptions :column="2" border>
-        <el-descriptions-item label="鎹愮尞缂栧彿">{{
-          caseData.donorNo
+        <el-descriptions-item label="妗堜緥缂栧彿">{{
+          caseData.caseNo || "-"
         }}</el-descriptions-item>
         <el-descriptions-item label="鎹愮尞鑰呭鍚�">{{
-          caseData.donorName
+          caseData.name || "-"
         }}</el-descriptions-item>
         <el-descriptions-item label="鎬у埆">
-          <dict-tag :options="genderOptions" :value="caseData.gender" />
+          <dict-tag :options="dict.type.sys_user_sex" :value="caseData.sex" />
         </el-descriptions-item>
-        <el-descriptions-item label="骞撮緞"
-          >{{ caseData.age }}宀�</el-descriptions-item
-        >
+        <el-descriptions-item label="骞撮緞">
+          {{ caseData.age || "-"
+          }}{{
+            caseData.ageunit ? `(${getAgeUnitText(caseData.ageunit)})` : ""
+          }}
+        </el-descriptions-item>
         <el-descriptions-item label="琛�鍨�">
-          <dict-tag :options="bloodTypeOptions" :value="caseData.bloodType" />
+          <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
+          caseData.idcardno || "-"
         }}</el-descriptions-item>
         <el-descriptions-item label="姘戞棌">{{
-          caseData.nation
+          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
+          caseData.phone || "-"
         }}</el-descriptions-item>
-        <el-descriptions-item label="浣忓潃" :span="2">{{
-          caseData.address
-        }}</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="1" border>
+        <el-descriptions-item label="鎴风睄鍦板潃">
+          {{ getFullRegisterAddress() }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鐜颁綇鍦板潃">
+          {{ getFullResidenceAddress() }}
+        </el-descriptions-item>
       </el-descriptions>
     </el-card>
 
@@ -42,24 +83,29 @@
         <span class="section-title">鍖荤枟淇℃伅</span>
       </div>
       <el-descriptions :column="1" border>
-        <el-descriptions-item label="鐤剧梾璇婃柇">{{
-          caseData.diagnosis
+        <el-descriptions-item label="鐤剧梾璇婃柇鍚嶇О">{{
+          caseData.diagnosisname || "-"
         }}</el-descriptions-item>
-        <el-descriptions-item label="浣忛櫌鍙�">{{
-          caseData.inpatientNo
+        <el-descriptions-item label="鐥呮儏姒傚喌">{{
+          caseData.illnessoverview || "-"
         }}</el-descriptions-item>
-        <el-descriptions-item label="鎵�鍦ㄧ瀹�">{{
-          caseData.departmentName
+        <el-descriptions-item label="鐥呬汉鐘跺喌">{{
+          caseData.patientstate || "-"
         }}</el-descriptions-item>
-        <el-descriptions-item label="涓绘不鍖荤敓">{{
-          caseData.doctorName
+        <el-descriptions-item label="GCS璇勫垎">{{
+          caseData.gcsScore || "-"
         }}</el-descriptions-item>
         <el-descriptions-item label="浼犳煋鐥呮儏鍐�">{{
-          caseData.infectiousDisease || "鏃�"
+          caseData.infectious || "鏃�"
         }}</el-descriptions-item>
-        <el-descriptions-item label="鍖荤枟璁板綍">{{
-          caseData.medicalRecord
-        }}</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>
 
@@ -69,214 +115,287 @@
         <span class="section-title">鍖婚櫌淇℃伅</span>
       </div>
       <el-descriptions :column="2" border>
-        <el-descriptions-item label="鍖婚櫌鍚嶇О">{{
-          caseData.hospitalName
+        <el-descriptions-item label="娌荤枟鍖婚櫌鍚嶇О">{{
+          caseData.treatmenthospitalname || "-"
         }}</el-descriptions-item>
-        <el-descriptions-item label="鍖婚櫌绾у埆">{{
-          caseData.hospitalLevel
+        <el-descriptions-item label="娌荤枟绉戝鍚嶇О">{{
+          caseData.treatmentdeptname || "-"
         }}</el-descriptions-item>
-        <el-descriptions-item label="鑱旂郴浜�">{{
-          caseData.contactPerson
+        <el-descriptions-item label="浣忛櫌鍙�">{{
+          caseData.inpatientno || "-"
         }}</el-descriptions-item>
-        <el-descriptions-item label="鑱旂郴鐢佃瘽">{{
-          caseData.contactPhone
+        <el-descriptions-item label="閮ㄩ棬鍚嶇О">{{
+          caseData.deptName || "-"
         }}</el-descriptions-item>
-        <el-descriptions-item label="鍖婚櫌鍦板潃" :span="2">{{
-          caseData.hospitalAddress
+        <el-descriptions-item label="閮ㄩ棬缂栧彿">{{
+          caseData.deptNo || "-"
+        }}</el-descriptions-item>
+        <el-descriptions-item label="涓婃姤鍖婚櫌">{{
+          caseData.toHospital || "-"
         }}</el-descriptions-item>
       </el-descriptions>
     </el-card>
 
-    <!-- 闄勪欢淇℃伅妯″潡 -->
+    <!-- 涓婃姤淇℃伅妯″潡 -->
     <el-card class="detail-section">
       <div slot="header" class="section-header">
-        <span class="section-title">闄勪欢淇℃伅</span>
-        <el-button type="text" icon="el-icon-upload" @click="handleUpload"
-          >涓婁紶闄勪欢</el-button
-        >
+        <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
-              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-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.createTime)
+        }}</el-descriptions-item>
+        <el-descriptions-item label="鏄惁缁堟妗堜緥">
+          {{ caseData.terminationCase === "1" ? "宸茬粓姝�" : "杩涜涓�" }}
+        </el-descriptions-item>
+      </el-descriptions>
     </el-card>
 
-    <!-- 瀹℃壒淇℃伅妯″潡锛堝鏈夛級 -->
-    <el-card class="detail-section" v-if="caseData.status !== '0'">
+    <!-- 闄勪欢淇℃伅妯″潡 -->
+    <el-card
+      class="detail-section"
+      v-if="caseData.annexfilesList && caseData.annexfilesList.length > 0"
+    >
+      <div slot="header" class="section-header">
+        <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>
+                </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>
+    </el-card>
+
+    <!-- 澶囨敞淇℃伅 -->
+    <el-card class="detail-section" v-if="caseData.remark">
+      <div slot="header" class="section-header">
+        <span class="section-title">澶囨敞淇℃伅</span>
+      </div>
+      <div class="remark-content">
+        {{ caseData.remark }}
+      </div>
+    </el-card>
+
+    <!-- 瀹℃壒淇℃伅妯″潡锛堢姸鎬佷负宸插悓鎰忔垨宸查┏鍥炴椂鏄剧ず锛� -->
+    <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.status | statusFilter">
-            {{ caseData.status | statusTextFilter }}
+          <el-tag :type="caseData.reportStatus === '3' ? 'success' : 'danger'">
+            {{ caseData.reportStatus === "3" ? "宸插悓鎰�" : "宸查┏鍥�" }}
           </el-tag>
         </el-descriptions-item>
-        <el-descriptions-item label="瀹℃壒鏃堕棿">{{
-          caseData.approveTime
-        }}</el-descriptions-item>
         <el-descriptions-item label="瀹℃壒浜�">{{
-          caseData.approverName
+          caseData.updateBy || "-"
+        }}</el-descriptions-item>
+        <el-descriptions-item label="瀹℃壒鏃堕棿">{{
+          formatDateTime(caseData.updateTime)
         }}</el-descriptions-item>
         <el-descriptions-item label="瀹℃壒鎰忚">{{
-          caseData.approveOpinion
+          caseData.remark || "鏃�"
         }}</el-descriptions-item>
       </el-descriptions>
     </el-card>
-
-    <!-- PDF棰勮寮圭獥 -->
-    <el-dialog
-      :title="previewTitle"
-      :append-to-body="true"
-      :visible.sync="pdfPreviewVisible"
-      width="90%"
-      top="5vh"
-      :close-on-click-modal="true"
-      class="pdf-preview-dialog"
-      @close="handlePdfDialogClose"
+    <el-card
+      class="detail-section"
+      v-if="
+        caseData.isTransport == '2' &&
+          caseData.serviceTransport &&
+          caseData.serviceTransport.length > 0
+      "
     >
-      <div class="pdf-preview-container" v-loading="pdfLoading">
-        <!-- PDF鎺у埗宸ュ叿鏍� -->
-        <div class="pdf-toolbar">
-          <el-button-group>
-            <el-button
-              size="mini"
-              @click="changePage(currentPage - 1)"
-              :disabled="currentPage <= 1"
-              icon="el-icon-arrow-left"
-            >
-              涓婁竴椤�
-            </el-button>
-            <el-button size="mini" disabled>
-              绗� {{ currentPage }} 椤� / 鍏� {{ pageCount }} 椤�
-            </el-button>
-            <el-button
-              size="mini"
-              @click="changePage(currentPage + 1)"
-              :disabled="currentPage >= pageCount"
-              icon="el-icon-arrow-right"
-            >
-              涓嬩竴椤�
-            </el-button>
-          </el-button-group>
-
-          <el-button-group class="zoom-controls">
-            <el-button size="mini" @click="zoomOut" :disabled="scale <= 50">
-              <i class="el-icon-zoom-out"></i> 缂╁皬
-            </el-button>
-            <el-button size="mini" disabled> {{ scale }}% </el-button>
-            <el-button size="mini" @click="zoomIn" :disabled="scale >= 200">
-              <i class="el-icon-zoom-in"></i> 鏀惧ぇ
-            </el-button>
-            <el-button size="mini" @click="resetZoom">
-              <i class="el-icon-refresh-left"></i> 閲嶇疆
-            </el-button>
-          </el-button-group>
-
-          <el-button
-            size="mini"
-            type="success"
-            @click="downloadPdf(currentFile)"
-            icon="el-icon-download"
-          >
-            涓嬭浇
-          </el-button>
-        </div>
-
-        <!-- PDF娓叉煋鍖哄煙 -->
-        <div class="pdf-viewport">
-          <pdf
-            ref="pdf"
-            :src="pdfUrl"
-            :page="currentPage"
-            :rotate="pageRotate"
-            @num-pages="pageCount = $event"
-            @page-loaded="currentPage = $event"
-            @loaded="loadPdfHandler"
-            @error="pdfErrorHandler"
-            :style="{
-              width: scale + '%',
-              transform: 'scale(' + scale / 100 + ')',
-              transformOrigin: '0 0'
-            }"
-          ></pdf>
-        </div>
+      <div slot="header" class="section-header">
+        <span class="section-title">杞繍淇℃伅</span>
+        <el-button
+          v-if="caseData.reportStatus === '3'"
+          type="primary"
+          size="small"
+          icon="el-icon-truck"
+          @click="handleViewTransport"
+        >
+          鏌ョ湅杞繍璇︽儏
+        </el-button>
       </div>
-    </el-dialog>
 
-    <!-- 鍥剧墖棰勮寮圭獥 -->
-    <el-dialog
-      :append-to-body="true"
-      :title="previewTitle"
-      :visible.sync="imagePreviewVisible"
-      width="60%"
-      top="10vh"
-      :close-on-click-modal="true"
+      <el-descriptions :column="2" border>
+        <el-descriptions-item
+          v-for="transport in caseData.serviceTransport"
+          :key="transport.id"
+        >
+          <!-- 杞繍鍗曞垪琛� -->
+          <div class="transport-info">
+            <div class="transport-item">
+              <strong>杞繍鍗曞彿:</strong> {{ transport.reportId || "-" }}
+            </div>
+            <div class="transport-item">
+              <strong>鎮h�呭鍚�:</strong> {{ transport.patName || "-" }}
+            </div>
+            <div class="transport-item">
+              <strong>鍑哄彂鍦扮偣:</strong>
+              {{ transport.transportStartPlace || "-" }}
+            </div>
+            <div class="transport-item">
+              <strong>鍑哄彂鏃堕棿:</strong>
+              {{ formatDateTime(transport.transportStartTime) }}
+            </div>
+            <div class="transport-item">
+              <strong>杞繍鐘舵��:</strong>
+              <el-tag :type="getTransportStatusTag(transport)" size="small">
+                {{ getTransportStatusText(transport) }}
+              </el-tag>
+            </div>
+            <div class="transport-item">
+              <strong>璐熻矗鍗忚皟鍛�:</strong> {{ transport.contactPerson || "-" }}
+            </div>
+            <div class="transport-item" v-if="transport.remark">
+              <strong>澶囨敞:</strong> {{ transport.remark }}
+            </div>
+          </div>
+        </el-descriptions-item>
+      </el-descriptions>
+    </el-card>
+
+    <!-- 鏃犺浆杩愪俊鎭絾闇�瑕佽浆杩愮殑鎻愮ず -->
+    <el-card
+      class="detail-section"
+      v-else-if="caseData.isTransport === '2' && caseData.reportStatus === '3'"
     >
-      <div class="image-preview-container">
-        <img :src="previewUrl" alt="棰勮鍥剧墖" class="preview-image" />
+      <div slot="header" class="section-header">
+        <span class="section-title">杞繍淇℃伅</span>
+        <el-button
+          type="primary"
+          size="small"
+          icon="el-icon-truck"
+          @click="handleCreateTransport"
+        >
+          鍒涘缓杞繍鍗�
+        </el-button>
       </div>
-    </el-dialog>
 
-    <!-- 涓嶆敮鎸侀瑙堢殑鏂囦欢绫诲瀷 -->
-    <el-dialog
-      :title="previewTitle"
-      :visible.sync="unsupportedPreviewVisible"
-      width="400px"
-      :close-on-click-modal="true"
-    >
-      <div class="unsupported-preview">
-        <el-alert
-          title="璇ユ枃浠舵牸寮忎笉鏀寔鍦ㄧ嚎棰勮锛岃涓嬭浇鍚庢煡鐪�"
-          type="warning"
-          show-icon
-          :closable="false"
-        />
-        <div style="text-align: center; margin-top: 20px;">
-          <el-button type="primary" @click="handleDownload(currentFile)">
-            <i class="el-icon-download"></i> 涓嬭浇鏂囦欢
-          </el-button>
-        </div>
-      </div>
-    </el-dialog>
+      <el-alert
+        title="璇ユ渚嬮渶瑕佽浆杩愶紝浣嗗皻鏈垱寤鸿浆杩愬崟"
+        type="warning"
+        description="璇风偣鍑讳笂鏂规寜閽垱寤鸿浆杩愬崟"
+        show-icon
+        :closable="false"
+      />
+    </el-card>
+    <!-- 鏂囦欢棰勮寮圭獥 -->
+    <FilePreviewDialog
+      :visible="previewVisible"
+      :file="currentPreviewFile"
+      @close="previewVisible = false"
+      @download="handleDownload"
+    />
 
     <div class="detail-footer" v-if="showtitle">
       <el-button @click="handleClose">鍏抽棴</el-button>
@@ -286,11 +405,13 @@
 
 <script>
 import pdf from "vue-pdf";
+import FilePreviewDialog from "@/components/FilePreviewDialog";
 
 export default {
   name: "CaseDetail",
   components: {
-    pdf
+    pdf,
+    FilePreviewDialog
   },
   props: {
     caseData: {
@@ -302,238 +423,318 @@
       default: true
     }
   },
-  filters: {
-    statusFilter(status) {
-      const statusMap = {
-        "0": "warning",
-        "1": "success",
-        "2": "danger"
-      };
-      return statusMap[status];
-    },
-    statusTextFilter(status) {
-      const statusMap = {
-        "0": "寰呭鎵�",
-        "1": "宸查�氳繃",
-        "2": "宸查┏鍥�"
-      };
-      return statusMap[status];
-    }
-  },
+  dicts: ["sys_user_sex", "sys_BloodType"],
   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,
-      pdfLoading: false,
-      pdfUrl: "",
-      currentPage: 1,
-      pageCount: 0,
-      scale: 100,
-      pageRotate: 0,
+      // 棰勮鐩稿叧
+      previewVisible: false,
+      currentPreviewFile: null,
 
       // 鍥剧墖棰勮鐩稿叧
-      imagePreviewVisible: false,
-
-      // 涓嶆敮鎸侀瑙堢浉鍏�
-      unsupportedPreviewVisible: false,
-
-      // 閫氱敤棰勮鏁版嵁
-      previewTitle: "",
-      previewUrl: "",
-      currentFile: null
+      imagePreviewUrls: []
     };
+  },
+  computed: {
+    // 鏀堕泦鎵�鏈夊浘鐗嘦RL鐢ㄤ簬棰勮
+    allImageUrls() {
+      if (
+        !this.caseData.annexfilesList ||
+        !Array.isArray(this.caseData.annexfilesList)
+      ) {
+        return [];
+      }
+      return this.caseData.annexfilesList
+        .filter(file => this.isImageFile(file.fileName || file.path))
+        .map(file => this.getFileUrl(file))
+        .filter(url => url);
+    }
   },
   methods: {
     handleClose() {
       this.$emit("close");
     },
 
-    // 鑾峰彇鏂囦欢绫诲瀷
+    // 鏍煎紡鍖栨棩鏈熸椂闂�
+    formatDateTime(dateTime) {
+      if (!dateTime) return "-";
+      return dateTime.replace("T", " ").substring(0, 19);
+    },
+
+    // 鏍煎紡鍖栨棩鏈�
+    formatDate(dateString) {
+      if (!dateString) return "-";
+      return dateString.split("T")[0];
+    },
+    getTransportStatusTag(transport) {
+      if (!transport.transitStatus) return "info";
+      switch (transport.transitStatus.toString()) {
+        case "1":
+          return "warning"; // 寰呰浆杩�
+        case "2":
+          return "primary"; // 杞繍涓�
+        case "3":
+          return "success"; // 杞繍瀹屾垚
+        case "4":
+          return "danger"; // 杞繍鍙栨秷
+        case "5":
+          return "info"; // 鏆傚瓨
+        default:
+          return "info";
+      }
+    },
+
+    /** 鑾峰彇杞繍鐘舵�佹枃鏈� */
+    getTransportStatusText(transport) {
+      if (!transport.transitStatus) return "鏈煡";
+      switch (transport.transitStatus.toString()) {
+        case "1":
+          return "寰呰浆杩�";
+        case "2":
+          return "杞繍涓�";
+        case "3":
+          return "杞繍瀹屾垚";
+        case "4":
+          return "杞繍鍙栨秷";
+        case "5":
+          return "鏆傚瓨";
+        default:
+          return "鏈煡";
+      }
+    },
+
+    /** 鏌ョ湅杞繍璇︽儏 */
+    handleViewTransport() {
+      if (
+        this.caseData.serviceTransport &&
+        this.caseData.serviceTransport.length > 0
+      ) {
+        const transport = this.caseData.serviceTransport[0];
+        this.$router.push({
+          path: "/business/transport/detail",
+          query: {
+            id: transport.id,
+            caseNo: this.caseData.caseNo
+          }
+        });
+      }
+    },
+
+    /** 鍒涘缓杞繍鍗� */
+    handleCreateTransport() {
+      this.$router.push({
+        path: "/business/transport/create",
+        query: {
+          caseId: this.caseData.id,
+          caseNo: this.caseData.caseNo,
+          patName: this.caseData.name,
+          age: this.caseData.age,
+          sex: this.caseData.sex,
+          diagnosisname: this.caseData.diagnosisname,
+          treatmentHospitalName: this.caseData.treatmenthospitalname
+        }
+      });
+    },
+    // 鑾峰彇瀹屾暣鎴风睄鍦板潃
+    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 || "-";
+    },
+
+    // 鏂囦欢澶勭悊鐩稿叧鏂规硶
+    isImageFile(fileName) {
+      if (!fileName) return false;
+      const imageExtensions = [
+        "jpg",
+        "jpeg",
+        "png",
+        "gif",
+        "bmp",
+        "webp",
+        "svg"
+      ];
+      const extension = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      return imageExtensions.includes(extension);
+    },
+
+    getFileUrl(file) {
+      return file.path || file.fileUrl || "";
+    },
+
+    getImagePreviewList(file) {
+      // 杩斿洖鎵�鏈夊浘鐗囩殑URL鍒楄〃锛屽疄鐜扮偣鍑讳换鎰忓浘鐗囨煡鐪嬫墍鏈夊浘鐗�
+      return this.allImageUrls;
+    },
+
+    getFileIcon(fileName) {
+      if (!fileName) return "el-icon-document";
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const iconMap = {
+        pdf: "el-icon-document",
+        doc: "el-icon-document",
+        docx: "el-icon-document",
+        xls: "el-icon-document",
+        xlsx: "el-icon-document",
+        jpg: "el-icon-picture",
+        jpeg: "el-icon-picture",
+        png: "el-icon-picture",
+        gif: "el-icon-picture"
+      };
+      return iconMap[ext] || "el-icon-document";
+    },
+
+    getFileTypeText(fileName) {
+      if (!fileName) return "鏂囦欢";
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const typeMap = {
+        pdf: "PDF鏂囨。",
+        doc: "Word鏂囨。",
+        docx: "Word鏂囨。",
+        xls: "Excel琛ㄦ牸",
+        xlsx: "Excel琛ㄦ牸",
+        jpg: "鍥剧墖",
+        jpeg: "鍥剧墖",
+        png: "鍥剧墖",
+        gif: "鍥剧墖"
+      };
+      return typeMap[ext] || "鏂囦欢";
+    },
+
+    canPreview(fileName) {
+      if (!fileName) return false;
+      const previewableExtensions = ["pdf", "jpg", "jpeg", "png", "gif"];
+      const extension = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      return previewableExtensions.includes(extension);
+    },
+
+    // 鏂囦欢棰勮
+    handlePreview(file) {
+      this.currentPreviewFile = {
+        fileName: file.fileName,
+        fileUrl: this.getFileUrl(file),
+        fileType: this.getFileType(file.fileName)
+      };
+      this.previewVisible = true;
+    },
+
     getFileType(fileName) {
+      if (!fileName) return "other";
       const extension = fileName
         .split(".")
         .pop()
         .toLowerCase();
       const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
       const pdfTypes = ["pdf"];
+      const officeTypes = ["doc", "docx", "xls", "xlsx"];
 
       if (imageTypes.includes(extension)) return "image";
       if (pdfTypes.includes(extension)) return "pdf";
+      if (officeTypes.includes(extension)) return "office";
       return "other";
-    },
-
-    // 鏂囦欢棰勮涓诲叆鍙�
-    handlePreview(file) {
-      this.currentFile = file;
-      this.previewTitle = `棰勮 - ${file.fileName}`;
-      this.previewUrl = file.fileUrl;
-      const fileType = this.getFileType(file.fileName);
-
-      switch (fileType) {
-        case "pdf":
-          this.previewPdf(file);
-          break;
-        case "image":
-          this.previewImage(file);
-          break;
-        default:
-          this.previewUnsupported(file);
-          break;
-      }
-    },
-
-    // PDF棰勮鏂规硶
-    previewPdf(file) {
-      this.pdfPreviewVisible = true;
-      this.pdfLoading = true;
-      this.currentPage = 1;
-      this.scale = 100;
-      this.pageRotate = 0;
-      this.pdfUrl = file.fileUrl;
-    },
-
-    // PDF鍔犺浇瀹屾垚鍥炶皟
-    loadPdfHandler() {
-      this.pdfLoading = false;
-      this.currentPage = 1;
-    },
-
-    // PDF鍔犺浇閿欒澶勭悊
-    pdfErrorHandler(error) {
-      console.error("PDF鍔犺浇澶辫触:", error);
-      this.pdfLoading = false;
-      this.$message.error("PDF鏂囦欢鍔犺浇澶辫触锛岃灏濊瘯涓嬭浇鍚庢煡鐪�");
-      this.pdfPreviewVisible = false;
-    },
-
-    // 缈婚〉鍔熻兘
-    changePage(newPage) {
-      if (newPage < 1 || newPage > this.pageCount) return;
-      this.currentPage = newPage;
-    },
-
-    // 缂╂斁鍔熻兘
-    zoomIn() {
-      if (this.scale >= 200) {
-        this.$message.info("宸叉斁澶у埌鏈�澶ф瘮渚�");
-        return;
-      }
-      this.scale += 10;
-    },
-
-    zoomOut() {
-      if (this.scale <= 50) {
-        this.$message.info("宸茬缉灏忓埌鏈�灏忔瘮渚�");
-        return;
-      }
-      this.scale -= 10;
-    },
-
-    resetZoom() {
-      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;
-      link.download = file.fileName;
-      link.style.display = "none";
-      document.body.appendChild(link);
-      link.click();
-      document.body.removeChild(link);
-      this.$message.success("寮�濮嬩笅杞芥枃浠�");
-    },
+      const fileUrl = this.getFileUrl(file);
+      const fileName = file.fileName;
 
-    // 涓撶敤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;
-      const sizes = ["B", "KB", "MB", "GB"];
-      const i = Math.floor(Math.log(bytes) / Math.log(k));
-      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
+      if (fileUrl) {
+        const link = document.createElement("a");
+        link.href = fileUrl;
+        link.download = fileName;
+        link.style.display = "none";
+        document.body.appendChild(link);
+        link.click();
+        document.body.removeChild(link);
+        this.$message.success("寮�濮嬩笅杞芥枃浠�");
+      } else {
+        this.$message.warning("鏂囦欢璺緞涓嶅瓨鍦紝鏃犳硶涓嬭浇");
+      }
     }
   }
 };
@@ -544,83 +745,144 @@
   padding: 0 20px;
 }
 
-/* PDF棰勮瀵硅瘽妗嗘牱寮� */
-.pdf-preview-dialog {
-  margin-top: 5vh !important;
+.detail-section {
+  margin-bottom: 16px;
 }
 
-.pdf-preview-dialog >>> .el-dialog {
-  min-height: 80vh;
-  display: flex;
-  flex-direction: column;
-}
-
-.pdf-preview-dialog >>> .el-dialog__body {
-  flex: 1;
-  padding: 0;
-  display: flex;
-  flex-direction: column;
-}
-
-.pdf-preview-container {
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-}
-
-/* PDF宸ュ叿鏍忔牱寮� */
-.pdf-toolbar {
-  padding: 15px 20px;
-  background: #f5f7fa;
-  border-bottom: 1px solid #ebeef5;
+.section-header {
   display: flex;
   justify-content: space-between;
   align-items: center;
-  flex-wrap: wrap;
-  gap: 10px;
 }
 
-.zoom-controls {
-  margin: 0 15px;
+.section-title {
+  font-size: 16px;
+  font-weight: bold;
+  color: #303133;
 }
 
-/* PDF瑙嗗浘鍖哄煙鏍峰紡 */
-.pdf-viewport {
-  flex: 1;
-  overflow: auto;
-  padding: 20px;
-  background: #f8f9fa;
+/* 闄勪欢鏍峰紡 */
+.detail-attachments {
+  padding: 10px 0;
+}
+
+.attachment-grid {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
+  gap: 16px;
+}
+
+.attachment-card {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+/* 鍥剧墖闄勪欢鏍峰紡 */
+.image-attachment {
+  border-radius: 4px;
+  border: 1px solid #ebeef5;
+  cursor: pointer;
+  transition: all 0.3s;
+  margin-bottom: 8px;
+}
+
+.image-attachment:hover {
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+  transform: translateY(-2px);
+}
+
+.image-info {
+  text-align: center;
+  width: 100%;
+}
+
+.image-info .file-name {
+  font-size: 12px;
+  color: #606266;
+  margin-bottom: 4px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  max-width: 120px;
+}
+
+.image-info .file-actions {
   display: flex;
   justify-content: center;
-  align-items: flex-start;
+  gap: 8px;
 }
 
-/* 鍥剧墖棰勮鏍峰紡 */
-.image-preview-container {
+.image-loading,
+.image-error {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+  color: #909399;
+  font-size: 12px;
+}
+
+.image-loading i,
+.image-error i {
+  font-size: 20px;
+  margin-bottom: 4px;
+}
+
+/* 鏂囦欢鍗$墖鏍峰紡 */
+.file-card {
+  width: 100%;
+  min-height: 60px;
+  margin-bottom: 8px;
+}
+
+.file-content {
+  display: flex;
+  align-items: center;
+  padding: 8px;
+}
+
+.file-icon {
+  font-size: 24px;
+  margin-right: 12px;
+  color: #409eff;
+  flex-shrink: 0;
+}
+
+.file-info {
+  flex: 1;
+  min-width: 0;
+}
+
+.file-name {
+  font-size: 13px;
+  font-weight: 500;
+  margin-bottom: 4px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.file-meta {
+  display: flex;
+  justify-content: space-between;
+  font-size: 12px;
+  color: #909399;
+}
+
+.file-actions {
   text-align: center;
-  padding: 20px;
+  padding: 8px;
+  border-top: 1px solid #f0f0f0;
 }
 
-.preview-image {
-  max-width: 100%;
-  max-height: 70vh;
-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-}
-
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 768px) {
-  .pdf-toolbar {
-    flex-direction: column;
-    gap: 10px;
-  }
-
-  .zoom-controls {
-    margin: 10px 0;
-  }
-
-  .pdf-preview-dialog {
-    width: 95% !important;
-  }
+/* 澶囨敞鏍峰紡 */
+.remark-content {
+  padding: 12px;
+  line-height: 1.6;
+  color: #606266;
+  white-space: pre-line;
 }
 
 .detail-footer {
@@ -635,4 +897,19 @@
   background-color: #f5f7fa;
   font-weight: bold;
 }
+/* 杞繍淇℃伅鏍峰紡 */
+.transport-info {
+  padding: 10px;
+}
+
+.transport-item {
+  margin-bottom: 8px;
+  line-height: 1.6;
+}
+
+.transport-item strong {
+  display: inline-block;
+  width: 100px;
+  color: #606266;
+}
 </style>

--
Gitblit v1.9.3