From dc082351978a1e9f75d7a1471a0ca7ebeac552a5 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期一, 01 六月 2026 11:07:50 +0800
Subject: [PATCH] opo维护

---
 src/views/business/maintain/maintainInfo.vue |  862 ++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 572 insertions(+), 290 deletions(-)

diff --git a/src/views/business/maintain/maintainInfo.vue b/src/views/business/maintain/maintainInfo.vue
index d6aa6ec..ec052b2 100644
--- a/src/views/business/maintain/maintainInfo.vue
+++ b/src/views/business/maintain/maintainInfo.vue
@@ -1,180 +1,25 @@
 <template>
   <div class="maintenance-detail">
-    <!-- 鍩虹淇℃伅 -->
-    <el-card class="detail-card">
-      <div slot="header" class="clearfix">
-        <span class="detail-title">渚涜�呭熀鏈俊鎭�</span>
-        <el-button type="success" style="float: right;" @click="handleSave">
-          淇濆瓨淇℃伅
-        </el-button>
-      </div>
-
-      <el-form :model="form" ref="form" label-width="120px">
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="浣忛櫌鍙�" prop="caseNo">
-              <el-input v-model="form.caseNo" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鎹愮尞鑰呭鍚�" prop="name">
-              <el-input v-model="form.name" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鎬у埆" prop="gender">
-              <el-select v-model="form.sex" style="width: 100%">
-                <el-option label="鐢�" value="0" />
-                <el-option label="濂�" value="1" />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="骞撮緞" prop="age">
-              <el-input v-model="form.age" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鐤剧梾璇婃柇" prop="diagnosisname">
-              <el-input v-model="form.diagnosisname" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="棣栬瘖鍖荤枟鏈烘瀯" prop="treatmenthospitalname">
-              <el-input v-model="form.treatmenthospitalname" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="鎮h�呯姸鎬�" prop="recordstate">
-              <el-select v-model="form.recordstate" style="width: 100%">
-                <!-- <el-option label="DCD" value="1" />
-                <el-option label="DBD" value="2" />
-                <el-option label="DBCD" value="3" />
-                <el-option label="宸插畬鎴愭崘鐚�" value="4" />
-                <el-option label="鏈畬鎴愭崘鐚�" value="5" /> -->
-                <el-option
-                  v-for="dict in dict.type.sys_DonationCategory || []"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-            <!-- <el-form-item
-              align="left"
-              label="鎮h�呮崘鐚姸鎬�"
-              prop="donationcategory"
-            >
-              <el-radio-group v-model="form.recordstate">
-                <el-radio
-                  v-for="dict in dict.type.sys_DonationCategory || []"
-                  :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
-              label="鏈畬鎴愬師鍥�"
-              prop="incompleteReason"
-              v-if="form.recordstate === '5'"
-            >
-              <el-input
-                v-model="form.incompleteReason"
-                placeholder="璇疯緭鍏ユ湭瀹屾垚鎹愮尞鐨勫師鍥�"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="涓婃姤鏃堕棿" prop="reporttime">
-              <el-date-picker
-                v-model="form.reporttime"
-                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="deathTime">
-              <el-date-picker
-                v-model="form.deathTime"
-                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="coordinatorName">
-              <el-input v-model="form.coordinatorName" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="琛�鍨�" prop="bloodtype">
-              <el-select v-model="form.bloodtype" style="width: 100%">
-                <!-- <el-option label="A鍨�" value="A" />
-                <el-option label="B鍨�" value="B" />
-                <el-option label="O鍨�" value="O" />
-                <el-option label="AB鍨�" value="AB" /> -->
-                <el-option
-                  v-for="dict in dict.type.sys_BloodType"
-                  :key="dict.value"
-                  :label="dict.label"
-                  :value="dict.value"
-                ></el-option>
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="Rh(D)" prop="rhYin">
-              <el-radio-group v-model="form.rhYin">
-                <el-radio
-                  v-for="dict in dict.type.sys_bloodtype_rhd || []"
-                  :key="dict.value"
-                  :label="dict.value"
-                  >{{ dict.label }}</el-radio
-                >
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-form-item label="鐗规畩鐥呭彶" prop="specialMedicalHistory">
-          <el-input
-            type="textarea"
-            :rows="3"
-            v-model="form.specialMedicalHistory"
-            placeholder="璁板綍鐗规畩鐥呭彶淇℃伅"
-          />
-        </el-form-item>
-      </el-form>
-    </el-card>
+    <case-basic-info :case-id="caseId" :show-attachment="true" />
 
     <el-card class="assessment-card">
       <div slot="header" class="clearfix">
