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/project/donatebaseinfo/EditCaseModal.vue |  748 +++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 538 insertions(+), 210 deletions(-)

diff --git a/src/views/project/donatebaseinfo/EditCaseModal.vue b/src/views/project/donatebaseinfo/EditCaseModal.vue
index e0cae19..71ff5b8 100644
--- a/src/views/project/donatebaseinfo/EditCaseModal.vue
+++ b/src/views/project/donatebaseinfo/EditCaseModal.vue
@@ -534,46 +534,66 @@
                 </el-form-item>
               </el-col>
             </el-row>
+             <el-row :gutter="20">
 
-            <!-- 淇℃伅鍛� -->
-            <el-row>
-              <el-col :span="8">
-                <el-form-item label="淇℃伅鍛�" prop="infoName">
-                  <el-input
-                    v-model="formData.infoName"
-                    placeholder="璇疯緭鍏ヤ俊鎭憳"
-                  />
-                </el-form-item>
-              </el-col>
-              <el-col :span="8">
-                <el-form-item label="鑱旂郴鐢佃瘽" prop="infophone">
-                  <el-input
-                    v-model="formData.infophone"
-                    placeholder="璇疯緭鍏ヤ俊鎭憳鑱旂郴鐢佃瘽"
-                  />
-                </el-form-item>
-              </el-col>
-            </el-row>
+            <el-col :span="20">
+              <el-form-item label="鑾峰彇缁勭粐鍚嶇О" prop="acquisitiontissuename">
+                <el-input
+                  v-model="formData.acquisitiontissuename"
+                  placeholder="璇疯緭鍏ヨ幏鍙栫粍缁囧悕绉�"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+            <!-- 涓婃姤闃舵鎶ュ憡浜� -->
             <el-col :span="8">
-              <el-form-item label="鎶ュ憡浜虹瀛�" prop="reportername">
+              <el-form-item label="涓婃姤闃舵鎶ュ憡浜�" prop="reportername">
                 <el-input
                   v-model="formData.reportername"
                   placeholder="鎶ュ憡浜哄鍚�"
-                  :disabled="true"
                 />
               </el-form-item>
             </el-col>
             <el-col :span="8">
-              <el-form-item label="鑱旂郴鐢佃瘽" prop="reporterphone">
+              <el-form-item label="鎶ュ憡浜鸿仈绯荤數璇�" prop="reporterphone">
                 <el-input
                   v-model="formData.reporterphone"
                   placeholder="鎶ュ憡浜鸿仈绯荤數璇�"
                 />
               </el-form-item>
             </el-col>
+            <el-col :span="8">
+              <el-form-item label="鎶ュ憡鏃堕棿" prop="reporttime">
+                <el-date-picker
+                  v-model="formData.reporttime"
+                  type="date"
+                  placeholder="閫夋嫨鎶ュ憡鏃堕棿"
+                  value-format="yyyy-MM-dd "
+                  style="width: 100%"
+                />
+              </el-form-item>
+            </el-col>
+            <!-- 鎶ュ憡淇℃伅鍛� -->
+            <el-col :span="8">
+              <el-form-item label="鎶ュ憡淇℃伅鍛�" prop="infoName">
+                <el-input
+                  v-model="formData.infoName"
+                  placeholder="璇疯緭鍏ユ姤鍛婁俊鎭憳"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="淇℃伅鍛樿仈绯荤數璇�" prop="infophone">
+                <el-input
+                  v-model="formData.infophone"
+                  placeholder="璇疯緭鍏ヤ俊鎭憳鑱旂郴鐢佃瘽"
+                />
+              </el-form-item>
+            </el-col>
           </el-row>
 
-          <el-row :gutter="20">
+          <!-- <el-row :gutter="20">
             <el-col :span="12">
               <el-form-item label="鎶ュ憡鏃堕棿" prop="reporttime">
                 <el-date-picker
@@ -585,21 +605,21 @@
                 />
               </el-form-item>
             </el-col>
-            <!-- <el-col :span="12">
+            <el-col :span="12">
               <el-form-item label="閮ㄩ棬ID" prop="deptid">
                 <el-input
                   v-model="formData.deptid"
                   placeholder="璇疯緭鍏ラ儴闂↖D"
                 />
               </el-form-item>
