From 7f67f2e6fbb7d47249fef0905a40a66f13ae2f2b Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期五, 21 八月 2026 10:05:32 +0800
Subject: [PATCH] 青岛维护

---
 src/views/business/GetWitness/GetWitnessInfo.vue | 1293 +++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 777 insertions(+), 516 deletions(-)

diff --git a/src/views/business/GetWitness/GetWitnessInfo.vue b/src/views/business/GetWitness/GetWitnessInfo.vue
index 838c7c5..ea5578b 100644
--- a/src/views/business/GetWitness/GetWitnessInfo.vue
+++ b/src/views/business/GetWitness/GetWitnessInfo.vue
@@ -1,148 +1,120 @@
 <template>
   <div class="organ-procurement-detail">
-    <case-basic-info :case-id="caseId" :show-attachment="true" />
+    <case-basic-info :case-id="caseId" :show-attachment="true":column="3" />
 
     <!-- 鍩烘湰淇℃伅 -->
-    <el-card class="detail-card">
+    <el-card class="detail-card paper-card">
       <div slot="header" class="clearfix">
         <span class="detail-title">鍣ㄥ畼鑾峰彇鍩烘湰淇℃伅</span>
-        <div style="float: right;">
-          <el-button type="primary" @click="handleSave" :loading="saveLoading">
-            淇濆瓨
-          </el-button>
-          <el-button
-            type="success"
-            @click="handleProcure"
-            :loading="confirmLoading"
-          >
-            纭鑾峰彇
-          </el-button>
-        </div>
       </div>
 
-      <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+      <el-form :model="form" ref="form" :rules="rules" label-width="120px" class="paper-form">
         <!-- 鎵嬫湳鐩稿叧淇℃伅 -->
         <el-divider content-position="left">鎵嬫湳淇℃伅</el-divider>
 
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="鎵嬫湳鍖荤敓" prop="operationdoctor">
-              <el-input v-model="form.operationdoctor" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鎵嬫湳寮�濮嬫椂闂�" prop="operationbegtime">
-              <el-date-picker
-                v-model="form.operationbegtime"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鎵嬫湳缁撴潫鏃堕棿" prop="operationendtime">
-              <el-date-picker
-                v-model="form.operationendtime"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
+        <div class="form-row">
+          <el-form-item label="鎵嬫湳鍖荤敓" prop="operationdoctor" class="col-1-3">
+            <el-input v-model="form.operationdoctor" />
+          </el-form-item>
+          <el-form-item label="鎵嬫湳寮�濮嬫椂闂�" prop="operationbegtime" class="col-1-3">
+            <el-date-picker
+              v-model="form.operationbegtime"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+            />
+          </el-form-item>
+          <el-form-item label="鎵嬫湳缁撴潫鏃堕棿" prop="operationendtime" class="col-1-3">
+            <el-date-picker
+              v-model="form.operationendtime"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </div>
 
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item
-              label="鑵逛富鍔ㄨ剦鎻掔鏃堕棿"
-              prop="abdominalaortacannulatime"
-            >
-              <el-date-picker
-                v-model="form.abdominalaortacannulatime"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item
-              label="鑵逛富鍔ㄨ剦鐏屾敞鏃堕棿"
-              prop="abdominalaortaperfusiontime"
-            >
-              <el-date-picker
-                v-model="form.abdominalaortaperfusiontime"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
+        <div class="form-row">
+          <el-form-item
+            label="鑵逛富鍔ㄨ剦鎻掔鏃堕棿"
+            prop="abdominalaortacannulatime"
+            class="col-1-3"
+          >
+            <el-date-picker
+              v-model="form.abdominalaortacannulatime"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+            />
+          </el-form-item>
+          <el-form-item
+            label="鑵逛富鍔ㄨ剦鐏屾敞鏃堕棿"
+            prop="abdominalaortaperfusiontime"
+            class="col-1-3"
+          >
+            <el-date-picker
+              v-model="form.abdominalaortaperfusiontime"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </div>
 
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="闂ㄩ潤鑴夋彃绠℃椂闂�" prop="portalveincannulatime">
-              <el-date-picker
-                v-model="form.portalveincannulatime"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="闂ㄩ潤鑴夌亴娉ㄦ椂闂�" prop="portalveinperfusiontime">
-              <el-date-picker
-                v-model="form.portalveinperfusiontime"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
+        <div class="form-row">
+          <el-form-item label="闂ㄩ潤鑴夋彃绠℃椂闂�" prop="portalveincannulatime" class="col-1-3">
+            <el-date-picker
+              v-model="form.portalveincannulatime"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+            />
+          </el-form-item>
+          <el-form-item label="闂ㄩ潤鑴夌亴娉ㄦ椂闂�" prop="portalveinperfusiontime" class="col-1-3">
+            <el-date-picker
+              v-model="form.portalveinperfusiontime"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </div>
 
         <!-- 鍗忚皟鍛樹俊鎭� -->
         <el-divider content-position="left">鍗忚皟鍛樹俊鎭�</el-divider>
 
-        <el-row :gutter="20">
+        <div class="form-row">
           <!-- <el-col :span="8">
             <el-form-item label="鍗忚皟鍛樺鍚�" prop="coordinatorName">
               <el-input v-model="form.coordinatorName" />
             </el-form-item>
           </el-col> -->
-          <el-col :span="8">
-            <el-form-item label="杩涙墜鏈鏃堕棿" prop="coordinatorInOperating">
-              <el-date-picker
-                v-model="form.coordinatorInOperating"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鍑烘墜鏈鏃堕棿" prop="coordinatorOutOperating">
-              <el-date-picker
-                v-model="form.coordinatorOutOperating"
-                type="datetime"
-                value-format="yyyy-MM-dd HH:mm:ss"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
+          <el-form-item label="杩涙墜鏈鏃堕棿" prop="coordinatorInOperating" class="col-1-3">
+            <el-date-picker
+              v-model="form.coordinatorInOperating"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+            />
+          </el-form-item>
+          <el-form-item label="鍑烘墜鏈鏃堕棿" prop="coordinatorOutOperating" class="col-1-3">
+            <el-date-picker
+              v-model="form.coordinatorOutOperating"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </div>
 
-        <el-row :gutter="20">
-          <el-col :span="8">
+        <div class="form-row">
+          <!-- <el-col :span="8">
             <el-form-item label="鍗忚皟鍛樼瀛�" prop="coordinatorSign">
               <el-input v-model="form.coordinatorSign" />
             </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="绛惧瓧鏃堕棿" prop="coordinatorSignTime">
+          </el-col> -->
+          <!-- <el-col :span="8">
+            <el-form-item label="鑾峰彇鏃堕棿" prop="coordinatorSignTime">
               <el-date-picker
                 v-model="form.coordinatorSignTime"
                 type="datetime"
@@ -150,51 +122,55 @@
                 style="width: 100%"
               />
             </el-form-item>
