From 4c9fdc87987140e8b2c3f0dfc2f6608cdb6be774 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期三, 21 十月 2026 17:39:24 +0800
Subject: [PATCH] 青岛维护

---
 src/views/business/OrganUtilization/OrganUtilizationInfo.vue |  948 ++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 613 insertions(+), 335 deletions(-)

diff --git a/src/views/business/OrganUtilization/OrganUtilizationInfo.vue b/src/views/business/OrganUtilization/OrganUtilizationInfo.vue
index 839a358..ead00f7 100644
--- a/src/views/business/OrganUtilization/OrganUtilizationInfo.vue
+++ b/src/views/business/OrganUtilization/OrganUtilizationInfo.vue
@@ -1,49 +1,45 @@
 <template>
   <div class="organ-utilization-detail">
-    <case-basic-info :case-id="caseId" :show-attachment="true" />
-    <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+    <case-basic-info :case-id="caseId" :show-attachment="true":column="3" />
+    <el-form :model="form" ref="form" :rules="rules" label-width="120px" class="paper-form">
       <!-- 鍩烘湰淇℃伅 -->
-      <el-card class="detail-card">
+      <el-card class="detail-card paper-card">
         <div slot="header" class="clearfix">
           <span class="detail-title">鍣ㄥ畼鍒╃敤鍩烘湰淇℃伅</span>
         </div>
 
-        <el-row :gutter="20">
-          <el-col :span="6">
-            <el-form-item label="璐熻矗浜�" prop="responsibleusername">
-              <el-input
-                v-model="form.responsibleusername"
-                placeholder="璇疯緭鍏ヨ礋璐d汉濮撳悕"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="6">
-            <el-form-item label="鍗忚皟鍛樹竴" prop="coordinatedusernameo">
-              <el-input
-                v-model="form.coordinatedusernameo"
-                placeholder="璇疯緭鍏ュ崗璋冨憳涓�濮撳悕"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="6">
-            <el-form-item label="鍗忚皟鍛樹簩" prop="coordinatedusernamet">
-              <el-input
-                v-model="form.coordinatedusernamet"
-                placeholder="璇疯緭鍏ュ崗璋冨憳浜屽鍚�"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="6">
-            <el-form-item label="瀹屾垚鏃堕棿" prop="completetime">
-              <el-date-picker
-                v-model="form.completetime"
-                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="responsibleusername" class="col-1-3">
+            <el-input
+              v-model="form.responsibleusername"
+              placeholder="璇疯緭鍏ヨ礋璐d汉濮撳悕"
+              :disabled="isReadOnly"
+            />
+          </el-form-item>
+          <el-form-item label="鍗忚皟鍛樹竴" prop="coordinatedusernameo" class="col-1-3">
+            <el-input
+              v-model="form.coordinatedusernameo"
+              placeholder="璇疯緭鍏ュ崗璋冨憳涓�濮撳悕"
+              :disabled="isReadOnly"
+            />
+          </el-form-item>
+          <el-form-item label="鍗忚皟鍛樹簩" prop="coordinatedusernamet" class="col-1-3">
+            <el-input
+              v-model="form.coordinatedusernamet"
+              placeholder="璇疯緭鍏ュ崗璋冨憳浜屽鍚�"
+              :disabled="isReadOnly"
+            />
+          </el-form-item>
+          <el-form-item label="瀹屾垚鏃堕棿" prop="completetime" class="col-1-3">
+            <el-date-picker
+              v-model="form.completetime"
+              type="datetime"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              style="width: 100%"
+              :disabled="isReadOnly"
+            />
+          </el-form-item>
+        </div>
 
         <!-- <el-row :gutter="20">
           <el-col :span="12">
@@ -63,48 +59,44 @@
           </el-col>
         </el-row> -->
       </el-card>
-      <el-card class="detail-card">
+      <el-card class="detail-card paper-card">
         <div slot="header" class="clearfix">
           <span class="detail-title">閬椾綋鎹愮尞淇℃伅</span>
         </div>
-        <el-row :gutter="20">
-          <el-col :span="6">
-            <el-form-item align="left" label="閬椾綋鎺ユ敹" prop="isbodydonation">
-              <el-radio-group v-model="form.isbodydonation">
-                <el-radio
-                  v-for="dict in dict.type.sys_0_1 || []"
-                  :key="dict.value"
-                  :label="dict.value"
-                  >{{ dict.label }}</el-radio
-                >
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-
-          <el-col :span="8">
-            <el-form-item align="left" label="鎺ユ敹瀹跺睘" prop="relationname">
-              <el-input
-                v-model="form.relationname"
-                placeholder="璇疯緭鍏ユ帴鏀跺灞�"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="6">
-            <el-form-item label="涓庢崘鐚�呭叧绯�" prop="signfamilyrelations">
-              <el-select
-                v-model="form.signfamilyrelations"
-                placeholder="璇烽�夋嫨涓庢崘鐚�呭叧绯�"
+        <div class="form-row">
+          <el-form-item align="left" label="閬椾綋鎺ユ敹" prop="isbodydonation" class="col-1-3">
+            <el-radio-group v-model="form.isbodydonation" :disabled="isReadOnly">
+              <el-radio
+                v-for="dict in dict.type.sys_0_1 || []"
+                :key="dict.value"
+                :label="dict.value"
+                >{{ dict.label }}</el-radio
               >