-        <span class="detail-title">渚涜�呰瘎浼板悇椤硅褰�</span>
+        <span class="detail-title">璇勪及鍚勯」璁板綍</span>
         <el-button
           type="primary"
           size="mini"
           @click="toggleEditMode"
-          style="float: right;"
+          style="float: right;margin-left: 20px;"
         >
-          {{ isEdit ? "瀹屾垚缂栬緫" : "寮�濮嬬紪杈�" }}
+          淇濆瓨缂栬緫
+        </el-button>
+        <el-button
+          type="success"
+          size="mini"
+          @click="accomplish"
+          style="float: right;margin-left: 20px;"
+        >
+          瀹屾垚缂栬緫
         </el-button>
       </div>
 
@@ -210,8 +55,17 @@
                   <el-tag
                     :type="scope.row.result === '闃存��' ? 'success' : 'danger'"
                     effect="plain"
+                    @click="handleResultClick(scope.row)"
+                    style="cursor: pointer;"
                   >
                     {{ scope.row.result }}
+                    <i
+                      v-if="
+                        scope.row.result === '闃虫��' && scope.row.positiveDetails
+                      "
+                      class="el-icon-info"
+                      style="margin-left: 4px;"
+                    ></i>
                   </el-tag>
                 </template>
               </el-table-column>
@@ -257,6 +111,82 @@
             </el-table>
           </el-card>
         </el-tab-pane>
+        <el-tab-pane label="鎶ょ悊鏍告煡璁板綍" name="hlihc">
+          <el-card class="record-card">
+            <div slot="header" class="clearfix">
+              <span class="detail-title">鎶ょ悊鏍告煡璁板綍</span>
+              <el-button
+                type="primary"
+                size="mini"
+                icon="el-icon-plus"
+                @click="handleAddRecord"
+              >
+                鏂板鏍告煡璁板綍
+              </el-button>
+            </div>
+
+            <el-table :data="recordList" v-loading="recordLoading">
+              <el-table-column
+                label="鏍告煡鏃堕棿"
+                align="center"
+                prop="recordTime"
+                width="160"
+              />
+              <el-table-column
+                label="鏍告煡浜�"
+                align="center"
+                prop="recorder"
+                width="100"
+              />
+              <el-table-column
+                label="鏍告煡璁板綍"
+                align="center"
+                prop="checkRecord"
+                min-width="200"
+                show-overflow-tooltip
+              />
+              <el-table-column label="闄勪欢" align="center" width="120">
+                <template slot-scope="scope">
+                  <el-button
+                    v-if="
+                      scope.row.attachments && scope.row.attachments.length > 0
+                    "
+                    size="mini"
+                    type="text"
+                    @click="handleViewRecordAttachments(scope.row)"
+                  >
+                    鏌ョ湅闄勪欢({{ scope.row.attachments.length }})
+                  </el-button>
+                  <span v-else>鏃犻檮浠�</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="鎿嶄綔"
+                align="center"
+                width="180"
+                class-name="small-padding fixed-width"
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    size="mini"
+                    type="text"
+                    icon="el-icon-edit"
+                    @click="handleEditRecord(scope.row)"
+                    >缂栬緫</el-button
+                  >
+                  <el-button
+                    size="mini"
+                    type="text"
+                    icon="el-icon-delete"
+                    style="color: #F56C6C;"
+                    @click="handleDeleteRecord(scope.row)"
+                    >鍒犻櫎</el-button
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-card>
+        </el-tab-pane>
 
         <!-- 鑲濆姛鑳借偩鍔熻兘 -->
         <el-tab-pane label="鑲濆姛鑳借偩鍔熻兘" name="liverKidney">
@@ -291,78 +221,6 @@
     </el-card>
 
     <!-- 鎶ょ悊鏍告煡璁板綍 -->