-          </el-col>
-        </el-row>
+          </el-col> -->
+          <el-form-item label="鏄惁榛樺搥缂呮��" prop="isspendremember" class="col-1-3">
+            <el-select v-model="form.isspendremember" style="width: 100%">
+              <el-option label="鏄�" :value="1" />
+              <el-option label="鍚�" :value="0" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鎭㈠閬椾綋浠" prop="isrestoreremains" class="col-1-3">
+            <el-select v-model="form.isrestoreremains" style="width: 100%">
+              <el-option label="鏄�" :value="1" />
+              <el-option label="鍚�" :value="0" />
+            </el-select>
+          </el-form-item>
+        </div>
 
         <!-- 璐熻矗浜轰俊鎭� -->
         <el-divider content-position="left">璐熻矗浜轰俊鎭�</el-divider>
 
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="璐熻矗浜哄鍚�" prop="responsibleusername">
-              <el-input v-model="form.responsibleusername" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鑱旂粶浜轰竴" prop="coordinatedusernameo">
-              <el-input v-model="form.coordinatedusernameo" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鑱旂粶浜轰簩" prop="coordinatedusernamet">
-              <el-input v-model="form.coordinatedusernamet" />
-            </el-form-item>
-          </el-col>
-        </el-row>
+        <div class="form-row">
+          <el-form-item label="璐熻矗浜哄鍚�" prop="responsibleusername" class="col-1-3">
+            <el-input v-model="form.responsibleusername" />
+          </el-form-item>
+          <el-form-item label="鍗忚皟鍛樹竴" prop="coordinatedusernameo" class="col-1-3">
+            <el-input v-model="form.coordinatedusernameo" />
+          </el-form-item>
+          <el-form-item label="鍗忚皟鍛樹簩" prop="coordinatedusernamet" class="col-1-3">
+            <el-input v-model="form.coordinatedusernamet" />
+          </el-form-item>
+        </div>
 
         <!-- 鑾峰彇鏈烘瀯淇℃伅 -->
         <el-divider content-position="left">鑾峰彇鏈烘瀯淇℃伅</el-divider>
 
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="鑾峰彇鏈烘瀯鍚嶇О" prop="gainhospitalname">
-              <el-input
-                v-model="form.gainhospitalname"
-                placeholder="璇疯緭鍏ヨ幏鍙栨満鏋勫悕绉�"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鑾峰彇鏈烘瀯缂栫爜" prop="gainhospitalno">
+        <div class="form-row">
+          <el-form-item label="鑾峰彇鏈烘瀯鍚嶇О" prop="gainhospitalname" class="col-1-3">
+            <el-input
+              v-model="form.gainhospitalname"
+              placeholder="璇疯緭鍏ヨ幏鍙栨満鏋勫悕绉�"
+            />
+          </el-form-item>
+          <!-- <el-col :span="8">
+            <el-form-item label="鎹愮尞缂栧彿" prop="gainhospitalno">
               <el-input
                 v-model="form.gainhospitalno"
-                placeholder="璇疯緭鍏ヨ幏鍙栨満鏋勭紪鐮�"
+                placeholder="璇疯緭鍏ユ崘鐚紪鍙�"
               />
             </el-form-item>
-          </el-col>
-        </el-row>
+          </el-col> -->
+        </div>
       </el-form>
     </el-card>
 
@@ -203,13 +179,8 @@
       <div slot="header" class="clearfix">
         <span class="detail-title">鍣ㄥ畼鑾峰彇璁板綍</span>
         <div style="float: right;">
-          <!-- <el-tag
-            :type="form.witnessState === 'completed' ? 'success' : 'warning'"
-          >
-            {{ form.witnessState === "completed" ? "宸插畬鎴�" : "杩涜涓�" }}
-          </el-tag> -->
           <dict-tag
-            :options="dict.type.sys_user_sex"
+            :options="dict.type.Obtain_status"
             :value="form.witnessState"
           />
         </div>
@@ -244,7 +215,7 @@
           <el-col>
             <el-form-item>
               <el-table
-                :data="procurementData.serviceDonationwitnessorgans"
+                :data="displayOrgans"
                 v-loading="loading"
                 border
                 style="width: 100%"
@@ -268,7 +239,7 @@
                 <el-table-column
                   label="鑾峰彇寮�濮嬫椂闂�"
                   align="center"
-                  width="180"
+                  width="260"
                   prop="organStartTime"
                 >
                   <template slot-scope="scope">
@@ -287,7 +258,7 @@
                 <el-table-column
                   label="鍣ㄥ畼绂讳綋鏃堕棿"
                   align="center"
-                  width="180"
+                  width="260"
                   prop="organgettime"
                 >
                   <template slot-scope="scope">
@@ -306,30 +277,39 @@
                 <el-table-column
                   label="鑾峰彇鍖婚櫌"
                   align="center"
-                  width="200"
-                  prop="gainhospitalno"
+                  width="300"
+                  prop="gainhospitalname"
                 >
-                  <template slot-scope="scope">
+                  <!-- <template slot-scope="scope">
                     <el-select
-                      v-model="scope.row.gainhospitalno"
+                      v-model="scope.row.gainhospitalname"
                       placeholder="璇烽�夋嫨鑾峰彇鍖婚櫌"
                       style="width: 100%"
-                      @change="handleHospitalChange(scope.row, $event)"
                     >
                       <el-option
-                        v-for="hospital in hospitalList"
-                        :key="hospital.hospitalNo"
-                        :label="hospital.hospitalName"
-                        :value="hospital.hospitalNo"
-                      />
+                        v-for="dict in dict.type.Geta_hospital"
+                        :key="dict.value"
+                        :label="dict.label"
+                        :value="dict.value"
+                      ></el-option>
+
                     </el-select>
+                  </template> -->
+                  <template slot-scope="scope">
+                    <el-autocomplete
+                      v-model="scope.row.gainhospitalname"
+                      :fetch-suggestions="queryHospitalSearch"
+                      placeholder="璇烽�夋嫨鎴栬緭鍏ヨ幏鍙栧尰闄�"
+                      style="width: 100%"
+                      clearable
+                    ></el-autocomplete>
                   </template>
                 </el-table-column>
 
                 <el-table-column
                   label="鑾峰彇鍖诲笀"
                   align="center"
-                  width="120"
+                  width="150"
                   prop="organgetdoct"
                 >
                   <template slot-scope="scope">
@@ -341,51 +321,6 @@
                 </el-table-column>
 
                 <!-- <el-table-column
-                  label="鍔╂墜"
-                  align="center"
-                  width="120"
-                  prop="assistant"
-                >
-                  <template slot-scope="scope">
-                    <el-input
-                      v-model="scope.row.assistant"
-                      placeholder="鍔╂墜"
-
-                    />
-                  </template>
-                </el-table-column> -->
-
-                <!-- <el-table-column
-                  label="鑾峰彇鎶ゅ+"
-                  align="center"
-                  width="120"
-                  prop="procurementNurse"
-                >
-                  <template slot-scope="scope">
-                    <el-input
-                      v-model="scope.row.procurementNurse"
-                      placeholder="鑾峰彇鎶ゅ+"
-
-                    />
-                  </template>
-                </el-table-column>
-
-                <el-table-column
-                  label="鎵嬫湳瀹ゆ姢澹�"
-                  align="center"
-                  width="120"
-                  prop="operatingRoomNurse"
-                >
-                  <template slot-scope="scope">
-                    <el-input
-                      v-model="scope.row.operatingRoomNurse"
-                      placeholder="鎵嬫湳瀹ゆ姢澹�"
-
-                    />
-                  </template>
-                </el-table-column> -->
-
-                <el-table-column
                   label="鑾峰彇鐘舵��"
                   align="center"
                   width="120"