-                <el-option
-                  v-for="dict in dict.type.sys_FamilyRelation || []"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
+            </el-radio-group>
+          </el-form-item>
+
+          <el-form-item align="left" label="鎺ユ敹瀹跺睘" prop="relationname" class="col-1-3">
+            <el-input
+              v-model="form.relationname"
+              placeholder="璇疯緭鍏ユ帴鏀跺灞�"
+              :disabled="isReadOnly"
+            />
+          </el-form-item>
+          <el-form-item label="涓庢崘鐚�呭叧绯�" prop="signfamilyrelations" class="col-1-3">
+            <el-select
+              v-model="form.signfamilyrelations"
+              placeholder="璇烽�夋嫨涓庢崘鐚�呭叧绯�"
+              :disabled="isReadOnly"
+            >
+              <el-option
+                v-for="dict in dict.type.sys_FamilyRelation || []"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </div>
       </el-card>
     </el-form>
     <!-- 鍣ㄥ畼鍒╃敤璁板綍閮ㄥ垎 - 鏁村悎鍙楄�呰鎯� -->
@@ -130,6 +122,7 @@
             <el-form-item label-width="100px" label="绉绘鍣ㄥ畼">
               <el-checkbox-group
                 v-model="selectedOrgans"
+                :disabled="isReadOnly"
                 @change="handleOrganSelectionChange"
               >
                 <el-checkbox
@@ -164,14 +157,14 @@
                       <div class="recipient-header">
                         <span class="recipient-title">鍙楄�呰缁嗕俊鎭�</span>
                         <el-tag
-                          v-if="scope.row.transplantstate === '1'"
+                          v-if="scope.row.transplantstate == '1'"
                           type="success"
                           size="small"
                         >
                           宸茬Щ妞�
                         </el-tag>
                         <el-tag
-                          v-else-if="scope.row.transplantstate === '0'"
+                          v-else-if="scope.row.transplantstate == '0'"
                           type="warning"
                           size="small"
                         >
@@ -195,7 +188,9 @@
                               <el-form-item label="鍙楄�呭鍚�">
                                 <el-input
                                   v-model="scope.row.name"
+                                  :class="{ 'field-error': isFieldError(scope.row, 'name') }"
                                   placeholder="璇疯緭鍏ュ彈鑰呭鍚�"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -207,6 +202,7 @@
                                   value-format="yyyy-MM-dd"
                                   placeholder="閫夋嫨鍑虹敓鏃ユ湡"
                                   style="width: 100%"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -216,6 +212,7 @@
                                   v-model="scope.row.sex"
                                   placeholder="璇烽�夋嫨鎬у埆"
                                   style="width: 100%"
+                                  :disabled="isReadOnly"
                                 >
                                   <el-option label="鐢�" :value="0" />
                                   <el-option label="濂�" :value="1" />
@@ -230,6 +227,7 @@
                                 <el-input
                                   v-model="scope.row.age"
                                   placeholder="骞撮緞"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -239,6 +237,7 @@
                                   v-model="scope.row.idcardtype"
                                   placeholder="璇烽�夋嫨璇佷欢绫诲瀷"
                                   style="width: 100%"
+                                  :disabled="isReadOnly"
                                 >
                                   <el-option label="韬唤璇�" :value="1" />
                                   <el-option label="鎶ょ収" :value="2" />
@@ -252,6 +251,7 @@
                                 <el-input
                                   v-model="scope.row.idcardno"
                                   placeholder="璇佷欢鍙风爜"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -267,6 +267,7 @@
                                 <el-input
                                   v-model="scope.row.hospitalname"
                                   placeholder="璇疯緭鍏ョЩ妞嶄腑蹇冨悕绉�"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -275,6 +276,7 @@
                                 <el-input
                                   v-model="scope.row.phone"
                                   placeholder="鑱旂郴鐢佃瘽"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -288,6 +290,7 @@
                                   :rows="2"
                                   v-model="scope.row.residenceaddress"
                                   placeholder="璇疯緭鍏ヨ缁嗗湴鍧�"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -297,7 +300,7 @@
                         <!-- 绉绘淇℃伅閮ㄥ垎 -->
                         <div
                           class="form-section"
-                          v-if="scope.row.transplantstate === '1'"
+                          v-if="scope.row.transplantstate == '1'"
                         >
                           <h4 class="section-title">绉绘淇℃伅</h4>
                           <el-row :gutter="20">