-            </el-col> -->
-          </el-row>
+            </el-col>
+          </el-row> -->
         </el-card>
 
         <!-- 鎹愮尞淇℃伅閮ㄥ垎 -->
-        <el-card header="鎹愮尞淇℃伅" class="form-section">
+        <!-- <el-card header="鎹愮尞淇℃伅" class="form-section">
           <el-row :gutter="20">
-            <!-- <el-col :span="8">
+            <el-col :span="8">
               <el-form-item label="鎹愮尞绫诲埆" prop="donationcategory">
                 <el-select
                   v-model="formData.donationcategory"
@@ -613,7 +633,7 @@
                   />
                 </el-select>
               </el-form-item>
-            </el-col> -->
+            </el-col>
             <el-col :span="8">
               <el-form-item label="妗堜緥涓婃姤鏃堕棿" prop="donatetime">
                 <el-date-picker
@@ -638,15 +658,10 @@
             </el-col>
           </el-row>
 
-          <!-- 绾㈠崄瀛椾細鍜岃仈绯讳汉 -->
           <el-row>
             <el-col :span="8">
               <el-form-item align="left" label="绾㈠崄瀛椾細" prop="redorganno">
-                <!-- <org-selecter
-                  ref="addCrossOrgSelect"
-                  :org-type="'2'"
-                  v-model="formData.redorganno"
-                /> -->
+
                 <el-select
                   v-model="formData.redorganname"
                   placeholder="璇烽�夋嫨绾㈠崄瀛椾細鏈烘瀯鍚嶇О"
@@ -681,14 +696,7 @@
             </el-col>
           </el-row>
           <el-row :gutter="20">
-            <!-- <el-col :span="12">
-              <el-form-item label="鑾峰彇缁勭粐缂栧彿" prop="acquisitiontissueno">
-                <el-input
-                  v-model="formData.acquisitiontissueno"
-                  placeholder="璇疯緭鍏ヨ幏鍙栫粍缁囩紪鍙�"
-                />
-              </el-form-item>
-            </el-col> -->
+
             <el-col :span="12">
               <el-form-item label="鑾峰彇缁勭粐鍚嶇О" prop="acquisitiontissuename">
                 <el-input
@@ -698,67 +706,95 @@
               </el-form-item>
             </el-col>
           </el-row>
-        </el-card>
-        <!-- 涓婃姤闃舵闄勪欢 -->
-<el-card v-if="reportAttachments && reportAttachments.length > 0" class="form-section" shadow="never">
-  <div slot="header" class="section-header">
-    <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i>
-    <span>涓婃姤闃舵闄勪欢</span>
-  </div>
-  <div class="attachment-list">
-    <el-tabs v-model="reportActiveTab" type="border-card">
-      <el-tab-pane
-        v-for="category in reportCategories"
-        :key="category"
-        :label="category + '(' + getReportCategoryCount(category) + ')'"
-        :name="category"
-      >
-        <el-table :data="getReportCategoryFiles(category)" style="width: 100%" size="small" border>
-          <el-table-column label="鏂囦欢鍚�" min-width="200">
-            <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="100">
-            <template #default="scope">
-              <el-tag size="small">{{ getFileType(scope.row.fileName) }}</el-tag>
-            </template>
-          </el-table-column>
-          <el-table-column label="鍒涘缓鏃堕棿" width="160">
-            <template #default="scope">
-              <span>{{ formatDateTime(scope.row.createTime) }}</span>
-            </template>
-          </el-table-column>
-          <el-table-column label="鎿嶄綔" width="120">
-            <template #default="scope">
-              <el-button size="mini" type="primary" @click="handleReportPreview(scope.row)">棰勮</el-button>
-            </template>
-          </el-table-column>
-        </el-table>
-      </el-tab-pane>
-    </el-tabs>
-  </div>
-</el-card>
-
-<!-- 鍔犺浇涓崰浣� -->
-<el-card v-else-if="reportAttachmentLoading" class="form-section" shadow="never">
-  <div slot="header" class="section-header">
-    <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i>
-    <span>涓婃姤闃舵闄勪欢</span>
-  </div>
-  <div style="text-align:center; padding:20px;">鍔犺浇闄勪欢涓�...</div>
-</el-card>
-
-<!-- 鏈� reportId 浣嗘棤闄勪欢 -->
-<el-card v-else-if="editData.reportId" class="form-section" shadow="never">
-  <div slot="header" class="section-header">
-    <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i>
-    <span>涓婃姤闃舵闄勪欢</span>
-  </div>
-  <div style="text-align:center; padding:20px; color:#909399;">鏆傛棤涓婃姤闄勪欢</div>
-</el-card>
+        </el-card> -->
       </el-form>