@@ -405,7 +340,7 @@
                       />
                     </el-select>
                   </template>
-                </el-table-column>
+                </el-table-column> -->
 
                 <el-table-column
                   label="璇存槑"
@@ -445,55 +380,6 @@
           </el-col>
         </el-row>
 
-        <!-- 鑾峰彇缁熻淇℃伅 -->
-        <!-- <div
-          class="procurement-stats"
-          v-if="
-            procurementData.serviceDonationwitnessorgans &&
-              procurementData.serviceDonationwitnessorgans.length > 0
-          "
-        >
-          <el-row :gutter="20">
-            <el-col :span="6">
-              <div class="stat-item">
-                <span class="stat-label">宸茶幏鍙栧櫒瀹�:</span>
-                <span class="stat-value"
-                  >{{
-                    procurementData.serviceDonationwitnessorgans.length
-                  }}
-                  涓�</span
-                >
-              </div>
-            </el-col>
-            <el-col :span="6">
-              <div class="stat-item">
-                <span class="stat-label">寰呭畬鍠勪俊鎭�:</span>
-                <span class="stat-value">{{ incompleteRecords }} 涓�</span>
-              </div>
-            </el-col>
-            <el-col :span="6">
-              <div class="stat-item">
-                <span class="stat-label">娑夊強鍖婚櫌:</span>
-                <span class="stat-value">{{ uniqueHospitals }} 瀹�</span>
-              </div>
-            </el-col>
-            <el-col :span="6">
-              <div class="stat-item">
-                <span class="stat-label">鑾峰彇鐘舵��:</span>
-                <span class="stat-value">
-                  <el-tag
-                    :type="
-                      form.witnessState === 'completed' ? 'success' : 'warning'
-                    "
-                  >
-                    {{ form.witnessState === "completed" ? "宸插畬鎴�" : "杩涜涓�" }}
-                  </el-tag>
-                </span>
-              </div>
-            </el-col>
-          </el-row>
-        </div> -->
-
         <div
           v-if="!procurementData.serviceDonationwitnessorgans"
           class="empty-procurement"
@@ -505,89 +391,118 @@
       </el-form>
     </el-card>
 
-    <!-- 闄勪欢绠$悊閮ㄥ垎浼樺寲 -->
+    <!-- 闄勪欢绠$悊閮ㄥ垎 - 鍒嗙被Tab灞曠ず -->
     <el-card class="attachment-card">
-      <div class="attachment-header">
-        <i class="el-icon-paperclip"></i>
-        <span class="attachment-title">鐩稿叧闄勪欢</span>
-        <span class="attachment-tip"
-          >鏀寔涓婁紶鍣ㄥ畼鑾峰彇鐩稿叧鏂囦欢 (鏈�澶歿{ attachmentLimit }}涓�)</span
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鐩稿叧闄勪欢</span>
+      </div>
+
+      <!-- 闄勪欢鍒楄〃 - 鍒嗙被Tab灞曠ず锛屾敮鎸佷慨鏀瑰垎绫� -->
+      <el-tabs v-model="activeTab" type="border-card">
+        <el-tab-pane
+          v-for="category in categories"
+          :key="category"
+          :label="category + '(' + getCategoryCount(category) + ')'"
+          :name="category"
         >