@@ -309,6 +312,7 @@
                                   value-format="yyyy-MM-dd HH:mm:ss"
                                   placeholder="閫夋嫨绉绘鏃ユ湡"
                                   style="width: 100%"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -317,6 +321,7 @@
                                 <el-input
                                   v-model="scope.row.transplantdoct"
                                   placeholder="璇疯緭鍏ョЩ妞嶅尰鐢�"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -326,7 +331,7 @@
                         <!-- 鏈Щ妞嶅師鍥� -->
                         <div
                           class="form-section"
-                          v-if="scope.row.transplantstate === '0'"
+                          v-if="scope.row.transplantstate == '0'"
                         >
                           <h4 class="section-title">鏈Щ妞嶄俊鎭�</h4>
                           <el-row :gutter="20">
@@ -335,8 +340,10 @@
                                 <el-input
                                   type="textarea"
                                   :rows="3"
+                                  :class="{ 'field-error': isFieldError(scope.row, 'abandonreason') }"
                                   v-model="scope.row.abandonreason"
                                   placeholder="璇疯緭鍏ユ湭绉绘鍘熷洜"
+                                  :disabled="isReadOnly"
                                 />
                               </el-form-item>
                             </el-col>
@@ -379,10 +386,12 @@
                   <template slot-scope="scope">
                     <el-autocomplete
                       v-model="scope.row.hospitalname"
+                      :class="{ 'field-error': isFieldError(scope.row, 'hospitalname') }"
                       :fetch-suggestions="queryHospitalSearch"
                       placeholder="璇烽�夋嫨鎴栬緭鍏ョЩ妞嶅尰闄�"
                       style="width: 100%"
                       clearable
+                      :disabled="isReadOnly"
                     ></el-autocomplete>
                   </template>
                 </el-table-column>
@@ -396,6 +405,7 @@
                       v-model="scope.row.transplantstate"
                       placeholder="璇烽�夋嫨绉绘鐘舵��"
                       style="width: 100%"
+                      :disabled="isReadOnly"
                       @change="handleTransplantStatusChange(scope.row, $event)"
                     >
                       <el-option
@@ -420,9 +430,11 @@
                       size="small"
                       style="width: 100%"
                       v-model="scope.row.transplanttime"
+                      :class="{ 'field-error': isFieldError(scope.row, 'transplanttime') }"
                       type="datetime"
                       value-format="yyyy-MM-dd HH:mm:ss"
                       placeholder="閫夋嫨绉绘鏃堕棿"
+                      :disabled="isReadOnly"
                     />
                   </template>
                 </el-table-column>
@@ -436,13 +448,18 @@
                     <el-input
                       v-model="scope.row.transplantdoct"
                       placeholder="鍖诲笀濮撳悕"
+                      :disabled="isReadOnly"
                     />
                   </template>
                 </el-table-column>
 
                 <el-table-column label="鍙楄�呭鍚�" align="center" prop="name">
                   <template slot-scope="scope">
-                    <el-input v-model="scope.row.name" placeholder="鍙楄�呭鍚�" />
+                    <el-input
+                      v-model="scope.row.name"
+                      placeholder="鍙楄�呭鍚�"
+                      :disabled="isReadOnly"
+                    />
                   </template>
                 </el-table-column>
               </el-table>
@@ -473,116 +490,117 @@
         <span class="detail-title">鐩稿叧闄勪欢</span>
       </div>
 
-      <!-- 涓婁紶鍖哄煙锛堟棤鍒嗙被閫夋嫨锛岀敱Tab鎺у埗锛� -->
-      <div class="upload-wrapper">
-        <UploadAttachment
-          ref="uploadAttachment"
-          :file-list="attachmentFileList"
-          :limit="attachmentLimit"
-          :accept="attachmentAccept"
-          :multiple="true"
-          @change="handleAttachmentChange"
-          @upload-success="handleUploadSuccess"
-          @upload-error="handleUploadError"
-          @remove="handleAttachmentRemove"
-        />
-        <div style="font-size:12px; color:#909399; margin-top:4px;">
-          褰撳墠涓婁紶鍒嗙被锛�<el-tag size="small" type="info">{{
-            activeTab === "鏈垎绫�" ? "鏈垎绫�" : activeTab
-          }}</el-tag>
-          锛堝垏鎹� Tab 鍙敼鍙樹笂浼犲垎绫伙級
-        </div>
-      </div>
-
       <!-- 闄勪欢鍒楄〃 - 鍒嗙被Tab灞曠ず锛屾敮鎸佷慨鏀瑰垎绫� -->
