From 5aa165156994b1b8a601063fa0a1107d1893ea57 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期四, 19 三月 2026 16:48:13 +0800
Subject: [PATCH] 更新

---
 src/views/business/course/components/DonorMaintenanceStage.vue | 1317 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 1,192 insertions(+), 125 deletions(-)

diff --git a/src/views/business/course/components/DonorMaintenanceStage.vue b/src/views/business/course/components/DonorMaintenanceStage.vue
index a7e82a9..e07bdc9 100644
--- a/src/views/business/course/components/DonorMaintenanceStage.vue
+++ b/src/views/business/course/components/DonorMaintenanceStage.vue
@@ -1,156 +1,1223 @@
 <template>
-  <base-stage :stage-data="stageData" :case-info="caseInfo">
-    <template #header>
-      <el-alert
-        title="渚涜�呯淮鎶ら樁娈�"
-        type="success"
-        description="渚涜�呬俊鎭淮鎶ゅ凡瀹屾垚锛屾墍鏈夊熀鏈俊鎭凡纭鏃犺"
-        show-icon
-        :closable="false"
-      />
-    </template>
-
-    <el-row :gutter="20" style="margin-top: 20px;">
-      <el-col :span="12">
-        <el-card class="info-card">
-          <div slot="header" class="card-header">
-            <span>渚涜�呭熀鏈俊鎭�</span>
-          </div>
-          <el-descriptions :column="1" border size="small">
-            <el-descriptions-item label="浣忛櫌鍙�">
-              {{ caseInfo.hospitalNo }}
-            </el-descriptions-item>
-            <el-descriptions-item label="鎹愮尞鑰呭鍚�">
-              {{ caseInfo.donorName }}
-            </el-descriptions-item>
-            <el-descriptions-item label="鎬у埆">
-              <dict-tag :options="dict.type.sys_user_sex" :value="parseInt(caseInfo.gender)" />
-            </el-descriptions-item>
-            <el-descriptions-item label="骞撮緞">
-              {{ caseInfo.age }} 宀�
-            </el-descriptions-item>
-            <el-descriptions-item label="鐤剧梾璇婃柇">
-              {{ caseInfo.diagnosis }}
-            </el-descriptions-item>
-          </el-descriptions>
-        </el-card>
-      </el-col>
-
-      <el-col :span="12">
-        <el-card class="timeline-card">
-          <div slot="header" class="card-header">
-            <span>缁存姢鏃堕棿绾�</span>
-          </div>
-          <el-timeline>
-            <el-timeline-item
-              v-for="event in maintenanceEvents"
-              :key="event.time"
-              :timestamp="formatTime(event.time)"
-              :type="event.type"
-            >
-              {{ event.content }}
-            </el-timeline-item>
-          </el-timeline>
-        </el-card>
-      </el-col>
-    </el-row>
-
-    <el-card style="margin-top: 20px;">
-      <div slot="header" class="card-header">
-        <span>缁存姢璁板綍璇︽儏</span>
+  <div class="maintenance-detail">
+    <!-- 鍩虹淇℃伅 -->
+    <el-card class="detail-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">渚涜�呭熀鏈俊鎭�</span>
       </div>