-      </div>
-
-      <!-- 浣跨敤 UploadAttachment 缁勪欢 -->
-      <UploadAttachment
-        ref="uploadAttachment"
-        :file-list="attachmentFileList"
-        :limit="attachmentLimit"
-        :accept="attachmentAccept"
-        :multiple="true"
-        @change="handleAttachmentChange"
-        @upload-success="handleUploadSuccess"
-        @upload-error="handleUploadError"
-        @remove="handleAttachmentRemove"
-      />
-
-      <!-- 闄勪欢鍒楄〃灞曠ず -->
-      <div class="attachment-list" v-if="attachments && attachments.length > 0">
-        <div class="list-title">宸蹭笂浼犻檮浠� ({{ attachments.length }})</div>
-        <el-table :data="attachments" style="width: 100%" size="small">
-          <el-table-column label="鏂囦欢鍚�" min-width="200">
-            <template slot-scope="scope">
-              <i
-                class="el-icon-document"
-                :style="{ color: getFileIconColor(scope.row.fileName) }"
-              ></i>
-              <span class="file-name">{{ scope.row.fileName }}</span>
-            </template>
-          </el-table-column>
-          <el-table-column label="鏂囦欢绫诲瀷" width="100">
-            <template slot-scope="scope">
-              <el-tag :type="getFileTagType(scope.row.fileName)" size="small">
-                {{ getFileTypeText(scope.row.fileName) }}
-              </el-tag>
-            </template>
-          </el-table-column>
-          <el-table-column label="涓婁紶鏃堕棿" width="160">
-            <template slot-scope="scope">
-              <span>{{ formatDateTime(scope.row.uploadTime) }}</span>
-            </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="200" fixed="right">
-            <template slot-scope="scope">
-              <el-button
-                size="mini"
-                type="primary"
-                @click="handlePreview(scope.row)"
-                :disabled="!isPreviewable(scope.row.fileName)"
-              >
-                棰勮
-              </el-button>
-              <el-button
-                size="mini"
-                type="success"
-                @click="handleDownload(scope.row)"
-              >
-                涓嬭浇
-              </el-button>
-              <el-button
-                size="mini"
-                type="danger"
-                @click="handleRemoveAttachment(scope.$index)"
-              >
-                鍒犻櫎
-              </el-button>
-            </template>
-          </el-table-column>
-        </el-table>
-      </div>
+          <div style="margin-bottom: 10px; text-align: right;">
+            <el-button
+              size="mini"
+              type="primary"
+              icon="el-icon-plus"
+              @click="openUploadDialog(category)"
+            >
+              娣诲姞闄勪欢
+            </el-button>
+          </div>
+          <el-table
+            :data="getCategoryFiles(category)"
+            style="width: 100%"
+            size="small"
+            border
+          >
+              <el-table-column label="鏂囦欢鍚�" min-width="180">
+                <template #default="scope">
+                  <i
+                    class="el-icon-document"
+                    style="margin-right: 8px; color: #409EFF;"
+                  ></i>
+                  <span class="file-name">{{ scope.row.fileName }}</span>
+                </template>
+              </el-table-column>
+              <!-- 鍙紪杈戝垎绫讳笅鎷� -->
+              <el-table-column label="鍒嗙被" width="150">
+                <template #default="scope">
+                  <el-select
+                    v-model="scope.row.fileType"
+                    size="small"
+                    @change="updateAttachmentCategory(scope.row, $event)"
+                    placeholder="閫夋嫨鍒嗙被"
+                  >
+                    <el-option label="鍘熻〃鎷嶇収" value="鍘熻〃鎷嶇収" />
+                    <el-option label="浼︾悊瀹℃煡鏉愭枡" value="浼︾悊瀹℃煡鏉愭枡" />
+                    <el-option label="姝讳骸鍒ゅ畾鏉愭枡" value="姝讳骸鍒ゅ畾鏉愭枡" />
+                    <el-option label="榛樺搥浠紡鐓х墖" value="榛樺搥浠紡鐓х墖" />
+                    <el-option label="鎹愮尞瑙佽瘉瑙嗛" value="鎹愮尞瑙佽瘉瑙嗛" />
+                    <el-option label="鏈垎绫�" value="" />
+                  </el-select>
+                </template>
+              </el-table-column>
+              <el-table-column label="鏂囦欢绫诲瀷" width="100">
+                <template #default="scope">
+                  <el-tag size="small">{{
+                    getFileTypeText(scope.row.fileName)
+                  }}</el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="涓婁紶鏃堕棿" width="160">
+                <template #default="scope">
+                  <span>{{ formatDateTime(scope.row.uploadTime) }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="鏂囦欢澶у皬" width="100">
+                <template #default="scope">
+                  <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="鎿嶄綔" width="180" fixed="right">
+                <template #default="scope">
+                  <el-button
+                    size="mini"
+                    type="primary"
+                    @click="handlePreview(scope.row)"
+                    >棰勮</el-button
+                  >
+                  <el-button
+                    size="mini"
+                    type="danger"
+                    @click="handleRemoveAttachmentByFile(scope.row)"
+                    >鍒犻櫎</el-button
+                  >
+                </template>
+              </el-table-column>
+          </el-table>
+          <div
+            v-if="getCategoryFiles(category).length === 0"
+            style="text-align:center; padding:20px; color:#909399;"
+          >
+            鏆傛棤闄勪欢
+          </div>
+        </el-tab-pane>
+      </el-tabs>
     </el-card>
-
+    <div style="text-align: center; margin: 30px 0;">
+      <el-button type="primary" @click="handleSave" :loading="saveLoading">
+        淇濆瓨
+      </el-button>
+      <el-button
+        type="success"
+        @click="handleProcure"
+        :loading="confirmLoading"
+      >
+        纭鑾峰彇
+      </el-button>
+    </div>
     <!-- 缂栬緫鑾峰彇璁板綍瀵硅瘽妗� -->
     <el-dialog
       title="缂栬緫鍣ㄥ畼鑾峰彇璁板綍"
@@ -601,7 +516,7 @@
               <el-input v-model="currentRecord.organname" readonly />
             </el-form-item>
           </el-col>
-          <el-col :span="12">
+          <!-- <el-col :span="12">
             <el-form-item label="鑾峰彇鐘舵��">
               <el-select v-model="currentRecord.organstate" style="width: 100%">
                 <el-option
@@ -612,7 +527,7 @@
                 />
               </el-select>
             </el-form-item>
-          </el-col>
+          </el-col> -->
         </el-row>
 
         <el-row :gutter="20">
@@ -660,10 +575,7 @@
           />
         </el-form-item>
 
-        <el-form-item
-          label="鏈幏鍙栬鏄�"
-          v-if="currentRecord.organstate === '0'"
-        >
+        <el-form-item label="鏈幏鍙栬鏄�">
           <el-input
             type="textarea"
             :rows="3"
@@ -679,49 +591,73 @@
       </div>
     </el-dialog>
 
-    <!-- 鏂囦欢棰勮寮圭獥 -->
+    <!-- 涓婁紶瀵硅瘽妗� -->
     <el-dialog
-      :title="filePreviewTitle"
-      :visible.sync="filePreviewVisible"
-      width="800px"
-      @close="filePreviewVisible = false"
+      :title="`涓婁紶${currentUploadCategory}闄勪欢`"
+      :visible.sync="uploadDialogVisible"
+      width="480px"
+      :close-on-click-modal="false"
     >
-      <div v-if="currentPreviewFile">
-        <div v-if="currentPreviewFile.fileType === 'image'">
-          <img
-            :src="currentPreviewFile.fileUrl"
-            style="max-width: 100%; max-height: 500px;"
-          />
+      <el-upload
+        ref="uploadRef"
+        class="upload-demo"
+        drag
+        :action="uploadAction"
+        :headers="headers"
+        multiple
+        :file-list="tempFileList"
+        :before-upload="beforeUpload"
+        :on-change="handleFileChange"
+        :on-remove="handleTempRemove"
+        :on-success="handleUploadSuccess"
+        :auto-upload="false"
+      >
+        <i class="el-icon-upload"></i>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <div class="el-upload__tip" slot="tip">
+          鏀寔涓婁紶pdf銆乯pg銆乸ng銆乨oc銆乨ocx鏍煎紡鏂囦欢锛屽崟涓枃浠朵笉瓒呰繃10MB
         </div>
-        <div v-else-if="currentPreviewFile.fileType === 'pdf'">
-          <iframe
-            :src="currentPreviewFile.fileUrl"
-            width="100%"
-            height="500px"
-          ></iframe>
-        </div>
-        <div v-else>
-          <p>涓嶆敮鎸侀瑙堟鏂囦欢绫诲瀷锛岃涓嬭浇鏌ョ湅</p>
-        </div>
-      </div>
+      </el-upload>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="uploadDialogVisible = false">鍙栨秷</el-button>
+        <el-button
+          type="primary"
+          @click="submitUpload"
+          :loading="uploadLoading"
+          :disabled="tempFileList.length === 0"
+        >
+          纭涓婁紶
+        </el-button>
+      </span>
     </el-dialog>
+
+    <!-- 鏂囦欢棰勮寮圭獥 -->
+    <FilePreviewDialog
+      :visible="previewVisible"
+      :file="currentPreviewFile"
+      @close="previewVisible = false"
+      @download="handleDownload"
+    />
   </div>
 </template>
 
 <script>
 import { witnessList, witnessadd, witnessedit } from "@/api/businessApi";
-import UploadAttachment from "@/components/UploadAttachment";
+import FilePreviewDialog from "@/components/FilePreviewDialog";
 import CaseBasicInfo from "@/components/CaseBasicInfo";
+import { getToken } from "@/utils/auth";
 import dayjs from "dayjs";
 
 export default {
   name: "OrganProcurementDetail",
   components: {
-    UploadAttachment,
+    FilePreviewDialog,
     CaseBasicInfo
   },
   dicts: [
     "sys_BloodType",
+    "Geta_hospital",
     "sys_DonationCategory",
     "sys_Organ",
     "Obtain_status"
@@ -782,6 +718,18 @@
         coordinatorSignTime: "",
         attachments: []
       },
+      activeTab: "鍘熻〃鎷嶇収", // 褰撳墠婵�娲荤殑闄勪欢鍒嗙被Tab
+      presetCategories: [
+        "鍘熻〃鎷嶇収",
+        "浼︾悊瀹℃煡鏉愭枡",
+        "姝讳骸鍒ゅ畾鏉愭枡",
+        "榛樺搥浠紡鐓х墖",
+        "鎹愮尞瑙佽瘉瑙嗛"
+      ], // 棰勮鍒嗙被
+      organExpansionMap: {
+        C64: { subItems: ["C64L", "C64R"], subNames: ["宸﹁偩", "鍙宠偩"] },
+        C34: { subItems: ["C34L", "C34R"], subNames: ["宸﹁偤", "鍙宠偤"] }
+      },
       // 琛ㄥ崟楠岃瘉瑙勫垯
       rules: {
         name: [
@@ -814,25 +762,54 @@
       },
       // 闄勪欢鏁版嵁
       attachments: [],
-      attachmentFileList: [],
-      // 闄勪欢鐩稿叧閰嶇疆
-      attachmentLimit: 10,
-      attachmentAccept:
-        ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
+      // 涓婁紶鐩稿叧
+      uploadAction: process.env.VUE_APP_BASE_API + "/common/upload",
+      headers: {
+        Authorization: "Bearer " + getToken()
+      },
+      uploadDialogVisible: false,
+      uploadLoading: false,
+      tempFileList: [],
+      currentUploadCategory: "",
       // 缂栬緫瀵硅瘽妗�
       editDialogVisible: false,
       currentRecord: {},
       currentEditIndex: -1,
       // 鏂囦欢棰勮鐩稿叧
-      filePreviewVisible: false,
-      currentPreviewFile: null,
-      filePreviewTitle: ""
+      previewVisible: false,
+      currentPreviewFile: null
     };
   },
   computed: {
     // 褰撳墠鐢ㄦ埛淇℃伅
     currentUser() {
       return JSON.parse(sessionStorage.getItem("user") || "{}");
+    },
+    displayOrgans() {
+      return (this.procurementData.serviceDonationwitnessorgans || []).filter(
+        item => item.delFlag !== 1
+      );
+    },
+    categories() {
+      // 濮嬬粓杩斿洖鎵�鏈夐璁惧垎绫� + 鏈垎绫伙紝鏃犺鏄惁鏈夋暟鎹�
+      return [
+        "鍘熻〃鎷嶇収",
+        "浼︾悊瀹℃煡鏉愭枡",
+        "姝讳骸鍒ゅ畾鏉愭枡",
+        "榛樺搥浠紡鐓х墖",
+        "鎹愮尞瑙佽瘉瑙嗛",
+        "鏈垎绫�"
+      ];
+    },
+    organReverseMap() {
+      const map = {};
+      for (const key in this.organExpansionMap) {
+        const { subItems } = this.organExpansionMap[key];
+        subItems.forEach(item => {
+          map[item] = key;
+        });
+      }
+      return map;
     },
     // 涓嶅畬鏁寸殑璁板綍鏁伴噺
     incompleteRecords() {
@@ -856,22 +833,6 @@
     // 鑾峰彇鍣ㄥ畼瀛楀吀
     organDict() {
       return this.dict.type.sys_Organ || [];
-    }
-  },
-  watch: {
-    // 鐩戝惉闄勪欢鏁版嵁鍙樺寲
-    attachments: {
-      handler(newAttachments) {
-        this.attachmentFileList = newAttachments.map(item => ({
-          uid: item.id || Math.random(),
-          name: item.fileName,
-          fileSize: item.fileSize,
-          url: item.path || item.fileUrl,
-          uploadTime: item.uploadTime,
-          status: "success"
-        }));
-      },
-      deep: true
     }
   },
   created() {
@@ -905,13 +866,18 @@
 
       this.getHospitalData();
     },
-    // 鐢熸垚鎹愮尞鑰呯紪鍙�
-    // generateDonorNo() {
-    //   const timestamp = Date.now().toString();
-    //   this.form.donorno = "D" + timestamp.slice(-8);
-    //   this.form.caseNo = "CASE" + timestamp.slice(-6);
-    //   this.form.inpatientno = "IP" + timestamp.slice(-6);
-    // },
+    getOrganNameByNo(organno) {
+      // 妫�鏌ユ槸鍚﹀湪鏄犲皠鐨勫瓙椤逛腑
+      for (const key in this.organExpansionMap) {
+        const { subItems, subNames } = this.organExpansionMap[key];
+        const idx = subItems.indexOf(organno);
+        if (idx !== -1) {
+          return subNames[idx];
+        }
+      }
+      // 鍚﹀垯浠庡瓧鍏镐腑鑾峰彇
+      return this.getOrganLabel(organno);
+    },
     // 鑾峰彇璇︽儏
     async getDetail(infoid) {
       this.loading = true;
@@ -932,10 +898,14 @@
 
           // 鍒濆鍖栭檮浠�
           if (this.form.deathjudgeannex) {
-            this.form.attachments = JSON.parse(this.form.deathjudgeannex);
-            this.attachments = Array.isArray(this.form.attachments)
-              ? [...this.form.attachments]
-              : [];
+            const parsed = JSON.parse(this.form.deathjudgeannex);
+            this.attachments = parsed.map(item => ({
+              ...item,
+              fileType: item.fileType || "" // 榛樿绌哄瓧绗︿覆琛ㄧず鏈垎绫�
+            }));
+            this.form.attachments = this.attachments;
+          } else {
+            this.attachments = [];
           }
 
           // 澶勭悊鎹愮尞鍣ㄥ畼瀛楁
@@ -957,6 +927,7 @@
           }
 
           this.$message.success("鏁版嵁鍔犺浇鎴愬姛");
+          this.syncOrgansFromSelection();
         } else {
           this.$message.warning("鏈壘鍒板搴旂殑鍣ㄥ畼鑾峰彇鏁版嵁");
         }
@@ -966,6 +937,52 @@
       } finally {
         this.loading = false;
       }