-      <div class="attachment-list" v-if="attachments && attachments.length > 0">
-        <el-tabs v-model="activeTab" type="border-card">
-          <el-tab-pane
-            v-for="category in categories"
-            :key="category"
-            :label="category + '(' + getCategoryCount(category) + ')'"
-            :name="category"
-          >
-            <el-table
-              :data="getCategoryFiles(category)"
-              style="width: 100%"
-              size="small"
-              border
+      <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 style="margin-bottom: 10px; text-align: right;">
+            <el-button
+              v-if="!isReadOnly"
+              size="mini"
+              type="primary"
+              icon="el-icon-plus"
+              @click="openUploadDialog(category)"
             >
-              <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-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="120">
-                <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>
-          </el-tab-pane>
-        </el-tabs>
-      </div>
-
-      <!-- 鏃犻檮浠舵椂鏄剧ず -->
-      <div v-else style="text-align:center; padding:20px; color:#909399;">
-        鏆傛棤闄勪欢锛岃涓婁紶
-      </div>
+              娣诲姞闄勪欢
+            </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"
+                  :disabled="isReadOnly"
+                  @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-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="120">
+              <template #default="scope">
+                <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column
+              v-if="!isReadOnly"
+              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
+        v-if="!isReadOnly"
+        type="primary"
+        @click="handleSave"
+        :loading="saveLoading"
+      >
         淇濆瓨
       </el-button>
       <el-button
+        v-if="!isReadOnly"
         type="success"
         @click="handleComplete"
         :loading="confirmLoading"
@@ -590,6 +608,47 @@
         瀹屾垚鍒╃敤
       </el-button>
     </div>
+    <!-- 涓婁紶瀵硅瘽妗� -->
+    <el-dialog
+      :title="`涓婁紶${currentUploadCategory}闄勪欢`"
+      :visible.sync="uploadDialogVisible"
+      width="480px"
+      :close-on-click-modal="false"
+    >
+      <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>
+      </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="filePreviewVisible"
@@ -606,15 +665,15 @@
   completionadd,
   completionedit
 } from "@/api/businessApi";
-import UploadAttachment from "@/components/UploadAttachment"; // 鏂板瀵煎叆
-import FilePreviewDialog from "@/components/FilePreviewDialog"; // 鏂板瀵煎叆
+import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
+import FilePreviewDialog from "@/components/FilePreviewDialog";
 import CaseBasicInfo from "@/components/CaseBasicInfo";
-import dayjs from "dayjs"; // 鏂板瀵煎叆锛岀敤浜庢椂闂村鐞�
+import { getToken } from "@/utils/auth";
+import dayjs from "dayjs";
 
 export default {
   name: "OrganUtilizationDetail",
   components: {
-    UploadAttachment,
     FilePreviewDialog,
     CaseBasicInfo
   },
@@ -692,7 +751,8 @@
         { value: "1", label: "宸茬Щ妞�" },
         { value: "0", label: "鏈Щ妞�" },
         { value: "2", label: "绉绘涓�" },
-        { value: "3", label: "搴撳瓨" }
+        { value: "3", label: "搴撳瓨" },
+        { value: "4", label: "寮冪敤" }
       ],
       organExpansionMap: {
         C64: { subItems: ["C64L", "C64R"], subNames: ["宸﹁偩", "鍙宠偩"] },
@@ -710,17 +770,23 @@
       attachments: [],
       // 灞曞紑鐨勮keys
       expandedRows: [],
+      // 鏍¢獙澶辫触鏃堕珮浜殑瀛楁锛坥rganno -> 缂哄け瀛楁鍚嶆暟缁勶級
+      errorFields: {},
       // 缂栬緫瀵硅瘽妗�
       editDialogVisible: false,
       currentRecord: {},
       currentEditIndex: -1,
-      // 闄勪欢鐩稿叧閰嶇疆 - 鏂板
-      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: "",
 
-      // 鏂囦欢棰勮鐩稿叧 - 鏂板
+      // 鏂囦欢棰勮鐩稿叧
       filePreviewVisible: false,
       currentPreviewFile: null,
       currentFollowup: {},
@@ -733,15 +799,21 @@
       return JSON.parse(sessionStorage.getItem("user") || "{}");
     },
     categories() {
-     // 濮嬬粓杩斿洖鎵�鏈夐璁惧垎绫� + 鏈垎绫伙紝鍗充娇娌℃湁鏁版嵁涔熸樉绀�
-    const allCategories = ['鍘熻〃鎷嶇収', '鎺ュ彈纭涔�', '寮冪敤璇存槑', '鎹愮尞璇佷功鐓х墖', '鏈垎绫�'];
-    return allCategories;
+      // 濮嬬粓杩斿洖鎵�鏈夐璁惧垎绫� + 鏈垎绫伙紝鍗充娇娌℃湁鏁版嵁涔熸樉绀�
+      const allCategories = [
+        "鍘熻〃鎷嶇収",
+        "鎺ュ彈纭涔�",
+        "寮冪敤璇存槑",
+        "鎹愮尞璇佷功鐓х墖",
+        "鏈垎绫�"
+      ];
+      return allCategories;
     },
     // 宸茬Щ妞嶆暟閲�
     transplantedCount() {
       if (!this.utilizationData.serviceDonatecomporganList) return 0;
       return this.utilizationData.serviceDonatecomporganList.filter(
-        record => record.transplantstate === "1"
+        record => record.transplantstate == "1"
       ).length;
     },
     // 鍞竴鍖婚櫌鏁伴噺