-      <el-table :data="maintenanceRecords" border>
-        <el-table-column label="缁存姢椤圭洰" prop="item" width="150" />
-        <el-table-column label="缁存姢鍐呭" prop="content" min-width="200" />
-        <el-table-column label="缁存姢浜�" prop="operator" width="120" />
-        <el-table-column label="缁存姢鏃堕棿" width="160">
+
+      <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
+                  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-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
+                  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>
+
+    <el-card class="assessment-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">渚涜�呰瘎浼板悇椤硅褰�</span>
+        <el-button
+          type="primary"
+          size="mini"
+          @click="toggleEditMode"
+          style="float: right;"
+        >
+          {{ isEdit ? "瀹屾垚缂栬緫" : "寮�濮嬬紪杈�" }}
+        </el-button>
+      </div>
+
+      <el-tabs v-model="activeTab" type="card" @tab-click="handleTabClick">
+        <!-- 鍩瑰吇缁撴灉璁板綍 -->
+        <el-tab-pane label="鍩瑰吇缁撴灉" name="culture">
+          <el-card class="culture-card">
+            <div slot="header" class="clearfix">
+              <span class="detail-title">鍩瑰吇缁撴灉璁板綍</span>
+              <el-button
+                type="primary"
+                size="mini"
+                icon="el-icon-plus"
+                @click="handleAddCulture"
+              >
+                鏂板鍩瑰吇璁板綍
+              </el-button>
+            </div>
+
+            <el-table :data="cultureList" v-loading="cultureLoading">
+              <el-table-column
+                label="鍩瑰吇绫诲瀷"
+                align="center"
+                prop="cultureType"
+              />
+              <el-table-column
+                label="閲囨牱鏃堕棿"
+                align="center"
+                prop="sampleTime"
+              />
+              <el-table-column label="鍩瑰吇缁撴灉" align="center" prop="result">
+                <template slot-scope="scope">
+                  <el-tag
+                    :type="scope.row.result === '闃存��' ? 'success' : 'danger'"
+                    effect="plain"
+                  >
+                    {{ scope.row.result }}
+                  </el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="闄勪欢" align="center">
+                <template slot-scope="scope">
+                  <el-button
+                    v-if="
+                      scope.row.attachments && scope.row.attachments.length > 0
+                    "
+                    size="mini"
+                    type="text"
+                    @click="handleViewCultureAttachments(scope.row)"
+                  >
+                    鏌ョ湅闄勪欢({{ scope.row.attachments.length }})
+                  </el-button>
+                  <span v-else>鏃犻檮浠�</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="鎿嶄綔"
+                align="center"
+                width="200"
+                class-name="small-padding fixed-width"
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    size="mini"
+                    type="text"
+                    icon="el-icon-edit"
+                    @click="handleEditCulture(scope.row)"
+                    >缂栬緫</el-button
+                  >
+                  <el-button
+                    size="mini"
+                    type="text"
+                    icon="el-icon-delete"
+                    style="color: #F56C6C;"
+                    @click="handleDeleteCulture(scope.row)"
+                    >鍒犻櫎</el-button
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-card>
+        </el-tab-pane>
+
+        <!-- 鑲濆姛鑳借偩鍔熻兘 -->
+        <el-tab-pane label="鑲濆姛鑳借偩鍔熻兘" name="liverKidney">
+          <liver-kidney-panel
+            ref="liverKidney"
+            :initial-data="assessmentData.liverKidney"
+            :is-editing="isEdit && activeTab === 'liverKidney'"
+            @data-change="handleLiverKidneyDataChange"
+          />
+        </el-tab-pane>
+
+        <!-- 琛�甯歌 -->
+        <el-tab-pane label="琛�甯歌" name="bloodRoutine">
+          <blood-routine-panel
+            ref="bloodRoutine"
+            :initial-data="assessmentData.bloodRoutine"
+            :is-editing="isEdit && activeTab === 'bloodRoutine'"
+            @data-change="handleBloodRoutineDataChange"
+          />
+        </el-tab-pane>
+
+        <!-- 灏垮父瑙� -->
+        <el-tab-pane label="灏垮父瑙�" name="urineRoutine">
+          <urine-routine-panel
+            ref="urineRoutine"
+            :initial-data="assessmentData.urineRoutine"
+            :is-editing="isEdit && activeTab === 'urineRoutine'"
+            @data-change="handleUrineRoutineDataChange"
+          />
+        </el-tab-pane>
+      </el-tabs>
+    </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">
-            {{ formatTime(scope.row.time) }}
+            <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="鐘舵��" width="100">
+        <el-table-column
+          label="鎿嶄綔"
+          align="center"
+          width="180"
+          class-name="small-padding fixed-width"
+        >
           <template slot-scope="scope">