+    },
+    syncOrgansFromSelection() {
+      const records = this.procurementData.serviceDonationwitnessorgans || [];
+      const targetNos = [];
+      this.selectedOrgans.forEach(val => {
+        if (this.organExpansionMap[val]) {
+          targetNos.push(...this.organExpansionMap[val].subItems);
+        } else {
+          targetNos.push(val);
+        }
+      });
+
+      // 鏂板鎴栨仮澶�
+      targetNos.forEach(no => {
+        const existing = records.find(r => r.organno === no);
+        if (existing) {
+          if (existing.delFlag === 1) {
+            existing.delFlag = 0; // 鎭㈠鏄剧ず
+          }
+        } else {
+          records.push({
+            id: null,
+            organname: this.getOrganNameByNo(no),
+            organno: no,
+            organStartTime: "",
+            organgettime: "",
+            gainhospitalno: "",
+            gainhospitalname: "",
+            organgetdoct: "",
+            assistant: "",
+            procurementNurse: "",
+            operatingRoomNurse: "",
+            anesthesiologist: "",
+            organstate: "1",
+            notgetreason: "",
+            delFlag: 0
+          });
+        }
+      });
+
+      // 锛堝彲閫夛級濡傛灉鍔犺浇鏃跺悗绔繑鍥炰簡 delFlag=1 鐨勮褰曪紝浣嗗疄闄呭簲璇ユ樉绀猴紝寮哄埗閲嶇疆
+      records.forEach(r => {
+        if (r.delFlag === 1) r.delFlag = 0;
+      });
+
+      this.form.organdonation = this.selectedOrgans.join(",");
     },
     // 鑾峰彇鍖婚櫌鏁版嵁
     async getHospitalData() {
@@ -984,87 +1001,139 @@
         this.$message.error("鑾峰彇鍖婚櫌鏁版嵁澶辫触");
       }
     },