-    <el-card class="record-card">
-      <div slot="header" class="clearfix">
-        <span class="detail-title">鎶ょ悊鏍告煡璁板綍</span>
-        <el-button
-          type="primary"
-          size="mini"
-          icon="el-icon-plus"
-          @click="handleAddRecord"
-        >
-          鏂板鏍告煡璁板綍
-        </el-button>
-      </div>
-
-      <el-table :data="recordList" v-loading="recordLoading">
-        <el-table-column
-          label="鏍告煡鏃堕棿"
-          align="center"
-          prop="recordTime"
-          width="160"
-        />
-        <el-table-column
-          label="鏍告煡浜�"
-          align="center"
-          prop="recorder"
-          width="100"
-        />
-        <el-table-column
-          label="鏍告煡璁板綍"
-          align="center"
-          prop="checkRecord"
-          min-width="200"
-          show-overflow-tooltip
-        />
-        <el-table-column label="闄勪欢" align="center" width="120">
-          <template slot-scope="scope">
-            <el-button
-              v-if="scope.row.attachments && scope.row.attachments.length > 0"
-              size="mini"
-              type="text"
-              @click="handleViewRecordAttachments(scope.row)"
-            >
-              鏌ョ湅闄勪欢({{ scope.row.attachments.length }})
-            </el-button>
-            <span v-else>鏃犻檮浠�</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          label="鎿嶄綔"
-          align="center"
-          width="180"
-          class-name="small-padding fixed-width"
-        >
-          <template slot-scope="scope">
-            <el-button
-              size="mini"
-              type="text"
-              icon="el-icon-edit"
-              @click="handleEditRecord(scope.row)"
-              >缂栬緫</el-button
-            >
-            <el-button
-              size="mini"
-              type="text"
-              icon="el-icon-delete"
-              style="color: #F56C6C;"
-              @click="handleDeleteRecord(scope.row)"
-              >鍒犻櫎</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
-    </el-card>
 
     <!-- 鍩瑰吇璁板綍缂栬緫瀵硅瘽妗� -->
     <el-dialog
@@ -414,6 +272,7 @@
                 v-model="cultureForm.result"
                 placeholder="璇烽�夋嫨鍩瑰吇缁撴灉"
                 style="width: 100%"
+                @change="handleResultChange"
               >
                 <el-option label="闃存��" value="闃存��" />
                 <el-option label="闃虫��" value="闃虫��" />
@@ -421,11 +280,30 @@
             </el-form-item>
           </el-col>
         </el-row>
-
+        <el-form-item
+          v-if="cultureForm.result === '闃虫��'"
+          label="闃虫�ц鎯�"
+          prop="positiveDetails"
+        >
+          <el-input
+            type="textarea"
+            :rows="2"
+            v-model="cultureForm.positiveDetails"
+            placeholder="璇疯緭鍏ラ槼鎬х粨鏋滅殑璇︾粏淇℃伅"
+            clearable
+          />
+        </el-form-item>
         <el-form-item label="闄勪欢">
-          <upload-attachment
-            :file-list="cultureForm.attachments"
+          <UploadAttachment
+            ref="cultureUploadAttachment"
+            :file-list="cultureFileList"
+            :limit="10"
+            :accept="attachmentAccept"
+            :multiple="true"
             @change="handleCultureAttachmentChange"
+            @upload-success="handleCultureUploadSuccess"
+            @upload-error="handleCultureUploadError"
+            @remove="handleCultureAttachmentRemove"
           />
         </el-form-item>
       </el-form>
@@ -486,9 +364,16 @@
         </el-form-item>
 
         <el-form-item label="闄勪欢">
-          <upload-attachment
-            :file-list="recordForm.attachments"
+          <UploadAttachment
+            ref="recordUploadAttachment"
+            :file-list="recordFileList"
+            :limit="10"
+            :accept="attachmentAccept"
+            :multiple="true"
             @change="handleRecordAttachmentChange"
+            @upload-success="handleRecordUploadSuccess"
+            @upload-error="handleRecordUploadError"
+            @remove="handleRecordAttachmentRemove"
           />
         </el-form-item>
       </el-form>
@@ -505,11 +390,67 @@
     </el-dialog>
 
     <!-- 闄勪欢棰勮瀵硅瘽妗� -->
-    <attachment-preview
-      :visible="attachmentPreviewVisible"
-      :file-list="currentAttachmentList"
+    <el-dialog
       :title="attachmentPreviewTitle"