-            <el-tag :type="scope.row.status === 'completed' ? 'success' : 'warning'">
-              {{ scope.row.status === 'completed' ? '宸插畬鎴�' : '杩涜涓�' }}
-            </el-tag>
+            <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>
-  </base-stage>
+
+    <!-- 鍩瑰吇璁板綍缂栬緫瀵硅瘽妗� -->
+    <el-dialog
+      :title="cultureDialogTitle"
+      :visible.sync="cultureDialogVisible"
+      width="700px"
+      :close-on-click-modal="false"
+    >
+      <el-form
+        :model="cultureForm"
+        ref="cultureForm"
+        :rules="cultureRules"
+        label-width="120px"
+      >
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍩瑰吇绫诲瀷" prop="cultureType">
+              <el-select
+                v-model="cultureForm.cultureType"
+                placeholder="璇烽�夋嫨鍩瑰吇绫诲瀷"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in cultureTypeOptions"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.label"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閲囨牱鏃堕棿" prop="sampleTime">
+              <el-date-picker
+                v-model="cultureForm.sampleTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                placeholder="閫夋嫨閲囨牱鏃堕棿"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍩瑰吇缁撴灉" prop="result">
+              <el-select
+                v-model="cultureForm.result"
+                placeholder="璇烽�夋嫨鍩瑰吇缁撴灉"
+                style="width: 100%"
+              >
+                <el-option label="闃存��" value="闃存��" />
+                <el-option label="闃虫��" value="闃虫��" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item label="闄勪欢">
+          <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>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="cultureDialogVisible = false">鍙栨秷</el-button>
+        <el-button
+          type="primary"
+          @click="handleSaveCulture"
+          :loading="cultureSaveLoading"
+          >淇濆瓨</el-button
+        >
+      </span>
+    </el-dialog>
+
+    <!-- 鎶ょ悊鏍告煡璁板綍缂栬緫瀵硅瘽妗� -->
+    <el-dialog
+      :title="recordDialogTitle"
+      :visible.sync="recordDialogVisible"
+      width="700px"
+      :close-on-click-modal="false"
+    >
+      <el-form
+        :model="recordForm"
+        ref="recordForm"
+        :rules="recordRules"
+        label-width="120px"
+      >
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鏍告煡鏃堕棿" prop="recordTime">
+              <el-date-picker
+                v-model="recordForm.recordTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                placeholder="閫夋嫨鏍告煡鏃堕棿"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏍告煡浜�" prop="recorder">
+              <el-input
+                v-model="recordForm.recorder"
+                placeholder="璇疯緭鍏ユ牳鏌ヤ汉濮撳悕"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item label="鏍告煡璁板綍" prop="checkRecord">
+          <el-input
+            type="textarea"
+            :rows="4"
+            v-model="recordForm.checkRecord"
+            placeholder="璇疯緭鍏ユ牳鏌ヨ褰曞唴瀹�"
+          />
+        </el-form-item>
+
+        <el-form-item label="闄勪欢">
+          <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>
+
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="recordDialogVisible = false">鍙栨秷</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 闄勪欢棰勮瀵硅瘽妗� -->
+    <el-dialog
+      :title="attachmentPreviewTitle"
+      :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>
 
 <script>