+
+      <!-- 鎹愮尞鑰呯櫥璁伴樁娈甸檮浠讹紙鍙紪杈戯紝瀛樺偍浜庝翰灞炵‘璁よ〃 assessannex锛� -->
+      <el-card header="鐧昏闃舵闄勪欢" class="form-section">
+        <el-tabs v-model="activeRegisterType" type="card">
+          <el-tab-pane
+            v-for="type in registerAttachmentTypes"
+            :key="type.value"
+            :label="type.label"
+            :name="type.value"
+          >
+            <div class="attachment-header">
+              <span class="upload-title">{{ type.label }}</span>
+              <el-button
+                size="mini"
+                type="primary"
+                icon="el-icon-plus"
+                @click="openUploadDialog(type.value)"
+              >
+                娣诲姞闄勪欢
+              </el-button>
+            </div>
+
+            <el-table
+              :data="getRegisterAttachments(type.value)"
+              size="small"
+              style="width: 100%"
+            >
+              <el-table-column label="鏂囦欢鍚�" min-width="200">
+                <template slot-scope="scope">
+                  <i
+                    class="el-icon-document"
+                    style="color: #409eff; margin-right: 8px"
+                  ></i>
+                  <span>{{ scope.row.fileName }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="鏂囦欢绫诲瀷" width="90" align="center">
+                <template slot-scope="scope">
+                  <el-tag size="small">{{
+                    getFileType(scope.row.fileName)
+                  }}</el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="鏂囦欢澶у皬" width="90" align="center">
+                <template slot-scope="scope">
+                  <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="涓婁紶鏃堕棿" width="155" align="center">
+                <template slot-scope="scope">
+                  <span>{{
+                    formatDateTime(scope.row.uploadTime || scope.row.createTime)
+                  }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="鎿嶄綔" width="145" align="center">
+                <template slot-scope="scope">
+                  <el-button
+                    size="mini"
+                    type="primary"
+                    @click="handlePreview(scope.row)"
+                  >
+                    棰勮
+                  </el-button>
+                  <el-button
+                    size="mini"
+                    type="danger"
+                    @click="handleRemoveAttachment(type.value, scope.$index)"
+                  >
+                    鍒犻櫎
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+
+            <div
+              v-if="getRegisterAttachments(type.value).length === 0"
+              class="empty-attachment"
+            >
+              <el-empty
+                :description="`鏆傛棤${type.label}`"
+                :image-size="80"
+              ></el-empty>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+      </el-card>
 
       <div slot="footer" class="dialog-footer">
         <el-button @click="handleClose">鍙栨秷</el-button>
@@ -771,6 +807,55 @@
         </el-button>
       </div>
     </el-dialog>
+
+    <!-- 涓婁紶闄勪欢瀵硅瘽妗� -->
+    <el-dialog
+      :title="`涓婁紶${getCurrentTypeLabel()}闄勪欢`"
+      :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="previewVisible"
+      :file="currentPreviewFile"
+      @close="previewVisible = false"
+      @download="handleDownload"
+    />
   </div>
 </template>
 
@@ -779,15 +864,18 @@
   getDonatebaseinfo,
   updateDonatebaseinfo
 } from "@/api/project/donatebaseinfo";
+import { relativesEdit, relativesAdd, relativesList } from "@/api/businessApi";
 import OrgSelecter from "@/views/project/components/orgselect";
-import { donateInfo } from "@/api/businessApi/index";
 import LiAreaSelect from "@/components/Address";
+import FilePreviewDialog from "@/components/FilePreviewDialog";
+import { getToken } from "@/utils/auth";
 
 export default {
   name: "EditCaseModal",
   components: {
     OrgSelecter,
-    LiAreaSelect
+    LiAreaSelect,
+    FilePreviewDialog
   },
 
   // 娣诲姞鎵�鏈夐渶瑕佺殑瀛楀吀绫诲瀷
@@ -836,10 +924,24 @@
       residenceAddress: {},
       registerAddress: {},
       formData: this.getDefaultFormData(),
-      reportAttachments: [], // 涓婃姤闃舵鐨勯檮浠跺垪琛�
-      reportAttachmentLoading: false, // 鍔犺浇鐘舵��
-      reportActiveTab: "鐧昏琛ㄩ檮浠�", // 褰撳墠婵�娲荤殑闄勪欢鍒嗙被 Tab
-      presetCategories: ["鐧昏琛ㄩ檮浠�", "璇佷欢鐓�", "鐤剧梾璇婃柇娌荤枟"], // 棰勮鍒嗙被
+      // 鐧昏闃舵闄勪欢锛堝彲缂栬緫锛屽瓨鍌ㄤ簬浜插睘纭琛� assessannex锛�
+      registerAttachmentTypes: [
+        { value: "1", label: "浜轰綋鍣ㄥ畼娼滃湪鎹愮尞鑰呯櫥璁拌〃闄勪欢" },
+        { value: "5", label: "璇佷欢鐓�" },
+        { value: "6", label: "鐤剧梾璇婃柇娌荤枟" }
+      ],
+      registerAttachmentData: { "1": [], "5": [], "6": [] },
+      otherAttachments: [],
+      confirmationRecord: null,
+      activeRegisterType: "1",
+      uploadAction: process.env.VUE_APP_BASE_API + "/common/upload",
+      headers: { Authorization: "Bearer " + getToken() },
+      uploadDialogVisible: false,
+      uploadLoading: false,
+      tempFileList: [],
+      currentUploadType: "",
+      previewVisible: false,
+      currentPreviewFile: null,
       rules: {
         name: [
           { required: true, message: "璇疯緭鍏ユ崘鐚�呭鍚�", trigger: "blur" }
@@ -866,9 +968,9 @@
         bloodtype: [
           { required: true, message: "璇烽�夋嫨琛�鍨�", trigger: "change" }
         ],
-        donatetime: [
-          { required: true, message: "璇烽�夋嫨妗堜緥鏃堕棿", trigger: "change" }
-        ],
+        // donatetime: [
+        //   { required: true, message: "璇烽�夋嫨妗堜緥鏃堕棿", trigger: "change" }
+        // ],
         reporttime: [
           { required: true, message: "璇烽�夋嫨鎶ュ憡鏃堕棿", trigger: "change" }
         ],
@@ -896,21 +998,6 @@
         }
       }
     },
-    reportCategories() {
-      if (!this.reportAttachments || this.reportAttachments.length === 0)
-        return [];
-      const cats = new Set();
-      this.reportAttachments.forEach(item => {
-        const type = item.fileType || item.filetype || "";
-        if (this.presetCategories.includes(type)) {
-          cats.add(type);
-        } else {
-          cats.add("鏈垎绫�");
-        }
-      });
-      const order = ["鐧昏琛ㄩ檮浠�", "璇佷欢鐓�", "鐤剧梾璇婃柇娌荤枟", "鏈垎绫�"];
-      return order.filter(c => cats.has(c));
-    }
   },
   watch: {
     visible(newVal) {
@@ -921,16 +1008,6 @@
         });
       } else {
         this.handleClose();
-      }
-    },
-    "editData.reportId": {
-      immediate: true,
-      handler(newVal) {
-        if (newVal) {
-          this.loadReportAttachments(newVal);
-        } else {
-          this.reportAttachments = [];
-        }
       }
     },
     editData: {
@@ -1125,6 +1202,7 @@
         console.log(this.registerAddress, "registerAddress12");
 
         this.calculateAge(data.birthday);
+        await this.loadRegisterAttachments();
       } catch (error) {
         console.error("鑾峰彇妗堜緥鏁版嵁澶辫触:", error);
         this.$message.error("鑾峰彇妗堜緥鏁版嵁澶辫触");
@@ -1262,6 +1340,310 @@
       this.formData.registercommunityname = address.qu;
     },
 