-      @close="attachmentPreviewVisible = false"
+      :visible.sync="attachmentPreviewVisible"
+      width="900px"
+      @close="handleAttachmentPreviewClose"
+    >
+      <el-table :data="currentAttachmentList" 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="150" fixed="right">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="primary"
+              @click="handlePreviewAttachment(scope.row)"
+              :disabled="!isPreviewable(scope.row.fileName)"
+            >
+              棰勮
+            </el-button>
+            <el-button
+              size="mini"
+              type="success"
+              @click="handleDownloadAttachment(scope.row)"
+            >
+              涓嬭浇
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+
+    <!-- 鏂囦欢棰勮寮圭獥 -->
+    <FilePreviewDialog
+      :visible="filePreviewVisible"
+      :file="currentPreviewFile"
+      @close="filePreviewVisible = false"
+      @download="handleDownloadAttachment"
     />
   </div>
 </template>
@@ -518,20 +459,24 @@
 import { maintainList, maintainedit, maintainAdd } from "@/api/businessApi";
 import Pagination from "@/components/Pagination";
 import UploadAttachment from "@/components/UploadAttachment";
-import AttachmentPreview from "@/components/AttachmentPreview";
-import LiverKidneyPanel from "./components/LiverKidneyPanel.vue";
-import BloodRoutinePanel from "./components/BloodRoutinePanel.vue";
-import UrineRoutinePanel from "./components/UrineRoutinePanel.vue";
+import FilePreviewDialog from "@/components/FilePreviewDialog";
+import LiverKidneyPanel from "@/components/MaintainComponents/LiverKidneyPanel.vue";
+import BloodRoutinePanel from "@/components/MaintainComponents/BloodRoutinePanel.vue";
+import UrineRoutinePanel from "@/components/MaintainComponents/UrineRoutinePanel.vue";
+import CaseBasicInfo from "@/components/CaseBasicInfo";
+import store from "@/store";
+import dayjs from "dayjs";
 
 export default {
   name: "MaintenanceDetail",
   components: {
     Pagination,
     UploadAttachment,
-    AttachmentPreview,
+    FilePreviewDialog,
     LiverKidneyPanel,
     BloodRoutinePanel,
-    UrineRoutinePanel
+    UrineRoutinePanel,
+    CaseBasicInfo
   },
   dicts: [
     "sys_donornode",
@@ -544,7 +489,8 @@
 
   data() {
     return {
-      isEdit: false,
+      caseId: null,
+      isEdit: true,
       currentMaintenanceId: null,
       isEditMode: false,
       form: {
@@ -565,9 +511,8 @@
         incompleteReason: ""
       },
       activeTab: "culture",
-      liverKidneyData: {}, // 浠� maintainList 鎺ュ彛鑾峰彇鐨勬暟鎹�
-      bloodRoutineData: {}, // 浠� maintainList 鎺ュ彛鑾峰彇鐨勬暟鎹�
-      liverKidneyData: {}, // 浠� maintainList 鎺ュ彛鑾峰彇鐨勬暟鎹�
+      extracontentinfo: {},
+
       // 鍩瑰吇缁撴灉鐩稿叧鏁版嵁
       cultureList: [],
       cultureLoading: false,
@@ -579,8 +524,10 @@
         cultureType: "",
         sampleTime: "",
         result: "闃存��",
+        positiveDetails: "", // 鏂板锛氶槼鎬ц鎯�
         attachments: []
       },
+      cultureFileList: [],
       cultureRules: {
         cultureType: [
           { required: true, message: "璇烽�夋嫨鍩瑰吇绫诲瀷", trigger: "change" }
@@ -590,7 +537,8 @@
         ],
         result: [
           { required: true, message: "璇烽�夋嫨鍩瑰吇缁撴灉", trigger: "change" }
-        ]
+        ],
+        positiveDetails: [] // 鍔ㄦ�侀獙璇佽鍒�
       },
       cultureTypeOptions: [
         { value: "1", label: "琛�鍩瑰吇" },
@@ -614,6 +562,7 @@
         checkRecord: "",
         attachments: []
       },
+      recordFileList: [],
       recordRules: {
         recordTime: [
           { required: true, message: "璇烽�夋嫨鏍告煡鏃堕棿", trigger: "change" }
@@ -631,6 +580,15 @@
       currentAttachmentList: [],
       attachmentPreviewTitle: "",
 
+      // 鏂囦欢棰勮鐩稿叧
+      filePreviewVisible: false,
+      currentPreviewFile: null,
+
+      // 闄勪欢鐩稿叧閰嶇疆
+      attachmentLimit: 10,
+      attachmentAccept:
+        ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
+
       // 璇勪及鏁版嵁瀛樺偍
       assessmentData: {
         liverKidney: {},
@@ -642,6 +600,8 @@
     };
   },
   created() {
+    this.caseId = this.$route.query.infoid;
+
     this.loadMaintenanceData();
   },
   watch: {
@@ -650,7 +610,7 @@
     }
   },
   methods: {
-    // 鍔犺浇缁存姢鏁版嵁[1,3](@ref)
+    // 鍔犺浇缁存姢鏁版嵁
     async loadMaintenanceData() {
       try {
         this.cultureLoading = true;
@@ -660,7 +620,7 @@
         const queryParams = {};
 
         if (id) {
-          queryParams.id = id;
+          queryParams.infoid = infoid;
           this.currentMaintenanceId = id;
           this.isEditMode = true;
         } else if (infoid) {
@@ -672,22 +632,26 @@
           return;
         }
 
+        queryParams.infoid = infoid;
         const response = await maintainList(queryParams);
         if (response.code === 200) {
           let maintenanceData = response.data[0];
 
-          // 澶勭悊鏁扮粍鍝嶅簲
           if (Array.isArray(maintenanceData)) {
             maintenanceData = maintenanceData[0] || {};
           }
+          if (maintenanceData.extracontent) {
+            this.extracontentinfo = JSON.parse(maintenanceData.extracontent);
+            if (this.extracontentinfo.specialMedicalHistory) {
+              this.form.specialMedicalHistory = this.extracontentinfo.specialMedicalHistory;
+            }
+          }
 
-          // 瑙f瀽itemDesc瀛楁涓殑JSON鏁版嵁[6,8](@ref)
           if (maintenanceData.itemDesc) {
             try {
-              const itemDescData = JSON.parse(maintenanceData.itemDesc);
+              const itemDescData = maintenanceData.itemDesc;
               this.assessmentData = { ...this.assessmentData, ...itemDescData };
 
-              // 濉厖鍚勪釜妯″潡鐨勬暟鎹�
               if (itemDescData.cultureResults) {
                 this.cultureList = itemDescData.cultureResults;
               }
@@ -708,7 +672,6 @@
             }
           }
 
-          // 濉厖鍩虹琛ㄥ崟鏁版嵁
           this.form = { ...this.form, ...maintenanceData };
           this.$message.success("鏁版嵁鍔犺浇鎴愬姛");
         } else {
@@ -722,37 +685,81 @@
         this.recordLoading = false;
       }
     },
+    // 澶勭悊鍩瑰吇缁撴灉閫夋嫨鍙樺寲
+    handleResultChange(value) {
+      this.$nextTick(() => {
+        if (value === "闃虫��") {
+          this.cultureRules.positiveDetails = [
+            { required: true, message: "璇疯緭鍏ラ槼鎬ц鎯�", trigger: "blur" }
+          ];
+        } else {
+          this.cultureRules.positiveDetails = [];
+          this.cultureForm.positiveDetails = "";
+        }
+        // 娓呴櫎楠岃瘉
+        if (this.$refs.cultureForm) {
+          this.$refs.cultureForm.clearValidate("positiveDetails");
+        }
+      });
+    },
 
-    // 淇濆瓨鎵�鏈夋暟鎹甗1,2](@ref)
+    // 澶勭悊鐐瑰嚮鍩瑰吇缁撴灉鏍囩
+    handleResultClick(row) {
+      if (row.result === "闃虫��" && row.positiveDetails) {
+        this.$alert(
+          `<div style="padding: 10px;">
+        <h4 style="margin-bottom: 10px; color: #f56c6c;">闃虫�ц鎯咃細</h4>
+        <div style="background: #fef0f0; padding: 15px; border-radius: 4px; border-left: 4px solid #f56c6c;">
+          <p style="margin: 0; white-space: pre-wrap; line-height: 1.5;">${row.positiveDetails}</p>
+        </div>
+      </div>`,
+          "闃虫�х粨鏋滆鎯�",
+          {
+            dangerouslyUseHTMLString: true,
+            confirmButtonText: "鍏抽棴",
+            customClass: "result-details-dialog",
+            showClose: false
+          }
+        );
+      } else if (row.result === "闃虫��") {
+        this.$message.warning("璇ラ槼鎬ц褰曟殏鏃犺鎯呬俊鎭�");
+      }
+    },
+    // 淇濆瓨鎵�鏈夋暟鎹�
     async handleSave() {
       try {
-        // 鏋勫缓淇濆瓨鏁版嵁
         const saveData = {
           ...this.form,
-          itemDesc: JSON.stringify({
+          itemDesc: {
             liverKidney: this.assessmentData.liverKidney,
             bloodRoutine: this.assessmentData.bloodRoutine,
             urineRoutine: this.assessmentData.urineRoutine,
             cultureResults: this.cultureList,
             nursingRecords: this.recordList
-          })
+          }
         };
-
+        if (saveData.state == 1 || !saveData.state) {
+          saveData.state = 2;
+        }
+        this.extracontentinfo.specialMedicalHistory = this.form.specialMedicalHistory;
         let response;
         if (this.isEditMode && this.currentMaintenanceId) {
-          // 缂栬緫妯″紡锛岃皟鐢╩aintainedit鎺ュ彛[1](@ref)
           saveData.id = this.currentMaintenanceId;
           response = await maintainedit(saveData);
         } else {
-          // 鏂板妯″紡锛岃皟鐢╩aintainAdd鎺ュ彛[2](@ref)
           response = await maintainAdd(saveData);
         }
 
         if (response.code === 200) {
           this.$message.success("淇濆瓨鎴愬姛");
           this.isEdit = false;
-
-          // 濡傛灉鏄柊澧炰繚瀛橈紝鏇存柊褰撳墠ID
+          if (!this.currentMaintenanceId) {
+            this.currentMaintenanceId = response.data;
+          }
+          // this.donatebaseinfoEdit({
+          //   id: this.$route.query.infoid,
+          //   extracontent: JSON.stringify(this.extracontentinfo)
+          // });
           if (!this.isEditMode && response.data && response.data.id) {
             this.currentMaintenanceId = response.data.id;
             this.isEditMode = true;
@@ -773,7 +780,19 @@
         this.handleSave();
       }
     },
+    accomplish() {
+      this.$confirm("鏄惁瀹屾垚璇ユ渚嬫崘鐚‘璁ゆ楠わ紵", "鎻愰啋", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.form.state = 3;
+          this.handleSave();
+        })
 
+        .catch(() => {});
+    },
     // 鍩瑰吇璁板綍鐩稿叧鏂规硶
     handleAddCulture() {
       this.cultureDialogTitle = "鏂板鍩瑰吇璁板綍";
@@ -784,41 +803,71 @@
         result: "闃存��",
         attachments: []
       };
+      this.cultureFileList = [];
       this.cultureDialogVisible = true;
       this.$nextTick(() => {
         this.$refs.cultureForm && this.$refs.cultureForm.clearValidate();
       });
     },
 
+    // 5. 淇敼缂栬緫鍩瑰吇璁板綍鏂规硶
     handleEditCulture(row) {
       this.cultureDialogTitle = "缂栬緫鍩瑰吇璁板綍";
-      this.cultureForm = { ...row };
+      this.cultureForm = {
+        ...row,
+        positiveDetails: row.positiveDetails || "" // 纭繚鏈塸ositiveDetails瀛楁
+      };
+      this.cultureFileList = row.attachments
+        ? row.attachments.map(item => ({
+            uid: item.id || Math.random(),
+            name: item.fileName,
+            fileSize: item.fileSize,
+            url: item.path || item.fileUrl,
+            uploadTime: item.uploadTime,
+            status: "success"
+          }))
+        : [];
       this.cultureDialogVisible = true;
       this.$nextTick(() => {
         this.$refs.cultureForm && this.$refs.cultureForm.clearValidate();
+        // 濡傛灉缂栬緫鏃舵槸闃虫�х粨鏋滐紝璁剧疆楠岃瘉瑙勫垯
+        if (row.result === "闃虫��") {
+          this.cultureRules.positiveDetails = [
+            { required: true, message: "璇疯緭鍏ラ槼鎬ц鎯�", trigger: "blur" }
+          ];
+        }
       });
     },
 
+    // 6. 淇敼淇濆瓨鍩瑰吇璁板綍鏂规硶
     handleSaveCulture() {
       this.$refs.cultureForm.validate(valid => {
         if (valid) {
           this.cultureSaveLoading = true;
 
-          if (this.cultureForm.id) {
-            // 缂栬緫鐜版湁璁板綍
+          // 鏋勫缓淇濆瓨鏁版嵁
+          const saveData = {
+            ...this.cultureForm,
+            // 濡傛灉鏄槾鎬э紝娓呯┖闃虫�ц鎯�
+            positiveDetails:
+              this.cultureForm.result === "闃虫��"
+                ? this.cultureForm.positiveDetails || ""
+                : ""
+          };
+
+          if (saveData.id) {
             const index = this.cultureList.findIndex(
-              item => item.id === this.cultureForm.id
+              item => item.id === saveData.id
             );
             if (index !== -1) {
-              this.cultureList.splice(index, 1, { ...this.cultureForm });
+              this.cultureList.splice(index, 1, { ...saveData });
             }
           } else {
-            // 鏂板璁板綍
-            this.cultureForm.id = Date.now();
-            this.cultureList.push({ ...this.cultureForm });
+            saveData.id = Date.now();
+            this.cultureList.push({ ...saveData });
           }
 
-          this.$message.success(this.cultureForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+          this.$message.success(saveData.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
           this.cultureDialogVisible = false;
           this.cultureSaveLoading = false;
         }
@@ -849,10 +898,11 @@
           .toISOString()
           .replace("T", " ")
           .substring(0, 19),
-        recorder: "褰撳墠鐢ㄦ埛",
+        recorder: store.getters.name,
         checkRecord: "",
         attachments: []
       };
+      this.recordFileList = [];
       this.recordDialogVisible = true;
       this.$nextTick(() => {
         this.$refs.recordForm && this.$refs.recordForm.clearValidate();
@@ -862,6 +912,16 @@
     handleEditRecord(row) {
       this.recordDialogTitle = "缂栬緫鎶ょ悊鏍告煡璁板綍";
       this.recordForm = { ...row };
+      this.recordFileList = row.attachments
+        ? row.attachments.map(item => ({
+            uid: item.id || Math.random(),
+            name: item.fileName,
+            fileSize: item.fileSize,
+            url: item.path || item.fileUrl,
+            uploadTime: item.uploadTime,
+            status: "success"
+          }))
+        : [];
       this.recordDialogVisible = true;
       this.$nextTick(() => {
         this.$refs.recordForm && this.$refs.recordForm.clearValidate();
@@ -874,7 +934,6 @@
           this.recordSaveLoading = true;
 
           if (this.recordForm.id) {
-            // 缂栬緫鐜版湁璁板綍
             const index = this.recordList.findIndex(
               item => item.id === this.recordForm.id
             );
@@ -882,7 +941,6 @@
               this.recordList.splice(index, 1, { ...this.recordForm });
             }
           } else {
-            // 鏂板璁板綍
             this.recordForm.id = Date.now();
             this.recordList.push({ ...this.recordForm });
           }
@@ -907,13 +965,90 @@
         .catch(() => {});
     },
 
-    // 闄勪欢鐩稿叧鏂规硶
+    // 鍩瑰吇璁板綍闄勪欢鐩稿叧鏂规硶
     handleCultureAttachmentChange(fileList) {
-      this.cultureForm.attachments = fileList;
+      this.cultureFileList = fileList;
     },
 
+    handleCultureUploadSuccess({ 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.cultureForm.attachments)) {
+          this.cultureForm.attachments = [];
+        }
+
+        this.cultureForm.attachments.push(attachmentObj);
+        this.cultureFileList = fileList;
+        this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+      }
+    },
+
+    handleCultureUploadError({ file, fileList, error }) {
+      console.error("鍩瑰吇璁板綍闄勪欢涓婁紶澶辫触:", error);
+      this.$message.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+    },
+
+    handleCultureAttachmentRemove(file) {
+      if (file.url) {
+        const index = this.cultureForm.attachments.findIndex(
+          item => item.path === file.url || item.fileUrl === file.url
+        );
+        if (index > -1) {
+          this.cultureForm.attachments.splice(index, 1);
+          this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+        }
+      }
+    },
+
+    // 鎶ょ悊璁板綍闄勪欢鐩稿叧鏂规硶
     handleRecordAttachmentChange(fileList) {
-      this.recordForm.attachments = fileList;
+      this.recordFileList = fileList;
+    },
+
+    handleRecordUploadSuccess({ 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.recordForm.attachments)) {
+          this.recordForm.attachments = [];
+        }
+
+        this.recordForm.attachments.push(attachmentObj);
+        this.recordFileList = fileList;
+        this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+      }
+    },
+
+    handleRecordUploadError({ file, fileList, error }) {
+      console.error("鎶ょ悊璁板綍闄勪欢涓婁紶澶辫触:", error);
+      this.$message.error("鏂囦欢涓婁紶澶辫触锛岃閲嶈瘯");
+    },
+
+    handleRecordAttachmentRemove(file) {
+      if (file.url) {
+        const index = this.recordForm.attachments.findIndex(
+          item => item.path === file.url || item.fileUrl === file.url
+        );
+        if (index > -1) {
+          this.recordForm.attachments.splice(index, 1);
+          this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+        }
+      }
     },
 
     handleViewCultureAttachments(row) {
@@ -926,6 +1061,130 @@
       this.currentAttachmentList = row.attachments || [];
       this.attachmentPreviewTitle = `鎶ょ悊鏍告煡璁板綍闄勪欢 - ${row.recorder}`;
       this.attachmentPreviewVisible = true;
+    },
+
+    handleAttachmentPreviewClose() {
+      this.currentAttachmentList = [];
+      this.attachmentPreviewTitle = "";
+    },
+
+    handlePreviewAttachment(file) {
+      this.currentPreviewFile = {
+        fileName: file.fileName,
+        fileUrl: file.path || file.fileUrl,
+        fileType: this.getFileType(file.fileName)
+      };
+      this.filePreviewVisible = true;
+    },
+
+    handleDownloadAttachment(file) {
+      const fileUrl = file.path || 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 = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
+      const pdfTypes = ["pdf"];
+      const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
+      if (imageTypes.includes(extension)) return "image";
+      if (pdfTypes.includes(extension)) return "pdf";
+      if (officeTypes.includes(extension)) return "office";
+      return "other";
+    },
+
+    /** 鑾峰彇鏂囦欢鍥炬爣棰滆壊 */
+    getFileIconColor(fileName) {
+      const type = this.getFileType(fileName);
+      const colorMap = {
+        image: "#67C23A",
+        pdf: "#F56C6C",
+        office: "#409EFF",
+        other: "#909399"
+      };
+      return colorMap[type] || "#909399";
+    },
+
+    /** 鑾峰彇鏂囦欢鏍囩绫诲瀷 */
+    getFileTagType(fileName) {
+      const type = this.getFileType(fileName);
+      const typeMap = {
+        image: "success",
+        pdf: "danger",
+        office: "primary",
+        other: "info"
+      };
+      return typeMap[type] || "info";
+    },
+
+    /** 鑾峰彇鏂囦欢绫诲瀷鏂囨湰 */
+    getFileTypeText(fileName) {
+      const type = this.getFileType(fileName);
+      const textMap = {
+        image: "鍥剧墖",
+        pdf: "PDF",
+        office: "鏂囨。",
+        other: "鍏朵粬"
+      };
+      return textMap[type] || "鏈煡";
+    },
+
+    /** 妫�鏌ユ槸鍚﹀彲棰勮 */
+    isPreviewable(fileName) {
+      const type = this.getFileType(fileName);
+      return ["image", "pdf"].includes(type);
+    },
+
+    /** 鑾峰彇鏂囦欢鎵╁睍鍚� */
+    getFileExtension(filename) {
+      return filename
+        .split(".")
+        .pop()
+        .toLowerCase();
+    },
+
+    /** 鏍煎紡鍖栨枃浠跺ぇ灏� */
+    formatFileSize(bytes) {
+      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));
+      return parseFloat((bytes / 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;
+      }
     },
 
     // 璇勪及鏁版嵁鍙樻洿澶勭悊
@@ -991,4 +1250,27 @@
 .fixed-width .el-button {
   margin: 0 2px;
 }
+
+.file-name {
+  font-size: 13px;
+  margin-left: 8px;
+}
+/* 7. 娣诲姞涓�浜涙牱寮� */
+.result-details-dialog {
+  width: 500px;
+}
+
+.result-details-dialog .el-message-box__content {
+  padding: 0;
+}
+
+.result-details-dialog .el-message-box__header {
+  background: #fef0f0;
+  border-bottom: 1px solid #fde2e2;
+}
+
+.result-details-dialog .el-message-box__title {
+  color: #f56c6c;
+  font-weight: bold;
+}
 </style>

--
Gitblit v1.9.3