-import BaseStage from './BaseStage.vue';
+import { maintainList, maintainedit, maintainAdd } from "@/api/businessApi";
+import Pagination from "@/components/Pagination";
+import UploadAttachment from "@/components/UploadAttachment";
+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 dayjs from "dayjs";
 
 export default {
-  name: 'DonorMaintenanceStage',
-  components: { BaseStage },
-  dicts: ['sys_user_sex'],
+  name: "MaintenanceDetail",
+  components: {
+    Pagination,
+    UploadAttachment,
+    FilePreviewDialog,
+    LiverKidneyPanel,
+    BloodRoutinePanel,
+    UrineRoutinePanel
+  },
+  dicts: [
+    "sys_donornode",
+    "sys_BloodType",
+    "sys_EthicalReview",
+    "sys_BaseAssessConclusion",
+    "sys_bloodtype_rhd",
+    "sys_DonationCategory"
+  ],
   props: {
-    stageData: {
-      type: Object,
-      default: () => ({})
-    },
-    caseInfo: {
-      type: Object,
-      default: () => ({})
+    infoid: {
+      type: String,
+      default: true
     }
   },
   data() {
     return {
-      maintenanceEvents: [
-        {
-          time: '2023-12-01 08:30:00',
-          content: '渚涜�呭熀鏈俊鎭綍鍏�',
-          type: 'primary'
-        },
-        {
-          time: '2023-12-01 09:15:00',
-          content: '鍖荤枟妗f寤虹珛',
-          type: 'success'
-        },
-        {
-          time: '2023-12-01 10:00:00',
-          content: '鍒濇璇勪及瀹屾垚',
-          type: 'success'
-        }
+      isEdit: false,
+      currentMaintenanceId: null,
+      isEditMode: false,
+      form: {
+        id: undefined,
+        caseNo: "",
+        name: "",
+        gender: "",
+        age: "",
+        diagnosisname: "",
+        treatmenthospitalname: "",
+        recordstate: "1",
+        reporttime: "",
+        deathTime: "",
+        coordinatorName: "",
+        bloodtype: "",
+        rhFactor: "",
+        specialMedicalHistory: "",
+        incompleteReason: ""
+      },
+      activeTab: "culture",
+      extracontentinfo: {},
+
+      // 鍩瑰吇缁撴灉鐩稿叧鏁版嵁
+      cultureList: [],
+      cultureLoading: false,
+      cultureDialogVisible: false,
+      cultureDialogTitle: "",
+      cultureSaveLoading: false,
+      cultureForm: {
+        id: undefined,
+        cultureType: "",
+        sampleTime: "",
+        result: "闃存��",
+        attachments: []
+      },
+      cultureFileList: [],
+      cultureRules: {
+        cultureType: [
+          { required: true, message: "璇烽�夋嫨鍩瑰吇绫诲瀷", trigger: "change" }
+        ],
+        sampleTime: [
+          { required: true, message: "璇烽�夋嫨閲囨牱鏃堕棿", trigger: "change" }
+        ],
+        result: [
+          { required: true, message: "璇烽�夋嫨鍩瑰吇缁撴灉", trigger: "change" }
+        ]
+      },
+      cultureTypeOptions: [
+        { value: "1", label: "琛�鍩瑰吇" },
+        { value: "2", label: "鐥板煿鍏�" },
+        { value: "3", label: "灏垮煿鍏�" },
+        { value: "4", label: "浼ゅ彛鍒嗘硨鐗�" },
+        { value: "5", label: "鑴戣剨娑插煿鍏�" },
+        { value: "6", label: "鍏朵粬" }
       ],
-      maintenanceRecords: [
-        {
-          item: '鍩烘湰淇℃伅',
-          content: '渚涜�呰韩浠戒俊鎭‘璁や笌褰曞叆',
-          operator: '寮犲尰鐢�',
-          time: '2023-12-01 08:30:00',
-          status: 'completed'
-        },
-        {
-          item: '鍖荤枟妗f',
-          content: '鐥呭彶璧勬枡鏀堕泦涓庢暣鐞�',
-          operator: '鏉庢姢澹�',
-          time: '2023-12-01 09:15:00',
-          status: 'completed'
-        },
-        {
-          item: '鍒濇璇勪及',
-          content: '鎹愮尞閫傚疁鎬у垵姝ヨ瘎浼�',
-          operator: '鐜嬩富浠�',
-          time: '2023-12-01 10:00:00',
-          status: 'completed'
-        }
-      ]
+
+      // 鎶ょ悊鏍告煡璁板綍鐩稿叧鏁版嵁
+      recordList: [],
+      recordLoading: false,
+      recordDialogVisible: false,
+      recordDialogTitle: "",
+      recordSaveLoading: false,
+      recordForm: {
+        id: undefined,
+        recordTime: "",
+        recorder: "",
+        checkRecord: "",
+        attachments: []
+      },
+      recordFileList: [],
+      recordRules: {
+        recordTime: [
+          { required: true, message: "璇烽�夋嫨鏍告煡鏃堕棿", trigger: "change" }
+        ],
+        recorder: [
+          { required: true, message: "璇疯緭鍏ユ牳鏌ヤ汉", trigger: "blur" }
+        ],
+        checkRecord: [
+          { required: true, message: "璇疯緭鍏ユ牳鏌ヨ褰�", trigger: "blur" }
+        ]
+      },
+
+      // 闄勪欢棰勮鐩稿叧
+      attachmentPreviewVisible: false,
+      currentAttachmentList: [],
+      attachmentPreviewTitle: "",
+
+      // 鏂囦欢棰勮鐩稿叧
+      filePreviewVisible: false,
+      currentPreviewFile: null,
+
+      // 闄勪欢鐩稿叧閰嶇疆
+      attachmentLimit: 10,
+      attachmentAccept:
+        ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
+
+      // 璇勪及鏁版嵁瀛樺偍
+      assessmentData: {
+        liverKidney: {},
+        bloodRoutine: {},
+        urineRoutine: {},
+        cultureResults: [],
+        nursingRecords: []
+      }
     };
+  },
+  created() {
+    this.loadMaintenanceData();
+  },
+  watch: {
+    $route(to, from) {
+      this.loadMaintenanceData();
+    }
+  },
+  methods: {
+    // 鍔犺浇缁存姢鏁版嵁
+    async loadMaintenanceData() {
+      try {
+        this.cultureLoading = true;
+        this.recordLoading = true;
+
+        const queryParams = {};
+        console.log(this.infoid, "this.infoid");
+
+        if (this.infoid) {
+          queryParams.infoid = this.infoid;
+        } else {
+          this.$message.error("缂哄皯蹇呰鐨勮矾鐢卞弬鏁�");
+          return;
+        }
+        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;
+            }
+          }
+
+          if (maintenanceData.itemDesc) {
+            try {
+              const itemDescData = maintenanceData.itemDesc;
+              this.assessmentData = { ...this.assessmentData, ...itemDescData };
+
+              if (itemDescData.cultureResults) {
+                this.cultureList = itemDescData.cultureResults;
+              }
+              if (itemDescData.nursingRecords) {
+                this.recordList = itemDescData.nursingRecords;
+              }
+              if (itemDescData.liverKidney) {
+                this.assessmentData.liverKidney = itemDescData.liverKidney;
+              }
+              if (itemDescData.bloodRoutine) {
+                this.assessmentData.bloodRoutine = itemDescData.bloodRoutine;
+              }
+              if (itemDescData.urineRoutine) {
+                this.assessmentData.urineRoutine = itemDescData.urineRoutine;
+              }
+            } catch (error) {
+              console.error("瑙f瀽itemDesc JSON澶辫触:", error);
+            }
+          }
+
+          this.form = { ...this.form, ...maintenanceData };
+          this.$message.success("鏁版嵁鍔犺浇鎴愬姛");
+        } else {
+          this.$message.error("鏁版嵁鍔犺浇澶辫触锛�" + (response.msg || "鏈煡閿欒"));
+        }
+      } catch (error) {
+        console.error("鍔犺浇缁存姢鏁版嵁澶辫触:", error);
+        this.$message.error("鏁版嵁鍔犺浇澶辫触");
+      } finally {
+        this.cultureLoading = false;
+        this.recordLoading = false;
+      }
+    },
+
+    // 鍒囨崲缂栬緫妯″紡
+    toggleEditMode() {
+      this.isEdit = !this.isEdit;
+      if (!this.isEdit) {
+      }
+    },
+
+    // 鍩瑰吇璁板綍鐩稿叧鏂规硶
+    handleAddCulture() {
+      this.cultureDialogTitle = "鏂板鍩瑰吇璁板綍";
+      this.cultureForm = {
+        id: undefined,
+        cultureType: "",
+        sampleTime: "",
+        result: "闃存��",
+        attachments: []
+      };
+      this.cultureFileList = [];
+      this.cultureDialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.cultureForm && this.$refs.cultureForm.clearValidate();
+      });
+    },
+
+    handleEditCulture(row) {
+      this.cultureDialogTitle = "缂栬緫鍩瑰吇璁板綍";
+      this.cultureForm = { ...row };
+      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();
+      });
+    },
+
+    handleSaveCulture() {
+      this.$refs.cultureForm.validate(valid => {
+        if (valid) {
+          this.cultureSaveLoading = true;
+
+          if (this.cultureForm.id) {
+            const index = this.cultureList.findIndex(
+              item => item.id === this.cultureForm.id
+            );
+            if (index !== -1) {
+              this.cultureList.splice(index, 1, { ...this.cultureForm });
+            }
+          } else {
+            this.cultureForm.id = Date.now();
+            this.cultureList.push({ ...this.cultureForm });
+          }
+
+          this.$message.success(this.cultureForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+          this.cultureDialogVisible = false;
+          this.cultureSaveLoading = false;
+        }
+      });
+    },
+
+    handleDeleteCulture(row) {
+      this.$confirm("纭畾瑕佸垹闄よ繖鏉″煿鍏昏褰曞悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.cultureList = this.cultureList.filter(
+            item => item.id !== row.id
+          );
+          this.$message.success("鍒犻櫎鎴愬姛");
+        })
+        .catch(() => {});
+    },
+
+    // 鎶ょ悊璁板綍鐩稿叧鏂规硶
+    handleAddRecord() {
+      this.recordDialogTitle = "鏂板鎶ょ悊鏍告煡璁板綍";
+      this.recordForm = {
+        id: undefined,
+        recordTime: new Date()
+          .toISOString()
+          .replace("T", " ")
+          .substring(0, 19),
+        recorder: "褰撳墠鐢ㄦ埛",
+        checkRecord: "",
+        attachments: []
+      };
+      this.recordFileList = [];
+      this.recordDialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.recordForm && this.$refs.recordForm.clearValidate();
+      });
+    },
+
+    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();
+      });
+    },
+
+    handleSaveRecord() {
+      this.$refs.recordForm.validate(valid => {
+        if (valid) {
+          this.recordSaveLoading = true;
+
+          if (this.recordForm.id) {
+            const index = this.recordList.findIndex(
+              item => item.id === this.recordForm.id
+            );
+            if (index !== -1) {
+              this.recordList.splice(index, 1, { ...this.recordForm });
+            }
+          } else {
+            this.recordForm.id = Date.now();
+            this.recordList.push({ ...this.recordForm });
+          }
+
+          this.$message.success(this.recordForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+          this.recordDialogVisible = false;
+          this.recordSaveLoading = false;
+        }
+      });
+    },
+
+    handleDeleteRecord(row) {
+      this.$confirm("纭畾瑕佸垹闄よ繖鏉℃姢鐞嗘牳鏌ヨ褰曞悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.recordList = this.recordList.filter(item => item.id !== row.id);
+          this.$message.success("鍒犻櫎鎴愬姛");
+        })
+        .catch(() => {});
+    },
+
+    // 鍩瑰吇璁板綍闄勪欢鐩稿叧鏂规硶
+    handleCultureAttachmentChange(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.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) {
+      this.currentAttachmentList = row.attachments || [];
+      this.attachmentPreviewTitle = `鍩瑰吇璁板綍闄勪欢 - ${row.cultureType}`;
+      this.attachmentPreviewVisible = true;
+    },
+
+    handleViewRecordAttachments(row) {
+      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;
+      }
+    },
+
+    // 璇勪及鏁版嵁鍙樻洿澶勭悊
+    handleLiverKidneyDataChange(data) {
+      this.assessmentData.liverKidney = data;
+    },
+
+    handleBloodRoutineDataChange(data) {
+      this.assessmentData.bloodRoutine = data;
+    },
+
+    handleUrineRoutineDataChange(data) {
+      this.assessmentData.urineRoutine = data;
+    },
+
+    handleTabClick(tab) {
+      this.$nextTick(() => {
+        let tableRef = null;
+        if (tab.name === "liverKidney") {
+          tableRef = this.$refs.liverKidney;
+        } else if (tab.name === "bloodRoutine") {
+          tableRef = this.$refs.bloodRoutine;
+        } else if (tab.name === "urineRoutine") {
+          tableRef = this.$refs.urineRoutine;
+        }
+
+        if (tableRef && tableRef.doLayout) {
+          tableRef.doLayout();
+        }
+      });
+    }
   }
 };
 </script>
 
 <style scoped>
-.card-header {
-  font-weight: 600;
-  color: #303133;
+.maintenance-detail {
+  padding: 20px;
 }
 
-.info-card, .timeline-card {
-  height: 100%;
+.detail-card {
+  margin-bottom: 20px;
+}
+
+.assessment-card {
+  margin-bottom: 20px;
+}
+
+.record-card {
+  margin-bottom: 20px;
+}
+
+.detail-title {
+  font-size: 16px;
+  font-weight: bold;
+  margin-right: 20px;
+}
+
+.culture-card {
+  margin-bottom: 20px;
+}
+
+.fixed-width .el-button {
+  margin: 0 2px;
+}
+
+.file-name {
+  font-size: 13px;
+  margin-left: 8px;
 }
 </style>

--
Gitblit v1.9.3