+    // 鍔犺浇鐧昏闃舵闄勪欢锛堣鍙栦翰灞炵‘璁よ〃 assessannex锛屼笌纭璇︽儏椤靛叡鐢ㄥ悓涓�浠芥暟鎹級
+    // 鎹愮尞纭淇℃伅缁熶竴閫氳繃 confirmationBaseInfoList 鎺ュ彛鑾峰彇
+    async loadRegisterAttachments() {
+      const infoid = this.editData && this.editData.id;
+      if (!infoid) {
+        this.resetAttachments();
+        return;
+      }
+      try {
+        const res = await relativesList({ infoid });
+        const record = this.parseConfirmationBaseInfo(res);
+        if (record && record.id) {
+          this.confirmationRecord = record;
+          this.parseAssessannex(record.assessannex);
+        } else {
+          this.confirmationRecord = null;
+          this.resetAttachments();
+        }
+      } catch (e) {
+        console.warn("鑾峰彇浜插睘纭闄勪欢澶辫触:", e);
+        this.resetAttachments();
+      }
+    },
+
+    // 瑙f瀽 confirmationBaseInfoList 杩斿洖鐨勭‘璁ゅ熀纭�淇℃伅锛堝吋瀹规暟缁� / rows / 鍗曞璞$粨鏋勶級
+    parseConfirmationBaseInfo(res) {
+      if (!res || res.code !== 200) return null;
+      const data = res.data;
+      if (!data) return null;
+      if (Array.isArray(data)) return data[0] || null;
+      if (Array.isArray(data.rows)) return data.rows[0] || null;
+      if (Array.isArray(data.list)) return data.list[0] || null;
+      return data;
+    },
+
+    resetAttachments() {
+      Object.keys(this.registerAttachmentData).forEach(key => {
+        this.registerAttachmentData[key] = [];
+      });
+      this.otherAttachments = [];
+    },
+
+    parseAssessannex(assessannex) {
+      this.resetAttachments();
+      if (!assessannex) return;
+      try {
+        const list =
+          typeof assessannex === "string" ? JSON.parse(assessannex) : assessannex;
+        if (!Array.isArray(list)) return;
+        list.forEach(item => {
+          const type = String(item.type || "");
+          if (this.registerAttachmentData[type]) {
+            this.registerAttachmentData[type].push(item);
+          } else {
+            this.otherAttachments.push(item);
+          }
+        });
+      } catch (e) {
+        console.warn("瑙f瀽assessannex澶辫触:", e);
+      }
+    },
+
+    getRegisterAttachments(type) {
+      return this.registerAttachmentData[type] || [];
+    },
+
+    // 搴忓垪鍖栫櫥璁伴樁娈甸檮浠讹紝骞朵繚鐣欑‘璁ら樁娈电瓑鍏朵粬闄勪欢
+    serializeAssessannex() {
+      const all = [...this.otherAttachments];
+      this.registerAttachmentTypes.forEach(t => {
+        all.push(...(this.registerAttachmentData[t.value] || []));
+      });
+      return JSON.stringify(all);
+    },
+
+    getCurrentTypeLabel() {
+      const type = this.registerAttachmentTypes.find(
+        t => t.value === this.currentUploadType
+      );
+      return type ? type.label : "";
+    },
+
+    openUploadDialog(type) {
+      this.currentUploadType = type;
+      this.tempFileList = [];
+      this.uploadDialogVisible = true;
+      this.$nextTick(() => {
+        if (this.$refs.uploadRef) {
+          this.$refs.uploadRef.clearFiles();
+        }
+      });
+    },
+
+    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) {
+      if (response.code !== 200) {
+        this.$message.error(response.msg || "涓婁紶澶辫触");
+        return;
+      }
+      const newAttachment = {
+        id: Date.now(),
+        fileName: file.name,
+        fileUrl: response.url,
+        fileSize: file.size,
+        fileType: this.getFileExtension(file.name),
+        type: this.currentUploadType,
+        uploadTime: this.getCurrentTime(),
+        uploader: "褰撳墠鐢ㄦ埛"
+      };
+      if (this.registerAttachmentData[this.currentUploadType]) {
+        this.registerAttachmentData[this.currentUploadType].push(newAttachment);
+      }
+      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();
+    },
+
+    handleRemoveAttachment(type, index) {
+      this.$confirm("纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          const container = this.registerAttachmentData[type];
+          if (container && container[index]) {
+            container.splice(index, 1);
+            this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+          }
+        })
+        .catch(() => {});
+    },
+
+    handlePreview(file) {
+      this.currentPreviewFile = {
+        fileName: file.fileName,
+        fileUrl: file.fileUrl,
+        fileType: this.getFileType(file.fileName)
+      };
+      this.previewVisible = true;
+    },
+
+    handleDownload(file) {
+      const fileUrl = file.fileUrl;
+      const fileName = file.fileName;
+      if (fileUrl) {
+        const link = document.createElement("a");
+        link.href = fileUrl;
+        link.download = fileName;
+        link.style.display = "none";
+        document.body.appendChild(link);
+        link.click();
+        document.body.removeChild(link);
+        this.$message.success("寮�濮嬩笅杞芥枃浠�");
+      } else {
+        this.$message.warning("鏂囦欢璺緞涓嶅瓨鍦紝鏃犳硶涓嬭浇");
+      }
+    },
+
+    getFileType(fileName) {
+      if (!fileName) return "other";
+      const extension = this.getFileExtension(fileName);
+      const imageTypes = ["jpg", "jpeg", "png"];
+      const pdfTypes = ["pdf"];
+      const officeTypes = ["doc", "docx"];
+      if (imageTypes.includes(extension)) return "image";
+      if (pdfTypes.includes(extension)) return "pdf";
+      if (officeTypes.includes(extension)) return "office";
+      return "other";
+    },
+
+    getFileExtension(filename) {
+      return filename
+        .split(".")
+        .pop()
+        .toLowerCase();
+    },
+
+    formatFileSize(size) {
+      if (!size) return "0 B";
+      const k = 1024;
+      const sizes = ["B", "KB", "MB", "GB"];
+      const i = Math.floor(Math.log(size) / Math.log(k));
+      return parseFloat((size / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
+    },
+
+    formatDateTime(dateTime) {
+      if (!dateTime) return "";
+      try {
+        const date = new Date(dateTime);
+        if (isNaN(date.getTime())) return dateTime;
+        const year = date.getFullYear();
+        const month = String(date.getMonth() + 1).padStart(2, "0");
+        const day = String(date.getDate()).padStart(2, "0");
+        const hours = String(date.getHours()).padStart(2, "0");
+        const minutes = String(date.getMinutes()).padStart(2, "0");
+        return `${year}-${month}-${day} ${hours}:${minutes}`;
+      } catch (error) {
+        return dateTime;
+      }
+    },
+
+    getCurrentTime() {
+      const now = new Date();
+      return `${now.getFullYear()}-${(now.getMonth() + 1)
+        .toString()
+        .padStart(2, "0")}-${now
+        .getDate()
+        .toString()
+        .padStart(2, "0")} ${now
+        .getHours()
+        .toString()
+        .padStart(2, "0")}:${now
+        .getMinutes()
+        .toString()
+        .padStart(2, "0")}:${now
+        .getSeconds()
+        .toString()
+        .padStart(2, "0")}`;
+    },
+
+    // 淇濆瓨鐧昏闃舵闄勪欢鍒颁翰灞炵‘璁よ〃 assessannex
+    async saveAssessannex() {
+      const infoid = this.formData.id;
+      if (!infoid) return;
+      const assessannex = this.serializeAssessannex();
+      try {
+        if (this.confirmationRecord && this.confirmationRecord.id) {
+          // 宸插瓨鍦ㄧ‘璁よ〃璁板綍锛氫粎鏇存柊闄勪欢瀛楁锛屼繚鐣欏叾浣欎俊鎭�
+          await relativesEdit({ ...this.confirmationRecord, assessannex });
+        } else {
+          // 纭琛ㄨ褰曚笉瀛樺湪锛氭柊澧炲畬鏁磋褰曪紙鎼哄甫鐧昏琛ㄥ熀纭�淇℃伅锛�
+          await relativesAdd(this.buildConfirmationRecord(infoid, assessannex));
+        }
+      } catch (e) {
+        console.warn("淇濆瓨鐧昏闃舵闄勪欢澶辫触:", e);
+        this.$message.warning("鐧昏闃舵闄勪欢淇濆瓨澶辫触锛岃閲嶈瘯");
+      }
+    },
+
+    // 鏋勫缓鏂板浜插睘纭琛ㄨ褰曪細鎼哄甫鎹愮尞鑰呭熀纭�淇℃伅锛岃�岄潪浠� infoid + assessannex
+    buildConfirmationRecord(infoid, assessannex) {
+      const f = this.formData;
+      return {
+        infoid,
+        caseNo: f.caseNo || "",
+        name: f.name || "",
+        sex: f.sex || "",
+        age: f.age != null ? f.age : "",
+        diagnosisname: f.diagnosisname || "",
+        treatmenthospitalname: f.treatmenthospitalname || "",
+        relativeconfirmationsign: "0",
+        state: 2,
+        assessannex
+      };
+    },
+
     handleClose() {
       console.log("鍏抽棴寮规");
       this.isEdit = false;
@@ -1269,6 +1651,7 @@
       this.formData = this.getDefaultFormData();
       this.residenceAddress = {};
       this.registerAddress = {};
+      this.resetAttachments();
       this.$emit("closed");
     },
 
@@ -1297,6 +1680,7 @@
 
         const result = await updateDonatebaseinfo(submitData);
         if (result.code === 200) {
+          await this.saveAssessannex();
           this.$message.success(this.isEdit ? "鏇存柊鎴愬姛" : "鏂板鎴愬姛");
           this.$emit("success", result.data);
           console.log(1122);
@@ -1366,79 +1750,6 @@
 
       return data;
     },
-    /** 鍔犺浇涓婃姤妗堜緥闄勪欢 */
-    async loadReportAttachments(reportId) {
-      this.reportAttachmentLoading = true;
-      try {
-        const res = await donateInfo(reportId);
-        const data = res.data || res;
-        this.reportAttachments = (data.annexfilesList || []).map(item => ({
-          ...item,
-          fileType: item.fileType || item.filetype || "" // 鍏煎瀛楁澶у皬鍐�
-        }));
-      } catch (error) {
-        console.error("鍔犺浇涓婃姤闄勪欢澶辫触:", error);
-        this.$message.error("鍔犺浇涓婃姤闄勪欢澶辫触");
-      } finally {
-        this.reportAttachmentLoading = false;
-      }
-    },
-
-    /** 鑾峰彇鏌愬垎绫绘枃浠舵暟閲� */
-    getReportCategoryCount(category) {
-      return this.reportAttachments.filter(item => {
-        const type = item.fileType || "";
-        if (category === "鏈垎绫�") {
-          return !this.presetCategories.includes(type);
-        }
-        return type === category;
-      }).length;
-    },
-
-    /** 鑾峰彇鏌愬垎绫绘枃浠跺垪琛� */
-    getReportCategoryFiles(category) {
-      return this.reportAttachments.filter(item => {
-        const type = item.fileType || "";
-        if (category === "鏈垎绫�") {
-          return !this.presetCategories.includes(type);
-        }
-        return type === category;
-      });
-    },
-
-    /** 棰勮涓婃姤闄勪欢锛堢洿鎺ュ湪鏂扮獥鍙f墦寮�锛� */
-    handleReportPreview(file) {
-      const url = file.fileUrl || file.path;
-      if (url) {
-        window.open(url, "_blank");
-      } else {
-        this.$message.warning("鏂囦欢鍦板潃涓嶅瓨鍦�");
-      }
-    },
-
-    /** 鑾峰彇鏂囦欢绫诲瀷锛堢敤浜庢爣绛炬樉绀猴級 */
-    getFileType(fileName) {
-      if (!fileName) return "other";
-      const extension = fileName
-        .split(".")
-        .pop()
-        .toLowerCase();
-      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
-      const pdfTypes = ["pdf"];
-      const officeTypes = ["doc", "docx", "xls", "xlsx"];
-      if (imageTypes.includes(extension)) return "image";
-      if (pdfTypes.includes(extension)) return "pdf";
-      if (officeTypes.includes(extension)) return "office";
-      return "other";
-    },
-
-    /** 鏃ユ湡鏃堕棿鏍煎紡鍖栵紙澶嶇敤锛� */
-    formatDateTime(dateTime) {
-      if (!dateTime) return "";
-      return this.$moment
-        ? this.$moment(dateTime).format("YYYY-MM-DD HH:mm:ss")
-        : dateTime;
-    }
   }
 };
 </script>
@@ -1451,4 +1762,21 @@
 .form-section:last-child {
   margin-bottom: 0;
 }
+
+.attachment-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.upload-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: #303133;
+}
+
+.empty-attachment {
+  padding: 12px 0;
+}
 </style>

--
Gitblit v1.9.3