@@ -771,26 +843,25 @@
     // 鑾峰彇鍣ㄥ畼瀛楀吀
     organDict() {
       return this.dict.type.sys_Organ || [];
+    },
+    // 鏌ョ湅妯″紡锛氬彧璇伙紝绂佺敤琛ㄥ崟骞堕殣钘忎繚瀛樻寜閽�
+    isReadOnly() {
+      return this.$route.query.mode === "view";
+    }
+  },
+  watch: {
+    // 鐢ㄦ埛淇敼鍒╃敤璁板綍鏃讹紝娓呴櫎瀛楁楂樹寒
+    "utilizationData.serviceDonatecomporganList": {
+      deep: true,
+      handler() {
+        if (Object.keys(this.errorFields).length > 0) {
+          this.errorFields = {};
+        }
+      }
     }
   },
   created() {
     this.initData();
-  },
-  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
-    }
   },
   methods: {
     // 鍒濆鍖栨暟鎹�
@@ -825,9 +896,9 @@
       });
 
       targetNos.forEach(no => {
-        const existing = records.find(r => r.organno === no);
+        const existing = records.find(r => r.organno == no);
         if (existing) {
-          if (existing.delFlag === 1) existing.delFlag = 0;
+          if (existing.delFlag == 1) existing.delFlag = 0;
         } else {
           // 浣跨敤鍒涘缓鏂规硶锛岃嚜鍔ㄥ寘鍚� delFlag:0
           this.createOrganRecord(no);
@@ -843,11 +914,7 @@
       this.loading = true;
       try {
         const response = await completionList({ infoid: this.caseId });
-        if (
-          response.code === 200 &&
-          response.data &&
-          response.data.length > 0
-        ) {
+        if (response.code == 200 && response.data && response.data.length > 0) {
           const data = response.data[0];
           if (!data.completeState || data.completeState == 1) {
             data.completeState = "2";
@@ -872,9 +939,10 @@
               ? data.serviceDonatecomporganList.map(record => ({
                   ...record,
                   transplanttime: record.transplanttime || "",
-                  transplantstate: record.transplantstate
-                    ? record.transplantstate.toString()
-                    : "1"
+                  transplantstate:
+                    record.transplantstate != null
+                      ? record.transplantstate.toString()
+                      : "1"
                 }))
               : [];
           }
@@ -889,19 +957,8 @@
               fileType: item.fileType || "" // 榛樿绌哄瓧绗︿覆琛ㄧず鏈垎绫�
             }));
             this.form.attachments = this.attachments;
-            // 鍚屾 attachmentFileList
-            this.attachmentFileList = this.attachments.map(item => ({
-              uid: item.id || Math.random(),
-              name: item.fileName,
-              url: item.path || item.fileUrl,
-              fileSize: item.fileSize,
-              uploadTime: item.uploadTime,
-              status: "success",
-              raw: item
-            }));
           } else {
             this.attachments = [];
-            this.attachmentFileList = [];
           }
 
           this.$message.success("鏁版嵁鍔犺浇鎴愬姛");
@@ -956,9 +1013,9 @@
 
       // 3. 鏂板鎴栨仮澶嶈褰曪紙鏃犻渶寮圭獥锛�
       targetOrganNos.forEach(no => {
-        const existing = records.find(r => r.organno === no);
+        const existing = records.find(r => r.organno == no);
         if (existing) {
-          if (existing.delFlag === 1) {
+          if (existing.delFlag == 1) {
             existing.delFlag = 0; // 鎭㈠鏄剧ず
           }
         } else {
@@ -1073,6 +1130,7 @@
       const organName = this.getOrganLabel(organValue);
 
       this.utilizationData.serviceDonatecomporganList.push({
+        infoid: this.caseId,
         organname: organName,
         organno: organValue,
         caseNo: "",
@@ -1107,19 +1165,19 @@
 
     // 鏍规嵁瀛楀吀value鑾峰彇label
     getOrganLabel(organValue) {
-      const dictItem = this.organDict.find(item => item.value === organValue);
+      const dictItem = this.organDict.find(item => item.value == organValue);
       return dictItem ? dictItem.label : organValue;
     },
 
     // 绉绘鐘舵�佸彉鍖栧鐞�
     handleTransplantStatusChange(row, status) {
-      if (status === "0") {
+      if (status == "0") {
         // 濡傛灉鐘舵�佷负鏈Щ妞嶏紝娓呴櫎鐩稿叧瀛楁
         // row.transplanttime = "";
         // row.transplantdoct = "";
         // row.hospitalno = "";
         // row.hospitalname = "";
-      } else if (status === "1") {
+      } else if (status == "1") {
         // 濡傛灉鐘舵�佷负宸茬Щ妞嶏紝鑷姩璁剧疆绉绘鏃堕棿涓哄綋鍓嶆椂闂�
         if (!row.transplanttime) {
           row.transplanttime = new Date().toISOString().split("T")[0];
@@ -1158,15 +1216,20 @@
     // 鍣ㄥ畼琛屾牱寮�
     getOrganRowClassName({ row }) {
       if (
-        row.transplantstate === "1" &&
-        (!row.hospitalno || !row.name || !row.transplanttime)
+        row.transplantstate == "1" &&
+        (!row.hospitalname || !row.name || !row.transplanttime)
       ) {
         return "warning-row";
       }
-      if (row.transplantstate === "0" && !row.abandonreason) {
+      if (row.transplantstate == "0" && !row.abandonreason) {
         return "warning-row";
       }
       return "";
+    },
+    // 鏍¢獙澶辫触鏃跺瓧娈垫槸鍚﹂珮浜�
+    isFieldError(row, field) {
+      const fields = this.errorFields[row.organno];
+      return fields && fields.includes(field);
     },
 
     // 鑾峰彇鐘舵�佹爣绛剧被鍨�
@@ -1211,10 +1274,19 @@
 
     // 淇濆瓨鍩烘湰淇℃伅
     async handleSave() {
+      if (this.saveLoading) return;
       this.$refs.form.validate(async valid => {
         if (valid) {
           this.saveLoading = true;
           try {
+            // 鏂板鏃舵牎楠屾槸鍚﹀凡鏈夌浉鍚屾偅鑰�
+            if (!this.form.id) {
+              const exists = await this.checkPatientExists();
+              if (exists) {
+                this.$message.warning("璇ユ偅鑰呭凡瀛樺湪锛岃鍕块噸澶嶆坊鍔�");
+                return;
+              }
+            }
             const saveData = {
               ...this.form,
               assessannex: JSON.stringify(this.attachments),
@@ -1226,7 +1298,7 @@
             const apiMethod = this.form.id ? completionedit : completionadd;
             const response = await apiMethod(saveData);
 
-            if (response.code === 200) {
+            if (response.code == 200) {
               this.$message.success("淇濆瓨鎴愬姛");
               if (!this.form.id && response.data && response.data.id) {
                 this.form.id = response.data.id;
@@ -1246,12 +1318,39 @@
         }
       });
     },
+    // 鏂板鏃舵牎楠屾槸鍚﹀凡鏈夌浉鍚屾偅鑰咃紙鎸変綇闄㈠彿锛�
+    async checkPatientExists() {
+      let inpatientno = this.form.inpatientno;
+      if (!inpatientno && this.caseId) {
+        try {
+          const caseRes = await getDonatebaseinfo(this.caseId);
+          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
+        } catch (e) {
+          inpatientno = "";
+        }
+      }
+      if (!inpatientno) return false;
+      try {
+        const res = await completionList({
+          inpatientno,
+          pageNum: 1,
+          pageSize: 1
+        });
+        let list = res.data || [];
+        if (!Array.isArray(list)) {
+          list = list.rows || list.list || [];
+        }
+        return list.some(item => item && item.id != null && item.id !== "");
+      } catch (e) {
+        return false;
+      }
+    },
 
     // 淇濆瓨鍒╃敤璁板綍
     async handleSaveUtilization() {
       if (
         !this.utilizationData.serviceDonatecomporganList ||
-        this.utilizationData.serviceDonatecomporganList.length === 0
+        this.utilizationData.serviceDonatecomporganList.length == 0
       ) {
         this.$message.warning("璇峰厛娣诲姞鍒╃敤璁板綍");
         return;
@@ -1269,7 +1368,7 @@
 
         const response = await completionedit(saveData);
 
-        if (response.code === 200) {
+        if (response.code == 200) {
           this.$message.success("鍒╃敤璁板綍淇濆瓨鎴愬姛");
         } else {
           this.$message.error(
@@ -1286,20 +1385,57 @@
 
     // 纭瀹屾垚鍒╃敤
     async handleConfirmUtilization() {
-      // 妫�鏌ュ埄鐢ㄨ褰曟槸鍚﹀畬鏁�
-      const incompleteRecords = this.utilizationData.serviceDonatecomporganList.filter(
-        record => {
-          if (record.transplantstate === "1") {
-            return !record.hospitalno || !record.name || !record.transplanttime;
-          } else if (record.transplantstate === "0") {
-            return !record.abandonreason;
-          }
-          return false;
+      if (
+        !this.utilizationData.serviceDonatecomporganList ||
+        this.utilizationData.serviceDonatecomporganList.length == 0
+      ) {
+        this.$message.warning("璇峰厛娣诲姞鍒╃敤璁板綍");
+        return;
+      }
+
+      // 妫�鏌ュ埄鐢ㄨ褰曟槸鍚﹀畬鏁达紝璁板綍缂哄け瀛楁
+      const errorFields = {};
+      const incompleteRecords = [];
+      this.utilizationData.serviceDonatecomporganList.forEach(record => {
+        const missing = [];
+        if (record.transplantstate == "1") {
+          if (!record.hospitalname) missing.push("hospitalname");
+          if (!record.name) missing.push("name");
+          if (!record.transplanttime) missing.push("transplanttime");
+        } else if (record.transplantstate == "0") {
+          if (!record.abandonreason) missing.push("abandonreason");
         }
-      );
+        if (missing.length > 0) {
+          errorFields[record.organno] = missing;
+          incompleteRecords.push(record);
+        }
+      });
+      this.errorFields = errorFields;
 
       if (incompleteRecords.length > 0) {
-        this.$message.warning("璇峰厛瀹屽杽鎵�鏈夊埄鐢ㄨ褰曠殑淇℃伅");
+        // 浠呭綋缂哄皯銆屾湭绉绘鍘熷洜銆嶆椂璇ュ瓧娈典綅浜庢姌鍙犻潰鏉垮唴锛屾墠鑷姩灞曞紑瀵瑰簲闈㈡澘
+        this.expandedRows = incompleteRecords
+          .filter(record =>
+            (errorFields[record.organno] || []).includes("abandonreason")
+          )
+          .map(record => record.organno);
+
+        // 缂哄け瀛楁涓枃鍚嶏紝鐢ㄤ簬鎻愮ず鍏蜂綋鏄摢涓」娌″~
+        const fieldLabels = {
+          hospitalname: "绉绘鍖婚櫌",
+          name: "鍙楄�呭鍚�",
+          transplanttime: "绉绘鏃堕棿",
+          abandonreason: "鏈Щ妞嶅師鍥�"
+        };
+        const details = incompleteRecords
+          .map(record => {
+            const missingLabels = (errorFields[record.organno] || [])
+              .map(field => fieldLabels[field] || field)
+              .join("銆�");
+            return `${record.organname || record.organno} ${missingLabels}`;
+          })
+          .join("锛�");
+        this.$message.warning(`璇峰畬鍠勪互涓嬪櫒瀹樼殑鍒╃敤淇℃伅锛�${details}`);
         return;
       }
 
@@ -1329,7 +1465,7 @@
 
             const response = await completionedit(saveData);
 
-            if (response.code === 200) {
+            if (response.code == 200) {
               this.$message.success("鍣ㄥ畼鍒╃敤宸插畬鎴�");
             } else {
               this.$message.error(
@@ -1371,7 +1507,7 @@
 
       // 鑾峰彇鍣ㄥ畼鍚嶇О
       const organRecord = this.utilizationData.serviceDonatecomporganList.find(
-        item => item.organno === this.currentFollowup.organNo
+        item => item.organno == this.currentFollowup.organNo
       );
       const organName = organRecord ? organRecord.organname : "";
 
@@ -1386,7 +1522,7 @@
         if (this.isEditingFollowup) {
           // 鏇存柊鐜版湁璁板綍
           const index = this.followupData.records.findIndex(
-            item => item.id === this.currentFollowup.id
+            item => item.id == this.currentFollowup.id
           );
           if (index !== -1) {
             this.followupData.records[index] = {
@@ -1403,53 +1539,107 @@
         this.saveLoading = false;
       }, 1000);
     },
-    /** 闄勪欢鍙樺寲澶勭悊 */
-    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
+    // 涓婁紶鍓嶆牎楠�
+    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鏍煎紡鏂囦欢"
         );
-        if (index > -1) {
-          this.attachments.splice(index, 1);
-          this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
-        }
+        return false;
       }
+      if (file.size > maxSize) {
+        this.$message.error("鏂囦欢澶у皬涓嶈兘瓒呰繃10MB");
+        return false;
+      }
+      return true;
     },
-    /** 涓婁紶鎴愬姛澶勭悊 */
-    handleUploadSuccess({ file, fileList, response }) {
-      if (response.code === 200) {
-        // 鏍规嵁褰撳墠婵�娲荤殑 Tab 鍐冲畾鍒嗙被锛堟湭鍒嗙被 Tab 瀵瑰簲绌哄瓧绗︿覆锛�
-        const category = this.activeTab === "鏈垎绫�" ? "" : this.activeTab;
-        const attachmentObj = {
-          fileName: file.name,
-          path: response.fileUrl || file.url,
-          fileUrl: response.fileUrl || 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.attachmentFileList = fileList; // 淇濇寔鍚屾
-        this.$message.success("鏂囦欢涓婁紶鎴愬姛");
-      }
+    // 鏂囦欢閫夋嫨鍙樺寲
+    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 === "鏈垎绫�") {
+        if (category == "鏈垎绫�") {
           return !this.presetCategories.includes(type);
         }
-        return type === category;
+        return type == category;
       }).length;
     },
 
@@ -1457,27 +1647,18 @@
     getCategoryFiles(category) {
       return this.attachments.filter(item => {
         const type = item.fileType || "";
-        if (category === "鏈垎绫�") {
+        if (category == "鏈垎绫�") {
           return !this.presetCategories.includes(type);
         }
-        return type === category;
+        return type == category;
       });
     },
 
     // 鏇存柊闄勪欢鍒嗙被锛堜笅鎷変慨鏀规椂瑙﹀彂锛�
     updateAttachmentCategory(row, newVal) {
-      const target = this.attachments.find(item => item === row);
+      const target = this.attachments.find(item => item == row);
       if (target) {
-        target.fileType = newVal; // 鍙兘涓虹┖瀛楃涓�
-        // 鍚屾鏇存柊 attachmentFileList
-        const fileItem = this.attachmentFileList.find(
-          f => f.raw === row || f.url === row.fileUrl
-        );
-        if (fileItem) {
-          fileItem.raw.fileType = newVal;
-          fileItem.fileType = newVal || "鏈垎绫�";
-        }
-        // 濡傛灉褰撳墠婵�娲荤殑tab娌℃湁鏂囦欢浜嗭紝鑷姩鍒囨崲鍒扮涓�涓湁鏂囦欢鐨則ab
+        target.fileType = newVal;
         const currentTabHasFiles =
           this.getCategoryFiles(this.activeTab).length > 0;
         if (!currentTabHasFiles) {
@@ -1489,32 +1670,22 @@
 
     // 鎸夋枃浠跺璞″垹闄わ紙鐢ㄤ簬琛ㄦ牸涓殑鍒犻櫎鎸夐挳锛�
     handleRemoveAttachmentByFile(file) {
-      const index = this.attachments.findIndex(item => item === file);
-      if (index > -1) {
-        this.attachments.splice(index, 1);
-        // 鍚屾鍒犻櫎 attachmentFileList
-        const fileIndex = this.attachmentFileList.findIndex(
-          f => f.raw === file || f.url === file.fileUrl
-        );
-        if (fileIndex > -1) {
-          this.attachmentFileList.splice(fileIndex, 1);
-        }
-        this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
-      }
-    },
-    /** 涓婁紶閿欒澶勭悊 */
-    handleUploadError({ file, fileList, error }) {
-      console.error("闄勪欢涓婁紶澶辫触:", error);
-      this.$message.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+      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(() => {});
     },
 
-    /** 鎵嬪姩鍒犻櫎闄勪欢 */
-    handleRemoveAttachment(index) {
-      // 鐩存帴璋冪敤鏂扮殑鍒犻櫎鏂规硶
-      this.handleRemoveAttachmentByFile(file.raw || file);
-    },
-
-    /** 鏂囦欢棰勮 */
+    // 鏂囦欢棰勮
     handlePreview(file) {
       this.currentPreviewFile = {
         fileName: file.fileName,
@@ -1523,7 +1694,8 @@
       };
       this.filePreviewVisible = true;
     },
-    /** 鏂囦欢涓嬭浇 */
+
+    // 鏂囦欢涓嬭浇
     handleDownloadAttachment(file) {
       const fileUrl = file.path || file.fileUrl;
       const fileName = file.fileName;
@@ -1610,7 +1782,7 @@
 
     /** 鏍煎紡鍖栨枃浠跺ぇ灏� */
     formatFileSize(bytes) {
-      if (!bytes || bytes === 0) return "0 B";
+      if (!bytes || bytes == 0) return "0 B";
       const k = 1024;
       const sizes = ["B", "KB", "MB", "GB"];
       const i = Math.floor(Math.log(bytes) / Math.log(k));
@@ -1727,6 +1899,13 @@
 /* 鏂戦┈绾硅〃鏍艰 */
 :deep(.el-table__row.warning-row) {
   background-color: #fdf6ec;
+}
+
+/* 鏍¢獙澶辫触瀛楁楂樹寒 */
+.field-error >>> .el-input__inner,
+.field-error >>> .el-textarea__inner {
+  border-color: #f56c6c !important;
+  box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.15);
 }
 
 :deep(.el-table__row.default-row) {
@@ -2033,4 +2212,103 @@
     padding: 10px 15px;
   }
 }
+
+/* ===== 绾歌川琛ㄦ牸缃戞牸鏍峰紡 ===== */
+.paper-card >>> .el-card__body {
+  padding: 16px;
+}
+
+.paper-form {
+  border-left: 1px solid #d0d3db;
+  background: #fff;
+}
+
+.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