+    // 绉绘鍖婚櫌妯$硦鎼滅储
+    queryHospitalSearch(queryString, cb) {
+      const hospitals = this.dict.type.Geta_hospital || [];
+      const results = queryString
+        ? hospitals.filter(item =>
+            item.label.toLowerCase().includes(queryString.toLowerCase())
+          )
+        : hospitals;
+
+      // el-autocomplete 闇�瑕� value 瀛楁
+      cb(results.map(item => ({ value: item.label })));
+    },
     // 鍣ㄥ畼閫夋嫨鐘舵�佸彉鍖�
-    handleOrganSelectionChange(selectedValues) {
-      if (!this.procurementData.serviceDonationwitnessorgans) {
-        this.procurementData.serviceDonationwitnessorgans = [];
-      }
-
-      const currentOrganValues = this.procurementData.serviceDonationwitnessorgans.map(
-        item => item.organno
-      );
-
-      // 澶勭悊浜掓枼閫昏緫
+    async handleOrganSelectionChange(selectedValues) {
+      // 1. 澶勭悊浜掓枼閫昏緫锛堜慨鏀� this.selectedOrgans锛�
       this.handleExclusiveSelections(selectedValues);
 
-      // 鏇存柊鎹愮尞鍣ㄥ畼瀛楁
-      this.form.organdonation = selectedValues.join(",");
+      const finalSelected = this.selectedOrgans;
+      const records = this.procurementData.serviceDonationwitnessorgans || [];
 
-      // 鏂板閫夋嫨鐨勫櫒瀹�
-      selectedValues.forEach(organValue => {
-        if (!currentOrganValues.includes(organValue)) {
-          this.createOrganRecord(organValue);
+      // 2. 鏋勫缓鐩爣鍣ㄥ畼缂栧彿鍒楄〃锛堝睍寮�缁勫悎鍣ㄥ畼锛�
+      const targetOrganNos = [];
+      finalSelected.forEach(val => {
+        if (this.organExpansionMap[val]) {
+          targetOrganNos.push(...this.organExpansionMap[val].subItems);
+        } else {
+          targetOrganNos.push(val);
         }
       });
 
-      // 绉婚櫎鍙栨秷閫夋嫨鐨勫櫒瀹�
-      this.procurementData.serviceDonationwitnessorgans = this.procurementData.serviceDonationwitnessorgans.filter(
-        record => {
-          if (selectedValues.includes(record.organno)) {
-            return true;
-          } else {
-            if (record.id) {
-              this.$confirm(
-                "鍒犻櫎鍣ㄥ畼鑾峰彇鏁版嵁鍚庡皢鏃犳硶鎭㈠锛屾偍纭鍒犻櫎璇ユ潯璁板綍鍚楋紵",
-                "鎻愮ず",
-                {
-                  confirmButtonText: "纭畾",
-                  cancelButtonText: "鍙栨秷",
-                  type: "warning"
-                }
-              )
-                .then(() => {
-                  this.procurementData.serviceDonationwitnessorgans = this.procurementData.serviceDonationwitnessorgans.filter(
-                    r => r.organno !== record.organno
-                  );
-                  this.$message.success("鍒犻櫎鎴愬姛");
-                })
-                .catch(() => {
-                  this.selectedOrgans.push(record.organno);
-                });
-              return true;
-            } else {
-              return false;
-            }
+      // 3. 鏂板鎴栨仮澶嶇洰鏍囧櫒瀹樿褰曪紙鏃犲脊绐楋級
+      targetOrganNos.forEach(no => {
+        const existing = records.find(r => r.organno === no);
+        if (existing) {
+          if (existing.delFlag === 1) {
+            existing.delFlag = 0; // 鎭㈠鏄剧ず
           }
+        } else {
+          records.push({
+            id: null,
+            organname: this.getOrganNameByNo(no),
+            organno: no,
+            organStartTime: "",
+            organgettime: "",
+            gainhospitalno: "",
+            gainhospitalname: "",
+            organgetdoct: "",
+            assistant: "",
+            procurementNurse: "",
+            operatingRoomNurse: "",
+            anesthesiologist: "",
+            organstate: "1",
+            notgetreason: "",
+            delFlag: 0
+          });
         }
-      );
+      });
+
+      // 4. 鎵惧嚭闇�瑕佸彇娑堢殑璁板綍锛堜笉鍦ㄧ洰鏍囬泦鍚堜腑锛�
+      const toRemove = records.filter(r => !targetOrganNos.includes(r.organno));
+      const toRemoveSaved = toRemove.filter(r => r.id); // 宸蹭繚瀛橈紝闇�纭
+      const toRemoveUnsaved = toRemove.filter(r => !r.id); // 鏈繚瀛橈紝鐩存帴绉婚櫎
+
+      // 4.1 鐩存帴绉婚櫎鏈繚瀛樼殑璁板綍
+      toRemoveUnsaved.forEach(r => {
+        const idx = records.indexOf(r);
+        if (idx !== -1) records.splice(idx, 1);
+      });
+
+      // 4.2 澶勭悊宸蹭繚瀛樼殑璁板綍锛氬脊绐楃‘璁�
+      if (toRemoveSaved.length > 0) {
+        const organNames = toRemoveSaved.map(r => r.organname).join("銆�");
+        try {
+          await this.$confirm(
+            `鎮ㄧ‘瀹氳鍙栨秷浠ヤ笅宸蹭繚瀛樼殑鍣ㄥ畼鑾峰彇璁板綍鍚楋紵\n${organNames}\n鍙栨秷鍚庯紝杩欎簺璁板綍灏嗕粠鍒楄〃涓Щ闄わ紙鏁版嵁浠嶄繚鐣欙紝鍙仮澶嶏級銆俙,
+            "鎻愮ず",
+            {
+              confirmButtonText: "纭畾绉婚櫎",
+              cancelButtonText: "鍙栨秷",
+              type: "warning"
+            }
+          );
+          // 鐢ㄦ埛纭锛氭爣璁� delFlag=1
+          toRemoveSaved.forEach(r => {
+            r.delFlag = 1;
+          });
+        } catch (error) {
+          // 鐢ㄦ埛鍙栨秷锛氭仮澶嶉�変腑鐘舵��
+          const parentToRestore = new Set();
+          toRemoveSaved.forEach(r => {
+            const parent = this.organReverseMap[r.organno];
+            if (parent) {
+              parentToRestore.add(parent);
+            } else {
+              parentToRestore.add(r.organno);
+            }
+          });
+          parentToRestore.forEach(val => {
+            if (!this.selectedOrgans.includes(val)) {
+              this.selectedOrgans.push(val);
+            }
+          });
+          this.$message.info("宸插彇娑堝垹闄ゆ搷浣�");
+          // 鏇存柊琛ㄥ崟瀛楁锛堜繚鎸佷竴鑷存�э級
+          this.form.organdonation = this.selectedOrgans.join(",");
+          return; // 閫�鍑烘柟娉曪紝閬垮厤缁х画鎵ц
+        }
+      }
+
+      // 5. 鏇存柊琛ㄥ崟瀛楁
+      this.form.organdonation = this.selectedOrgans.join(",");
     },
 
     // 澶勭悊浜掓枼閫夋嫨
     handleExclusiveSelections(selectedValues) {
-      // 濡傛灉閫夋嫨浜�"鍙岃偩"(鍋囪瀛楀吀鍊间负C64)锛岃嚜鍔ㄥ彇娑堝崟鐙殑"宸﹁偩"(C64L)鍜�"鍙宠偩"(C64R)閫夋嫨
+      // 鍙岃偩涓庡乏鍙宠偩浜掓枼
       if (selectedValues.includes("C64")) {
         this.selectedOrgans = selectedValues.filter(
           item => item !== "C64L" && item !== "C64R"
         );
-      }
-      // 濡傛灉閫夋嫨浜�"宸﹁偩"鎴�"鍙宠偩"锛屽彇娑�"鍙岃偩"閫夋嫨
-      else if (
+      } else if (
         selectedValues.includes("C64L") ||
         selectedValues.includes("C64R")
       ) {
         this.selectedOrgans = selectedValues.filter(item => item !== "C64");
       }
 
-      // 濡傛灉閫夋嫨浜�"鍏ㄨ偤"(鍋囪瀛楀吀鍊间负C34)锛岃嚜鍔ㄥ彇娑堝崟鐙殑"宸﹁偤"(C34L)鍜�"鍙宠偤"(C34R)閫夋嫨
+      // 鍏ㄨ偤涓庡乏鍙宠偤浜掓枼
       if (selectedValues.includes("C34")) {
         this.selectedOrgans = selectedValues.filter(
           item => item !== "C34L" && item !== "C34R"
         );
-      }
-      // 濡傛灉閫夋嫨浜�"宸﹁偤"鎴�"鍙宠偤"锛屽彇娑�"鍏ㄨ偤"閫夋嫨
-      else if (
+      } else if (
         selectedValues.includes("C34L") ||
         selectedValues.includes("C34R")
       ) {
@@ -1144,13 +1213,19 @@
         if (valid) {
           this.saveLoading = true;
           try {
+            console.log(this.procurementData.serviceDonationwitnessorgans);
+
             const saveData = {
               ...this.form,
               deathjudgeannex: JSON.stringify(this.attachments),
               organdonation: this.selectedOrgans.join(","),
               serviceDonationwitnessorganList:
+                this.procurementData.serviceDonationwitnessorgans || [],
+              serviceDonationwitnessorgans:
                 this.procurementData.serviceDonationwitnessorgans || []
             };
+            console.log(saveData.serviceDonationwitnessorganList);
+            console.log(saveData.serviceDonationwitnessorgans);
 
             const apiMethod = this.form.id ? witnessedit : witnessadd;
             const response = await apiMethod(saveData);
@@ -1266,72 +1341,157 @@
       this.handleConfirmProcurement();
     },
 
-    // 闄勪欢鐩稿叧鏂规硶
-    /** 闄勪欢鍙樺寲澶勭悊 */
-    handleAttachmentChange(fileList) {
-      this.attachmentFileList = fileList;
+    // ===== 闄勪欢鐩稿叧鏂规硶 =====
+    // 鎵撳紑涓婁紶瀵硅瘽妗�
+    openUploadDialog(category) {
+      this.currentUploadCategory = category;
+      this.tempFileList = [];
+      this.uploadDialogVisible = true;
+      this.$nextTick(() => {
+        if (this.$refs.uploadRef) {
+          this.$refs.uploadRef.clearFiles();
+        }
+      });
     },
 
-    /** 闄勪欢绉婚櫎澶勭悊 */
-    handleAttachmentRemove(file) {
-      if (file.url) {
-        const index = this.attachments.findIndex(
-          item => item.path === file.url || item.fileUrl === file.url
-        );
-        if (index > -1) {
-          this.attachments.splice(index, 1);
-          this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+    // 涓婁紶鍓嶆牎楠�
+    beforeUpload(file) {
+      const allowedTypes = [
+        "application/pdf",
+        "image/jpeg",
+        "image/png",
+        "application/msword",
+        "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+      ];
+      const maxSize = 10 * 1024 * 1024;
+      const isTypeOk =
+        allowedTypes.includes(file.type) ||
+        file.name.endsWith(".pdf") ||
+        file.name.endsWith(".jpg") ||
+        file.name.endsWith(".jpeg") ||
+        file.name.endsWith(".png") ||
+        file.name.endsWith(".doc") ||
+        file.name.endsWith(".docx");
+      if (!isTypeOk) {
+        this.$message.error("鏂囦欢鏍煎紡涓嶆敮鎸侊紝璇蜂笂浼爌df銆乯pg銆乸ng銆乨oc鎴杁ocx鏍煎紡鏂囦欢");
+        return false;
+      }
+      if (file.size > maxSize) {
+        this.$message.error("鏂囦欢澶у皬涓嶈兘瓒呰繃10MB");
+        return false;
+      }
+      return true;
+    },
+
+    // 鏂囦欢閫夋嫨鍙樺寲
+    handleFileChange(file, fileList) {
+      this.tempFileList = fileList;
+    },
+
+    // 涓存椂绉婚櫎
+    handleTempRemove(file, fileList) {
+      this.tempFileList = fileList;
+    },
+
+    // 涓婁紶鎴愬姛澶勭悊
+    handleUploadSuccess(response, file, fileList) {
+      if (response.code !== 200) {
+        this.$message.error(response.msg || "涓婁紶澶辫触");
+        return;
+      }
+      // 鏈垎绫诲搴旂┖瀛楃涓诧紝涓庡睍绀�/淇濆瓨閫昏緫涓�鑷�
+      const category = this.currentUploadCategory === "鏈垎绫�" ? "" : this.currentUploadCategory;
+      const attachmentObj = {
+        fileName: file.name,
+        path: response.fileUrl || response.url || response.data || file.url,
+        fileUrl: response.fileUrl || response.url || response.data || file.url,
+        fileType: category,
+        fileSize: file.size,
+        uploadTime: dayjs().format("YYYY-MM-DD HH:mm:ss")
+      };
+      if (!Array.isArray(this.attachments)) {
+        this.attachments = [];
+      }
+      this.attachments.push(attachmentObj);
+      this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+      this.uploadLoading = false;
+      this.uploadDialogVisible = false;
+      this.tempFileList = [];
+    },
+
+    // 鎻愪氦涓婁紶
+    submitUpload() {
+      if (this.tempFileList.length === 0) {
+        this.$message.warning("璇峰厛閫夋嫨瑕佷笂浼犵殑鏂囦欢");
+        return;
+      }
+      this.uploadLoading = true;
+      this.$refs.uploadRef.submit();
+    },
+
+    // 鑾峰彇鏌愬垎绫荤殑鏂囦欢鏁伴噺
+    getCategoryCount(category) {
+      return this.attachments.filter(item => {
+        const type = item.fileType || "";
+        if (category === "鏈垎绫�") {
+          return !this.presetCategories.includes(type);
+        }
+        return type === category;
+      }).length;
+    },
+
+    // 鑾峰彇鏌愬垎绫荤殑鏂囦欢鍒楄〃
+    getCategoryFiles(category) {
+      return this.attachments.filter(item => {
+        const type = item.fileType || "";
+        if (category === "鏈垎绫�") {
+          return !this.presetCategories.includes(type);
+        }
+        return type === category;
+      });
+    },
+
+    // 鏇存柊闄勪欢鍒嗙被锛堜笅鎷変慨鏀规椂瑙﹀彂锛�
+    updateAttachmentCategory(row, newVal) {
+      const target = this.attachments.find(item => item === row);
+      if (target) {
+        target.fileType = newVal;
+        const currentTabHasFiles = this.getCategoryFiles(this.activeTab).length > 0;
+        if (!currentTabHasFiles) {
+          const firstCategory = this.categories[0];
+          if (firstCategory) this.activeTab = firstCategory;
         }
       }
     },
 
-    /** 涓婁紶鎴愬姛澶勭悊 */
-    handleUploadSuccess({ file, fileList, response }) {
-      if (response.code === 200) {
-        const attachmentObj = {
-          fileName: file.name,
-          path: response.fileUrl || file.url,
-          fileUrl: response.fileUrl || file.url,
-          fileType: this.getFileExtension(file.name),
-          fileSize: file.size,
-          uploadTime: dayjs().format("YYYY-MM-DD HH:mm:ss")
-        };
-
-        if (!Array.isArray(this.attachments)) {
-          this.attachments = [];
-        }
-
-        this.attachments.push(attachmentObj);
-        this.attachmentFileList = fileList;
-        this.$message.success("鏂囦欢涓婁紶鎴愬姛");
-      }
+    // 鎸夋枃浠跺璞″垹闄わ紙鐢ㄤ簬琛ㄦ牸涓殑鍒犻櫎鎸夐挳锛�
+    handleRemoveAttachmentByFile(file) {
+      this.$confirm("纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          const index = this.attachments.findIndex(item => item === file);
+          if (index > -1) {
+            this.attachments.splice(index, 1);
+            this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+          }
+        })
+        .catch(() => {});
     },
 
-    /** 涓婁紶閿欒澶勭悊 */
-    handleUploadError({ file, fileList, error }) {
-      console.error("闄勪欢涓婁紶澶辫触:", error);
-      this.$message.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
-    },
-
-    /** 鎵嬪姩鍒犻櫎闄勪欢 */
-    handleRemoveAttachment(index) {
-      this.attachments.splice(index, 1);
-      this.attachmentFileList.splice(index, 1);
-      this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
-    },
-
-    /** 鏂囦欢棰勮 */
+    // 鏂囦欢棰勮
     handlePreview(file) {
       this.currentPreviewFile = {
         fileName: file.fileName,
         fileUrl: file.path || file.fileUrl,
         fileType: this.getFileType(file.fileName)
       };
-      this.filePreviewTitle = file.fileName;
-      this.filePreviewVisible = true;
+      this.previewVisible = true;
     },
 
-    /** 鏂囦欢涓嬭浇 */
+    // 鏂囦欢涓嬭浇
     handleDownload(file) {
       const fileUrl = file.path || file.fileUrl;
       const fileName = file.fileName;
@@ -1590,4 +1750,105 @@
     margin-bottom: 10px;
   }
 }
+
+/* ===== 绾歌川琛ㄦ牸缃戞牸鏍峰紡 ===== */
+.paper-card >>> .el-card__body {
+  padding: 16px;
+}
+
+.paper-form {
+  border-left: 1px solid #d0d3db;
+  background: #fff;
+  /* 瓒呭灞忛檺鍒惰〃鍗曟渶澶у搴︼紝鍙充晶鐣欑櫧锛岄伩鍏嶅瓧娈靛垎甯冭繃寮� */
+  max-width: 1400px;
+}
+
+.paper-form >>> .form-row {
+  display: flex;
+  width: 100%;
+  border-top: 1px solid #d0d3db;
+  /* 涓婄Щ1px涓庝笂涓�琛岀殑border-bottom閲嶅彔锛屼袱琛屼箣闂村彧鏄剧ず涓�鏉�1px缁嗙嚎 */
+  margin-top: -1px;
+}
+.paper-form >>> .form-row:first-child {
+  margin-top: 0;
+}
+
+/* 琛屽熬绌虹櫧濉厖锛氫笉婊℃暣琛岀殑鍙充晶鑷姩琛ヤ竴涓┖鐧芥牸瀛愶紝缃戞牸淇濇寔闂悎锛堝彸渚ч�傚綋鐣欑櫧锛� */
+.paper-form >>> .form-row::after {
+  content: "";
+  flex: 1 1 0;
+  min-height: 42px;
+  background: linear-gradient(to left, #d0d3db 1px, transparent 1px),
+    linear-gradient(to top, #d0d3db 1px, transparent 1px);
+  background-color: #fff;
+}
+
+.paper-form >>> .el-form-item {
+  flex: 0 0 33.3333%;
+  display: flex;
+  margin: 0;
+  background: #fff;
+  border-right: 1px solid #d0d3db;
+  border-bottom: 1px solid #d0d3db;
+}
+.paper-form >>> .el-form-item::after,
+.paper-form >>> .el-form-item::before {
+  display: none;
+}
+
+.paper-form >>> .col-1-3 { flex: 0 0 33.3333%; }
+.paper-form >>> .col-half { flex: 0 0 50%; }
+.paper-form >>> .col-2-3 { flex: 0 0 66.6666%; }
+.paper-form >>> .col-full { flex: 0 0 100%; }
+
+.paper-form >>> .el-form-item__label {
+  flex: 0 0 150px;
+  width: 150px !important;
+  float: none;
+  padding: 0 8px !important;
+  background: #ecf5ff;
+  border-right: 1px solid #d0d3db;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+  font-size: 13px;
+  font-weight: 600;
+  color: #2c3038;
+  line-height: 1.3;
+  white-space: nowrap;
+}
+.paper-form >>> .el-form-item.is-required:not(.is-no-asterisk) > .el-form-item__label:before {
+  color: #f56c6c;
+  margin-right: 2px;
+}
+
+.paper-form >>> .el-form-item__content {
+  flex: 1;
+  margin-left: 0 !important;
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  padding: 6px 10px;
+  background: #fff;
+  min-height: 42px;
+  line-height: 1.4;
+}
+
+/* 鎺т欢瀹藉害閫備腑锛屼笉閾烘弧鏁存牸锛堝唴瀹圭煭鏃惰緭鍏ユ涓嶅啀鎷夊緱寰堥暱锛� */
+.paper-form >>> .el-form-item__content .el-input,
+.paper-form >>> .el-form-item__content .el-select,
+.paper-form >>> .el-form-item__content .el-cascader {
+  width: 220px;
+  max-width: 100%;
+}
+.paper-form >>> .el-form-item__content .el-date-editor {
+  width: 240px;
+  max-width: 100%;
+}
+.paper-form >>> .el-form-item__content .el-range-editor {
+  width: 360px;
+  max-width: 100%;
+}
 </style>

--
Gitblit v1.9.3