From 40bd04c1299a0edf63771b90b5f9e78bfb943474 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期日, 28 十二月 2025 17:27:57 +0800
Subject: [PATCH] 办公及业务页面推送

---
 src/views/OfficeRelated/checkingIn/index.vue                               |  317 
 src/views/business/OrganUtilization/index.vue                              |  377 +
 src/views/project/donatebaseinfo/index.vue                                 |    2 
 src/views/OfficeRelated/checkingIn/components/BusinessTripTable.vue        |  234 
 src/views/business/allocation/organAllocation.js                           |  329 
 src/views/business/GetWitness/GetWitnessInfo.vue                           | 1577 ++++
 src/views/business/GetWitness/index.vue                                    |  372 +
 src/views/business/course/components/MedicalAssessmentStage.vue            |  208 
 src/views/business/course/components/DonationConfirmStage.vue              |  217 
 src/views/business/decide/DecideInfo.vue                                   |  653 +
 src/views/OfficeRelated/checkingIn/components/MileageCalculation.vue       |  325 
 src/views/business/course/components/OrganUtilizationStage.vue             |  812 ++
 src/views/OfficeRelated/checkingIn/components/PersonalAttendanceTable.vue  |  331 
 src/views/business/OrganUtilization/organUtilization.js                    |  439 +
 src/views/business/maintain/components/LiverKidneyPanel.vue                |  492 +
 src/components/AttachmentPreview/ImagePreview/index.vue                    |  187 
 src/views/business/GetWitness/organProcurement.js                          |  353 
 src/views/business/course/components/EthicalReviewStage.vue                |  206 
 src/main.js                                                                |    2 
 src/views/business/allocation/allocationInfo.vue                           | 1014 ++
 src/views/business/ethicalReview/index.vue                                 |  480 +
 src/views/OfficeRelated/checkingIn/mockData.js                             |  165 
 src/views/OfficeRelated/checkingIn/components/PersonBusiness.vue           |  500 +
 src/views/business/maintain/components/UrineRoutinePanel.vue               |  751 ++
 src/components/UploadAttachment/index.vue                                  |   35 
 src/views/OfficeRelated/checkingIn/components/AttendanceTable.vue          |  187 
 src/api/case/deathJudgment.js                                              |    0 
 src/views/business/ethicalReview/ethicalReviewInfo.vue                     | 1526 ++++
 src/views/business/course/components/DeathJudgmentStage.vue                |  206 
 src/views/OfficeRelated/checkingIn/components/AttendanceCalendar.vue       |  588 +
 src/views/business/ethicalReview/ethicsReview.js                           |  392 +
 src/components/AttachmentPreview/index.vue                                 |  154 
 src/views/business/OrganUtilization/OrganUtilizationInfo.vue               | 1656 ++++
 src/views/business/course/donationProcess.js                               |  453 +
 src/views/business/course/components/OrganProcurementStage.vue             |  499 +
 src/views/business/maintain/maintainInfo.vue                               | 1135 ++
 src/views/OfficeRelated/checkingIn/components/PersonalAttendanceReport.vue |  682 +
 src/views/business/maintain/components/BloodRoutinePanel.vue               |  693 +
 src/views/business/affirm/mockConfirmationApi.js                           |   13 
 src/views/business/course/components/OrganAllocationStage.vue              |  447 +
 src/views/business/decide/mockDeathJudgmentApi.js                          |  391 +
 src/views/business/allocation/index.vue                                    |  372 +
 src/views/business/course/components/DonorMaintenanceStage.vue             |  156 
 src/views/business/decide/index.vue                                        |  437 +
 src/views/business/course/index.vue                                        |  677 +
 src/views/OfficeRelated/checkingIn/components/AttendanceStatistics.vue     |  277 
 src/views/OfficeRelated/checkingIn/checkingInInfo.vue                      |  307 
 src/views/business/appear/caseDetail.vue                                   |  115 
 src/views/business/course/components/BaseStage.vue                         |   51 
 src/components/AttachmentPreview/PdfPreview/index.vue                      |  200 
 50 files changed, 21,592 insertions(+), 400 deletions(-)

diff --git a/src/api/case/deathJudgment.js b/src/api/case/deathJudgment.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/api/case/deathJudgment.js
diff --git a/src/components/AttachmentPreview/ImagePreview/index.vue b/src/components/AttachmentPreview/ImagePreview/index.vue
new file mode 100644
index 0000000..fc7b872
--- /dev/null
+++ b/src/components/AttachmentPreview/ImagePreview/index.vue
@@ -0,0 +1,187 @@
+<template>
+  <div class="image-preview-container" v-loading="loading">
+    <!-- 鎺у埗宸ュ叿鏍� -->
+    <div class="image-controls">
+      <el-button-group>
+        <el-button size="mini" @click="zoomOut" :disabled="scale <= 0.2">
+          <i class="el-icon-zoom-out"></i> 缂╁皬
+        </el-button>
+        <el-button size="mini" @click="resetZoom">
+          <i class="el-icon-refresh-left"></i> 閲嶇疆 ({{ Math.round(scale * 100) }}%)
+        </el-button>
+        <el-button size="mini" @click="zoomIn" :disabled="scale >= 3">
+          <i class="el-icon-zoom-in"></i> 鏀惧ぇ
+        </el-button>
+      </el-button-group>
+
+      <el-button-group>
+        <el-button size="mini" @click="rotate(-90)">
+          <i class="el-icon-refresh-left"></i> 宸︽棆
+        </el-button>
+        <el-button size="mini" @click="rotate(90)">
+          <i class="el-icon-refresh-right"></i> 鍙虫棆
+        </el-button>
+      </el-button-group>
+
+      <el-button size="mini" type="success" @click="handleDownload" icon="el-icon-download">
+        涓嬭浇
+      </el-button>
+    </div>
+
+    <!-- 鍥剧墖娓叉煋鍖哄煙 -->
+    <div class="image-render-area" @mousemove="onMouseMove" @mouseleave="onMouseLeave">
+      <div class="image-wrapper" :style="imageWrapperStyle">
+        <img
+          ref="imageEl"
+          :src="imageUrl"
+          :alt="fileName"
+          :style="imageStyle"
+          @load="onImageLoad"
+          @error="onImageError"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'ImagePreview',
+  props: {
+    imageUrl: {
+      type: String,
+      required: true
+    },
+    fileName: {
+      type: String,
+      default: ''
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      scale: 1.0,
+      rotation: 0,
+      naturalWidth: 0,
+      naturalHeight: 0
+    }
+  },
+  computed: {
+    imageStyle() {
+      return {
+        transform: `scale(${this.scale}) rotate(${this.rotation}deg)`,
+        cursor: 'default',
+        maxWidth: '100%',
+        maxHeight: '100%',
+        transition: 'transform 0.3s ease'
+      }
+    },
+
+    imageWrapperStyle() {
+      return {
+        width: '100%',
+        height: '100%',
+        display: 'flex',
+        justifyContent: 'center',
+        alignItems: 'center',
+        overflow: 'auto'
+      }
+    }
+  },
+  methods: {
+    onImageLoad() {
+      this.loading = false;
+    },
+
+    onImageError() {
+      this.loading = false;
+      this.$message.error('鍥剧墖鍔犺浇澶辫触');
+    },
+
+    zoomIn() {
+      this.scale = Math.min(this.scale + 0.1, 3.0);
+    },
+
+    zoomOut() {
+      this.scale = Math.max(this.scale - 0.1, 0.2);
+    },
+
+    resetZoom() {
+      this.scale = 1.0;
+      this.rotation = 0;
+    },
+
+    rotate(degrees) {
+      this.rotation = (this.rotation + degrees) % 360;
+    },
+
+    onMouseMove() {
+      // 鍙坊鍔犻紶鏍囦氦浜掓晥鏋�
+    },
+
+    onMouseLeave() {
+      // 鍙坊鍔犻紶鏍囩寮�鏁堟灉
+    },
+
+    handleDownload() {
+      const link = document.createElement('a');
+      link.href = this.imageUrl;
+      link.download = this.fileName;
+      link.style.display = 'none';
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+      this.$message.success('寮�濮嬩笅杞芥枃浠�');
+    }
+  },
+  mounted() {
+    this.loading = true;
+  }
+}
+</script>
+
+<style scoped>
+.image-preview-container {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+}
+
+.image-controls {
+  padding: 15px 20px;
+  background: #f5f7fa;
+  border-bottom: 1px solid #ebeef5;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.image-render-area {
+  flex: 1;
+  position: relative;
+  overflow: hidden;
+  background: #f8f9fa;
+}
+
+.image-wrapper {
+  padding: 20px;
+}
+
+.image-wrapper img {
+  max-width: 100%;
+  max-height: 100%;
+  object-fit: contain;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+@media (max-width: 768px) {
+  .image-controls {
+    flex-direction: column;
+    gap: 10px;
+  }
+}
+</style>
diff --git a/src/components/AttachmentPreview/PdfPreview/index.vue b/src/components/AttachmentPreview/PdfPreview/index.vue
new file mode 100644
index 0000000..730bc5b
--- /dev/null
+++ b/src/components/AttachmentPreview/PdfPreview/index.vue
@@ -0,0 +1,200 @@
+<template>
+  <div class="pdf-preview-container" v-loading="loading">
+    <!-- 鎺у埗宸ュ叿鏍� -->
+    <div class="pdf-controls">
+      <el-button-group>
+        <el-button
+          size="mini"
+          @click="prevPage"
+          :disabled="currentPage <= 1"
+          icon="el-icon-arrow-left"
+        >
+          涓婁竴椤�
+        </el-button>
+        <el-button size="mini" disabled>
+          绗� {{ currentPage }} 椤� / 鍏� {{ totalPages }} 椤�
+        </el-button>
+        <el-button
+          size="mini"
+          @click="nextPage"
+          :disabled="currentPage >= totalPages"
+          icon="el-icon-arrow-right"
+        >
+          涓嬩竴椤�
+        </el-button>
+      </el-button-group>
+
+      <el-button-group class="zoom-controls">
+        <el-button size="mini" @click="zoomOut" :disabled="scale <= 50">
+          <i class="el-icon-zoom-out"></i> 缂╁皬
+        </el-button>
+        <el-button size="mini" disabled>{{ scale }}%</el-button>
+        <el-button size="mini" @click="zoomIn" :disabled="scale >= 200">
+          <i class="el-icon-zoom-in"></i> 鏀惧ぇ
+        </el-button>
+        <el-button size="mini" @click="resetZoom">
+          <i class="el-icon-refresh-left"></i> 閲嶇疆
+        </el-button>
+      </el-button-group>
+
+      <el-button size="mini" type="success" @click="handleDownload" icon="el-icon-download">
+        涓嬭浇
+      </el-button>
+    </div>
+
+    <!-- PDF娓叉煋鍖哄煙 -->
+    <div class="pdf-render-area">
+      <pdf
+        ref="pdf"
+        :src="pdfUrl"
+        :page="currentPage"
+        @num-pages="totalPages = $event"
+        @page-loaded="currentPage = $event"
+        @loaded="loadPdfHandler"
+        @error="pdfErrorHandler"
+        :style="{
+          width: scale + '%',
+          transform: 'scale(' + scale / 100 + ')',
+          transformOrigin: '0 0'
+        }"
+      ></pdf>
+    </div>
+  </div>
+</template>
+
+<script>
+import pdf from 'vue-pdf'
+
+export default {
+  name: 'PdfPreview',
+  components: {
+    pdf
+  },
+  props: {
+    pdfUrl: {
+      type: String,
+      required: true
+    },
+    fileName: {
+      type: String,
+      default: ''
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      currentPage: 1,
+      totalPages: 0,
+      scale: 100
+    }
+  },
+  methods: {
+    loadPdfHandler() {
+      this.loading = false;
+    },
+
+    pdfErrorHandler(error) {
+      console.error('PDF鍔犺浇澶辫触:', error);
+      this.loading = false;
+      this.$message.error('PDF鏂囦欢鍔犺浇澶辫触锛岃灏濊瘯涓嬭浇鍚庢煡鐪�');
+    },
+
+    prevPage() {
+      if (this.currentPage > 1) {
+        this.currentPage--;
+      }
+    },
+
+    nextPage() {
+      if (this.currentPage < this.totalPages) {
+        this.currentPage++;
+      }
+    },
+
+    zoomIn() {
+      if (this.scale >= 200) {
+        this.$message.info("宸叉斁澶у埌鏈�澶ф瘮渚�");
+        return;
+      }
+      this.scale += 10;
+    },
+
+    zoomOut() {
+      if (this.scale <= 50) {
+        this.$message.info("宸茬缉灏忓埌鏈�灏忔瘮渚�");
+        return;
+      }
+      this.scale -= 10;
+    },
+
+    resetZoom() {
+      this.scale = 100;
+    },
+
+    handleDownload() {
+      const link = document.createElement('a');
+      link.href = this.pdfUrl;
+      link.download = this.fileName;
+      link.style.display = 'none';
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+      this.$message.success('寮�濮嬩笅杞芥枃浠�');
+    }
+  },
+  mounted() {
+    this.loading = true;
+  },
+  watch: {
+    pdfUrl() {
+      this.loading = true;
+      this.currentPage = 1;
+      this.scale = 100;
+    }
+  }
+}
+</script>
+
+<style scoped>
+.pdf-preview-container {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.pdf-controls {
+  padding: 15px 20px;
+  background: #f5f7fa;
+  border-bottom: 1px solid #ebeef5;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.pdf-render-area {
+  flex: 1;
+  overflow: auto;
+  padding: 20px;
+  background: #f8f9fa;
+  display: flex;
+  justify-content: center;
+  align-items: flex-start;
+}
+
+.zoom-controls {
+  margin: 0 15px;
+}
+
+@media (max-width: 768px) {
+  .pdf-controls {
+    flex-direction: column;
+    gap: 10px;
+  }
+
+  .zoom-controls {
+    margin: 10px 0;
+  }
+}
+</style>
diff --git a/src/components/AttachmentPreview/index.vue b/src/components/AttachmentPreview/index.vue
new file mode 100644
index 0000000..d2c520a
--- /dev/null
+++ b/src/components/AttachmentPreview/index.vue
@@ -0,0 +1,154 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="visible"
+    width="90%"
+    top="5vh"
+    :close-on-click-modal="true"
+    class="attachment-preview-dialog"
+    @close="handleClose"
+  >
+    <div class="attachment-preview">
+      <el-tabs v-model="activeTab" type="card">
+        <el-tab-pane
+          v-for="(file, index) in fileList"
+          :key="index"
+          :label="getTabLabel(file)"
+          :name="index.toString()"
+        >
+          <div class="preview-content">
+            <!-- PDF棰勮 -->
+            <PdfPreview
+              v-if="getFileType(file.fileName) === 'pdf'"
+              :pdf-url="file.fileUrl"
+              :file-name="file.fileName"
+            />
+
+            <!-- 鍥剧墖棰勮 -->
+            <ImagePreview
+              v-else-if="getFileType(file.fileName) === 'image'"
+              :image-url="file.fileUrl"
+              :file-name="file.fileName"
+            />
+
+            <!-- 涓嶆敮鎸侀瑙堢殑鏂囦欢绫诲瀷 -->
+            <div v-else class="unsupported-preview">
+              <el-alert
+                title="璇ユ枃浠舵牸寮忎笉鏀寔鍦ㄧ嚎棰勮锛岃涓嬭浇鍚庢煡鐪�"
+                type="warning"
+                show-icon
+                :closable="false"
+              />
+              <div class="download-action">
+                <el-button type="primary" @click="handleDownload(file)">
+                  <i class="el-icon-download"></i> 涓嬭浇鏂囦欢
+                </el-button>
+              </div>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="$emit('close')">鍏抽棴</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import PdfPreview from "./PdfPreview";
+import ImagePreview from "./ImagePreview";
+
+export default {
+  name: "AttachmentPreview",
+  components: { PdfPreview, ImagePreview },
+  props: {
+    visible: Boolean,
+    fileList: {
+      type: Array,
+      default: () => []
+    },
+    title: String
+  },
+  data() {
+    return {
+      activeTab: "0"
+    };
+  },
+  methods: {
+    getFileType(fileName) {
+      const extension = fileName.split('.').pop().toLowerCase();
+      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
+      const pdfTypes = ["pdf"];
+
+      if (imageTypes.includes(extension)) return "image";
+      if (pdfTypes.includes(extension)) return "pdf";
+      return "other";
+    },
+
+    getTabLabel(file) {
+      const type = this.getFileType(file.fileName);
+      const icon = type === 'pdf' ? 'el-icon-document' :
+                  type === 'image' ? 'el-icon-picture' : 'el-icon-files';
+      return `${file.fileName}`;
+    },
+
+    handleDownload(file) {
+      const link = document.createElement("a");
+      link.href = file.fileUrl;
+      link.download = file.fileName;
+      link.style.display = "none";
+      document.body.appendChild(link);
+      link.click();
+      document.body.removeChild(link);
+      this.$message.success("寮�濮嬩笅杞芥枃浠�");
+    },
+
+    handleClose() {
+      this.activeTab = "0";
+      this.$emit('close');
+    }
+  }
+};
+</script>
+
+<style scoped>
+.attachment-preview-dialog >>> .el-dialog {
+  min-height: 80vh;
+  display: flex;
+  flex-direction: column;
+}
+
+.attachment-preview-dialog >>> .el-dialog__body {
+  flex: 1;
+  padding: 0;
+  display: flex;
+  flex-direction: column;
+}
+
+.attachment-preview {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+}
+
+.preview-content {
+  flex: 1;
+  height: 800px;
+  padding: 0;
+}
+
+.unsupported-preview {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  padding: 40px;
+}
+
+.download-action {
+  margin-top: 20px;
+}
+</style>
diff --git a/src/components/UploadAttachment/index.vue b/src/components/UploadAttachment/index.vue
new file mode 100644
index 0000000..290362c
--- /dev/null
+++ b/src/components/UploadAttachment/index.vue
@@ -0,0 +1,35 @@
+<template>
+  <div class="upload-attachment">
+    <el-upload
+      action="#"
+      :file-list="fileList"
+      :auto-upload="false"
+      :on-change="handleFileChange"
+      :on-remove="handleFileRemove"
+      multiple
+    >
+      <el-button size="small" type="primary">鐐瑰嚮涓婁紶</el-button>
+      <div slot="tip" class="el-upload__tip">鏀寔jpg銆乸ng銆乸df銆乨oc銆乨ocx绛夋牸寮忥紝鍗曚釜鏂囦欢涓嶈秴杩�10MB</div>
+    </el-upload>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "UploadAttachment",
+  props: {
+    fileList: {
+      type: Array,
+      default: () => []
+    }
+  },
+  methods: {
+    handleFileChange(file, fileList) {
+      this.$emit('change', fileList);
+    },
+    handleFileRemove(file, fileList) {
+      this.$emit('change', fileList);
+    }
+  }
+};
+</script>
diff --git a/src/main.js b/src/main.js
index 60b8011..74bada1 100644
--- a/src/main.js
+++ b/src/main.js
@@ -26,6 +26,7 @@
 import { getDicts } from "@/api/system/dict/data";
 import { getConfigKey } from "@/api/system/config";
 import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
+import { formatTime } from "@/utils/index";
 import dataV from '@jiaminghi/data-view';//dataV
 // 鍒嗛〉缁勪欢
 import Pagination from "@/components/Pagination";
@@ -65,6 +66,7 @@
 Vue.prototype.getDicts = getDicts
 Vue.prototype.getConfigKey = getConfigKey
 Vue.prototype.parseTime = parseTime
+Vue.prototype.formatTime = formatTime
 Vue.prototype.resetForm = resetForm
 Vue.prototype.addDateRange = addDateRange
 Vue.prototype.selectDictLabel = selectDictLabel
diff --git a/src/views/OfficeRelated/checkingIn/checkingInInfo.vue b/src/views/OfficeRelated/checkingIn/checkingInInfo.vue
new file mode 100644
index 0000000..f0c23c0
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/checkingInInfo.vue
@@ -0,0 +1,307 @@
+<template>
+  <div class="attendance-detail">
+    <!-- 鍛樺伐鍩烘湰淇℃伅 -->
+    <el-card class="employee-info-card">
+      <div class="employee-header">
+        <div class="employee-basic">
+          <el-avatar :size="60" :src="employeeInfo.avatar" class="employee-avatar">
+            {{ employeeInfo.name.charAt(0) }}
+          </el-avatar>
+          <div class="employee-details">
+            <h3>{{ employeeInfo.name }}</h3>
+            <p class="employee-department">{{ employeeInfo.department }} 路 {{ employeeInfo.position }}</p>
+            <p class="employee-contact">
+              <span>宸ュ彿: {{ employeeInfo.employeeId }}</span>
+              <span>鐢佃瘽: {{ employeeInfo.phone }}</span>
+            </p>
+          </div>
+        </div>
+        <div class="employee-stats">
+          <div class="stat-item">
+            <div class="stat-value">{{ employeeStats.attendanceRate }}%</div>
+            <div class="stat-label">鏈湀鍑哄嫟鐜�</div>
+          </div>
+          <div class="stat-item">
+            <div class="stat-value">{{ employeeStats.workHours }}h</div>
+            <div class="stat-label">鎬诲伐浣滄椂闀�</div>
+          </div>
+          <div class="stat-item">
+            <div class="stat-value">{{ employeeStats.businessTripDays }}</div>
+            <div class="stat-label">鍑哄樊澶╂暟</div>
+          </div>
+        </div>
+      </div>
+    </el-card>
+
+    <!-- 閫夐」鍗� -->
+    <el-card>
+      <el-tabs v-model="activeTab">
+        <el-tab-pane label="鏃ュ巻瑙嗗浘" name="calendar">
+          <attendance-calendar
+            :attendance-data="attendanceData"
+            :business-trip-data="businessTripData"
+          />
+        </el-tab-pane>
+
+        <el-tab-pane label="鍑哄嫟璁板綍" name="attendanceList">
+          <personal-attendance-table
+            :data="attendanceData"
+            :loading="loading"
+          />
+        </el-tab-pane>
+
+        <el-tab-pane label="鍑哄樊璁板綍" name="businessTripList">
+          <personal-business-trip-table
+            :data="businessTripData"
+            :loading="loading"
+          />
+        </el-tab-pane>
+
+        <el-tab-pane label="缁熻鎶ヨ〃" name="report">
+          <personal-attendance-report
+            :stats="employeeStats"
+            :attendance-data="attendanceData"
+          />
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+  </div>
+</template>
+
+<script>
+  import { generateMockData } from './mockData'
+
+import AttendanceCalendar from './components/AttendanceCalendar.vue'
+import PersonalAttendanceTable from './components/PersonalAttendanceTable.vue'
+import PersonBusiness from './components/PersonBusiness.vue'
+import PersonalAttendanceReport from './components/PersonalAttendanceReport.vue'
+
+export default {
+  name: 'AttendanceDetail',
+  components: {
+    AttendanceCalendar,
+    PersonalAttendanceTable,
+    PersonBusiness,
+    PersonalAttendanceReport
+  },
+  data() {
+    return {
+       activeTab: 'calendar',
+      loading: false,
+      employeeInfo: {
+        name: '寮犱笁',
+        department: 'OPO椤圭洰閮�',
+        position: '椤圭洰缁忕悊',
+        employeeId: 'OPO001',
+        phone: '138-1234-5678',
+        avatar: ''
+      },
+      employeeStats: {
+        attendanceRate: 0,
+        workHours: 0,
+        businessTripDays: 0,
+        lateTimes: 0,
+        leaveEarlyTimes: 0
+      },
+      attendanceData: [],
+      businessTripData: []
+    }
+  },
+  created() {
+        this.loadMockData()
+
+    this.getEmployeeInfo()
+    this.loadAttendanceData()
+  },
+  methods: {
+    getEmployeeInfo() {
+      const { employeeId, employeeName } = this.$route.query
+      // 妯℃嫙鍛樺伐淇℃伅
+      this.employeeInfo = {
+        name: employeeName || '寮犱笁',
+        department: 'OPO椤圭洰閮�',
+        position: '椤圭洰缁忕悊',
+        employeeId: employeeId || 'OPO001',
+        phone: '138****1234',
+        avatar: ''
+      }
+    },
+ loadMockData() {
+      this.loading = true
+
+      // 妯℃嫙寮傛鍔犺浇
+      setTimeout(() => {
+        const mockData = generateMockData()
+        this.attendanceData = mockData.attendanceData
+        this.businessTripData = mockData.businessTripData
+        this.calculateStats()
+        this.loading = false
+      }, 500)
+    },
+
+    calculateStats() {
+      const totalDays = 31 // 12鏈堟湁31澶�
+      const attendanceDays = this.attendanceData.filter(item =>
+        item.status === 'present' || item.status === 'late'
+      ).length
+
+      const lateTimes = this.attendanceData.filter(item =>
+        item.status === 'late'
+      ).length
+
+      // 璁$畻鍑哄樊鎬诲ぉ鏁�
+      const businessTripDays = this.businessTripData.reduce((total, trip) => {
+        const start = new Date(trip.startDate)
+        const end = new Date(trip.endDate)
+        const days = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1
+        return total + days
+      }, 0)
+
+      // 璁$畻鎬诲伐浣滄椂闀�
+      const totalWorkHours = this.attendanceData.reduce((total, item) => {
+        return total + (item.workHours || 0)
+      }, 0)
+
+      this.employeeStats = {
+        attendanceRate: Math.round((attendanceDays / totalDays) * 100),
+        workHours: totalWorkHours.toFixed(1),
+        businessTripDays: businessTripDays,
+        lateTimes: lateTimes,
+        leaveEarlyTimes: this.attendanceData.filter(item =>
+          item.status === 'leaveEarly'
+        ).length
+      }
+    },
+    async loadAttendanceData() {
+      this.loading = true
+      try {
+        await new Promise(resolve => setTimeout(resolve, 500))
+
+        // 鐢熸垚涓汉鑰冨嫟妯℃嫙鏁版嵁
+        this.attendanceData = this.generatePersonalAttendanceData()
+        this.businessTripData = this.generatePersonalBusinessTripData()
+        this.calculateStats()
+      } catch (error) {
+        console.error('鍔犺浇鏁版嵁澶辫触:', error)
+      } finally {
+        this.loading = false
+      }
+    },
+
+    generatePersonalAttendanceData() {
+      const data = []
+      const currentMonth = 12 // 12鏈�
+
+      for (let day = 1; day <= 31; day++) {
+        if (Math.random() > 0.2) { // 80%鐨勫嚭鍕ょ巼
+          data.push({
+            id: day,
+            date: `2024-${currentMonth.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`,
+            checkIn: `08:${String(Math.floor(Math.random() * 30)).padStart(2, '0')}`,
+            checkOut: `18:${String(Math.floor(Math.random() * 30)).padStart(2, '0')}`,
+            status: Math.random() > 0.1 ? '姝e父' : '杩熷埌',
+            workHours: (8 + Math.random() * 2).toFixed(1)
+          })
+        }
+      }
+      return data
+    },
+
+    generatePersonalBusinessTripData() {
+      return [
+        {
+          id: 1,
+          tripNumber: 'BT202412001',
+          startCity: '鍖椾含',
+          endCity: '涓婃捣',
+          startDate: '2024-12-05',
+          endDate: '2024-12-08',
+          distance: 1200,
+          purpose: '瀹㈡埛浼氳',
+          status: '宸插畬鎴�'
+        },
+        {
+          id: 2,
+          tripNumber: 'BT202412002',
+          startCity: '鍖椾含',
+          endCity: '骞垮窞',
+          startDate: '2024-12-15',
+          endDate: '2024-12-18',
+          distance: 1900,
+          purpose: '椤圭洰璋冪爺',
+          status: '宸插畬鎴�'
+        }
+      ]
+    },
+
+  }
+}
+</script>
+
+<style scoped>
+.attendance-detail {
+  padding: 20px;
+}
+
+.employee-info-card {
+  margin-bottom: 20px;
+}
+
+.employee-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.employee-basic {
+  display: flex;
+  align-items: center;
+}
+
+.employee-avatar {
+  margin-right: 16px;
+  background-color: #409eff;
+}
+
+.employee-details h3 {
+  margin: 0 0 8px 0;
+  font-size: 24px;
+  color: #303133;
+}
+
+.employee-department {
+  margin: 0 0 8px 0;
+  color: #606266;
+}
+
+.employee-contact {
+  margin: 0;
+  color: #909399;
+  font-size: 14px;
+}
+
+.employee-contact span {
+  margin-right: 16px;
+}
+
+.employee-stats {
+  display: flex;
+  gap: 30px;
+}
+
+.stat-item {
+  text-align: center;
+}
+
+.stat-value {
+  font-size: 28px;
+  font-weight: bold;
+  color: #409eff;
+  margin-bottom: 4px;
+}
+
+.stat-label {
+  color: #909399;
+  font-size: 14px;
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/components/AttendanceCalendar.vue b/src/views/OfficeRelated/checkingIn/components/AttendanceCalendar.vue
new file mode 100644
index 0000000..c43976e
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/components/AttendanceCalendar.vue
@@ -0,0 +1,588 @@
+<template>
+  <div class="attendance-calendar">
+    <!-- 鏃ュ巻澶撮儴缁熻淇℃伅 -->
+    <div class="calendar-stats">
+      <div class="stat-item">
+        <span class="stat-dot present"></span>
+        <span>姝e父鍑哄嫟: {{ stats.presentDays }}澶�</span>
+      </div>
+      <div class="stat-item">
+        <span class="stat-dot absent"></span>
+        <span>缂哄嫟/寮傚父: {{ stats.absentDays }}澶�</span>
+      </div>
+      <div class="stat-item">
+        <span class="stat-dot trip"></span>
+        <span>鍑哄樊: {{ stats.tripDays }}澶�</span>
+      </div>
+      <div class="stat-item">
+        <span class="stat-dot late"></span>
+        <span>杩熷埌/鏃╅��: {{ stats.lateDays }}澶�</span>
+      </div>
+    </div>
+
+    <!-- Element UI 鏃ュ巻缁勪欢 -->
+    <el-calendar v-model="calendarValue" :first-day-of-week="1">
+      <template #date-cell="{ data }">
+        <div
+          class="calendar-date"
+          :class="getDateStatusClass(data.day)"
+          @click="handleDateClick(data)"
+        >
+          <div class="date-number">{{ data.day.split('-')[2] }}</div>
+
+          <!-- 鐘舵�佽儗鏅壊鍧� -->
+          <div class="status-background" :class="getBackgroundStatus(data.day)"></div>
+
+          <div class="date-events">
+            <!-- 鍑哄嫟鐘舵�佹爣璁� -->
+            <div v-if="getAttendanceStatus(data.day) !== 'absent'" class="status-mark">
+              <el-tooltip
+                :content="getAttendanceTooltip(data.day)"
+                placement="top"
+              >
+                <span class="status-dot" :class="getAttendanceStatus(data.day)"></span>
+              </el-tooltip>
+            </div>
+
+            <!-- 鍑哄樊鏍囪 -->
+            <div v-if="hasBusinessTrip(data.day)" class="trip-mark">
+              <el-tooltip content="鍑哄樊" placement="top">
+                <i class="el-icon-location-outline"></i>
+              </el-tooltip>
+            </div>
+
+            <!-- 缂哄嫟鏍囪 -->
+            <div v-if="getAttendanceStatus(data.day) === 'absent'" class="absent-mark">
+              <el-tooltip content="缂哄嫟" placement="top">
+                <i class="el-icon-close"></i>
+              </el-tooltip>
+            </div>
+          </div>
+
+          <!-- 绠�鐣ヤ俊鎭樉绀� -->
+          <div class="brief-info">
+            <div v-if="getAttendanceStatus(data.day) === 'present'" class="info-item present-info">
+              鈭�
+            </div>
+            <div v-else-if="getAttendanceStatus(data.day) === 'late'" class="info-item late-info">
+              !
+            </div>
+            <div v-else-if="getAttendanceStatus(data.day) === 'absent'" class="info-item absent-info">
+              脳
+            </div>
+            <div v-if="hasBusinessTrip(data.day)" class="info-item trip-info">
+              鉁�
+            </div>
+          </div>
+
+          <!-- 鏃ユ湡璇︾粏淇℃伅锛堟偓娴樉绀猴級 -->
+          <div class="date-details">
+            <div
+              v-for="event in getDateEvents(data.day)"
+              :key="event.id"
+              class="detail-item"
+            >
+              <span class="detail-type">{{ event.type === 'attendance' ? '鍑哄嫟' : '鍑哄樊' }}</span>
+              <span class="detail-info">{{ event.text }}</span>
+            </div>
+            <div v-if="getDateEvents(data.day).length === 0" class="detail-item">
+              <span class="detail-type">鏃犺褰�</span>
+            </div>
+          </div>
+        </div>
+      </template>
+    </el-calendar>
+
+    <!-- 鏃ユ湡璇︽儏瀵硅瘽妗� -->
+    <el-dialog
+      :title="`${selectedDate} 鑰冨嫟璇︽儏`"
+      v-model="detailDialogVisible"
+      width="500px"
+    >
+      <div v-if="selectedDateInfo">
+        <div class="detail-section">
+          <h4>鍑哄嫟淇℃伅</h4>
+          <div v-if="selectedDateInfo.attendance">
+            <p>涓婄彮鏃堕棿: {{ selectedDateInfo.attendance.checkIn || '鏈墦鍗�' }}</p>
+            <p>涓嬬彮鏃堕棿: {{ selectedDateInfo.attendance.checkOut || '鏈墦鍗�' }}</p>
+            <p>鐘舵��:
+              <el-tag :type="getStatusTagType(selectedDateInfo.attendance.status)">
+                {{ getStatusText(selectedDateInfo.attendance.status) }}
+              </el-tag>
+            </p>
+          </div>
+          <div v-else>
+            <p class="no-data">鏃犲嚭鍕よ褰�</p>
+          </div>
+        </div>
+
+        <div class="detail-section" v-if="selectedDateInfo.businessTrip">
+          <h4>鍑哄樊淇℃伅</h4>
+          <p>鐩殑鍦�: {{ selectedDateInfo.businessTrip.destination }}</p>
+          <p>浜嬬敱: {{ selectedDateInfo.businessTrip.reason }}</p>
+          <p>閲岀▼: {{ selectedDateInfo.businessTrip.distance }}鍏噷</p>
+        </div>
+      </div>
+      <template #footer>
+        <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'AttendanceCalendar',
+  props: {
+    attendanceData: {
+      type: Array,
+      default: () => []
+    },
+    businessTripData: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      calendarValue: new Date(),
+      detailDialogVisible: false,
+      selectedDate: '',
+      selectedDateInfo: null,
+      stats: {
+        presentDays: 0,
+        absentDays: 0,
+        tripDays: 0,
+        lateDays: 0
+      }
+    }
+  },
+  mounted() {
+    this.calculateStats()
+  },
+  watch: {
+    attendanceData: {
+      handler() {
+        this.calculateStats()
+      },
+      deep: true
+    },
+    businessTripData: {
+      handler() {
+        this.calculateStats()
+      },
+      deep: true
+    }
+  },
+  methods: {
+    // 鑾峰彇鏃ユ湡鐘舵�佺被鍚�
+    getDateStatusClass(date) {
+      const classes = []
+      if (this.isToday(date)) {
+        classes.push('today')
+      }
+      if (this.isSelected(date)) {
+        classes.push('selected')
+      }
+
+      // 娣诲姞鐘舵�佺被鍚�
+      const status = this.getBackgroundStatus(date)
+      if (status) {
+        classes.push(status)
+      }
+
+      return classes
+    },
+
+    // 鑾峰彇鑳屾櫙鐘舵�侊紙鐢ㄤ簬鑳屾櫙鑹诧級
+    getBackgroundStatus(date) {
+      const attendance = this.attendanceData.find(item => item.date === date)
+      const hasTrip = this.hasBusinessTrip(date)
+
+      if (hasTrip) {
+        return 'has-trip'
+      }
+
+      if (attendance) {
+        switch (attendance.status) {
+          case 'present': return 'has-attendance'
+          case 'late': return 'has-late'
+          case 'absent': return 'has-absent'
+          default: return ''
+        }
+      }
+
+      return ''
+    },
+
+    // 鍒ゆ柇鏄惁涓轰粖澶�
+    isToday(date) {
+      const today = new Date()
+      const compareDate = new Date(date)
+      return today.toDateString() === compareDate.toDateString()
+    },
+
+    // 鍒ゆ柇鏄惁琚�変腑
+    isSelected(date) {
+      return this.selectedDate === date
+    },
+
+    // 鑾峰彇鑰冨嫟鐘舵��
+    getAttendanceStatus(date) {
+      const attendance = this.attendanceData.find(item => item.date === date)
+      if (!attendance) return 'absent'
+
+      switch (attendance.status) {
+        case 'present': return 'present'
+        case 'late': return 'late'
+        case 'absent': return 'absent'
+        default: return 'absent'
+      }
+    },
+
+    // 鑾峰彇鐘舵�佹枃鏈�
+    getStatusText(status) {
+      const statusMap = {
+        present: '姝e父鍑哄嫟',
+        late: '杩熷埌/鏃╅��',
+        absent: '缂哄嫟/寮傚父'
+      }
+      return statusMap[status] || '鏈煡鐘舵��'
+    },
+
+    // 鑾峰彇鑰冨嫟鐘舵�佹彁绀�
+    getAttendanceTooltip(date) {
+      const statusMap = {
+        present: '姝e父鍑哄嫟',
+        late: '杩熷埌/鏃╅��',
+        absent: '缂哄嫟/寮傚父'
+      }
+      return statusMap[this.getAttendanceStatus(date)] || '鏃犺褰�'
+    },
+
+    // 鍒ゆ柇鏄惁鏈夊嚭宸�
+    hasBusinessTrip(date) {
+      return this.businessTripData.some(item =>
+        date >= item.startDate && date <= item.endDate
+      )
+    },
+
+    // 鑾峰彇鏃ユ湡浜嬩欢
+    getDateEvents(date) {
+      const events = []
+      const attendance = this.attendanceData.find(item => item.date === date)
+
+      if (attendance) {
+        events.push({
+          id: `attendance-${date}`,
+          type: 'attendance',
+          text: `${attendance.checkIn || '鏈墦鍗�'} - ${attendance.checkOut || '鏈墦鍗�'}`
+        })
+      }
+
+      const businessTrip = this.businessTripData.find(item =>
+        date >= item.startDate && date <= item.endDate
+      )
+      if (businessTrip) {
+        events.push({
+          id: `business-trip-${date}`,
+          type: 'businessTrip',
+          text: `鍓嶅線${businessTrip.destination}`
+        })
+      }
+
+      return events
+    },
+
+    // 澶勭悊鏃ユ湡鐐瑰嚮浜嬩欢
+    handleDateClick(data) {
+      this.selectedDate = data.day
+      this.selectedDateInfo = {
+        attendance: this.attendanceData.find(item => item.date === data.day),
+        businessTrip: this.businessTripData.find(item =>
+          data.day >= item.startDate && data.day <= item.endDate
+        )
+      }
+      this.detailDialogVisible = true
+    },
+
+    // 鑾峰彇鐘舵�佹爣绛剧被鍨�
+    getStatusTagType(status) {
+      const typeMap = {
+        present: 'success',
+        late: 'warning',
+        absent: 'danger'
+      }
+      return typeMap[status] || 'info'
+    },
+
+    // 璁$畻缁熻淇℃伅
+    calculateStats() {
+      // 閲嶇疆缁熻
+      this.stats = { presentDays: 0, absentDays: 0, tripDays: 0, lateDays: 0 }
+
+      this.attendanceData.forEach(item => {
+        switch (item.status) {
+          case 'present': this.stats.presentDays++; break
+          case 'late': this.stats.lateDays++; break
+          case 'absent': this.stats.absentDays++; break
+        }
+      })
+
+      // 璁$畻鍑哄樊澶╂暟
+      const tripDays = new Set()
+      this.businessTripData.forEach(item => {
+        const start = new Date(item.startDate)
+        const end = new Date(item.endDate)
+        for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
+          tripDays.add(d.toISOString().split('T')[0])
+        }
+      })
+      this.stats.tripDays = tripDays.size
+    }
+  }
+}
+</script>
+
+<style scoped>
+.attendance-calendar {
+  padding: 20px;
+  max-width: 100%;
+}
+
+.calendar-stats {
+  display: flex;
+  justify-content: space-around;
+  margin-bottom: 20px;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 8px;
+}
+
+.stat-item {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.stat-dot {
+  width: 12px;
+  height: 12px;
+  border-radius: 50%;
+  display: inline-block;
+}
+
+.stat-dot.present { background-color: #67c23a; }
+.stat-dot.absent { background-color: #f56c6c; }
+.stat-dot.trip { background-color: #409eff; }
+.stat-dot.late { background-color: #e6a23c; }
+
+.calendar-date {
+  height: 80px;
+  padding: 4px;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+  cursor: pointer;
+  transition: all 0.3s;
+  position: relative;
+  overflow: hidden;
+}
+
+.calendar-date:hover {
+  background-color: #f0f9ff;
+  border-color: #409eff;
+  transform: translateY(-2px);
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+.calendar-date.today {
+  border-color: #409eff;
+  background-color: #f0f9ff;
+}
+
+.calendar-date.selected {
+  background-color: #ecf5ff;
+  border-color: #409eff;
+}
+
+/* 鐘舵�佽儗鏅壊 */
+.status-background {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  opacity: 0.1;
+  z-index: 0;
+}
+
+.calendar-date.has-attendance .status-background {
+  background-color: #67c23a;
+}
+
+.calendar-date.has-late .status-background {
+  background-color: #e6a23c;
+}
+
+.calendar-date.has-absent .status-background {
+  background-color: #f56c6c;
+}
+
+.calendar-date.has-trip .status-background {
+  background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
+}
+
+.date-number {
+  font-weight: bold;
+  font-size: 14px;
+  margin-bottom: 2px;
+  position: relative;
+  z-index: 1;
+}
+
+.date-events {
+  display: flex;
+  flex-direction: column;
+  gap: 2px;
+  position: relative;
+  z-index: 1;
+}
+
+.status-mark, .trip-mark, .absent-mark {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+}
+
+.status-dot {
+  width: 8px;
+  height: 8px;
+  border-radius: 50%;
+  display: inline-block;
+}
+
+.status-dot.present { background-color: #67c23a; }
+.status-dot.late { background-color: #e6a23c; }
+.status-dot.absent { background-color: #f56c6c; }
+
+.trip-mark i {
+  color: #409eff;
+  font-size: 12px;
+}
+
+.absent-mark i {
+  color: #f56c6c;
+  font-size: 12px;
+}
+
+/* 绠�鐣ヤ俊鎭樉绀� */
+.brief-info {
+  position: absolute;
+  bottom: 4px;
+  right: 4px;
+  display: flex;
+  gap: 2px;
+  z-index: 1;
+}
+
+.info-item {
+  width: 16px;
+  height: 16px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 10px;
+  font-weight: bold;
+}
+
+.present-info {
+  background-color: #67c23a;
+  color: white;
+}
+
+.late-info {
+  background-color: #e6a23c;
+  color: white;
+}
+
+.absent-info {
+  background-color: #f56c6c;
+  color: white;
+}
+
+.trip-info {
+  background-color: #409eff;
+  color: white;
+}
+
+.date-details {
+  position: absolute;
+  top: 100%;
+  left: 0;
+  right: 0;
+  background: white;
+  border: 1px solid #ddd;
+  border-radius: 4px;
+  padding: 8px;
+  z-index: 1000;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  display: none;
+}
+
+.calendar-date:hover .date-details {
+  display: block;
+}
+
+.detail-item {
+  font-size: 12px;
+  margin-bottom: 4px;
+  display: flex;
+  align-items: center;
+}
+
+.detail-type {
+  font-weight: bold;
+  margin-right: 4px;
+  min-width: 40px;
+}
+
+.detail-info {
+  color: #606266;
+}
+
+.detail-section {
+  margin-bottom: 20px;
+}
+
+.detail-section h4 {
+  margin-bottom: 10px;
+  color: #303133;
+  border-left: 4px solid #409eff;
+  padding-left: 8px;
+}
+
+.no-data {
+  color: #909399;
+  font-style: italic;
+}
+
+:deep(.el-calendar__header) {
+  padding: 10px;
+  border-bottom: 1px solid #ebeef5;
+}
+
+:deep(.el-calendar-day) {
+  padding: 0 !important;
+  height: 80px;
+}
+
+:deep(.el-calendar-table:not(.is-range) td) {
+  border: 1px solid #f0f0f0;
+}
+
+:deep(.el-calendar-table .el-calendar-day) {
+  height: 80px !important;
+  padding: 0 !important;
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/components/AttendanceStatistics.vue b/src/views/OfficeRelated/checkingIn/components/AttendanceStatistics.vue
new file mode 100644
index 0000000..10e94ca
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/components/AttendanceStatistics.vue
@@ -0,0 +1,277 @@
+<template>
+  <div class="attendance-statistics">
+    <div class="statistics-controls">
+      <el-date-picker
+        v-model="selectedMonth"
+        type="month"
+        placeholder="閫夋嫨缁熻鏈堜唤"
+        value-format="yyyy-MM"
+        @change="handleMonthChange"
+      />
+      <el-button type="primary" icon="el-icon-refresh" @click="refreshData">
+        鍒锋柊鏁版嵁
+      </el-button>
+    </div>
+
+    <el-row :gutter="20" class="stats-cards">
+      <el-col :span="6">
+        <el-card shadow="hover">
+          <div class="stat-card">
+            <div class="stat-icon primary">
+              <i class="el-icon-user-solid"></i>
+            </div>
+            <div class="stat-content">
+              <div class="stat-value">{{ stats.totalEmployees }}</div>
+              <div class="stat-label">鎬诲憳宸ユ暟</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover">
+          <div class="stat-card">
+            <div class="stat-icon success">
+              <i class="el-icon-success"></i>
+            </div>
+            <div class="stat-content">
+              <div class="stat-value">{{ stats.attendanceRate }}%</div>
+              <div class="stat-label">骞冲潎鍑哄嫟鐜�</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover">
+          <div class="stat-card">
+            <div class="stat-icon warning">
+              <i class="el-icon-warning"></i>
+            </div>
+            <div class="stat-content">
+              <div class="stat-value">{{ stats.totalLate }}</div>
+              <div class="stat-label">鎬昏繜鍒版鏁�</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover">
+          <div class="stat-card">
+            <div class="stat-icon danger">
+              <i class="el-icon-error"></i>
+            </div>
+            <div class="stat-content">
+              <div class="stat-value">{{ stats.totalAbsence }}</div>
+              <div class="stat-label">鎬荤己鍕ゅぉ鏁�</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-row :gutter="20" class="charts-section">
+      <el-col :span="12">
+        <el-card header="鍑哄嫟瓒嬪娍鍒嗘瀽" shadow="never">
+          <div class="chart-container">
+            <!-- 杩欓噷鍙互闆嗘垚 ECharts 鍥捐〃 -->
+            <div class="chart-placeholder">
+              <i class="el-icon-data-analysis"></i>
+              <p>鍑哄嫟瓒嬪娍鍥捐〃</p>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card header="鑰冨嫟鍒嗗竷" shadow="never">
+          <div class="chart-container">
+            <div class="chart-placeholder">
+              <i class="el-icon-pie-chart"></i>
+              <p>鑰冨嫟鍒嗗竷鍥捐〃</p>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-card header="璇︾粏缁熻琛�" shadow="never" class="detail-table">
+      <el-table :data="stats.detailData" border>
+        <el-table-column prop="department" label="閮ㄩ棬"  />
+        <el-table-column prop="employeeCount" label="鍛樺伐鏁�"  />
+        <el-table-column prop="attendanceDays" label="搴斿嚭鍕ゅぉ鏁�"  />
+        <el-table-column prop="actualDays" label="瀹為檯鍑哄嫟"  />
+        <el-table-column prop="lateTimes" label="杩熷埌娆℃暟" >
+          <template #default="scope">
+            <el-tag v-if="scope.row.lateTimes > 0" type="warning" size="small">
+              {{ scope.row.lateTimes }}
+            </el-tag>
+            <span v-else>{{ scope.row.lateTimes }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="absenceDays" label="缂哄嫟澶╂暟" >
+          <template #default="scope">
+            <el-tag v-if="scope.row.absenceDays > 0" type="danger" size="small">
+              {{ scope.row.absenceDays }}
+            </el-tag>
+            <span v-else>{{ scope.row.absenceDays }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="attendanceRate" label="鍑哄嫟鐜�" >
+          <template #default="scope">
+            <el-progress
+              :percentage="scope.row.attendanceRate"
+              :show-text="false"
+            />
+            <span>{{ scope.row.attendanceRate }}%</span>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'attendance-statistics',
+  props: {
+    data: {
+      type: Array,
+      default: () => []
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      selectedMonth: new Date().toISOString().slice(0, 7), // 褰撳墠骞存湀
+      stats: {
+        totalEmployees: 0,
+        attendanceRate: 0,
+        totalLate: 0,
+        totalAbsence: 0,
+        detailData: []
+      }
+    }
+  },
+  watch: {
+    data: {
+      handler(newData) {
+        this.calculateStats(newData)
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    calculateStats(data) {
+      // 妯℃嫙缁熻璁$畻
+      this.stats = {
+        totalEmployees: 156,
+        attendanceRate: 92.5,
+        totalLate: 24,
+        totalAbsence: 12,
+        detailData: [
+          { department: '鎶�鏈儴', employeeCount: 45, attendanceDays: 22,
+            actualDays: 41, lateTimes: 8, absenceDays: 2, attendanceRate: 93.2 },
+          { department: '甯傚満閮�', employeeCount: 32, attendanceDays: 22,
+            actualDays: 30, lateTimes: 5, absenceDays: 1, attendanceRate: 95.5 },
+          { department: '浜轰簨閮�', employeeCount: 18, attendanceDays: 22,
+            actualDays: 17, lateTimes: 3, absenceDays: 4, attendanceRate: 89.3 },
+          { department: '璐㈠姟閮�', employeeCount: 15, attendanceDays: 22,
+            actualDays: 14, lateTimes: 2, absenceDays: 1, attendanceRate: 93.8 }
+        ]
+      }
+    },
+
+    handleMonthChange(month) {
+      this.$message.info(`鍒囨崲缁熻鏈堜唤: ${month}`)
+      this.refreshData()
+    },
+
+    refreshData() {
+      this.$emit('refresh')
+    }
+  }
+}
+</script>
+
+<style scoped>
+.attendance-statistics {
+  padding: 20px;
+}
+
+.statistics-controls {
+  margin-bottom: 24px;
+  display: flex;
+  gap: 16px;
+  align-items: center;
+}
+
+.stats-cards {
+  margin-bottom: 24px;
+}
+
+.stat-card {
+  display: flex;
+  align-items: center;
+  padding: 16px;
+}
+
+.stat-icon {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 16px;
+  font-size: 28px;
+  color: white;
+}
+
+.stat-icon.primary { background: #409EFF; }
+.stat-icon.success { background: #67C23A; }
+.stat-icon.warning { background: #E6A23C; }
+.stat-icon.danger { background: #F56C6C; }
+
+.stat-content {
+  flex: 1;
+}
+
+.stat-value {
+  font-size: 28px;
+  font-weight: bold;
+  color: #303133;
+  margin-bottom: 4px;
+}
+
+.stat-label {
+  color: #909399;
+  font-size: 14px;
+}
+
+.charts-section {
+  margin-bottom: 24px;
+}
+
+.chart-container {
+  height: 300px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.chart-placeholder {
+  text-align: center;
+  color: #909399;
+}
+
+.chart-placeholder i {
+  font-size: 48px;
+  margin-bottom: 16px;
+  display: block;
+}
+
+.detail-table {
+  margin-top: 24px;
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/components/AttendanceTable.vue b/src/views/OfficeRelated/checkingIn/components/AttendanceTable.vue
new file mode 100644
index 0000000..87dbcb5
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/components/AttendanceTable.vue
@@ -0,0 +1,187 @@
+<template>
+  <div class="attendance-table">
+    <div class="table-actions">
+      <el-button type="primary" size="small" icon="el-icon-download" @click="exportData">
+        瀵煎嚭鏁版嵁
+      </el-button>
+      <el-button size="small" icon="el-icon-refresh" @click="$emit('refresh')">
+        鍒锋柊
+      </el-button>
+    </div>
+
+    <el-table
+      :data="tableData"
+      border
+      v-loading="loading"
+      style="width: 100%"
+      @sort-change="handleSortChange"
+    >
+      <el-table-column prop="id" label="ID" width="80" sortable />
+      <el-table-column prop="employeeName" label="鍛樺伐濮撳悕"  sortable />
+      <el-table-column prop="date" label="鏃ユ湡"  sortable />
+      <el-table-column prop="checkIn" label="绛惧埌鏃堕棿"  />
+      <el-table-column prop="checkOut" label="绛鹃��鏃堕棿"  />
+      <el-table-column prop="workHours" label="宸ヤ綔鏃堕暱"  sortable>
+        <template #default="scope">
+          <el-tag :type="getHoursType(scope.row.workHours)" size="small">
+            {{ scope.row.workHours }}h
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="status" label="鐘舵��" >
+        <template #default="scope">
+          <el-tag
+            :type="getStatusType(scope.row.status)"
+            effect="light"
+          >
+            {{ scope.row.status }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" width="150" fixed="right">
+        <template #default="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleViewDetail(scope.row)"
+            icon="el-icon-view"
+          >
+            璇︽儏
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleEdit(scope.row)"
+            icon="el-icon-edit"
+          >
+            缂栬緫
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <div class="pagination-container">
+      <el-pagination
+        :current-page="currentPage"
+        :page-size="pageSize"
+        :total="total"
+        layout="total, sizes, prev, pager, next, jumper"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'AttendanceTable',
+  props: {
+    data: {
+      type: Array,
+      default: () => []
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      currentPage: 1,
+      pageSize: 10,
+      sortProp: '',
+      sortOrder: ''
+    }
+  },
+  computed: {
+    total() {
+      return this.data.length
+    },
+    tableData() {
+      let data = [...this.data]
+
+      // 鎺掑簭澶勭悊
+      if (this.sortProp) {
+        data.sort((a, b) => {
+          let aVal = a[this.sortProp]
+          let bVal = b[this.sortProp]
+
+          if (this.sortOrder === 'ascending') {
+            return aVal > bVal ? 1 : -1
+          } else {
+            return aVal < bVal ? 1 : -1
+          }
+        })
+      }
+
+      // 鍒嗛〉澶勭悊
+      const start = (this.currentPage - 1) * this.pageSize
+      const end = start + this.pageSize
+      return data.slice(start, end)
+    }
+  },
+  methods: {
+    getStatusType(status) {
+      const typeMap = {
+        '姝e父': 'success',
+        '杩熷埌': 'warning',
+        '鏃╅��': 'warning',
+        '缂哄嫟': 'danger'
+      }
+      return typeMap[status] || 'info'
+    },
+
+    getHoursType(hours) {
+      const numHours = parseFloat(hours)
+      if (numHours >= 8) return 'success'
+      if (numHours >= 6) return 'warning'
+      return 'danger'
+    },
+
+    handleViewDetail(row) {
+      this.$emit('view-detail', row)
+    },
+
+    handleEdit(row) {
+      this.$message.info(`缂栬緫鍑哄嫟璁板綍: ${row.employeeName} - ${row.date}`)
+    },
+
+    exportData() {
+      this.$message.success('瀵煎嚭鍔熻兘寮�鍙戜腑')
+    },
+
+    handleSortChange({ prop, order }) {
+      this.sortProp = prop
+      this.sortOrder = order
+    },
+
+    handleSizeChange(size) {
+      this.pageSize = size
+      this.currentPage = 1
+    },
+
+    handleCurrentChange(page) {
+      this.currentPage = page
+    }
+  }
+}
+</script>
+
+<style scoped>
+.attendance-table {
+  padding: 20px;
+}
+
+.table-actions {
+  margin-bottom: 16px;
+  display: flex;
+  gap: 10px;
+}
+
+.pagination-container {
+  margin-top: 20px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/components/BusinessTripTable.vue b/src/views/OfficeRelated/checkingIn/components/BusinessTripTable.vue
new file mode 100644
index 0000000..a07a9d4
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/components/BusinessTripTable.vue
@@ -0,0 +1,234 @@
+<template>
+  <div class="business-trip-table">
+    <div class="table-header">
+      <div class="header-actions">
+        <el-button type="primary" size="small" icon="el-icon-plus" @click="handleAddTrip">
+          鏂板鍑哄樊
+        </el-button>
+        <el-button size="small" icon="el-icon-download" @click="exportData">
+          瀵煎嚭鏁版嵁
+        </el-button>
+      </div>
+
+      <div class="header-filters">
+        <el-input
+          v-model="filters.employeeName"
+          placeholder="鎼滅储鍛樺伐濮撳悕"
+          prefix-icon="el-icon-search"
+          style="width: 200px"
+          clearable
+        />
+        <el-select v-model="filters.status" placeholder="鐘舵�佺瓫閫�" clearable>
+          <el-option label="杩涜涓�" value="杩涜涓�" />
+          <el-option label="宸插畬鎴�" value="宸插畬鎴�" />
+        </el-select>
+      </div>
+    </div>
+
+    <el-table
+      :data="filteredData"
+      border
+      v-loading="loading"
+      style="width: 100%"
+    >
+      <el-table-column prop="tripNumber" label="鍑哄樊鍗曞彿" width="140" />
+      <el-table-column prop="employeeName" label="鍛樺伐濮撳悕"  />
+      <el-table-column prop="startCity" label="鍑哄彂鍩庡競"  />
+      <el-table-column prop="endCity" label="鐩殑鍩庡競"  />
+      <el-table-column prop="startDate" label="寮�濮嬫棩鏈�"  sortable />
+      <el-table-column prop="endDate" label="缁撴潫鏃ユ湡"  sortable />
+      <el-table-column prop="duration" label="鍑哄樊澶╂暟" >
+        <template #default="scope">
+          <el-tag size="small">{{ calculateDuration(scope.row) }}澶�</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="distance" label="閲岀▼(km)"  sortable />
+      <el-table-column prop="status" label="鐘舵��" >
+        <template #default="scope">
+          <el-tag
+            :type="scope.row.status === '宸插畬鎴�' ? 'success' : 'primary'"
+            effect="light"
+          >
+            {{ scope.row.status }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" width="180" fixed="right">
+        <template #default="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleViewDetail(scope.row)"
+            icon="el-icon-view"
+          >
+            璇︽儏
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleEdit(scope.row)"
+            icon="el-icon-edit"
+          >
+            缂栬緫
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleDelete(scope.row)"
+            icon="el-icon-delete"
+            style="color: #f56c6c;"
+          >
+            鍒犻櫎
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <div class="pagination-container">
+      <el-pagination
+        :current-page="currentPage"
+        :page-size="pageSize"
+        :total="total"
+        layout="total, sizes, prev, pager, next, jumper"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'BusinessTripTable',
+  props: {
+    data: {
+      type: Array,
+      default: () => []
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      currentPage: 1,
+      pageSize: 10,
+      filters: {
+        employeeName: '',
+        status: ''
+      }
+    }
+  },
+  computed: {
+    filteredData() {
+      let data = this.data.filter(item => {
+        const nameMatch = !this.filters.employeeName ||
+          item.employeeName.includes(this.filters.employeeName)
+        const statusMatch = !this.filters.status ||
+          item.status === this.filters.status
+        return nameMatch && statusMatch
+      })
+
+      const start = (this.currentPage - 1) * this.pageSize
+      const end = start + this.pageSize
+      return data.slice(start, end)
+    },
+    total() {
+      return this.data.filter(item => {
+        const nameMatch = !this.filters.employeeName ||
+          item.employeeName.includes(this.filters.employeeName)
+        const statusMatch = !this.filters.status ||
+          item.status === this.filters.status
+        return nameMatch && statusMatch
+      }).length
+    }
+  },
+  methods: {
+    calculateDuration(row) {
+      const start = new Date(row.startDate)
+      const end = new Date(row.endDate)
+      const duration = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1
+      return duration
+    },
+
+    handleViewDetail(row) {
+      this.$emit('view-detail', row)
+    },
+
+    handleAddTrip() {
+      this.$message.info('鎵撳紑鏂板鍑哄樊瀵硅瘽妗�')
+    },
+
+    handleEdit(row) {
+      this.$message.info(`缂栬緫鍑哄樊璁板綍: ${row.tripNumber}`)
+    },
+
+    handleDelete(row) {
+      this.$confirm('纭畾瑕佸垹闄よ繖鏉″嚭宸褰曞悧锛�', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.$message.success('鍒犻櫎鎴愬姛')
+      }).catch(() => {})
+    },
+
+    exportData() {
+      this.$message.success('瀵煎嚭鍔熻兘寮�鍙戜腑')
+    },
+
+    handleSizeChange(size) {
+      this.pageSize = size
+      this.currentPage = 1
+    },
+
+    handleCurrentChange(page) {
+      this.currentPage = page
+    }
+  }
+}
+</script>
+
+<style scoped>
+.business-trip-table {
+  padding: 20px;
+}
+
+.table-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+  flex-wrap: wrap;
+  gap: 16px;
+}
+
+.header-actions {
+  display: flex;
+  gap: 10px;
+}
+
+.header-filters {
+  display: flex;
+  gap: 10px;
+  align-items: center;
+}
+
+.pagination-container {
+  margin-top: 20px;
+  display: flex;
+  justify-content: flex-end;
+}
+
+@media (max-width: 768px) {
+  .table-header {
+    flex-direction: column;
+    align-items: stretch;
+  }
+
+  .header-actions {
+    justify-content: space-between;
+  }
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/components/MileageCalculation.vue b/src/views/OfficeRelated/checkingIn/components/MileageCalculation.vue
new file mode 100644
index 0000000..be879ec
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/components/MileageCalculation.vue
@@ -0,0 +1,325 @@
+<template>
+  <div class="mileage-calculation">
+    <div class="calculation-header">
+      <h3>鍑哄樊閲岀▼鏍哥畻</h3>
+      <div class="header-actions">
+        <el-button type="primary" icon="el-icon-calculator" @click="recalculateAll">
+          閲嶆柊璁$畻閲岀▼
+        </el-button>
+        <el-button icon="el-icon-download" @click="exportReport">
+          瀵煎嚭鏍哥畻鎶ュ憡
+        </el-button>
+      </div>
+    </div>
+
+    <div class="filters-section">
+      <el-form :model="filters" inline>
+        <el-form-item label="鍛樺伐濮撳悕">
+          <el-input
+            v-model="filters.employeeName"
+            placeholder="杈撳叆鍛樺伐濮撳悕"
+            clearable
+          />
+        </el-form-item>
+        <el-form-item label="鏃堕棿鑼冨洿">
+          <el-date-picker
+            v-model="filters.dateRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="yyyy-MM-dd"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleFilter">鏌ヨ</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <el-table
+      :data="filteredMileageData"
+      border
+      v-loading="loading"
+      style="width: 100%"
+    >
+      <el-table-column prop="tripNumber" label="鍑哄樊鍗曞彿" width="140" />
+      <el-table-column prop="employeeName" label="鍛樺伐濮撳悕"  />
+      <el-table-column prop="startCity" label="鍑哄彂鍩庡競"  />
+      <el-table-column prop="endCity" label="鐩殑鍩庡競"  />
+      <el-table-column prop="startDate" label="寮�濮嬫棩鏈�"  />
+      <el-table-column prop="endDate" label="缁撴潫鏃ユ湡"  />
+      <el-table-column prop="calculatedDistance" label="鏍哥畻閲岀▼(km)"  sortable>
+        <template #default="scope">
+          <el-tag type="info" size="small">
+            {{ scope.row.calculatedDistance }}km
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="fuelCost" label="鐕冩补璐圭敤(鍏�)"  sortable>
+        <template #default="scope">
+          <span class="amount">楼{{ scope.row.fuelCost }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="allowance" label="鍑哄樊琛ヨ创(鍏�)"  sortable>
+        <template #default="scope">
+          <span class="amount">楼{{ scope.row.allowance }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="totalCost" label="鎬昏垂鐢�(鍏�)"  sortable>
+        <template #default="scope">
+          <span class="amount total">楼{{ scope.row.totalCost }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" width="150" fixed="right">
+        <template #default="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleRecalculate(scope.row)"
+            icon="el-icon-refresh"
+          >
+            閲嶆柊璁$畻
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="handleDetail(scope.row)"
+            icon="el-icon-document"
+          >
+            鏄庣粏
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <div class="summary-section">
+      <el-card shadow="never">
+        <h4>璐圭敤姹囨��</h4>
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <div class="summary-item">
+              <span class="label">鎬婚噷绋�:</span>
+              <span class="value">{{ totalMileage }}鍏噷</span>
+            </div>
+          </el-col>
+          <el-col :span="6">
+            <div class="summary-item">
+              <span class="label">鐕冩补璐圭敤:</span>
+              <span class="value">楼{{ totalFuelCost }}</span>
+            </div>
+          </el-col>
+          <el-col :span="6">
+            <div class="summary-item">
+              <span class="label">鍑哄樊琛ヨ创:</span>
+              <span class="value">楼{{ totalAllowance }}</span>
+            </div>
+          </el-col>
+          <el-col :span="6">
+            <div class="summary-item">
+              <span class="label">鎬昏垂鐢�:</span>
+              <span class="value total">楼{{ totalCost }}</span>
+            </div>
+          </el-col>
+        </el-row>
+      </el-card>
+    </div>
+
+    <div class="pagination-container">
+      <el-pagination
+        :current-page="currentPage"
+        :page-size="pageSize"
+        :total="total"
+        layout="total, sizes, prev, pager, next, jumper"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'MileageCalculation',
+  props: {
+    data: {
+      type: Array,
+      default: () => []
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      currentPage: 1,
+      pageSize: 10,
+      filters: {
+        employeeName: '',
+        dateRange: []
+      }
+    }
+  },
+  computed: {
+    filteredMileageData() {
+      let data = this.data.filter(item => {
+        const nameMatch = !this.filters.employeeName ||
+          item.employeeName.includes(this.filters.employeeName)
+        const dateMatch = !this.filters.dateRange || this.filters.dateRange.length !== 2 ||
+          (item.startDate >= this.filters.dateRange[0] && item.endDate <= this.filters.dateRange[1])
+        return nameMatch && dateMatch
+      })
+
+      const start = (this.currentPage - 1) * this.pageSize
+      const end = start + this.pageSize
+      return data.slice(start, end)
+    },
+    total() {
+      return this.data.filter(item => {
+        const nameMatch = !this.filters.employeeName ||
+          item.employeeName.includes(this.filters.employeeName)
+        const dateMatch = !this.filters.dateRange || this.filters.dateRange.length !== 2 ||
+          (item.startDate >= this.filters.dateRange[0] && item.endDate <= this.filters.dateRange[1])
+        return nameMatch && dateMatch
+      }).length
+    },
+    totalMileage() {
+      return this.filteredMileageData.reduce((sum, item) =>
+        sum + parseFloat(item.calculatedDistance), 0
+      ).toFixed(2)
+    },
+    totalFuelCost() {
+      return this.filteredMileageData.reduce((sum, item) =>
+        sum + parseFloat(item.fuelCost), 0
+      ).toFixed(2)
+    },
+    totalAllowance() {
+      return this.filteredMileageData.reduce((sum, item) =>
+        sum + parseFloat(item.allowance), 0
+      ).toFixed(2)
+    },
+    totalCost() {
+      return this.filteredMileageData.reduce((sum, item) =>
+        sum + parseFloat(item.totalCost), 0
+      ).toFixed(2)
+    }
+  },
+  methods: {
+    handleFilter() {
+      this.currentPage = 1
+    },
+
+    handleReset() {
+      this.filters = {
+        employeeName: '',
+        dateRange: []
+      }
+      this.currentPage = 1
+    },
+
+    recalculateAll() {
+      this.$confirm('纭畾瑕侀噸鏂拌绠楁墍鏈夊嚭宸褰曠殑閲岀▼鍚楋紵', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.$message.success('閲岀▼閲嶆柊璁$畻瀹屾垚')
+      }).catch(() => {})
+    },
+
+    handleRecalculate(row) {
+      this.$message.info(`閲嶆柊璁$畻 ${row.employeeName} 鐨勯噷绋媊)
+    },
+
+    handleDetail(row) {
+      this.$message.info(`鏌ョ湅 ${row.tripNumber} 鐨勮缁嗚垂鐢ㄦ槑缁哷)
+    },
+
+    exportReport() {
+      this.$message.success('瀵煎嚭鍔熻兘寮�鍙戜腑')
+    },
+
+    handleSizeChange(size) {
+      this.pageSize = size
+      this.currentPage = 1
+    },
+
+    handleCurrentChange(page) {
+      this.currentPage = page
+    }
+  }
+}
+</script>
+
+<style scoped>
+.mileage-calculation {
+  padding: 20px;
+}
+
+.calculation-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 24px;
+}
+
+.calculation-header h3 {
+  margin: 0;
+  color: #303133;
+}
+
+.header-actions {
+  display: flex;
+  gap: 10px;
+}
+
+.filters-section {
+  margin-bottom: 20px;
+  padding: 16px;
+  background: #f8f9fa;
+  border-radius: 4px;
+}
+
+.amount {
+  font-weight: 600;
+  color: #409EFF;
+}
+
+.amount.total {
+  color: #F56C6C;
+  font-size: 14px;
+}
+
+.summary-section {
+  margin: 24px 0;
+}
+
+.summary-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 8px 0;
+}
+
+.summary-item .label {
+  color: #606266;
+}
+
+.summary-item .value {
+  font-weight: 600;
+  color: #303133;
+}
+
+.summary-item .value.total {
+  color: #F56C6C;
+  font-size: 16px;
+}
+
+.pagination-container {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 20px;
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/components/PersonBusiness.vue b/src/views/OfficeRelated/checkingIn/components/PersonBusiness.vue
new file mode 100644
index 0000000..2165dbc
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/components/PersonBusiness.vue
@@ -0,0 +1,500 @@
+<template>
+  <div class="personal-business-trip-table">
+    <div class="table-header">
+      <h4>鍑哄樊璁板綍</h4>
+      <div class="header-actions">
+        <el-button
+          size="small"
+          type="primary"
+          @click="handleAddTrip"
+          icon="el-icon-plus"
+        >
+          鏂板鍑哄樊
+        </el-button>
+        <el-button size="small" @click="exportToExcel" icon="el-icon-download">
+          瀵煎嚭Excel
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 绛涢�夋潯浠� -->
+    <el-card class="filter-card" shadow="never">
+      <el-form :model="filterForm" inline>
+        <el-form-item label="鍑哄樊鏃ユ湡">
+          <el-date-picker
+            v-model="filterForm.dateRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="yyyy-MM-dd"
+          />
+        </el-form-item>
+        <el-form-item label="鐩殑鍦�">
+          <el-input
+            v-model="filterForm.destination"
+            placeholder="杈撳叆鐩殑鍦�"
+            clearable
+          />
+        </el-form-item>
+        <el-form-item label="鐘舵��">
+          <el-select v-model="filterForm.status" clearable>
+            <el-option label="鍏ㄩ儴" value="" />
+            <el-option label="杩涜涓�" value="杩涜涓�" />
+            <el-option label="宸插畬鎴�" value="宸插畬鎴�" />
+            <el-option label="宸插彇娑�" value="宸插彇娑�" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleFilter">鏌ヨ</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <el-table
+      :data="filteredTrips"
+      border
+      style="width: 100%"
+      v-loading="loading"
+      class="business-trip-table"
+    >
+      <el-table-column prop="tripNumber" label="鍑哄樊鍗曞彿" width="140" fixed>
+        <template #default="scope">
+          <el-tag type="info" size="small">{{ scope.row.tripNumber }}</el-tag>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="startCity" label="鍑哄彂鍩庡競" >
+        <template #default="scope">
+          <span class="city-cell">{{ scope.row.startCity }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="endCity" label="鐩殑鍩庡競" >
+        <template #default="scope">
+          <span class="city-cell">{{ scope.row.endCity }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="startDate" label="寮�濮嬫棩鏈�"  sortable>
+        <template #default="scope">
+          <span class="date-cell">{{ scope.row.startDate }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="endDate" label="缁撴潫鏃ユ湡"  sortable>
+        <template #default="scope">
+          <span class="date-cell">{{ scope.row.endDate }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="duration" label="鍑哄樊澶╂暟" >
+        <template #default="scope">
+          <el-tag>{{ scope.row.duration }}澶�</el-tag>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="distance" label="閲岀▼(km)"  sortable>
+        <template #default="scope">
+          <span class="distance-cell">{{ scope.row.distance }}km</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column
+        prop="purpose"
+        label="鍑哄樊鐩殑"
+        min-width="150"
+        show-overflow-tooltip
+      >
+        <template #default="scope">
+          <span class="purpose-cell">{{ scope.row.purpose }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="status" label="鐘舵��"  fixed="right">
+        <template #default="scope">
+          <el-tag :type="getStatusType(scope.row.status)" effect="light">
+            {{ scope.row.status }}
+          </el-tag>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="鎿嶄綔" width="150" fixed="right">
+        <template #default="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="viewTripDetails(scope.row)"
+            icon="el-icon-view"
+          >
+            璇︽儏
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            @click="editTrip(scope.row)"
+            icon="el-icon-edit"
+            :disabled="scope.row.status === '宸插畬鎴�'"
+          >
+            缂栬緫
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 鍒嗛〉 -->
+    <div class="pagination-container">
+      <el-pagination
+        :current-page="currentPage"
+        :page-size="pageSize"
+        :total="totalRecords"
+        layout="total, sizes, prev, pager, next, jumper"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+
+    <!-- 鍑哄樊璇︽儏瀵硅瘽妗� -->
+    <el-dialog
+    :title="`鍑哄樊璇︽儏 - ${currentTrip ? currentTrip.tripNumber : ''}`"
+      :visible.sync="detailDialogVisible"
+      width="600px"
+    >
+      <div v-if="currentTrip" class="trip-details">
+        <el-descriptions :column="2" border>
+          <el-descriptions-item label="鍑哄樊鍗曞彿">
+            {{ currentTrip.tripNumber }}
+          </el-descriptions-item>
+          <el-descriptions-item label="鐘舵��">
+            <el-tag :type="getStatusType(currentTrip.status)">
+              {{ currentTrip.status }}
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="鍑哄彂鍩庡競">
+            {{ currentTrip.startCity }}
+          </el-descriptions-item>
+          <el-descriptions-item label="鐩殑鍩庡競">
+            {{ currentTrip.endCity }}
+          </el-descriptions-item>
+          <el-descriptions-item label="寮�濮嬫棩鏈�">
+            {{ currentTrip.startDate }}
+          </el-descriptions-item>
+          <el-descriptions-item label="缁撴潫鏃ユ湡">
+            {{ currentTrip.endDate }}
+          </el-descriptions-item>
+          <el-descriptions-item label="鍑哄樊澶╂暟">
+            {{ currentTrip.duration }}澶�
+          </el-descriptions-item>
+          <el-descriptions-item label="閲岀▼璺濈">
+            {{ currentTrip.distance }}鍏噷
+          </el-descriptions-item>
+          <el-descriptions-item label="鍑哄樊鐩殑" :span="2">
+            {{ currentTrip.purpose }}
+          </el-descriptions-item>
+          <el-descriptions-item label="澶囨敞" :span="2">
+            {{ currentTrip.remarks || "鏃�" }}
+          </el-descriptions-item>
+        </el-descriptions>
+
+        <div
+          v-if="currentTrip.expenses && currentTrip.expenses.length > 0"
+          class="expenses-section"
+        >
+          <h5>璐圭敤鏄庣粏</h5>
+          <el-table :data="currentTrip.expenses" size="small">
+            <el-table-column prop="item" label="璐圭敤椤圭洰" />
+            <el-table-column prop="amount" label="閲戦" />
+            <el-table-column prop="date" label="鏃ユ湡" />
+          </el-table>
+        </div>
+      </div>
+    </el-dialog>
+
+    <!-- 鏂板/缂栬緫鍑哄樊瀵硅瘽妗� -->
+    <el-dialog
+      :title="isEditing ? '缂栬緫鍑哄樊璁板綍' : '鏂板鍑哄樊璁板綍'"
+      :visible.sync="editDialogVisible"
+      width="500px"
+    >
+      <el-form
+        :model="tripForm"
+        :rules="tripRules"
+        ref="tripForm"
+        label-width="100px"
+      >
+        <el-form-item label="鐩殑鍩庡競" prop="endCity">
+          <el-input v-model="tripForm.endCity" placeholder="璇疯緭鍏ョ洰鐨勫煄甯�" />
+        </el-form-item>
+        <el-form-item label="寮�濮嬫棩鏈�" prop="startDate">
+          <el-date-picker
+            v-model="tripForm.startDate"
+            type="date"
+            placeholder="閫夋嫨寮�濮嬫棩鏈�"
+            value-format="yyyy-MM-dd"
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="缁撴潫鏃ユ湡" prop="endDate">
+          <el-date-picker
+            v-model="tripForm.endDate"
+            type="date"
+            placeholder="閫夋嫨缁撴潫鏃ユ湡"
+            value-format="yyyy-MM-dd"
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="鍑哄樊鐩殑" prop="purpose">
+          <el-input
+            v-model="tripForm.purpose"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ュ嚭宸洰鐨�"
+          />
+        </el-form-item>
+      </el-form>
+      <span slot="footer">
+        <el-button @click="editDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="saveTrip">淇濆瓨</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "PersonBusiness",
+  props: {
+    data: {
+      type: Array,
+      default: () => []
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      currentPage: 1,
+      pageSize: 10,
+      filterForm: {
+        dateRange: [],
+        destination: "",
+        status: ""
+      },
+      detailDialogVisible: false,
+      editDialogVisible: false,
+      isEditing: false,
+      currentTrip: null,
+      tripForm: {
+        endCity: "",
+        startDate: "",
+        endDate: "",
+        purpose: ""
+      },
+      tripRules: {
+        endCity: [
+          { required: true, message: "璇疯緭鍏ョ洰鐨勫煄甯�", trigger: "blur" }
+        ],
+        startDate: [
+          { required: true, message: "璇烽�夋嫨寮�濮嬫棩鏈�", trigger: "change" }
+        ],
+        endDate: [
+          { required: true, message: "璇烽�夋嫨缁撴潫鏃ユ湡", trigger: "change" }
+        ],
+        purpose: [
+          { required: true, message: "璇疯緭鍏ュ嚭宸洰鐨�", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  computed: {
+    totalRecords() {
+      return this.filteredTrips.length;
+    },
+    filteredTrips() {
+      let filtered = this.data;
+
+      // 鎸夋棩鏈熻寖鍥磋繃婊�
+      if (this.filterForm.dateRange && this.filterForm.dateRange.length === 2) {
+        const [start, end] = this.filterForm.dateRange;
+        filtered = filtered.filter(item => {
+          const itemStart = new Date(item.startDate);
+          return itemStart >= new Date(start) && itemStart <= new Date(end);
+        });
+      }
+
+      // 鎸夌洰鐨勫湴杩囨护
+      if (this.filterForm.destination) {
+        filtered = filtered.filter(item =>
+          item.endCity.includes(this.filterForm.destination)
+        );
+      }
+
+      // 鎸夌姸鎬佽繃婊�
+      if (this.filterForm.status) {
+        filtered = filtered.filter(
+          item => item.status === this.filterForm.status
+        );
+      }
+
+      return filtered;
+    }
+  },
+  methods: {
+    getStatusType(status) {
+      const typeMap = {
+        杩涜涓�: "primary",
+        宸插畬鎴�: "success",
+        宸插彇娑�: "danger"
+      };
+      return typeMap[status] || "info";
+    },
+
+    viewTripDetails(trip) {
+      this.currentTrip = trip;
+      this.detailDialogVisible = true;
+    },
+
+    handleAddTrip() {
+      this.isEditing = false;
+      this.tripForm = {
+        endCity: "",
+        startDate: "",
+        endDate: "",
+        purpose: ""
+      };
+      this.editDialogVisible = true;
+    },
+
+    editTrip(trip) {
+      this.isEditing = true;
+      this.currentTrip = trip;
+      this.tripForm = { ...trip };
+      this.editDialogVisible = true;
+    },
+
+    saveTrip() {
+      this.$refs.tripForm.validate(valid => {
+        if (valid) {
+          // 杩欓噷搴旇璋冪敤API淇濆瓨鏁版嵁
+          this.$message.success(this.isEditing ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+          this.editDialogVisible = false;
+          this.$emit("refresh");
+        }
+      });
+    },
+
+    handleFilter() {
+      this.currentPage = 1;
+    },
+
+    handleReset() {
+      this.filterForm = {
+        dateRange: [],
+        destination: "",
+        status: ""
+      };
+      this.currentPage = 1;
+    },
+
+    exportToExcel() {
+      // 绠�鍖栫増瀵煎嚭閫昏緫
+      this.$message.success("瀵煎嚭鍔熻兘寮�鍙戜腑");
+    },
+
+    handleSizeChange(size) {
+      this.pageSize = size;
+      this.currentPage = 1;
+    },
+
+    handleCurrentChange(page) {
+      this.currentPage = page;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.personal-business-trip-table {
+  padding: 20px;
+}
+
+.table-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.table-header h4 {
+  margin: 0;
+  color: #303133;
+  font-size: 16px;
+}
+
+.header-actions {
+  display: flex;
+  gap: 10px;
+}
+
+.filter-card {
+  margin-bottom: 20px;
+}
+
+.business-trip-table {
+  margin-bottom: 20px;
+}
+
+.city-cell {
+  font-weight: 500;
+}
+
+.date-cell {
+  color: #606266;
+}
+
+.distance-cell {
+  font-weight: 600;
+  color: #409eff;
+}
+
+.purpose-cell {
+  color: #606266;
+  font-size: 13px;
+}
+
+.pagination-container {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 20px;
+}
+
+.trip-details {
+  padding: 10px;
+}
+
+.expenses-section {
+  margin-top: 20px;
+}
+
+.expenses-section h5 {
+  margin-bottom: 10px;
+  color: #303133;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+  .table-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 10px;
+  }
+
+  .header-actions {
+    width: 100%;
+    justify-content: flex-end;
+  }
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/components/PersonalAttendanceReport.vue b/src/views/OfficeRelated/checkingIn/components/PersonalAttendanceReport.vue
new file mode 100644
index 0000000..8c5d0bd
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/components/PersonalAttendanceReport.vue
@@ -0,0 +1,682 @@
+<template>
+  <div class="personal-attendance-report">
+    <div class="report-header">
+      <h4>鑰冨嫟缁熻鎶ヨ〃</h4>
+      <div class="header-actions">
+        <el-select v-model="reportPeriod" @change="handlePeriodChange" size="small">
+          <el-option label="鏈湀" value="month" />
+          <el-option label="鏈搴�" value="quarter" />
+          <el-option label="鏈勾搴�" value="year" />
+        </el-select>
+        <el-button
+          size="small"
+          @click="exportReport"
+          icon="el-icon-download"
+        >
+          瀵煎嚭鎶ヨ〃
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 缁熻姒傝 -->
+    <el-row :gutter="20" class="stats-overview">
+      <el-col :span="6">
+        <el-card shadow="hover" class="stat-card">
+          <div class="stat-content">
+            <div class="stat-icon attendance-icon">
+              <i class="el-icon-date"></i>
+            </div>
+            <div class="stat-info">
+              <div class="stat-value">{{ overview.totalDays }}</div>
+              <div class="stat-label">鎬诲嚭鍕ゅぉ鏁�</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover" class="stat-card">
+          <div class="stat-content">
+            <div class="stat-icon present-icon">
+              <i class="el-icon-success"></i>
+            </div>
+            <div class="stat-info">
+              <div class="stat-value">{{ overview.presentDays }}</div>
+              <div class="stat-label">姝e父鍑哄嫟</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover" class="stat-card">
+          <div class="stat-content">
+            <div class="stat-icon abnormal-icon">
+              <i class="el-icon-warning"></i>
+            </div>
+            <div class="stat-info">
+              <div class="stat-value">{{ overview.abnormalDays }}</div>
+              <div class="stat-label">寮傚父澶╂暟</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover" class="stat-card">
+          <div class="stat-content">
+            <div class="stat-icon rate-icon">
+              <i class="el-icon-data-analysis"></i>
+            </div>
+            <div class="stat-info">
+              <div class="stat-value">{{ overview.attendanceRate }}%</div>
+              <div class="stat-label">鍑哄嫟鐜�</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 鍥捐〃鍖哄煙 -->
+    <el-row :gutter="20" class="charts-section">
+      <el-col :span="12">
+        <el-card header="鍑哄嫟瓒嬪娍" shadow="never">
+          <div id="attendanceTrendChart" class="chart-container"></div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card header="鑰冨嫟鍒嗗竷" shadow="never">
+          <div id="attendanceDistributionChart" class="chart-container"></div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 璇︾粏缁熻琛ㄦ牸 -->
+    <el-card header="璇︾粏缁熻" class="detail-table-card" shadow="never">
+      <el-table :data="detailedStats" border style="width: 100%">
+        <el-table-column prop="month" label="鏈堜唤"  />
+        <el-table-column prop="workDays" label="搴斿嚭鍕ゅぉ鏁�"  />
+        <el-table-column prop="actualDays" label="瀹為檯鍑哄嫟"  />
+        <el-table-column prop="lateTimes" label="杩熷埌娆℃暟" >
+          <template #default="scope">
+            <el-tag v-if="scope.row.lateTimes > 0" type="warning" size="small">
+              {{ scope.row.lateTimes }}
+            </el-tag>
+            <span v-else>{{ scope.row.lateTimes }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="leaveEarlyTimes" label="鏃╅��娆℃暟" >
+          <template #default="scope">
+            <el-tag v-if="scope.row.leaveEarlyTimes > 0" type="warning" size="small">
+              {{ scope.row.leaveEarlyTimes }}
+            </el-tag>
+            <span v-else>{{ scope.row.leaveEarlyTimes }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="absenceDays" label="缂哄嫟澶╂暟" >
+          <template #default="scope">
+            <el-tag v-if="scope.row.absenceDays > 0" type="danger" size="small">
+              {{ scope.row.absenceDays }}
+            </el-tag>
+            <span v-else>{{ scope.row.absenceDays }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="businessTripDays" label="鍑哄樊澶╂暟" >
+          <template #default="scope">
+            <el-tag v-if="scope.row.businessTripDays > 0" type="primary" size="small">
+              {{ scope.row.businessTripDays }}
+            </el-tag>
+            <span v-else>{{ scope.row.businessTripDays }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="attendanceRate" label="鍑哄嫟鐜�" >
+          <template #default="scope">
+            <el-progress
+              :percentage="scope.row.attendanceRate"
+              :show-text="false"
+              :color="getProgressColor(scope.row.attendanceRate)"
+            />
+            <span>{{ scope.row.attendanceRate }}%</span>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <!-- 寮傚父璁板綍 -->
+    <el-card header="寮傚父璁板綍" class="abnormal-records-card" shadow="never">
+      <el-table :data="abnormalRecords" border style="width: 100%">
+        <el-table-column prop="date" label="鏃ユ湡"  />
+        <el-table-column prop="type" label="寮傚父绫诲瀷" >
+          <template #default="scope">
+            <el-tag :type="getAbnormalType(scope.row.type)" size="small">
+              {{ scope.row.type }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="description" label="鎻忚堪" min-width="200" />
+        <el-table-column prop="duration" label="鏃堕暱"  />
+        <el-table-column prop="status" label="鐘舵��" >
+          <template #default="scope">
+            <el-tag
+              :type="scope.row.status === '宸插鐞�' ? 'success' : 'warning'"
+              size="small"
+            >
+              {{ scope.row.status }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" >
+          <template #default="scope">
+            <el-button type="text" size="mini" @click="viewAbnormalDetail(scope.row)">
+              鏌ョ湅
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+
+export default {
+  name: 'PersonalAttendanceReport',
+  props: {
+    stats: {
+      type: Object,
+      default: () => ({})
+    },
+    attendanceData: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      reportPeriod: 'month',
+      overview: {
+        totalDays: 0,
+        presentDays: 0,
+        abnormalDays: 0,
+        attendanceRate: 0
+      },
+      detailedStats: [],
+      abnormalRecords: [],
+      trendChart: null,
+      distributionChart: null
+    }
+  },
+  mounted() {
+    this.initData()
+    this.$nextTick(() => {
+      this.initCharts()
+    })
+  },
+  beforeDestroy() {
+    // 閿�姣佸浘琛ㄥ疄渚�
+    if (this.trendChart) {
+      this.trendChart.dispose()
+    }
+    if (this.distributionChart) {
+      this.distributionChart.dispose()
+    }
+  },
+  methods: {
+    initData() {
+      // 鍒濆鍖栨瑙堟暟鎹�
+      this.overview = {
+        totalDays: this.stats.totalDays || 22,
+        presentDays: this.stats.presentDays || 20,
+        abnormalDays: this.stats.abnormalDays || 2,
+        attendanceRate: this.stats.attendanceRate || 90.9
+      }
+
+      // 鍒濆鍖栬缁嗙粺璁�
+      this.detailedStats = [
+        { month: '2024-12', workDays: 22, actualDays: 20, lateTimes: 2,
+          leaveEarlyTimes: 1, absenceDays: 0, businessTripDays: 3, attendanceRate: 90.9 },
+        { month: '2024-11', workDays: 21, actualDays: 19, lateTimes: 1,
+          leaveEarlyTimes: 0, absenceDays: 1, businessTripDays: 2, attendanceRate: 90.5 },
+        { month: '2024-10', workDays: 23, actualDays: 22, lateTimes: 0,
+          leaveEarlyTimes: 0, absenceDays: 0, businessTripDays: 1, attendanceRate: 95.7 }
+      ]
+
+      // 鍒濆鍖栧紓甯歌褰�
+      this.abnormalRecords = [
+        { date: '2024-12-15', type: '杩熷埌', description: '鏃╀笂杩熷埌30鍒嗛挓', duration: '30鍒嗛挓', status: '宸插鐞�' },
+        { date: '2024-12-08', type: '鏃╅��', description: '涓嬪崍鎻愬墠1灏忔椂绂诲紑', duration: '1灏忔椂', status: '宸插鐞�' },
+        { date: '2024-11-20', type: '缂哄嫟', description: '鐥呭亣', duration: '1澶�', status: '宸插鐞�' }
+      ]
+    },
+
+    initCharts() {
+      this.initTrendChart()
+      this.initDistributionChart()
+      this.setupChartResize()
+    },
+
+    initTrendChart() {
+      const chartDom = document.getElementById('attendanceTrendChart')
+      if (!chartDom) return
+
+      this.trendChart = echarts.init(chartDom)
+      const option = {
+        tooltip: {
+          trigger: 'axis',
+          formatter: function(params) {
+            let result = params[0].axisValue + '<br/>'
+            params.forEach(param => {
+              result += `${param.seriesName}: ${param.value}<br/>`
+            })
+            return result
+          }
+        },
+        legend: {
+          data: ['鍑哄嫟澶╂暟', '寮傚父澶╂暟', '鍑哄嫟鐜�'],
+          bottom: 10
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '15%',
+          top: '10%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          data: ['10鏈�', '11鏈�', '12鏈�']
+        },
+        yAxis: [
+          {
+            type: 'value',
+            name: '澶╂暟',
+            min: 0,
+            max: 30
+          },
+          {
+            type: 'value',
+            name: '鍑哄嫟鐜�(%)',
+            min: 0,
+            max: 100,
+            axisLabel: {
+              formatter: '{value}%'
+            }
+          }
+        ],
+        series: [
+          {
+            name: '鍑哄嫟澶╂暟',
+            type: 'bar',
+            barWidth: '30%',
+            data: [22, 19, 20],
+            itemStyle: {
+              color: '#409EFF'
+            }
+          },
+          {
+            name: '寮傚父澶╂暟',
+            type: 'bar',
+            barWidth: '30%',
+            data: [1, 2, 2],
+            itemStyle: {
+              color: '#F56C6C'
+            }
+          },
+          {
+            name: '鍑哄嫟鐜�',
+            type: 'line',
+            yAxisIndex: 1,
+            data: [95.7, 90.5, 90.9],
+            itemStyle: {
+              color: '#67C23A'
+            },
+            lineStyle: {
+              width: 3
+            }
+          }
+        ]
+      }
+      this.trendChart.setOption(option)
+    },
+
+    initDistributionChart() {
+      const chartDom = document.getElementById('attendanceDistributionChart')
+      if (!chartDom) return
+
+      this.distributionChart = echarts.init(chartDom)
+      const option = {
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b}: {c} ({d}%)'
+        },
+        legend: {
+          orient: 'vertical',
+          right: 10,
+          top: 'center',
+          data: ['姝e父鍑哄嫟', '杩熷埌', '鏃╅��', '缂哄嫟', '鍑哄樊']
+        },
+        series: [
+          {
+            name: '鑰冨嫟鍒嗗竷',
+            type: 'pie',
+            radius: ['40%', '70%'],
+            center: ['40%', '50%'],
+            avoidLabelOverlap: false,
+            itemStyle: {
+              borderColor: '#fff',
+              borderWidth: 2
+            },
+            label: {
+              show: false,
+              position: 'center'
+            },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: 18,
+                fontWeight: 'bold'
+              }
+            },
+            labelLine: {
+              show: false
+            },
+            data: [
+              { value: 20, name: '姝e父鍑哄嫟', itemStyle: { color: '#67C23A' } },
+              { value: 2, name: '杩熷埌', itemStyle: { color: '#E6A23C' } },
+              { value: 1, name: '鏃╅��', itemStyle: { color: '#F56C6C' } },
+              { value: 0, name: '缂哄嫟', itemStyle: { color: '#909399' } },
+              { value: 3, name: '鍑哄樊', itemStyle: { color: '#409EFF' } }
+            ]
+          }
+        ]
+      }
+      this.distributionChart.setOption(option)
+    },
+
+    setupChartResize() {
+      // 鐩戝惉绐楀彛鍙樺寲锛岄噸鏂版覆鏌撳浘琛�
+      const handleResize = () => {
+        if (this.trendChart) {
+          this.trendChart.resize()
+        }
+        if (this.distributionChart) {
+          this.distributionChart.resize()
+        }
+      }
+
+      window.addEventListener('resize', handleResize)
+      this.$once('hook:beforeDestroy', () => {
+        window.removeEventListener('resize', handleResize)
+      })
+    },
+
+    handlePeriodChange(period) {
+      this.reportPeriod = period
+      this.updateChartData()
+    },
+
+    updateChartData() {
+      // 鏍规嵁閫夋嫨鐨勫懆鏈熸洿鏂板浘琛ㄦ暟鎹�
+      let data
+      switch (this.reportPeriod) {
+        case 'month':
+          data = this.getMonthlyData()
+          break
+        case 'quarter':
+          data = this.getQuarterlyData()
+          break
+        case 'year':
+          data = this.getYearlyData()
+          break
+        default:
+          data = this.getMonthlyData()
+      }
+
+      this.updateCharts(data)
+    },
+
+    getMonthlyData() {
+      // 妯℃嫙鏈堝害鏁版嵁
+      return {
+        xAxis: ['10鏈�', '11鏈�', '12鏈�'],
+        attendance: [22, 19, 20],
+        abnormal: [1, 2, 2],
+        rate: [95.7, 90.5, 90.9]
+      }
+    },
+
+    getQuarterlyData() {
+      // 妯℃嫙瀛e害鏁版嵁
+      return {
+        xAxis: ['Q1', 'Q2', 'Q3', 'Q4'],
+        attendance: [65, 62, 58, 61],
+        abnormal: [5, 8, 6, 4],
+        rate: [92.8, 88.6, 90.2, 93.5]
+      }
+    },
+
+    getYearlyData() {
+      // 妯℃嫙骞村害鏁版嵁
+      return {
+        xAxis: ['2022', '2023', '2024'],
+        attendance: [240, 248, 252],
+        abnormal: [25, 18, 15],
+        rate: [90.2, 92.5, 94.1]
+      }
+    },
+
+    updateCharts(data) {
+      if (this.trendChart) {
+        const option = this.trendChart.getOption()
+        option.xAxis[0].data = data.xAxis
+        option.series[0].data = data.attendance
+        option.series[1].data = data.abnormal
+        option.series[2].data = data.rate
+        this.trendChart.setOption(option)
+      }
+    },
+
+    getProgressColor(rate) {
+      if (rate >= 95) return '#67C23A'
+      if (rate >= 90) return '#E6A23C'
+      if (rate >= 80) return '#F56C6C'
+      return '#909399'
+    },
+
+    getAbnormalType(type) {
+      const typeMap = {
+        '杩熷埌': 'warning',
+        '鏃╅��': 'warning',
+        '缂哄嫟': 'danger',
+        '璇峰亣': 'info'
+      }
+      return typeMap[type] || 'info'
+    },
+
+    viewAbnormalDetail(record) {
+      this.$message.info(`鏌ョ湅寮傚父璁板綍: ${record.date} - ${record.type}`)
+      // 杩欓噷鍙互鎵撳紑璇︽儏瀵硅瘽妗�
+    },
+
+    exportReport() {
+      this.$message.success('鎶ヨ〃瀵煎嚭鍔熻兘寮�鍙戜腑')
+      // 杩欓噷鍙互瀹炵幇瀵煎嚭PDF鎴朎xcel鍔熻兘
+    }
+  }
+}
+</script>
+
+<style scoped>
+.personal-attendance-report {
+  padding: 20px;
+  background: #fff;
+  border-radius: 8px;
+}
+
+.report-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 24px;
+  padding-bottom: 16px;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.report-header h4 {
+  margin: 0;
+  color: #303133;
+  font-size: 20px;
+  font-weight: 600;
+}
+
+.header-actions {
+  display: flex;
+  gap: 12px;
+  align-items: center;
+}
+
+.stats-overview {
+  margin-bottom: 24px;
+}
+
+.stat-card {
+  border-radius: 8px;
+  transition: all 0.3s ease;
+}
+
+.stat-card:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.stat-content {
+  display: flex;
+  align-items: center;
+  padding: 16px;
+}
+
+.stat-icon {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 16px;
+  font-size: 24px;
+  color: white;
+}
+
+.attendance-icon {
+  background: linear-gradient(135deg, #409EFF, #79BBFF);
+}
+
+.present-icon {
+  background: linear-gradient(135deg, #67C23A, #95D475);
+}
+
+.abnormal-icon {
+  background: linear-gradient(135deg, #E6A23C, #EEBD6D);
+}
+
+.rate-icon {
+  background: linear-gradient(135deg, #F56C6C, #F89898);
+}
+
+.stat-info {
+  flex: 1;
+}
+
+.stat-value {
+  font-size: 28px;
+  font-weight: bold;
+  color: #303133;
+  margin-bottom: 4px;
+}
+
+.stat-label {
+  color: #909399;
+  font-size: 14px;
+}
+
+.charts-section {
+  margin-bottom: 24px;
+}
+
+.chart-container {
+  width: 100%;
+  height: 300px;
+}
+
+.detail-table-card,
+.abnormal-records-card {
+  margin-bottom: 20px;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 1200px) {
+  .stats-overview .el-col {
+    margin-bottom: 16px;
+  }
+}
+
+@media (max-width: 768px) {
+  .personal-attendance-report {
+    padding: 12px;
+  }
+
+  .report-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+  }
+
+  .header-actions {
+    width: 100%;
+    justify-content: space-between;
+  }
+
+  .stat-content {
+    padding: 12px;
+  }
+
+  .stat-icon {
+    width: 50px;
+    height: 50px;
+    font-size: 20px;
+    margin-right: 12px;
+  }
+
+  .stat-value {
+    font-size: 24px;
+  }
+
+  .chart-container {
+    height: 250px;
+  }
+}
+
+/* 鍔ㄧ敾鏁堟灉 */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.3s;
+}
+.fade-enter, .fade-leave-to {
+  opacity: 0;
+}
+
+/* 琛ㄦ牸鏍峰紡浼樺寲 */
+.el-table {
+  border-radius: 4px;
+  overflow: hidden;
+}
+
+.el-table::before {
+  display: none;
+}
+
+/* 鍗$墖鏍囬鏍峰紡 */
+.el-card__header {
+  background: #f8f9fa;
+  border-bottom: 1px solid #ebeef5;
+  font-weight: 600;
+  color: #303133;
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/components/PersonalAttendanceTable.vue b/src/views/OfficeRelated/checkingIn/components/PersonalAttendanceTable.vue
new file mode 100644
index 0000000..55e3e3a
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/components/PersonalAttendanceTable.vue
@@ -0,0 +1,331 @@
+<template>
+  <div class="personal-attendance-table">
+    <div class="table-header">
+      <h4>鍑哄嫟璁板綍璇︽儏</h4>
+      <div class="header-actions">
+        <el-button size="small" @click="exportToCSV" icon="el-icon-download">
+          瀵煎嚭CSV
+        </el-button>
+        <el-tooltip content="鍒锋柊鏁版嵁" placement="top">
+          <el-button size="small" @click="refreshData" icon="el-icon-refresh">
+            鍒锋柊
+          </el-button>
+        </el-tooltip>
+      </div>
+    </div>
+
+    <el-table
+      :data="filteredData"
+      border
+      style="width: 100%"
+      v-loading="loading"
+      class="attendance-table"
+    >
+      <el-table-column prop="date" label="鏃ユ湡"  sortable>
+        <template #default="scope">
+          <span class="date-cell">{{ scope.row.date }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="checkIn" label="绛惧埌鏃堕棿" >
+        <template #default="scope">
+          <span :class="getTimeClass(scope.row.checkIn, 'checkIn')">
+            {{ scope.row.checkIn || '-' }}
+          </span>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="checkOut" label="绛鹃��鏃堕棿" >
+        <template #default="scope">
+          <span :class="getTimeClass(scope.row.checkOut, 'checkOut')">
+            {{ scope.row.checkOut || '-' }}
+          </span>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="workHours" label="宸ヤ綔鏃堕暱"  sortable>
+        <template #default="scope">
+          <el-tag
+            :type="getWorkHoursType(scope.row.workHours)"
+            size="small"
+          >
+            {{ scope.row.workHours }}h
+          </el-tag>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="status" label="鐘舵��" >
+        <template #default="scope">
+          <el-tag
+            :type="getStatusType(scope.row.status)"
+            effect="plain"
+          >
+            {{ scope.row.status }}
+          </el-tag>
+        </template>
+      </el-table-column>
+
+      <el-table-column prop="remarks" label="澶囨敞" min-width="150" show-overflow-tooltip>
+        <template #default="scope">
+          <span class="remarks-cell">{{ scope.row.remarks || '鏃�' }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="鎿嶄綔"  fixed="right">
+        <template #default="scope">
+          <el-button
+            size="mini"
+            type="text"
+            @click="viewDetails(scope.row)"
+            icon="el-icon-view"
+          >
+            璇︽儏
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 鍒嗛〉 -->
+    <div class="pagination-container">
+      <el-pagination
+        :current-page="currentPage"
+        :page-size="pageSize"
+        :total="total"
+        layout="total, sizes, prev, pager, next, jumper"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+
+    <!-- 璇︽儏瀵硅瘽妗� -->
+    <el-dialog
+      title="鍑哄嫟璁板綍璇︽儏"
+      :visible.sync="detailDialogVisible"
+      width="500px"
+    >
+      <div v-if="currentRecord" class="record-details">
+        <el-descriptions :column="1" border>
+          <el-descriptions-item label="鏃ユ湡">
+            {{ currentRecord.date }}
+          </el-descriptions-item>
+          <el-descriptions-item label="绛惧埌鏃堕棿">
+            <el-tag :type="getTimeClass(currentRecord.checkIn, 'checkIn')">
+              {{ currentRecord.checkIn }}
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="绛鹃��鏃堕棿">
+            <el-tag :type="getTimeClass(currentRecord.checkOut, 'checkOut')">
+              {{ currentRecord.checkOut }}
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="宸ヤ綔鏃堕暱">
+            <el-tag :type="getWorkHoursType(currentRecord.workHours)">
+              {{ currentRecord.workHours }} 灏忔椂
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="鐘舵��">
+            <el-tag :type="getStatusType(currentRecord.status)">
+              {{ currentRecord.status }}
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="澶囨敞">
+            {{ currentRecord.remarks || '鏃�' }}
+          </el-descriptions-item>
+        </el-descriptions>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'PersonalAttendanceTable',
+  props: {
+    data: {
+      type: Array,
+      default: () => []
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      currentPage: 1,
+      pageSize: 10,
+      detailDialogVisible: false,
+      currentRecord: null,
+      filterForm: {
+        dateRange: [],
+        status: ''
+      }
+    }
+  },
+  computed: {
+    total() {
+      return this.data.length
+    },
+    filteredData() {
+      let filtered = this.data
+
+      // 鎸夋棩鏈熻寖鍥磋繃婊�
+      if (this.filterForm.dateRange && this.filterForm.dateRange.length === 2) {
+        const [start, end] = this.filterForm.dateRange
+        filtered = filtered.filter(item => {
+          const itemDate = new Date(item.date)
+          return itemDate >= new Date(start) && itemDate <= new Date(end)
+        })
+      }
+
+      // 鎸夌姸鎬佽繃婊�
+      if (this.filterForm.status) {
+        filtered = filtered.filter(item => item.status === this.filterForm.status)
+      }
+
+      // 鍒嗛〉
+      const start = (this.currentPage - 1) * this.pageSize
+      const end = start + this.pageSize
+      return filtered.slice(start, end)
+    }
+  },
+  methods: {
+    getTimeClass(time, type) {
+      if (!time) return 'text-muted'
+
+      const hour = parseInt(time.split(':')[0])
+      if (type === 'checkIn') {
+        return hour > 9 ? 'text-danger' : 'text-success'
+      } else {
+        return hour < 18 ? 'text-warning' : 'text-success'
+      }
+    },
+
+    getWorkHoursType(hours) {
+      const numHours = parseFloat(hours)
+      if (numHours >= 8) return 'success'
+      if (numHours >= 6) return 'warning'
+      return 'danger'
+    },
+
+    getStatusType(status) {
+      const typeMap = {
+        '姝e父': 'success',
+        '杩熷埌': 'warning',
+        '鏃╅��': 'warning',
+        '缂哄嫟': 'danger',
+        '鍑哄樊': 'primary'
+      }
+      return typeMap[status] || 'info'
+    },
+
+    viewDetails(record) {
+      this.currentRecord = record
+      this.detailDialogVisible = true
+    },
+
+    exportToCSV() {
+      // 绠�鍖栫増CSV瀵煎嚭閫昏緫
+      const headers = ['鏃ユ湡', '绛惧埌鏃堕棿', '绛鹃��鏃堕棿', '宸ヤ綔鏃堕暱', '鐘舵��', '澶囨敞']
+      const csvData = this.data.map(item => [
+        item.date,
+        item.checkIn,
+        item.checkOut,
+        item.workHours,
+        item.status,
+        item.remarks || ''
+      ])
+
+      const csvContent = [headers, ...csvData]
+        .map(row => row.map(field => `"${field}"`).join(','))
+        .join('\n')
+
+      const blob = new Blob([`\uFEFF${csvContent}`], { type: 'text/csv;charset=utf-8;' })
+      const link = document.createElement('a')
+      link.href = URL.createObjectURL(blob)
+      link.download = `鍑哄嫟璁板綍_${new Date().toISOString().split('T')[0]}.csv`
+      link.click()
+    },
+
+    refreshData() {
+      this.$emit('refresh')
+    },
+
+    handleSizeChange(size) {
+      this.pageSize = size
+      this.currentPage = 1
+    },
+
+    handleCurrentChange(page) {
+      this.currentPage = page
+    }
+  }
+}
+</script>
+
+<style scoped>
+.personal-attendance-table {
+  padding: 20px;
+}
+
+.table-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.table-header h4 {
+  margin: 0;
+  color: #303133;
+  font-size: 16px;
+}
+
+.header-actions {
+  display: flex;
+  gap: 10px;
+}
+
+.attendance-table {
+  margin-bottom: 20px;
+}
+
+.date-cell {
+  font-weight: 500;
+}
+
+.text-success { color: #67c23a; }
+.text-warning { color: #e6a23c; }
+.text-danger { color: #f56c6c; }
+.text-muted { color: #909399; }
+.text-primary { color: #409eff; }
+
+.remarks-cell {
+  color: #606266;
+  font-size: 13px;
+}
+
+.pagination-container {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 20px;
+}
+
+.record-details {
+  padding: 10px;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+  .table-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 10px;
+  }
+
+  .header-actions {
+    width: 100%;
+    justify-content: flex-end;
+  }
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/index.vue b/src/views/OfficeRelated/checkingIn/index.vue
new file mode 100644
index 0000000..18d21aa
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/index.vue
@@ -0,0 +1,317 @@
+<template>
+  <div class="attendance-management">
+    <!-- 椤堕儴缁熻淇℃伅 -->
+    <el-card class="statistics-card">
+      <div class="statistics-header">
+        <h3>鑰冨嫟缁熻姒傝</h3>
+        <span class="statistics-date">{{ currentDate }}</span>
+      </div>
+
+      <el-row :gutter="20" class="statistics-content">
+        <el-col :span="6">
+          <div class="stat-item">
+            <div class="stat-value">{{ statistics.totalEmployees }}</div>
+            <div class="stat-label">鎬诲憳宸ユ暟</div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="stat-item">
+            <div class="stat-value text-success">{{ statistics.onDuty }}</div>
+            <div class="stat-label">浠婃棩鍑哄嫟</div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="stat-item">
+            <div class="stat-value text-warning">{{ statistics.onBusinessTrip }}</div>
+            <div class="stat-label">鍑哄樊涓�</div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="stat-item">
+            <div class="stat-value text-danger">{{ statistics.absent }}</div>
+            <div class="stat-label">缂哄嫟</div>
+          </div>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+    <el-card class="filter-card">
+      <el-form :model="queryParams" inline>
+        <el-form-item label="骞存湀">
+          <el-date-picker
+            v-model="queryParams.month"
+            type="month"
+            placeholder="閫夋嫨骞存湀"
+            value-format="yyyy-MM"
+          />
+        </el-form-item>
+        <el-form-item label="鍛樺伐濮撳悕">
+          <el-input
+            v-model="queryParams.employeeName"
+            placeholder="璇疯緭鍏ュ憳宸ュ鍚�"
+            clearable
+          />
+        </el-form-item>
+        <el-form-item label="鑰冨嫟绫诲瀷">
+          <el-select v-model="queryParams.attendanceType" clearable>
+            <el-option label="鍏ㄩ儴" value="" />
+            <el-option label="鍑哄嫟" value="attendance" />
+            <el-option label="鍑哄樊" value="business_trip" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleQuery">鏌ヨ</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 閫夐」鍗� -->
+    <el-card>
+      <el-tabs v-model="activeTab" @tab-click="handleTabChange">
+        <el-tab-pane label="鍑哄嫟璁板綍" name="attendance">
+          <attendance-table
+            :data="attendanceData"
+            :loading="loading"
+            @view-detail="handleViewDetail"
+          />
+        </el-tab-pane>
+
+        <el-tab-pane label="鍑哄樊璁板綍" name="businessTrip">
+          <business-trip-table
+            :data="businessTripData"
+            :loading="loading"
+            @view-detail="handleViewDetail"
+          />
+        </el-tab-pane>
+
+        <el-tab-pane label="缁熻鍑哄嫟" name="statistics">
+          <attendance-statistics
+            :data="statisticsData"
+            :loading="loading"
+          />
+        </el-tab-pane>
+
+        <el-tab-pane label="鍑哄樊閲岀▼鏍哥畻" name="mileage">
+          <mileage-calculation
+            :data="mileageData"
+            :loading="loading"
+          />
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import AttendanceTable from './components/AttendanceTable.vue'
+import BusinessTripTable from './components/BusinessTripTable.vue'
+import AttendanceStatistics from './components/AttendanceStatistics.vue'
+import MileageCalculation from './components/MileageCalculation.vue'
+
+export default {
+  name: 'AttendanceList',
+  components: {
+    AttendanceTable,
+    BusinessTripTable,
+    AttendanceStatistics,
+    MileageCalculation
+  },
+  data() {
+    return {
+      currentDate: new Date().toLocaleDateString('zh-CN'),
+      statistics: {
+        totalEmployees: 156,
+        onDuty: 142,
+        onBusinessTrip: 8,
+        absent: 6
+      },
+      queryParams: {
+        month: '',
+        employeeName: '',
+        attendanceType: ''
+      },
+      activeTab: 'attendance',
+      loading: false,
+      attendanceData: [],
+      businessTripData: [],
+      statisticsData: [],
+      mileageData: []
+    }
+  },
+  created() {
+    this.loadData()
+  },
+  methods: {
+    // 鍔犺浇妯℃嫙鏁版嵁
+    async loadData() {
+      this.loading = true
+      try {
+        // 妯℃嫙API璋冪敤寤惰繜
+        await new Promise(resolve => setTimeout(resolve, 500))
+
+        // 鐢熸垚妯℃嫙鏁版嵁
+        this.attendanceData = this.generateAttendanceData()
+        this.businessTripData = this.generateBusinessTripData()
+        this.statisticsData = this.generateStatisticsData()
+        this.mileageData = this.generateMileageData()
+      } catch (error) {
+        console.error('鍔犺浇鏁版嵁澶辫触:', error)
+      } finally {
+        this.loading = false
+      }
+    },
+
+    // 鐢熸垚鍑哄嫟妯℃嫙鏁版嵁
+    generateAttendanceData() {
+      const employees = ['寮犱笁', '鏉庡洓', '鐜嬩簲', '璧靛叚', '閽变竷', '瀛欏叓']
+      const statuses = ['姝e父', '杩熷埌', '鏃╅��', '缂哄嫟']
+      const data = []
+
+      for (let i = 0; i < 20; i++) {
+        data.push({
+          id: i + 1,
+          employeeName: employees[Math.floor(Math.random() * employees.length)],
+          date: `2024-12-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`,
+          checkIn: `08:${String(Math.floor(Math.random() * 30)).padStart(2, '0')}`,
+          checkOut: `18:${String(Math.floor(Math.random() * 30)).padStart(2, '0')}`,
+          status: statuses[Math.floor(Math.random() * statuses.length)],
+          workHours: (8 + Math.random() * 2).toFixed(1)
+        })
+      }
+      return data
+    },
+
+    // 鐢熸垚鍑哄樊妯℃嫙鏁版嵁
+    generateBusinessTripData() {
+      const cities = ['鍖椾含', '涓婃捣', '骞垮窞', '娣卞湷', '鏉窞', '鎴愰兘']
+      const data = []
+
+      for (let i = 0; i < 15; i++) {
+        const startDate = new Date(2024, 11, Math.floor(Math.random() * 28) + 1)
+        const endDate = new Date(startDate.getTime() + Math.random() * 5 * 24 * 60 * 60 * 1000)
+
+        data.push({
+          id: i + 1,
+          employeeName: `鍛樺伐${String(i + 1).padStart(3, '0')}`,
+          tripNumber: `BT202412${String(i + 1).padStart(3, '0')}`,
+          startCity: cities[Math.floor(Math.random() * cities.length)],
+          endCity: cities[Math.floor(Math.random() * cities.length)],
+          startDate: startDate.toISOString().split('T')[0],
+          endDate: endDate.toISOString().split('T')[0],
+          distance: Math.floor(Math.random() * 1000) + 200,
+          status: ['杩涜涓�', '宸插畬鎴�'][Math.floor(Math.random() * 2)]
+        })
+      }
+      return data
+    },
+
+    // 鐢熸垚缁熻妯℃嫙鏁版嵁
+    generateStatisticsData() {
+      const months = ['2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06']
+      return months.map(month => ({
+        month,
+        attendanceDays: Math.floor(Math.random() * 20) + 15,
+        lateTimes: Math.floor(Math.random() * 5),
+        leaveEarlyTimes: Math.floor(Math.random() * 3),
+        absenceDays: Math.floor(Math.random() * 3)
+      }))
+    },
+
+    // 鐢熸垚閲岀▼妯℃嫙鏁版嵁
+    generateMileageData() {
+      return this.businessTripData.map(item => ({
+        ...item,
+        calculatedDistance: item.distance,
+        fuelCost: (item.distance * 0.8).toFixed(2),
+        allowance: (item.distance * 0.5).toFixed(2)
+      }))
+    },
+
+    handleQuery() {
+      this.loadData()
+    },
+
+    handleReset() {
+      this.queryParams = {
+        month: '',
+        employeeName: '',
+        attendanceType: ''
+      }
+      this.loadData()
+    },
+
+    handleTabChange(tab) {
+      this.activeTab = tab.name
+    },
+
+    handleViewDetail(employee) {
+      this.$router.push({
+        path: '/office/checkingInInfo',
+        query: {
+          employeeId: employee.id,
+          employeeName: employee.employeeName
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.attendance-management {
+  padding: 20px;
+}
+
+.statistics-card {
+  margin-bottom: 20px;
+}
+
+.statistics-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.statistics-header h3 {
+  margin: 0;
+  color: #303133;
+}
+
+.statistics-date {
+  color: #909399;
+  font-size: 14px;
+}
+
+.statistics-content {
+  text-align: center;
+}
+
+.stat-item {
+  padding: 20px;
+  border-radius: 8px;
+  background: #f8f9fa;
+}
+
+.stat-value {
+  font-size: 32px;
+  font-weight: bold;
+  color: #409eff;
+  margin-bottom: 8px;
+}
+
+.stat-label {
+  color: #606266;
+  font-size: 14px;
+}
+
+.text-success { color: #67c23a; }
+.text-warning { color: #e6a23c; }
+.text-danger { color: #f56c6c; }
+
+.filter-card {
+  margin-bottom: 20px;
+}
+</style>
diff --git a/src/views/OfficeRelated/checkingIn/mockData.js b/src/views/OfficeRelated/checkingIn/mockData.js
new file mode 100644
index 0000000..f419c38
--- /dev/null
+++ b/src/views/OfficeRelated/checkingIn/mockData.js
@@ -0,0 +1,165 @@
+// 鍦ㄧ埗缁勪欢 data() 涓垨鍗曠嫭鍒涘缓 mockData.js 鏂囦欢
+export const generateMockData = () => {
+  return {
+    // 鍛樺伐鑰冨嫟鏁版嵁
+    attendanceData: [
+      {
+        id: 1,
+        date: '2024-12-01',
+        checkIn: '08:30',
+        checkOut: '18:00',
+        status: 'present',
+        workHours: 9.5
+      },
+      {
+        id: 2,
+        date: '2024-12-02',
+        checkIn: '09:15',
+        checkOut: '18:00',
+        status: 'late',
+        workHours: 8.75
+      },
+      {
+        id: 3,
+        date: '2024-12-03',
+        checkIn: '08:45',
+        checkOut: '17:30',
+        status: 'present',
+        workHours: 8.75
+      },
+      {
+        id: 4,
+        date: '2024-12-04',
+        checkIn: '08:25',
+        checkOut: '18:10',
+        status: 'present',
+        workHours: 9.75
+      },
+      {
+        id: 5,
+        date: '2024-12-05',
+        checkIn: null,
+        checkOut: null,
+        status: 'absent',
+        workHours: 0
+      },
+      {
+        id: 6,
+        date: '2024-12-08',
+        checkIn: '08:40',
+        checkOut: '17:45',
+        status: 'present',
+        workHours: 9.0
+      },
+      {
+        id: 7,
+        date: '2024-12-09',
+        checkIn: '08:35',
+        checkOut: '18:05',
+        status: 'present',
+        workHours: 9.5
+      },
+      {
+        id: 8,
+        date: '2024-12-10',
+        checkIn: '09:05',
+        checkOut: '17:50',
+        status: 'late',
+        workHours: 8.75
+      },
+      {
+        id: 9,
+        date: '2024-12-11',
+        checkIn: '08:50',
+        checkOut: '18:15',
+        status: 'present',
+        workHours: 9.5
+      },
+      {
+        id: 10,
+        date: '2024-12-12',
+        checkIn: '08:30',
+        checkOut: '17:40',
+        status: 'present',
+        workHours: 9.0
+      },
+      {
+        id: 11,
+        date: '2024-12-15',
+        checkIn: '08:45',
+        checkOut: '18:00',
+        status: 'present',
+        workHours: 9.25
+      },
+      {
+        id: 12,
+        date: '2024-12-16',
+        checkIn: '08:55',
+        checkOut: '17:55',
+        status: 'present',
+        workHours: 9.0
+      },
+      {
+        id: 13,
+        date: '2024-12-17',
+        checkIn: '08:40',
+        checkOut: '18:10',
+        status: 'present',
+        workHours: 9.5
+      },
+      {
+        id: 14,
+        date: '2024-12-18',
+        checkIn: '09:20',
+        checkOut: '17:30',
+        status: 'late',
+        workHours: 8.0
+      },
+      {
+        id: 15,
+        date: '2024-12-19',
+        checkIn: '08:35',
+        checkOut: '18:05',
+        status: 'present',
+        workHours: 9.5
+      }
+    ],
+
+    // 鍑哄樊鏁版嵁
+    businessTripData: [
+      {
+        id: 1,
+        tripNumber: 'BT202412001',
+        startCity: '鍖椾含',
+        endCity: '涓婃捣',
+        startDate: '2024-12-05',
+        endDate: '2024-12-08',
+        distance: 1200,
+        purpose: '瀹㈡埛浼氳',
+        status: 'completed'
+      },
+      {
+        id: 2,
+        tripNumber: 'BT202412002',
+        startCity: '鍖椾含',
+        endCity: '骞垮窞',
+        startDate: '2024-12-15',
+        endDate: '2024-12-18',
+        distance: 1900,
+        purpose: '椤圭洰璋冪爺',
+        status: 'completed'
+      },
+      {
+        id: 3,
+        tripNumber: 'BT202412003',
+        startCity: '鍖椾含',
+        endCity: '娣卞湷',
+        startDate: '2024-12-22',
+        endDate: '2024-12-24',
+        distance: 1950,
+        purpose: '鎶�鏈氦娴�',
+        status: 'completed'
+      }
+    ]
+  }
+}
diff --git a/src/views/business/GetWitness/GetWitnessInfo.vue b/src/views/business/GetWitness/GetWitnessInfo.vue
new file mode 100644
index 0000000..41bde72
--- /dev/null
+++ b/src/views/business/GetWitness/GetWitnessInfo.vue
@@ -0,0 +1,1577 @@
+<template>
+  <div class="organ-procurement-detail">
+    <!-- 鍩烘湰淇℃伅 -->
+    <el-card class="detail-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鍣ㄥ畼鑾峰彇鍩烘湰淇℃伅</span>
+        <div style="float: right;">
+          <el-button type="primary" @click="handleSave" :loading="saveLoading">
+            淇濆瓨
+          </el-button>
+          <el-button
+            type="success"
+            @click="handleProcure"
+            :disabled="form.procurementStatus === 'procured'"
+          >
+            纭鑾峰彇
+          </el-button>
+        </div>
+      </div>
+
+      <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+              <el-input v-model="form.hospitalNo" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="妗堜緥缂栧彿" prop="caseNo">
+              <el-input v-model="form.caseNo" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+              <el-input v-model="form.donorName" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="鎬у埆" prop="gender">
+              <el-select v-model="form.gender" style="width: 100%">
+                <el-option label="鐢�" value="0" />
+                <el-option label="濂�" value="1" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <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="birthDate">
+              <el-date-picker
+                v-model="form.birthDate"
+                type="date"
+                value-format="yyyy-MM-dd"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐤剧梾璇婃柇" prop="diagnosis">
+              <el-input
+                type="textarea"
+                :rows="2"
+                v-model="form.diagnosis"
+                placeholder="璇疯緭鍏ョ柧鐥呰瘖鏂俊鎭�"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鑾峰彇鏃堕棿" prop="procurementTime">
+              <el-date-picker
+                v-model="form.procurementTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+                :disabled="form.procurementStatus !== 'procured'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="鎵嬫湳鍚嶇О" prop="surgeryName">
+              <el-input v-model="form.surgeryName" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎵嬫湳寮�濮嬫椂闂�" prop="surgeryStartTime">
+              <el-date-picker
+                v-model="form.surgeryStartTime"
+                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="donorDeathTime">
+              <el-date-picker
+                v-model="form.donorDeathTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="鑵逛富鍔ㄨ剦鎻掔鏃堕棿" prop="abdominalAortaCannulationTime">
+              <el-date-picker
+                v-model="form.abdominalAortaCannulationTime"
+                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="inferiorVenaCavaCannulationTime">
+              <el-date-picker
+                v-model="form.inferiorVenaCavaCannulationTime"
+                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="superiorMesentericVeinCannulationTime">
+              <el-date-picker
+                v-model="form.superiorMesentericVeinCannulationTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐧昏浜�" prop="registrant">
+              <el-input v-model="form.registrant" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐧昏鏃堕棿" prop="registrationTime">
+              <el-date-picker
+                v-model="form.registrationTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+                readonly
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+
+    <!-- 鍣ㄥ畼鑾峰彇璁板綍閮ㄥ垎 -->
+    <el-card class="procurement-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鍣ㄥ畼鑾峰彇璁板綍</span>
+        <div style="float: right;">
+          <el-tag :type="form.procurementStatus === 'procured' ? 'success' : 'warning'">
+            {{ form.procurementStatus === 'procured' ? '宸茶幏鍙�' : '寰呰幏鍙�' }}
+          </el-tag>
+        </div>
+      </div>
+
+      <el-form
+        ref="procurementForm"
+        :rules="procurementRules"
+        :model="procurementData"
+        label-position="right"
+      >
+        <el-row>
+          <el-col>
+            <el-form-item label-width="100px" label="鑾峰彇鍣ㄥ畼">
+              <el-checkbox-group v-model="selectedOrgans" @change="handleOrganSelectionChange">
+                <el-checkbox
+                  v-for="dict in dict.type.sys_Organ || []"
+                  :key="dict.value"
+                  :label="dict.value"
+                  :disabled="form.procurementStatus === 'procured'"
+                >
+                  {{ dict.label }}
+                </el-checkbox>
+              </el-checkbox-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col>
+            <el-form-item>
+              <el-table
+                :data="procurementData.records"
+                v-loading="loading"
+                border
+                style="width: 100%"
+                :row-class-name="getOrganRowClassName"
+              >
+                <el-table-column
+                  label="鍣ㄥ畼鍚嶇О"
+                  align="center"
+                  width="120"
+                  prop="organName"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.organName"
+                      placeholder="鍣ㄥ畼鍚嶇О"
+                      :disabled="true"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鑾峰彇寮�濮嬫椂闂�"
+                  align="center"
+                  width="180"
+                  prop="organStartTime"
+                >
+                  <template slot-scope="scope">
+                    <el-date-picker
+                      clearable
+                      size="small"
+                      style="width: 100%"
+                      v-model="scope.row.organStartTime"
+                      type="datetime"
+                      value-format="yyyy-MM-dd HH:mm:ss"
+                      placeholder="閫夋嫨鑾峰彇寮�濮嬫椂闂�"
+                      :disabled="form.procurementStatus === 'procured'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鍣ㄥ畼绂讳綋鏃堕棿"
+                  align="center"
+                  width="180"
+                  prop="organGetTime"
+                >
+                  <template slot-scope="scope">
+                    <el-date-picker
+                      clearable
+                      size="small"
+                      style="width: 100%"
+                      v-model="scope.row.organGetTime"
+                      type="datetime"
+                      value-format="yyyy-MM-dd HH:mm:ss"
+                      placeholder="閫夋嫨鍣ㄥ畼绂讳綋鏃堕棿"
+                      :disabled="form.procurementStatus === 'procured'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鑾峰彇鍖婚櫌"
+                  align="center"
+                  width="200"
+                  prop="gainHospitalNo"
+                >
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.gainHospitalNo"
+                      placeholder="璇烽�夋嫨鑾峰彇鍖婚櫌"
+                      style="width: 100%"
+                      :disabled="form.procurementStatus === 'procured'"
+                      @change="handleHospitalChange(scope.row, $event)"
+                    >
+                      <el-option
+                        v-for="hospital in hospitalList"
+                        :key="hospital.hospitalNo"
+                        :label="hospital.hospitalName"
+                        :value="hospital.hospitalNo"
+                      />
+                    </el-select>
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鑾峰彇鍖诲笀"
+                  align="center"
+                  width="120"
+                  prop="organGetDoctor"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.organGetDoctor"
+                      placeholder="鑾峰彇鍖诲笀"
+                      :disabled="form.procurementStatus === 'procured'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鍔╂墜"
+                  align="center"
+                  width="120"
+                  prop="assistant"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.assistant"
+                      placeholder="鍔╂墜"
+                      :disabled="form.procurementStatus === 'procured'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鑾峰彇鎶ゅ+"
+                  align="center"
+                  width="120"
+                  prop="procurementNurse"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.procurementNurse"
+                      placeholder="鑾峰彇鎶ゅ+"
+                      :disabled="form.procurementStatus === 'procured'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鎵嬫湳瀹ゆ姢澹�"
+                  align="center"
+                  width="120"
+                  prop="operatingRoomNurse"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.operatingRoomNurse"
+                      placeholder="鎵嬫湳瀹ゆ姢澹�"
+                      :disabled="form.procurementStatus === 'procured'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="楹婚唹鍖荤敓"
+                  align="center"
+                  width="120"
+                  prop="anesthesiologist"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.anesthesiologist"
+                      placeholder="楹婚唹鍖荤敓"
+                      :disabled="form.procurementStatus === 'procured'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鑾峰彇鐘舵��"
+                  align="center"
+                  width="120"
+                  prop="organState"
+                >
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.organState"
+                      placeholder="璇烽�夋嫨鑾峰彇鐘舵��"
+                      style="width: 100%"
+                      :disabled="form.procurementStatus === 'procured'"
+                    >
+                      <el-option
+                        v-for="dict in organStateList"
+                        :key="dict.value"
+                        :label="dict.label"
+                        :value="dict.value"
+                      />
+                    </el-select>
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="璇存槑"
+                  align="center"
+                  prop="notGetReason"
+                  min-width="200"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      type="textarea"
+                      clearable
+                      v-model="scope.row.notGetReason"
+                      placeholder="璇疯緭鍏ユ湭鑾峰彇璇存槑"
+                      :disabled="form.procurementStatus === 'procured'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鎿嶄綔"
+                  align="center"
+                  width="120"
+                  class-name="small-padding fixed-width"
+                  v-if="form.procurementStatus !== 'procured'"
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="mini"
+                      type="text"
+                      icon="el-icon-edit"
+                      @click="handleEditProcurement(scope.row)"
+                    >
+                      缂栬緫
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <!-- 鑾峰彇缁熻淇℃伅 -->
+        <div class="procurement-stats" v-if="procurementData.records.length > 0">
+          <el-row :gutter="20">
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">宸茶幏鍙栧櫒瀹�:</span>
+                <span class="stat-value">{{ procurementData.records.length }} 涓�</span>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">寰呭畬鍠勪俊鎭�:</span>
+                <span class="stat-value">{{ incompleteRecords }} 涓�</span>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">娑夊強鍖婚櫌:</span>
+                <span class="stat-value">{{ uniqueHospitals }} 瀹�</span>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">鑾峰彇鐘舵��:</span>
+                <span class="stat-value">
+                  <el-tag :type="form.procurementStatus === 'procured' ? 'success' : 'warning'">
+                    {{ form.procurementStatus === 'procured' ? '宸插畬鎴�' : '杩涜涓�' }}
+                  </el-tag>
+                </span>
+              </div>
+            </el-col>
+          </el-row>
+        </div>
+
+        <div v-else class="empty-procurement">
+          <el-empty description="鏆傛棤鑾峰彇璁板綍" :image-size="80">
+            <span>璇峰厛閫夋嫨瑕佽幏鍙栫殑鍣ㄥ畼</span>
+          </el-empty>
+        </div>
+      </el-form>
+
+      <div class="dialog-footer" v-if="form.procurementStatus !== 'procured'">
+        <el-button
+          type="primary"
+          @click="handleSaveProcurement"
+          :loading="saveLoading"
+          :disabled="procurementData.records.length === 0"
+        >
+          淇濆瓨鑾峰彇璁板綍
+        </el-button>
+        <el-button
+          type="success"
+          @click="handleConfirmProcurement"
+          :loading="confirmLoading"
+          :disabled="incompleteRecords > 0"
+        >
+          纭瀹屾垚鑾峰彇
+        </el-button>
+      </div>
+    </el-card>
+
+    <!-- 闄勪欢绠$悊閮ㄥ垎 -->
+    <el-card class="attachment-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鐩稿叧闄勪欢</span>
+        <el-button
+          type="primary"
+          size="mini"
+          icon="el-icon-upload"
+          @click="handleUploadAttachment"
+        >
+          涓婁紶闄勪欢
+        </el-button>
+      </div>
+
+      <div class="attachment-list">
+        <el-table :data="attachments" style="width: 100%">
+          <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
+            <template slot-scope="scope">
+              <div class="file-info">
+                <i :class="getFileIcon(scope.row.fileName)" style="margin-right: 8px; color: #409EFF;"></i>
+                <span>{{ scope.row.fileName }}</span>
+              </div>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="鏂囦欢绫诲瀷" width="100" 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="100" align="center">
+            <template slot-scope="scope">
+              <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="涓婁紶鏃堕棿" width="160" align="center">
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.uploadTime) }}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="鎿嶄綔" width="150" align="center">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-view"
+                @click="handlePreviewAttachment(scope.row)"
+              >棰勮</el-button>
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-download"
+                @click="handleDownloadAttachment(scope.row)"
+              >涓嬭浇</el-button>
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-delete"
+                style="color: #F56C6C;"
+                @click="handleRemoveAttachment(scope.row)"
+              >鍒犻櫎</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-card>
+
+    <!-- 缂栬緫鑾峰彇璁板綍瀵硅瘽妗� -->
+    <el-dialog
+      title="缂栬緫鍣ㄥ畼鑾峰彇璁板綍"
+      :visible.sync="editDialogVisible"
+      width="600px"
+    >
+      <el-form :model="currentRecord" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍣ㄥ畼鍚嶇О">
+              <el-input v-model="currentRecord.organName" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鑾峰彇鐘舵��">
+              <el-select v-model="currentRecord.organState" style="width: 100%">
+                <el-option
+                  v-for="dict in organStateList"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鑾峰彇鍖诲笀">
+              <el-input v-model="currentRecord.organGetDoctor" placeholder="璇疯緭鍏ヨ幏鍙栧尰甯�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍔╂墜">
+              <el-input v-model="currentRecord.assistant" placeholder="璇疯緭鍏ュ姪鎵嬪鍚�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鑾峰彇鎶ゅ+">
+              <el-input v-model="currentRecord.procurementNurse" placeholder="璇疯緭鍏ヨ幏鍙栨姢澹�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎵嬫湳瀹ゆ姢澹�">
+              <el-input v-model="currentRecord.operatingRoomNurse" placeholder="璇疯緭鍏ユ墜鏈鎶ゅ+" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item label="楹婚唹鍖荤敓">
+          <el-input v-model="currentRecord.anesthesiologist" placeholder="璇疯緭鍏ラ夯閱夊尰鐢�" />
+        </el-form-item>
+
+        <el-form-item label="鏈幏鍙栬鏄�" v-if="currentRecord.organState === '0'">
+          <el-input
+            type="textarea"
+            :rows="3"
+            v-model="currentRecord.notGetReason"
+            placeholder="璇疯緭鍏ユ湭鑾峰彇鐨勫師鍥犺鏄�"
+          />
+        </el-form-item>
+      </el-form>
+
+      <div slot="footer">
+        <el-button @click="editDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleEditConfirm">纭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getOrganProcurementDetail,
+  updateOrganProcurement,
+  saveProcurementRecords,
+  getHospitalList,
+  getCoordinatorList
+} from "./organProcurement";
+
+export default {
+  name: "OrganProcurementDetail",
+  dicts: ["sys_user_sex", "sys_Organ", "sys_0_1", "sys_DonationCategory"],
+  data() {
+    return {
+      // 琛ㄥ崟鏁版嵁
+      form: {
+        id: undefined,
+        hospitalNo: "",
+        caseNo: "",
+        donorName: "",
+        gender: "",
+        age: "",
+        birthDate: "",
+        diagnosis: "",
+        procurementStatus: "pending",
+        procurementTime: "",
+        registrant: "",
+        registrationTime: "",
+        surgeryName: "",
+        surgeryStartTime: "",
+        donorDeathTime: "",
+        abdominalAortaCannulationTime: "",
+        inferiorVenaCavaCannulationTime: "",
+        superiorMesentericVeinCannulationTime: "",
+        donationCategory: "1",
+        deathJudgeDoctor1: "",
+        deathJudgeDoctor2: "",
+        deathReason: "",
+        operationEndTime: "",
+        coordinatorInOperating: "",
+        coordinatorOutOperating: "",
+        coordinatorSignTime: "",
+        responsibleUserName: "",
+        coordinatedUserId1: "",
+        coordinatedUserId2: "",
+        isSpendRemember: 1,
+        isRestoreRemains: 1
+      },
+      // 琛ㄥ崟楠岃瘉瑙勫垯
+      rules: {
+        donorName: [
+          { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+        ],
+        diagnosis: [
+          { required: true, message: "鐤剧梾璇婃柇涓嶈兘涓虹┖", trigger: "blur" }
+        ],
+        surgeryName: [
+          { required: true, message: "鎵嬫湳鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+      },
+      // 鑾峰彇璁板綍楠岃瘉瑙勫垯
+      procurementRules: {},
+      // 淇濆瓨鍔犺浇鐘舵��
+      saveLoading: false,
+      confirmLoading: false,
+      // 鍔犺浇鐘舵��
+      loading: false,
+      // 閫変腑鐨勫櫒瀹�
+      selectedOrgans: [],
+      // 鍖婚櫌鍒楄〃
+      hospitalList: [],
+      // 鍗忚皟鍛樺垪琛�
+      coordinatorList: [],
+      // 鍣ㄥ畼鐘舵�佸垪琛�
+      organStateList: [
+        { value: "1", label: "宸茶幏鍙�" },
+        { value: "0", label: "鏈幏鍙�" },
+        { value: "2", label: "閮ㄥ垎鑾峰彇" }
+      ],
+      // 鑾峰彇璁板綍鏁版嵁
+      procurementData: {
+        records: []
+      },
+      // 闄勪欢鏁版嵁
+      attachments: [],
+      // 缂栬緫瀵硅瘽妗�
+      editDialogVisible: false,
+      currentRecord: {},
+      currentEditIndex: -1
+    };
+  },
+  computed: {
+    // 褰撳墠鐢ㄦ埛淇℃伅
+    currentUser() {
+      return JSON.parse(sessionStorage.getItem("user") || "{}");
+    },
+    // 涓嶅畬鏁寸殑璁板綍鏁伴噺
+    incompleteRecords() {
+      return this.procurementData.records.filter(
+        record =>
+          !record.organStartTime ||
+          !record.organGetTime ||
+          !record.gainHospitalNo ||
+          !record.organGetDoctor
+      ).length;
+    },
+    // 鍞竴鍖婚櫌鏁伴噺
+    uniqueHospitals() {
+      const hospitals = this.procurementData.records
+        .map(record => record.gainHospitalNo)
+        .filter(Boolean);
+      return new Set(hospitals).size;
+    }
+  },
+  created() {
+    const id = this.$route.query.id;
+    if (id) {
+      this.getDetail(id);
+    } else {
+      this.generateCaseNo();
+      this.form.registrant = this.currentUser.username || "褰撳墠鐢ㄦ埛";
+      this.form.registrationTime = new Date()
+        .toISOString()
+        .replace("T", " ")
+        .substring(0, 19);
+    }
+    this.getHospitalData();
+    this.getCoordinatorData();
+  },
+  methods: {
+    // 鐢熸垚妗堜緥缂栧彿
+    generateCaseNo() {
+      const timestamp = Date.now().toString();
+      this.form.hospitalNo = "D" + timestamp.slice(-6);
+      this.form.caseNo = "C" + timestamp.slice(-6);
+    },
+    // 鑾峰彇璇︽儏
+    getDetail(id) {
+      this.loading = true;
+      getOrganProcurementDetail(id)
+        .then(response => {
+          if (response.code === 200) {
+            this.form = response.data;
+            if (response.data.procurementRecords) {
+              this.procurementData.records = response.data.procurementRecords;
+              this.selectedOrgans = response.data.procurementRecords.map(
+                item => item.organNo
+              );
+            }
+          }
+          this.loading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇鍣ㄥ畼鑾峰彇璇︽儏澶辫触:", error);
+          this.loading = false;
+          this.$message.error("鑾峰彇璇︽儏澶辫触");
+        });
+    },
+    // 鑾峰彇鍖婚櫌鏁版嵁
+    getHospitalData() {
+      getHospitalList().then(response => {
+        if (response.code === 200) {
+          this.hospitalList = response.data;
+        }
+      });
+    },
+    // 鑾峰彇鍗忚皟鍛樻暟鎹�
+    getCoordinatorData() {
+      getCoordinatorList().then(response => {
+        if (response.code === 200) {
+          this.coordinatorList = response.data;
+        }
+      });
+    },
+    // 鍣ㄥ畼閫夋嫨鐘舵�佸彉鍖�
+    handleOrganSelectionChange(selectedValues) {
+      const currentOrganNos = this.procurementData.records.map(
+        item => item.organNo
+      );
+
+      // 鏂板閫夋嫨鐨勫櫒瀹�
+      selectedValues.forEach(organValue => {
+        if (!currentOrganNos.includes(organValue)) {
+          const organInfo = this.dict.type.sys_Organ.find(
+            item => item.value === organValue
+          );
+          if (organInfo) {
+            this.procurementData.records.push({
+              organName: organInfo.label,
+              organNo: organValue,
+              id: null,
+              procurementId: this.form.id,
+              organStartTime: "",
+              organGetTime: "",
+              gainHospitalNo: "",
+              gainHospitalName: "",
+              organGetDoctor: "",
+              assistant: "",
+              procurementNurse: "",
+              operatingRoomNurse: "",
+              anesthesiologist: "",
+              organState: "1",
+              notGetReason: ""
+            });
+          }
+        }
+      });
+
+      // 绉婚櫎鍙栨秷閫夋嫨鐨勫櫒瀹�
+      this.procurementData.records = this.procurementData.records.filter(
+        record => {
+          if (selectedValues.includes(record.organNo)) {
+            return true;
+          } else {
+            if (record.id) {
+              this.$confirm(
+                "鍒犻櫎鍣ㄥ畼鑾峰彇鏁版嵁鍚庡皢鏃犳硶鎭㈠锛屾偍纭鍒犻櫎璇ユ潯璁板綍鍚楋紵",
+                "鎻愮ず",
+                {
+                  confirmButtonText: "纭畾",
+                  cancelButtonText: "鍙栨秷",
+                  type: "warning"
+                }
+              )
+                .then(() => {
+                  this.procurementData.records = this.procurementData.records.filter(
+                    r => r.organNo !== record.organNo
+                  );
+                  this.$message.success("鍒犻櫎鎴愬姛");
+                })
+                .catch(() => {
+                  this.selectedOrgans.push(record.organNo);
+                });
+              return true;
+            } else {
+              return false;
+            }
+          }
+        }
+      );
+    },
+    // 鍖婚櫌閫夋嫨鍙樺寲
+    handleHospitalChange(row, hospitalNo) {
+      const hospital = this.hospitalList.find(
+        item => item.hospitalNo === hospitalNo
+      );
+      if (hospital) {
+        row.gainHospitalName = hospital.hospitalName;
+      }
+    },
+    // 缂栬緫鑾峰彇璁板綍
+    handleEditProcurement(row) {
+      const index = this.procurementData.records.findIndex(
+        item => item.organNo === row.organNo
+      );
+      if (index !== -1) {
+        this.currentRecord = { ...row };
+        this.currentEditIndex = index;
+        this.editDialogVisible = true;
+      }
+    },
+    // 纭缂栬緫
+    handleEditConfirm() {
+      if (this.currentEditIndex !== -1) {
+        this.procurementData.records[this.currentEditIndex] = {
+          ...this.currentRecord
+        };
+        this.$message.success("鑾峰彇璁板綍鏇存柊鎴愬姛");
+        this.editDialogVisible = false;
+      }
+    },
+    // 鍣ㄥ畼琛屾牱寮�
+    getOrganRowClassName({ row }) {
+      if (
+        !row.organStartTime ||
+        !row.organGetTime ||
+        !row.gainHospitalNo ||
+        !row.organGetDoctor
+      ) {
+        return "warning-row";
+      }
+      return "";
+    },
+    // 淇濆瓨鍩烘湰淇℃伅
+    handleSave() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.saveLoading = true;
+          const apiMethod = this.form.id
+            ? updateOrganProcurement
+            : addOrganProcurement;
+
+          apiMethod(this.form)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("淇濆瓨鎴愬姛");
+                if (!this.form.id) {
+                  this.form.id = response.data.id;
+                  this.$router.replace({
+                    query: { ...this.$route.query, id: this.form.id }
+                  });
+                }
+              }
+            })
+            .catch(error => {
+              console.error("淇濆瓨澶辫触:", error);
+              this.$message.error("淇濆瓨澶辫触");
+            })
+            .finally(() => {
+              this.saveLoading = false;
+            });
+        }
+      });
+    },
+    // 淇濆瓨鑾峰彇璁板綍
+    handleSaveProcurement() {
+      if (!this.form.id) {
+        this.$message.warning("璇峰厛淇濆瓨鍩烘湰淇℃伅");
+        return;
+      }
+
+      this.saveLoading = true;
+      saveProcurementRecords(this.form.id, this.procurementData.records)
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鑾峰彇璁板綍淇濆瓨鎴愬姛");
+          }
+        })
+        .catch(error => {
+          console.error("淇濆瓨鑾峰彇璁板綍澶辫触:", error);
+          this.$message.error("淇濆瓨鑾峰彇璁板綍澶辫触");
+        })
+        .finally(() => {
+          this.saveLoading = false;
+        });
+    },
+    // 纭瀹屾垚鑾峰彇
+    handleConfirmProcurement() {
+      if (this.incompleteRecords > 0) {
+        this.$message.warning("璇峰厛瀹屽杽鎵�鏈夎幏鍙栬褰曠殑淇℃伅");
+        return;
+      }
+
+      this.$confirm("纭瀹屾垚鍣ㄥ畼鑾峰彇鍚楋紵瀹屾垚鍚庡皢鏃犳硶淇敼鑾峰彇淇℃伅銆�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.confirmLoading = true;
+          this.form.procurementStatus = "procured";
+          this.form.procurementTime = new Date()
+            .toISOString()
+            .replace("T", " ")
+            .substring(0, 19);
+
+          updateOrganProcurement(this.form)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("鍣ㄥ畼鑾峰彇宸插畬鎴�");
+              }
+            })
+            .catch(error => {
+              console.error("纭鑾峰彇澶辫触:", error);
+              this.$message.error("纭鑾峰彇澶辫触");
+            })
+            .finally(() => {
+              this.confirmLoading = false;
+            });
+        })
+        .catch(() => {});
+    },
+    // 涓婁紶闄勪欢
+    handleUploadAttachment() {
+      this.$message.info("闄勪欢涓婁紶鍔熻兘");
+    },
+    // 棰勮闄勪欢
+    handlePreviewAttachment(attachment) {
+      this.$message.info("闄勪欢棰勮鍔熻兘");
+    },
+    // 涓嬭浇闄勪欢
+    handleDownloadAttachment(attachment) {
+      this.$message.info("闄勪欢涓嬭浇鍔熻兘");
+    },
+    // 鍒犻櫎闄勪欢
+    handleRemoveAttachment(attachment) {
+      this.$confirm("纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+        })
+        .catch(() => {});
+    },
+    // 鑾峰彇鏂囦欢鍥炬爣
+    getFileIcon(fileName) {
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const iconMap = {
+        pdf: "el-icon-document",
+        doc: "el-icon-document",
+        docx: "el-icon-document",
+        xls: "el-icon-document",
+        xlsx: "el-icon-document",
+        jpg: "el-icon-picture",
+        jpeg: "el-icon-picture",
+        png: "el-icon-picture"
+      };
+      return iconMap[ext] || "el-icon-document";
+    },
+    // 鑾峰彇鏂囦欢绫诲瀷
+    getFileType(fileName) {
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const typeMap = {
+        pdf: "PDF",
+        doc: "DOC",
+        docx: "DOCX",
+        xls: "XLS",
+        xlsx: "XLSX",
+        jpg: "JPG",
+        jpeg: "JPEG",
+        png: "PNG"
+      };
+      return typeMap[ext] || ext.toUpperCase();
+    },
+    // 鏂囦欢澶у皬鏍煎紡鍖�
+    formatFileSize(size) {
+      if (size === 0) 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];
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time) {
+      if (!time) return "";
+      const date = new Date(time);
+      return `${date.getFullYear()}-${(date.getMonth() + 1)
+        .toString()
+        .padStart(2, "0")}-${date
+        .getDate()
+        .toString()
+        .padStart(2, "0")} ${date
+        .getHours()
+        .toString()
+        .padStart(2, "0")}:${date
+        .getMinutes()
+        .toString()
+        .padStart(2, "0")}`;
+    }
+  }
+};
+</script>
+<style scoped>
+.organ-procurement-detail {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.detail-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  border: 1px solid #e4e7ed;
+}
+
+.procurement-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  border: 1px solid #e4e7ed;
+}
+
+.attachment-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  border: 1px solid #e4e7ed;
+}
+
+.detail-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+  line-height: 1.4;
+}
+
+/* 缁熻淇℃伅鏍峰紡 */
+.procurement-stats {
+  margin-top: 20px;
+  padding: 15px;
+  background: linear-gradient(135deg, #a6b2e7 0%, #8a66ad 100%);
+  border-radius: 8px;
+  color: white;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 10px;
+  text-align: center;
+}
+
+.stat-label {
+  font-size: 12px;
+  opacity: 0.9;
+  margin-bottom: 5px;
+  color: rgba(255, 255, 255, 0.9);
+}
+
+.stat-value {
+  font-size: 18px;
+  font-weight: bold;
+  color: white;
+}
+
+/* 绌虹姸鎬佹牱寮� */
+.empty-procurement {
+  text-align: center;
+  padding: 40px 0;
+  color: #909399;
+  background: #fafafa;
+  border-radius: 4px;
+  margin: 20px 0;
+}
+
+/* 瀵硅瘽妗嗗簳閮ㄦ寜閽� */
+.dialog-footer {
+  margin-top: 20px;
+  text-align: center;
+  padding-top: 20px;
+  border-top: 1px solid #e4e7ed;
+}
+
+.dialog-footer .el-button {
+  margin: 0 10px;
+  min-width: 120px;
+}
+
+/* 琛ㄦ牸琛屾牱寮� */
+:deep(.warning-row) {
+  background-color: #fff7e6 !important;
+}
+
+:deep(.warning-row:hover) {
+  background-color: #ffecc2 !important;
+}
+
+:deep(.el-table .cell) {
+  padding: 8px 12px;
+  line-height: 1.5;
+}
+
+:deep(.el-table th) {
+  background-color: #f5f7fa;
+  color: #606266;
+  font-weight: 600;
+}
+
+:deep(.el-table--border) {
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+}
+
+:deep(.el-table--border th) {
+  border-right: 1px solid #e4e7ed;
+}
+
+:deep(.el-table--border td) {
+  border-right: 1px solid #e4e7ed;
+}
+
+/* 琛ㄥ崟鏍峰紡浼樺寲 */
+:deep(.el-form-item__label) {
+  font-weight: 500;
+  color: #606266;
+}
+
+:deep(.el-input__inner) {
+  border-radius: 4px;
+  border: 1px solid #dcdfe6;
+  transition: border-color 0.3s ease;
+}
+
+:deep(.el-input__inner:focus) {
+  border-color: #409EFF;
+  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+}
+
+:deep(.el-textarea__inner) {
+  border-radius: 4px;
+  resize: vertical;
+  min-height: 60px;
+}
+
+:deep(.el-select) {
+  width: 100%;
+}
+
+/* 鎸夐挳鏍峰紡浼樺寲 */
+:deep(.el-button--primary) {
+  background: linear-gradient(135deg, #409EFF 0%, #3375e0 100%);
+  border: none;
+  border-radius: 4px;
+  transition: all 0.3s ease;
+}
+
+:deep(.el-button--primary:hover) {
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
+}
+
+:deep(.el-button--success) {
+  background: linear-gradient(135deg, #67C23A 0%, #529b2f 100%);
+  border: none;
+  border-radius: 4px;
+  transition: all 0.3s ease;
+}
+
+:deep(.el-button--success:hover) {
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(103, 194, 58, 0.4);
+}
+
+:deep(.el-button--warning) {
+  background: linear-gradient(135deg, #E6A23C 0%, #d18c2a 100%);
+  border: none;
+  border-radius: 4px;
+  transition: all 0.3s ease;
+}
+
+:deep(.el-button--warning:hover) {
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(230, 162, 60, 0.4);
+}
+
+:deep(.el-button--danger) {
+  background: linear-gradient(135deg, #F56C6C 0%, #e05b5b 100%);
+  border: none;
+  border-radius: 4px;
+  transition: all 0.3s ease;
+}
+
+:deep(.el-button--danger:hover) {
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(245, 108, 108, 0.4);
+}
+
+/* 鏍囩鏍峰紡 */
+:deep(.el-tag) {
+  border-radius: 12px;
+  border: none;
+  font-weight: 500;
+  padding: 4px 12px;
+}
+
+:deep(.el-tag--success) {
+  background: linear-gradient(135deg, #67C23A 0%, #529b2f 100%);
+  color: white;
+}
+
+:deep(.el-tag--warning) {
+  background: linear-gradient(135deg, #E6A23C 0%, #d18c2a 100%);
+  color: white;
+}
+
+/* 澶嶉�夋缁勬牱寮� */
+:deep(.el-checkbox-group) {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 15px;
+  margin-top: 10px;
+}
+
+:deep(.el-checkbox) {
+  margin-right: 0;
+}
+
+:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
+  background: linear-gradient(135deg, #409EFF 0%, #3375e0 100%);
+  border-color: #409EFF;
+}
+
+:deep(.el-checkbox__input.is-checked + .el-checkbox__label) {
+  color: #409EFF;
+  font-weight: 500;
+}
+
+/* 鏃ユ湡閫夋嫨鍣ㄦ牱寮� */
+:deep(.el-date-editor) {
+  width: 100%;
+}
+
+:deep(.el-picker-panel) {
+  border-radius: 8px;
+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+}
+
+/* 鍔犺浇鐘舵�� */
+:deep(.el-loading-mask) {
+  border-radius: 4px;
+}
+
+/* 鍗$墖澶撮儴鏍峰紡浼樺寲 */
+:deep(.el-card__header) {
+  background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
+  border-bottom: 1px solid #e4e7ed;
+  padding: 15px 20px;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 1200px) {
+  .organ-procurement-detail {
+    padding: 15px;
+  }
+
+  :deep(.el-col) {
+    margin-bottom: 10px;
+  }
+}
+
+@media (max-width: 768px) {
+  .organ-procurement-detail {
+    padding: 10px;
+  }
+
+  .detail-title {
+    font-size: 16px;
+  }
+
+  .stat-item {
+    padding: 5px;
+  }
+
+  .stat-label {
+    font-size: 10px;
+  }
+
+  .stat-value {
+    font-size: 14px;
+  }
+
+  :deep(.el-table .cell) {
+    padding: 4px 8px;
+    font-size: 12px;
+  }
+
+  :deep(.el-checkbox-group) {
+    gap: 8px;
+  }
+
+  .dialog-footer .el-button {
+    margin: 5px;
+    min-width: 100px;
+  }
+}
+
+@media (max-width: 480px) {
+  .organ-procurement-detail {
+    padding: 5px;
+  }
+
+  :deep(.el-card__header) {
+    padding: 10px 15px;
+  }
+
+  :deep(.el-form-item__label) {
+    font-size: 12px;
+  }
+
+  :deep(.el-table) {
+    font-size: 11px;
+  }
+}
+
+/* 鍔ㄧ敾鏁堟灉 */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+
+.fade-enter, .fade-leave-to {
+  opacity: 0;
+}
+
+/* 鑷畾涔夋粴鍔ㄦ潯 */
+:deep(::-webkit-scrollbar) {
+  width: 6px;
+  height: 6px;
+}
+
+:deep(::-webkit-scrollbar-track) {
+  background: #f1f1f1;
+  border-radius: 3px;
+}
+
+:deep(::-webkit-scrollbar-thumb) {
+  background: #c1c1c1;
+  border-radius: 3px;
+}
+
+:deep(::-webkit-scrollbar-thumb:hover) {
+  background: #a8a8a8;
+}
+
+/* 鏂囦欢淇℃伅鏍峰紡 */
+.file-info {
+  display: flex;
+  align-items: center;
+  padding: 5px 0;
+}
+
+.file-info i {
+  font-size: 18px;
+  margin-right: 10px;
+}
+
+/* 鎿嶄綔鎸夐挳缁勬牱寮� */
+:deep(.small-padding .el-button) {
+  margin: 0 2px;
+  padding: 4px 8px;
+}
+
+/* 琛ㄥ崟琛岄棿璺濅紭鍖� */
+:deep(.el-form-item) {
+  margin-bottom: 18px;
+}
+
+:deep(.el-row) {
+  margin-bottom: 10px;
+}
+
+/* 瀵硅瘽妗嗘牱寮忎紭鍖� */
+:deep(.el-dialog) {
+  border-radius: 8px;
+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+}
+
+:deep(.el-dialog__header) {
+  background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
+  border-bottom: 1px solid #e4e7ed;
+  padding: 15px 20px;
+  border-radius: 8px 8px 0 0;
+}
+
+:deep(.el-dialog__title) {
+  font-weight: 600;
+  color: #303133;
+}
+
+:deep(.el-dialog__body) {
+  padding: 20px;
+}
+
+:deep(.el-dialog__footer) {
+  padding: 15px 20px;
+  border-top: 1px solid #e4e7ed;
+}
+
+/* 鐗规畩鐘舵�佹彁绀� */
+.procurement-warning {
+  background-color: #fff7e6;
+  border: 1px solid #ffecc2;
+  border-radius: 4px;
+  padding: 10px 15px;
+  margin: 10px 0;
+  color: #e6a23c;
+  font-size: 14px;
+}
+
+.procurement-success {
+  background-color: #f0f9ff;
+  border: 1px solid #b3e0ff;
+  border-radius: 4px;
+  padding: 10px 15px;
+  margin: 10px 0;
+  color: #409EFF;
+  font-size: 14px;
+}
+
+/* 鏃堕棿绾挎牱寮忥紙鐢ㄤ簬鎵嬫湳鏃堕棿灞曠ず锛� */
+.procurement-timeline {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f8f9fa;
+  border-radius: 4px;
+}
+
+.timeline-item {
+  display: flex;
+  align-items: center;
+  margin-bottom: 10px;
+  padding: 8px 12px;
+  background: white;
+  border-radius: 4px;
+  border-left: 4px solid #409EFF;
+}
+
+.timeline-label {
+  font-weight: 500;
+  min-width: 120px;
+  color: #606266;
+}
+
+.timeline-value {
+  color: #303133;
+  font-weight: 500;
+}
+
+/* 鎵撳嵃鏍峰紡 */
+@media print {
+  .organ-procurement-detail {
+    padding: 0;
+    background: white;
+  }
+
+  .detail-card,
+  .procurement-card,
+  .attachment-card {
+    box-shadow: none;
+    border: 1px solid #ddd;
+    margin-bottom: 15px;
+    page-break-inside: avoid;
+  }
+
+  .dialog-footer,
+  .el-button {
+    display: none;
+  }
+}
+</style>
diff --git a/src/views/business/GetWitness/index.vue b/src/views/business/GetWitness/index.vue
new file mode 100644
index 0000000..79c858e
--- /dev/null
+++ b/src/views/business/GetWitness/index.vue
@@ -0,0 +1,372 @@
+<template>
+  <div class="organ-procurement-list">
+    <!-- 鏌ヨ鏉′欢 -->
+    <el-card class="search-card">
+      <el-form
+        :model="queryParams"
+        ref="queryForm"
+        :inline="true"
+        label-width="100px"
+      >
+        <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+          <el-input
+            v-model="queryParams.hospitalNo"
+            placeholder="璇疯緭鍏ヤ綇闄㈠彿"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+          <el-input
+            v-model="queryParams.donorName"
+            placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="鑾峰彇鐘舵��" prop="procurementStatus">
+          <el-select
+            v-model="queryParams.procurementStatus"
+            placeholder="璇烽�夋嫨鑾峰彇鐘舵��"
+            clearable
+            style="width: 200px"
+          >
+            <el-option label="宸茶幏鍙�" value="procured" />
+            <el-option label="寰呰幏鍙�" value="pending" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" @click="handleQuery"
+            >鎼滅储</el-button
+          >
+          <el-button icon="el-icon-refresh" @click="resetQuery">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 鎿嶄綔鎸夐挳 -->
+    <el-card class="tool-card">
+      <el-row :gutter="10">
+        <el-col :span="16">
+          <el-button type="primary" icon="el-icon-plus" @click="handleCreate"
+            >鏂板缓鑾峰彇</el-button
+          >
+          <el-button
+            type="success"
+            icon="el-icon-edit"
+            :disabled="single"
+            @click="handleUpdate"
+            >淇敼</el-button
+          >
+          <el-button
+            type="danger"
+            icon="el-icon-delete"
+            :disabled="multiple"
+            @click="handleDelete"
+            >鍒犻櫎</el-button
+          >
+        </el-col>
+        <el-col :span="8" style="text-align: right">
+          <el-tooltip content="鍒锋柊" placement="top">
+            <el-button icon="el-icon-refresh" circle @click="getList" />
+          </el-tooltip>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <el-card>
+      <el-table
+        v-loading="loading"
+        :data="organProcurementList"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column
+          label="浣忛櫌鍙�"
+          align="center"
+          prop="hospitalNo"
+          width="120"
+        />
+        <el-table-column
+          label="鎹愮尞鑰呭鍚�"
+          align="center"
+          prop="donorName"
+          width="120"
+        />
+        <el-table-column label="鎬у埆" align="center" prop="gender" width="80">
+          <template slot-scope="scope">
+            <dict-tag
+              :options="dict.type.sys_user_sex"
+              :value="parseInt(scope.row.gender)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="骞撮緞" align="center" prop="age" width="80" />
+        <el-table-column
+          label="鐤剧梾璇婃柇"
+          align="center"
+          prop="diagnosis"
+          min-width="180"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="鑾峰彇鐘舵��"
+          align="center"
+          prop="procurementStatus"
+          width="100"
+        >
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.procurementStatus === 'procured' ? 'success' : 'warning'">
+              {{ scope.row.procurementStatus === 'procured' ? '宸茶幏鍙�' : '寰呰幏鍙�' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鑾峰彇鏃堕棿"
+          align="center"
+          prop="procurementTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.procurementTime
+                ? parseTime(scope.row.procurementTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鐧昏浜�"
+          align="center"
+          prop="registrant"
+          width="100"
+        />
+        <el-table-column
+          label="鐧昏鏃堕棿"
+          align="center"
+          prop="registrationTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.registrationTime
+                ? parseTime(scope.row.registrationTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鎿嶄綔"
+          align="center"
+          width="150"
+          class-name="small-padding fixed-width"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleView(scope.row)"
+              >璇︽儏</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdate(scope.row)"
+              >淇敼</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-delete"
+              style="color: #F56C6C"
+              @click="handleDelete(scope.row)"
+              >鍒犻櫎</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 鍒嗛〉缁勪欢 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { listOrganProcurement, delOrganProcurement } from "./organProcurement";
+import Pagination from "@/components/Pagination";
+
+export default {
+  name: "OrganProcurementList",
+  components: { Pagination },
+  dicts: ["sys_user_sex"],
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 鍣ㄥ畼鑾峰彇琛ㄦ牸鏁版嵁
+      organProcurementList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        hospitalNo: undefined,
+        donorName: undefined,
+        procurementStatus: undefined
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 鏌ヨ鍣ㄥ畼鑾峰彇鍒楄〃
+    getList() {
+      this.loading = true;
+      listOrganProcurement(this.queryParams)
+        .then(response => {
+          if (response.code === 200) {
+            this.organProcurementList = response.data.rows;
+            this.total = response.data.total;
+          } else {
+            this.$message.error("鑾峰彇鏁版嵁澶辫触");
+          }
+          this.loading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇鍣ㄥ畼鑾峰彇鍒楄〃澶辫触:", error);
+          this.loading = false;
+          this.$message.error("鑾峰彇鏁版嵁澶辫触");
+        });
+    },
+    // 鎼滅储鎸夐挳鎿嶄綔
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    // 閲嶇疆鎸夐挳鎿嶄綔
+    resetQuery() {
+      this.$refs.queryForm.resetFields();
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    // 鏌ョ湅璇︽儏
+    handleView(row) {
+      this.$router.push({
+        path: "/case/GetWitnessInfo",
+        query: { id: row.id }
+      });
+    },
+    // 鏂板鎸夐挳鎿嶄綔
+    handleCreate() {
+      this.$router.push("/case/GetWitnessInfo");
+    },
+    // 淇敼鎸夐挳鎿嶄綔
+    handleUpdate(row) {
+      const id = row.id || this.ids[0];
+      this.$router.push({
+        path: "/case/GetWitnessInfo",
+        query: { id: id }
+      });
+    },
+    // 鍒犻櫎鎸夐挳鎿嶄綔
+    handleDelete(row) {
+      const ids = row.id ? [row.id] : this.ids;
+      this.$confirm("鏄惁纭鍒犻櫎閫変腑鐨勬暟鎹」锛�", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          return delOrganProcurement(ids);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍒犻櫎鎴愬姛");
+            this.getList();
+          }
+        })
+        .catch(() => {});
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time, pattern) {
+      if (!time) return "";
+      const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
+      let date;
+      if (typeof time === "object") {
+        date = time;
+      } else {
+        if (typeof time === "string" && /^[0-9]+$/.test(time)) {
+          time = parseInt(time);
+        }
+        if (typeof time === "number" && time.toString().length === 10) {
+          time = time * 1000;
+        }
+        date = new Date(time);
+      }
+      const formatObj = {
+        y: date.getFullYear(),
+        m: date.getMonth() + 1,
+        d: date.getDate(),
+        h: date.getHours(),
+        i: date.getMinutes(),
+        s: date.getSeconds(),
+        a: date.getDay()
+      };
+      const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+        let value = formatObj[key];
+        if (key === "a") {
+          return ["鏃�", "涓�", "浜�", "涓�", "鍥�", "浜�", "鍏�"][value];
+        }
+        if (result.length > 0 && value < 10) {
+          value = "0" + value;
+        }
+        return value || 0;
+      });
+      return time_str;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.organ-procurement-list {
+  padding: 20px;
+}
+
+.search-card {
+  margin-bottom: 20px;
+}
+
+.tool-card {
+  margin-bottom: 20px;
+}
+
+.fixed-width .el-button {
+  margin: 0 5px;
+}
+</style>
diff --git a/src/views/business/GetWitness/organProcurement.js b/src/views/business/GetWitness/organProcurement.js
new file mode 100644
index 0000000..c64774e
--- /dev/null
+++ b/src/views/business/GetWitness/organProcurement.js
@@ -0,0 +1,353 @@
+// 妯℃嫙鍣ㄥ畼鑾峰彇鏁版嵁
+const mockOrganProcurementData = [
+  {
+    id: 1,
+    hospitalNo: "D202312001",
+    caseNo: "C202312001",
+    donorName: "寮犱笁",
+    gender: "0",
+    age: 45,
+    birthDate: "1978-05-15",
+    diagnosis: "鑴戝浼�",
+    procurementStatus: "procured",
+    procurementTime: "2023-12-01 16:30:00",
+    registrant: "鏉庡崗璋冨憳",
+    registrationTime: "2023-12-01 15:00:00",
+    createTime: "2023-12-01 10:00:00",
+    surgeryName: "澶氬櫒瀹樿幏鍙栨墜鏈�",
+    surgeryStartTime: "2023-12-01 14:00:00",
+    donorDeathTime: "2023-12-01 13:30:00",
+    abdominalAortaCannulationTime: "2023-12-01 14:30:00",
+    inferiorVenaCavaCannulationTime: "2023-12-01 14:35:00",
+    superiorMesentericVeinCannulationTime: "2023-12-01 14:40:00"
+  },
+  {
+    id: 2,
+    hospitalNo: "D202312002",
+    caseNo: "C202312002",
+    donorName: "鏉庡洓",
+    gender: "1",
+    age: 38,
+    birthDate: "1985-08-22",
+    diagnosis: "蹇冭剰楠ゅ仠",
+    procurementStatus: "procured",
+    procurementTime: "2023-12-02 11:20:00",
+    registrant: "寮犲崗璋冨憳",
+    registrationTime: "2023-12-02 10:00:00",
+    createTime: "2023-12-02 08:30:00",
+    surgeryName: "蹇冭剰鑾峰彇鎵嬫湳",
+    surgeryStartTime: "2023-12-02 10:30:00",
+    donorDeathTime: "2023-12-02 10:00:00",
+    abdominalAortaCannulationTime: "2023-12-02 10:45:00",
+    inferiorVenaCavaCannulationTime: "2023-12-02 10:50:00",
+    superiorMesentericVeinCannulationTime: "2023-12-02 10:55:00"
+  },
+  {
+    id: 3,
+    hospitalNo: "D202312003",
+    caseNo: "C202312003",
+    donorName: "鐜嬩簲",
+    gender: "0",
+    age: 52,
+    birthDate: "1971-03-10",
+    diagnosis: "鑴戞姝�",
+    procurementStatus: "pending",
+    procurementTime: "",
+    registrant: "璧靛崗璋冨憳",
+    registrationTime: "2023-12-03 17:20:00",
+    createTime: "2023-12-03 14:00:00",
+    surgeryName: "",
+    surgeryStartTime: "",
+    donorDeathTime: "",
+    abdominalAortaCannulationTime: "",
+    inferiorVenaCavaCannulationTime: "",
+    superiorMesentericVeinCannulationTime: ""
+  }
+];
+
+// 妯℃嫙鍣ㄥ畼鑾峰彇璁板綍鏁版嵁
+const mockProcurementRecordData = [
+  {
+    id: 1,
+    procurementId: 1,
+    organName: "鑲濊剰",
+    organNo: "L001",
+    organStartTime: "2023-12-01 15:00:00",
+    organGetTime: "2023-12-01 15:45:00",
+    gainHospitalNo: "H1001",
+    gainHospitalName: "鍖椾含鍗忓拰鍖婚櫌",
+    organGetDoctor: "鐜嬪尰鐢�",
+    assistant: "鏉庡尰鐢�",
+    procurementNurse: "寮犳姢澹�",
+    operatingRoomNurse: "鍒樻姢澹�",
+    anesthesiologist: "闄堥夯閱夊笀",
+    organState: "1",
+    notGetReason: ""
+  },
+  {
+    id: 2,
+    procurementId: 1,
+    organName: "鑲捐剰",
+    organNo: "K001",
+    organStartTime: "2023-12-01 15:10:00",
+    organGetTime: "2023-12-01 15:50:00",
+    gainHospitalNo: "H1002",
+    gainHospitalName: "涓婃捣鐟為噾鍖婚櫌",
+    organGetDoctor: "璧靛尰鐢�",
+    assistant: "閽卞尰鐢�",
+    procurementNurse: "瀛欐姢澹�",
+    operatingRoomNurse: "鍛ㄦ姢澹�",
+    anesthesiologist: "鍚撮夯閱夊笀",
+    organState: "1",
+    notGetReason: ""
+  },
+  {
+    id: 3,
+    procurementId: 1,
+    organName: "蹇冭剰",
+    organNo: "H001",
+    organStartTime: "2023-12-01 15:20:00",
+    organGetTime: "2023-12-01 16:00:00",
+    gainHospitalNo: "H1003",
+    gainHospitalName: "骞垮窞涓北鍖婚櫌",
+    organGetDoctor: "閮戝尰鐢�",
+    assistant: "鐜嬪尰鐢�",
+    procurementNurse: "鏋楁姢澹�",
+    operatingRoomNurse: "榛勬姢澹�",
+    anesthesiologist: "鏉ㄩ夯閱夊笀",
+    organState: "1",
+    notGetReason: ""
+  }
+];
+
+// 妯℃嫙鍖婚櫌鏁版嵁
+const mockHospitalData = [
+  { id: 1, hospitalNo: "H1001", hospitalName: "鍖椾含鍗忓拰鍖婚櫌", type: "4" },
+  { id: 2, hospitalNo: "H1002", hospitalName: "涓婃捣鐟為噾鍖婚櫌", type: "4" },
+  { id: 3, hospitalNo: "H1003", hospitalName: "骞垮窞涓北鍖婚櫌", type: "4" },
+  { id: 4, hospitalNo: "H1004", hospitalName: "姝︽眽鍚屾祹鍖婚櫌", type: "4" },
+  { id: 5, hospitalNo: "H1005", hospitalName: "鎴愰兘鍗庤タ鍖婚櫌", type: "4" }
+];
+
+// 妯℃嫙鍗忚皟鍛樻暟鎹�
+const mockCoordinatorData = [
+  { reportNo: "C001", reportName: "寮犲崗璋冨憳" },
+  { reportNo: "C002", reportName: "鏉庡崗璋冨憳" },
+  { reportNo: "C003", reportName: "鐜嬪崗璋冨憳" },
+  { reportNo: "C004", reportName: "璧靛崗璋冨憳" }
+];
+
+// 妯℃嫙API鍝嶅簲寤惰繜
+const delay = (ms = 500) => new Promise(resolve => setTimeout(resolve, ms));
+
+// 鏌ヨ鍣ㄥ畼鑾峰彇鍒楄〃
+export const listOrganProcurement = async (queryParams = {}) => {
+  await delay();
+
+  const {
+    pageNum = 1,
+    pageSize = 10,
+    hospitalNo,
+    donorName,
+    procurementStatus
+  } = queryParams;
+
+  // 杩囨护鏁版嵁
+  let filteredData = mockOrganProcurementData.filter(item => {
+    let match = true;
+
+    if (hospitalNo && !item.hospitalNo.includes(hospitalNo)) {
+      match = false;
+    }
+
+    if (donorName && !item.donorName.includes(donorName)) {
+      match = false;
+    }
+
+    if (procurementStatus && item.procurementStatus !== procurementStatus) {
+      match = false;
+    }
+
+    return match;
+  });
+
+  // 鍒嗛〉
+  const startIndex = (pageNum - 1) * pageSize;
+  const endIndex = startIndex + parseInt(pageSize);
+  const paginatedData = filteredData.slice(startIndex, endIndex);
+
+  return {
+    code: 200,
+    message: "success",
+    data: {
+      rows: paginatedData,
+      total: filteredData.length,
+      pageNum: parseInt(pageNum),
+      pageSize: parseInt(pageSize)
+    }
+  };
+};
+
+// 鑾峰彇鍣ㄥ畼鑾峰彇璇︾粏淇℃伅
+export const getOrganProcurementDetail = async (id) => {
+  await delay();
+
+  const detail = mockOrganProcurementData.find(item => item.id == id);
+
+  if (detail) {
+    // 鑾峰彇鑾峰彇璁板綍
+    const procurementRecords = mockProcurementRecordData.filter(item => item.procurementId == id);
+
+    return {
+      code: 200,
+      message: "success",
+      data: {
+        ...detail,
+        procurementRecords
+      }
+    };
+  } else {
+    return {
+      code: 404,
+      message: "鍣ㄥ畼鑾峰彇璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鏂板鍣ㄥ畼鑾峰彇
+export const addOrganProcurement = async (data) => {
+  await delay();
+
+  const newId = Math.max(...mockOrganProcurementData.map(item => item.id), 0) + 1;
+  const hospitalNo = `D${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(newId).padStart(3, '0')}`;
+  const caseNo = `C${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(newId).padStart(3, '0')}`;
+
+  const newRecord = {
+    ...data,
+    id: newId,
+    hospitalNo,
+    caseNo,
+    registrationTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+    createTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+  };
+
+  mockOrganProcurementData.unshift(newRecord);
+
+  return {
+    code: 200,
+    message: "鏂板鎴愬姛",
+    data: newRecord
+  };
+};
+
+// 淇敼鍣ㄥ畼鑾峰彇
+export const updateOrganProcurement = async (data) => {
+  await delay();
+
+  const index = mockOrganProcurementData.findIndex(item => item.id == data.id);
+
+  if (index !== -1) {
+    mockOrganProcurementData[index] = {
+      ...mockOrganProcurementData[index],
+      ...data,
+      updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+    };
+
+    return {
+      code: 200,
+      message: "淇敼鎴愬姛",
+      data: mockOrganProcurementData[index]
+    };
+  } else {
+    return {
+      code: 404,
+      message: "鍣ㄥ畼鑾峰彇璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鍒犻櫎鍣ㄥ畼鑾峰彇
+export const delOrganProcurement = async (ids) => {
+  await delay();
+
+  const idArray = Array.isArray(ids) ? ids : [ids];
+
+  idArray.forEach(id => {
+    const index = mockOrganProcurementData.findIndex(item => item.id == id);
+    if (index !== -1) {
+      mockOrganProcurementData.splice(index, 1);
+    }
+  });
+
+  return {
+    code: 200,
+    message: "鍒犻櫎鎴愬姛"
+  };
+};
+
+// 淇濆瓨鍣ㄥ畼鑾峰彇璁板綍
+export const saveProcurementRecords = async (procurementId, records) => {
+  await delay();
+
+  // 鍒犻櫎璇ヨ幏鍙朓D鐨勬墍鏈夎褰�
+  const existingIndexes = [];
+  mockProcurementRecordData.forEach((item, index) => {
+    if (item.procurementId == procurementId) {
+      existingIndexes.push(index);
+    }
+  });
+
+  // 浠庡悗寰�鍓嶅垹闄ら伩鍏嶇储寮曢棶棰�
+  existingIndexes.reverse().forEach(index => {
+    mockProcurementRecordData.splice(index, 1);
+  });
+
+  // 娣诲姞鏂拌褰�
+  records.forEach(record => {
+    const newId = Math.max(...mockProcurementRecordData.map(item => item.id), 0) + 1;
+    mockProcurementRecordData.push({
+      ...record,
+      id: newId,
+      procurementId: procurementId
+    });
+  });
+
+  return {
+    code: 200,
+    message: "淇濆瓨鎴愬姛",
+    data: records
+  };
+};
+
+// 鑾峰彇鍖婚櫌鍒楄〃
+export const getHospitalList = async () => {
+  await delay();
+
+  return {
+    code: 200,
+    message: "success",
+    data: mockHospitalData
+  };
+};
+
+// 鑾峰彇鍗忚皟鍛樺垪琛�
+export const getCoordinatorList = async () => {
+  await delay();
+
+  return {
+    code: 200,
+    message: "success",
+    data: mockCoordinatorData
+  };
+};
+
+export default {
+  listOrganProcurement,
+  getOrganProcurementDetail,
+  addOrganProcurement,
+  updateOrganProcurement,
+  delOrganProcurement,
+  saveProcurementRecords,
+  getHospitalList,
+  getCoordinatorList
+};
diff --git a/src/views/business/OrganUtilization/OrganUtilizationInfo.vue b/src/views/business/OrganUtilization/OrganUtilizationInfo.vue
new file mode 100644
index 0000000..920f752
--- /dev/null
+++ b/src/views/business/OrganUtilization/OrganUtilizationInfo.vue
@@ -0,0 +1,1656 @@
+<template>
+  <div class="organ-utilization-detail">
+    <!-- 鍩烘湰淇℃伅 -->
+    <el-card class="detail-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鍣ㄥ畼鍒╃敤鍩烘湰淇℃伅</span>
+        <div style="float: right;">
+          <el-button type="primary" @click="handleSave" :loading="saveLoading">
+            淇濆瓨
+          </el-button>
+          <el-button
+            type="success"
+            @click="handleComplete"
+            :disabled="form.utilizationStatus === 'completed'"
+          >
+            瀹屾垚鍒╃敤
+          </el-button>
+        </div>
+      </div>
+
+      <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+              <el-input v-model="form.hospitalNo" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="妗堜緥缂栧彿" prop="caseNo">
+              <el-input v-model="form.caseNo" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+              <el-input v-model="form.donorName" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="鎬у埆" prop="gender">
+              <el-select v-model="form.gender" style="width: 100%">
+                <el-option label="鐢�" value="0" />
+                <el-option label="濂�" value="1" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <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="birthDate">
+              <el-date-picker
+                v-model="form.birthDate"
+                type="date"
+                value-format="yyyy-MM-dd"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐤剧梾璇婃柇" prop="diagnosis">
+              <el-input
+                type="textarea"
+                :rows="2"
+                v-model="form.diagnosis"
+                placeholder="璇疯緭鍏ョ柧鐥呰瘖鏂俊鎭�"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍒嗛厤鏃堕棿" prop="allocationTime">
+              <el-date-picker
+                v-model="form.allocationTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item align="left" label="閬椾綋鎹愮尞" prop="isBodyDonation">
+              <el-radio-group v-model="form.isBodyDonation">
+                <el-radio
+                  v-for="dict in dict.type.sys_0_1 || []"
+                  :key="dict.value"
+                  :label="dict.value"
+                  >{{ dict.label }}</el-radio
+                >
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="18">
+            <el-form-item align="left" label="鎺ユ敹鍗曚綅" prop="receivingUnit">
+              <el-input
+                v-model="form.receivingUnit"
+                placeholder="璇疯緭鍏ユ帴鏀跺崟浣�"
+                :disabled="form.isBodyDonation !== '1'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <el-form-item label="璐熻矗浜�" prop="responsibleUserId">
+              <el-select
+                v-model="form.responsibleUserId"
+                placeholder="璇烽�夋嫨璐熻矗浜�"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in leaderList"
+                  :key="item.reportNo"
+                  :label="item.reportName"
+                  :value="item.reportNo"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="鍗忚皟鍛樹竴" prop="coordinatedUserId1">
+              <el-select
+                v-model="form.coordinatedUserId1"
+                placeholder="璇烽�夋嫨鍗忚皟鍛�"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in coordinatorList"
+                  :key="item.reportNo"
+                  :label="item.reportName"
+                  :value="item.reportNo"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="鍗忚皟鍛樹簩" prop="coordinatedUserId2">
+              <el-select
+                v-model="form.coordinatedUserId2"
+                placeholder="璇烽�夋嫨鍗忚皟鍛�"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="item in coordinatorList"
+                  :key="item.reportNo"
+                  :label="item.reportName"
+                  :value="item.reportNo"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="瀹屾垚鏃堕棿" prop="completionTime">
+              <el-date-picker
+                v-model="form.completionTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+                :disabled="form.utilizationStatus !== 'completed'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐧昏浜�" prop="registrant">
+              <el-input v-model="form.registrant" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐧昏鏃堕棿" prop="registrationTime">
+              <el-date-picker
+                v-model="form.registrationTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+                readonly
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+
+    <!-- 鍣ㄥ畼鍒╃敤璁板綍閮ㄥ垎 -->
+    <el-card class="utilization-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鍣ㄥ畼鍒╃敤璁板綍</span>
+        <div style="float: right;">
+          <el-tag :type="getStatusTagType(form.utilizationStatus)">
+            {{ getStatusText(form.utilizationStatus) }}
+          </el-tag>
+        </div>
+      </div>
+
+      <el-form
+        ref="utilizationForm"
+        :rules="utilizationRules"
+        :model="utilizationData"
+        label-position="right"
+      >
+        <el-row>
+          <el-col>
+            <el-form-item label-width="100px" label="绉绘鍣ㄥ畼">
+              <el-checkbox-group v-model="selectedOrgans" @change="handleOrganSelectionChange">
+                <el-checkbox
+                  v-for="dict in dict.type.sys_Organ || []"
+                  :key="dict.value"
+                  :label="dict.value"
+                  :disabled="form.utilizationStatus === 'completed'"
+                >
+                  {{ dict.label }}
+                </el-checkbox>
+              </el-checkbox-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col>
+            <el-form-item>
+              <el-table
+                :data="utilizationData.records"
+                v-loading="loading"
+                border
+                style="width: 100%"
+                :row-class-name="getOrganRowClassName"
+              >
+                <el-table-column
+                  label="鍣ㄥ畼鍚嶇О"
+                  align="center"
+                  width="120"
+                  prop="organName"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.organName"
+                      placeholder="鍣ㄥ畼鍚嶇О"
+                      :disabled="true"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="绯荤粺缂栧彿"
+                  align="center"
+                  width="120"
+                  prop="caseNo"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.caseNo"
+                      placeholder="绯荤粺缂栧彿"
+                      :disabled="form.utilizationStatus === 'completed'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="绉绘鍖婚櫌"
+                  align="center"
+                  width="200"
+                  prop="hospitalNo"
+                >
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.hospitalNo"
+                      placeholder="璇烽�夋嫨绉绘鍖婚櫌"
+                      style="width: 100%"
+                      :disabled="form.utilizationStatus === 'completed'"
+                      @change="handleHospitalChange(scope.row, $event)"
+                    >
+                      <el-option
+                        v-for="hospital in hospitalList"
+                        :key="hospital.hospitalNo"
+                        :label="hospital.hospitalName"
+                        :value="hospital.hospitalNo"
+                      />
+                    </el-select>
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鍙椾綋濮撴皬"
+                  align="center"
+                  width="120"
+                  prop="recipientName"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.recipientName"
+                      placeholder="鍙椾綋濮撴皬"
+                      :disabled="form.utilizationStatus === 'completed'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="绉绘璐熻矗浜�"
+                  align="center"
+                  width="120"
+                  prop="transplantDoctor"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.transplantDoctor"
+                      placeholder="鍖诲笀濮撳悕"
+                      :disabled="form.utilizationStatus === 'completed'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="绉绘鏃堕棿"
+                  align="center"
+                  width="150"
+                  prop="transplantTime"
+                >
+                  <template slot-scope="scope">
+                    <el-date-picker
+                      clearable
+                      size="small"
+                      style="width: 100%"
+                      v-model="scope.row.transplantTime"
+                      type="date"
+                      value-format="yyyy-MM-dd"
+                      placeholder="閫夋嫨绉绘鏃堕棿"
+                      :disabled="form.utilizationStatus === 'completed'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="绉绘鐘舵��"
+                  align="center"
+                  width="120"
+                  prop="transplantStatus"
+                >
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.transplantStatus"
+                      placeholder="璇烽�夋嫨绉绘鐘舵��"
+                      style="width: 100%"
+                      :disabled="form.utilizationStatus === 'completed'"
+                    >
+                      <el-option
+                        v-for="dict in transplantStatusList"
+                        :key="dict.value"
+                        :label="dict.label"
+                        :value="dict.value"
+                      />
+                    </el-select>
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="璇存槑"
+                  align="center"
+                  prop="abandonReason"
+                  min-width="200"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      type="textarea"
+                      clearable
+                      v-model="scope.row.abandonReason"
+                      placeholder="璇疯緭鍏ュ純鐢ㄨ鏄�"
+                      :disabled="form.utilizationStatus === 'completed'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鎿嶄綔"
+                  align="center"
+                  width="120"
+                  class-name="small-padding fixed-width"
+                  v-if="form.utilizationStatus !== 'completed'"
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="mini"
+                      type="text"
+                      icon="el-icon-edit"
+                      @click="handleEditUtilization(scope.row)"
+                    >
+                      缂栬緫
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <!-- 鍒╃敤缁熻淇℃伅 -->
+        <div class="utilization-stats" v-if="utilizationData.records.length > 0">
+          <el-row :gutter="20">
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">宸插埄鐢ㄥ櫒瀹�:</span>
+                <span class="stat-value">{{ utilizationData.records.length }} 涓�</span>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">寰呭畬鍠勪俊鎭�:</span>
+                <span class="stat-value">{{ incompleteRecords }} 涓�</span>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">娑夊強鍖婚櫌:</span>
+                <span class="stat-value">{{ uniqueHospitals }} 瀹�</span>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">鍒╃敤鐘舵��:</span>
+                <span class="stat-value">
+                  <el-tag :type="getStatusTagType(form.utilizationStatus)">
+                    {{ getStatusText(form.utilizationStatus) }}
+                  </el-tag>
+                </span>
+              </div>
+            </el-col>
+          </el-row>
+        </div>
+
+        <div v-else class="empty-utilization">
+          <el-empty description="鏆傛棤鍒╃敤璁板綍" :image-size="80">
+            <span>璇峰厛閫夋嫨瑕佸埄鐢ㄧ殑鍣ㄥ畼</span>
+          </el-empty>
+        </div>
+      </el-form>
+
+      <div class="dialog-footer" v-if="form.utilizationStatus !== 'completed'">
+        <el-button
+          type="primary"
+          @click="handleSaveUtilization"
+          :loading="saveLoading"
+          :disabled="utilizationData.records.length === 0"
+        >
+          淇濆瓨鍒╃敤璁板綍
+        </el-button>
+        <el-button
+          type="success"
+          @click="handleConfirmUtilization"
+          :loading="confirmLoading"
+          :disabled="incompleteRecords > 0"
+        >
+          纭瀹屾垚鍒╃敤
+        </el-button>
+      </div>
+    </el-card>
+
+    <!-- 鍙楄�呰缁嗕俊鎭儴鍒� -->
+    <el-card class="recipient-card" v-if="utilizationData.records.length > 0">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鍙楄�呰缁嗕俊鎭�</span>
+      </div>
+
+      <el-tabs v-model="activeRecipientTab" type="card">
+        <el-tab-pane
+          v-for="record in utilizationData.records"
+          :key="record.organNo"
+          :label="record.organName"
+          :name="record.organNo"
+        >
+          <el-form :model="record" label-width="140px">
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <el-form-item label="鍙楄�呭鍚�">
+                  <el-input v-model="record.recipientName" placeholder="璇疯緭鍏ュ彈鑰呭鍚�" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鍑虹敓骞存湀">
+                  <el-date-picker
+                    v-model="record.recipientBirthDate"
+                    type="month"
+                    value-format="yyyy-MM"
+                    placeholder="閫夋嫨鍑虹敓骞存湀"
+                    style="width: 100%"
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="鎬у埆">
+                  <el-select v-model="record.recipientGender" placeholder="璇烽�夋嫨鎬у埆" 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="12">
+                <el-form-item label="绉绘涓績鍚嶇О">
+                  <el-input v-model="record.transplantCenter" placeholder="璇疯緭鍏ョЩ妞嶄腑蹇冨悕绉�" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="鎵�鍦ㄥ湴">
+                  <el-input v-model="record.location" placeholder="璇疯緭鍏ユ墍鍦ㄥ湴" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <el-form-item label="绉绘鏃ユ湡">
+                  <el-date-picker
+                    v-model="record.transplantTime"
+                    type="date"
+                    value-format="yyyy-MM-dd"
+                    placeholder="閫夋嫨绉绘鏃ユ湡"
+                    style="width: 100%"
+                  />
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="鍘熷彂鐥�">
+                  <el-input v-model="record.originalDisease" placeholder="璇疯緭鍏ュ師鍙戠梾" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+
+            <el-row :gutter="20">
+              <el-col :span="24">
+                <el-form-item label="妫�娴嬫寚鏍�">
+                  <el-input
+                    type="textarea"
+                    :rows="3"
+                    v-model="record.testIndicators"
+                    placeholder="璇疯緭鍏ュ悇绫诲繀瑕佺殑妫�娴嬫寚鏍�"
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+
+    <!-- 闅忚璁板綍閮ㄥ垎 -->
+    <el-card class="followup-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">闅忚璁板綍</span>
+        <el-button
+          type="primary"
+          size="mini"
+          icon="el-icon-plus"
+          @click="handleAddFollowup"
+          style="float: right;"
+        >
+          鏂板闅忚
+        </el-button>
+      </div>
+
+      <el-table :data="followupData.records" v-loading="loading" border>
+        <el-table-column label="鍣ㄥ畼鍚嶇О" align="center" width="120" prop="organName" />
+        <el-table-column label="闅忚鏃堕棿" align="center" width="160" prop="followupTime">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.followupTime) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="闅忚绫诲瀷" align="center" width="100" prop="followupType">
+          <template slot-scope="scope">
+            <el-tag :type="getFollowupTypeTag(scope.row.followupType)">
+              {{ getFollowupTypeText(scope.row.followupType) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍙楄�呮儏鍐�" align="center" prop="recipientCondition" min-width="200" show-overflow-tooltip />
+        <el-table-column label="闅忚鍖荤敓" align="center" width="120" prop="followupDoctor" />
+        <el-table-column label="涓嬫闅忚鏃堕棿" align="center" width="160" prop="nextFollowupTime">
+          <template slot-scope="scope">
+            <span>{{ scope.row.nextFollowupTime || '-' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" align="center" width="150">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleViewFollowup(scope.row)"
+            >鏌ョ湅</el-button>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleEditFollowup(scope.row)"
+            >缂栬緫</el-button>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-delete"
+              style="color: #F56C6C;"
+              @click="handleDeleteFollowup(scope.row)"
+            >鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <!-- 闄勪欢绠$悊閮ㄥ垎 -->
+    <el-card class="attachment-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鐩稿叧闄勪欢</span>
+        <el-button
+          type="primary"
+          size="mini"
+          icon="el-icon-upload"
+          @click="handleUploadAttachment"
+        >
+          涓婁紶闄勪欢
+        </el-button>
+      </div>
+
+      <div class="attachment-list">
+        <el-table :data="attachments" style="width: 100%">
+          <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
+            <template slot-scope="scope">
+              <div class="file-info">
+                <i :class="getFileIcon(scope.row.fileName)" style="margin-right: 8px; color: #409EFF;"></i>
+                <span>{{ scope.row.fileName }}</span>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="鏂囦欢绫诲瀷" width="100" 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="100" align="center">
+            <template slot-scope="scope">
+              <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="涓婁紶鏃堕棿" width="160" align="center">
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.uploadTime) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鎿嶄綔" width="150" align="center">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-view"
+                @click="handlePreviewAttachment(scope.row)"
+              >棰勮</el-button>
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-download"
+                @click="handleDownloadAttachment(scope.row)"
+              >涓嬭浇</el-button>
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-delete"
+                style="color: #F56C6C;"
+                @click="handleRemoveAttachment(scope.row)"
+              >鍒犻櫎</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-card>
+
+    <!-- 缂栬緫鍒╃敤璁板綍瀵硅瘽妗� -->
+    <el-dialog
+      title="缂栬緫鍣ㄥ畼鍒╃敤璁板綍"
+      :visible.sync="editDialogVisible"
+      width="600px"
+    >
+      <el-form :model="currentRecord" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍣ㄥ畼鍚嶇О">
+              <el-input v-model="currentRecord.organName" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="绉绘鐘舵��">
+              <el-select v-model="currentRecord.transplantStatus" style="width: 100%">
+                <el-option
+                  v-for="dict in transplantStatusList"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="寮冪敤璇存槑" v-if="currentRecord.transplantStatus === '0'">
+          <el-input
+            type="textarea"
+            :rows="3"
+            v-model="currentRecord.abandonReason"
+            placeholder="璇疯緭鍏ュ純鐢ㄧ殑鍘熷洜璇存槑"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="editDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleEditConfirm">纭</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 闅忚璁板綍瀵硅瘽妗� -->
+    <el-dialog
+      :title="followupDialogTitle"
+      :visible.sync="followupDialogVisible"
+      width="700px"
+    >
+      <el-form :model="currentFollowup" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍣ㄥ畼鍚嶇О">
+              <el-select v-model="currentFollowup.organNo" style="width: 100%">
+                <el-option
+                  v-for="organ in utilizationData.records"
+                  :key="organ.organNo"
+                  :label="organ.organName"
+                  :value="organ.organNo"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="闅忚绫诲瀷">
+              <el-select v-model="currentFollowup.followupType" style="width: 100%">
+                <el-option label="甯歌闅忚" value="routine" />
+                <el-option label="绱ф�ラ殢璁�" value="emergency" />
+                <el-option label="鐗规畩闅忚" value="special" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="闅忚鏃堕棿">
+              <el-date-picker
+                v-model="currentFollowup.followupTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="闅忚鍖荤敓">
+              <el-input v-model="currentFollowup.followupDoctor" placeholder="璇疯緭鍏ラ殢璁垮尰鐢�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鍙楄�呮儏鍐�">
+          <el-input
+            type="textarea"
+            :rows="3"
+            v-model="currentFollowup.recipientCondition"
+            placeholder="璇疯緭鍏ュ彈鑰呭綋鍓嶆儏鍐�"
+          />
+        </el-form-item>
+        <el-form-item label="鐢ㄨ嵂鎯呭喌">
+          <el-input
+            type="textarea"
+            :rows="2"
+            v-model="currentFollowup.medicationSituation"
+            placeholder="璇疯緭鍏ョ敤鑽儏鍐�"
+          />
+        </el-form-item>
+        <el-form-item label="妫�鏌ョ粨鏋�">
+          <el-input
+            type="textarea"
+            :rows="2"
+            v-model="currentFollowup.testResults"
+            placeholder="璇疯緭鍏ユ鏌ョ粨鏋�"
+          />
+        </el-form-item>
+        <el-form-item label="涓嬫闅忚鏃堕棿">
+          <el-date-picker
+            v-model="currentFollowup.nextFollowupTime"
+            type="date"
+            value-format="yyyy-MM-dd"
+            style="width: 100%"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="followupDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleSaveFollowup">淇濆瓨</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getOrganUtilizationDetail,
+  updateOrganUtilization,
+  addOrganUtilization,
+  saveUtilizationRecords,
+  saveFollowupRecord,
+  getHospitalList,
+  getLeaderList,
+  getCoordinatorList
+} from "./organUtilization";
+
+export default {
+  name: "OrganUtilizationDetail",
+  dicts: ["sys_user_sex", "sys_Organ", "sys_0_1"],
+  data() {
+    return {
+      // 琛ㄥ崟鏁版嵁
+      form: {
+        id: undefined,
+        hospitalNo: "",
+        caseNo: "",
+        donorName: "",
+        gender: "",
+        age: "",
+        birthDate: "",
+        diagnosis: "",
+        utilizationStatus: "pending",
+        allocationTime: "",
+        registrant: "",
+        registrationTime: "",
+        isBodyDonation: "0",
+        receivingUnit: "",
+        responsibleUserId: "",
+        coordinatedUserId1: "",
+        coordinatedUserId2: "",
+        completionTime: ""
+      },
+      // 琛ㄥ崟楠岃瘉瑙勫垯
+      rules: {
+        donorName: [
+          { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+        ],
+        diagnosis: [
+          { required: true, message: "鐤剧梾璇婃柇涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+      },
+      // 鍒╃敤璁板綍楠岃瘉瑙勫垯
+      utilizationRules: {},
+      // 淇濆瓨鍔犺浇鐘舵��
+      saveLoading: false,
+      confirmLoading: false,
+      // 鍔犺浇鐘舵��
+      loading: false,
+      // 閫変腑鐨勫櫒瀹�
+      selectedOrgans: [],
+      // 鍖婚櫌鍒楄〃
+      hospitalList: [],
+      // 璐熻矗浜哄垪琛�
+      leaderList: [],
+      // 鍗忚皟鍛樺垪琛�
+      coordinatorList: [],
+      // 绉绘鐘舵�佸垪琛�
+      transplantStatusList: [
+        { value: "1", label: "宸茬Щ妞�" },
+        { value: "0", label: "鏈Щ妞�" },
+        { value: "2", label: "绉绘涓�" }
+      ],
+      // 鍒╃敤璁板綍鏁版嵁
+      utilizationData: {
+        records: []
+      },
+      // 闅忚璁板綍鏁版嵁
+      followupData: {
+        records: []
+      },
+      // 闄勪欢鏁版嵁
+      attachments: [],
+      // 褰撳墠婵�娲荤殑鍙楄�呮爣绛�
+      activeRecipientTab: "",
+      // 缂栬緫瀵硅瘽妗�
+      editDialogVisible: false,
+      currentRecord: {},
+      currentEditIndex: -1,
+      // 闅忚瀵硅瘽妗�
+      followupDialogVisible: false,
+      followupDialogTitle: "鏂板闅忚璁板綍",
+      currentFollowup: {},
+      isEditingFollowup: false
+    };
+  },
+  computed: {
+    // 褰撳墠鐢ㄦ埛淇℃伅
+    currentUser() {
+      return JSON.parse(sessionStorage.getItem("user") || "{}");
+    },
+    // 涓嶅畬鏁寸殑璁板綍鏁伴噺
+    incompleteRecords() {
+      return this.utilizationData.records.filter(
+        record =>
+          !record.caseNo ||
+          !record.hospitalNo ||
+          !record.recipientName ||
+          !record.transplantTime
+      ).length;
+    },
+    // 鍞竴鍖婚櫌鏁伴噺
+    uniqueHospitals() {
+      const hospitals = this.utilizationData.records
+        .map(record => record.hospitalNo)
+        .filter(Boolean);
+      return new Set(hospitals).size;
+    }
+  },
+  created() {
+    const id = this.$route.query.id;
+    if (id) {
+      this.getDetail(id);
+    } else {
+      this.generateCaseNo();
+      this.form.registrant = this.currentUser.username || "褰撳墠鐢ㄦ埛";
+      this.form.registrationTime = new Date()
+        .toISOString()
+        .replace("T", " ")
+        .substring(0, 19);
+    }
+    this.getHospitalData();
+    this.getLeaderData();
+    this.getCoordinatorData();
+  },
+  methods: {
+    // 鐢熸垚妗堜緥缂栧彿
+    generateCaseNo() {
+      const timestamp = Date.now().toString();
+      this.form.hospitalNo = "D" + timestamp.slice(-6);
+      this.form.caseNo = "C" + timestamp.slice(-6);
+    },
+    // 鑾峰彇璇︽儏
+    getDetail(id) {
+      this.loading = true;
+      getOrganUtilizationDetail(id)
+        .then(response => {
+          if (response.code === 200) {
+            this.form = response.data;
+            if (response.data.utilizationRecords) {
+              this.utilizationData.records = response.data.utilizationRecords;
+              this.selectedOrgans = response.data.utilizationRecords.map(
+                item => item.organNo
+              );
+              if (this.utilizationData.records.length > 0) {
+                this.activeRecipientTab = this.utilizationData.records[0].organNo;
+              }
+            }
+            if (response.data.followupRecords) {
+              this.followupData.records = response.data.followupRecords;
+            }
+          }
+          this.loading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇鍣ㄥ畼鍒╃敤璇︽儏澶辫触:", error);
+          this.loading = false;
+          this.$message.error("鑾峰彇璇︽儏澶辫触");
+        });
+    },
+    // 鑾峰彇鍖婚櫌鏁版嵁
+    getHospitalData() {
+      getHospitalList().then(response => {
+        if (response.code === 200) {
+          this.hospitalList = response.data;
+        }
+      });
+    },
+    // 鑾峰彇璐熻矗浜烘暟鎹�
+    getLeaderData() {
+      getLeaderList().then(response => {
+        if (response.code === 200) {
+          this.leaderList = response.data;
+        }
+      });
+    },
+    // 鑾峰彇鍗忚皟鍛樻暟鎹�
+    getCoordinatorData() {
+      getCoordinatorList().then(response => {
+        if (response.code === 200) {
+          this.coordinatorList = response.data;
+        }
+      });
+    },
+    // 鍣ㄥ畼閫夋嫨鐘舵�佸彉鍖�
+    handleOrganSelectionChange(selectedValues) {
+      const currentOrganNos = this.utilizationData.records.map(
+        item => item.organNo
+      );
+
+      // 鏂板閫夋嫨鐨勫櫒瀹�
+      selectedValues.forEach(organValue => {
+        if (!currentOrganNos.includes(organValue)) {
+          const organInfo = this.dict.type.sys_Organ.find(
+            item => item.value === organValue
+          );
+          if (organInfo) {
+            this.utilizationData.records.push({
+              organName: organInfo.label,
+              organNo: organValue,
+              id: null,
+              utilizationId: this.form.id,
+              caseNo: "",
+              hospitalNo: "",
+              hospitalName: "",
+              recipientName: "",
+              transplantDoctor: "",
+              transplantTime: "",
+              transplantStatus: "1",
+              abandonReason: "",
+              recipientBirthDate: "",
+              recipientGender: "",
+              transplantCenter: "",
+              location: "",
+              originalDisease: "",
+              testIndicators: ""
+            });
+          }
+        }
+      });
+
+      // 绉婚櫎鍙栨秷閫夋嫨鐨勫櫒瀹�
+      this.utilizationData.records = this.utilizationData.records.filter(
+        record => {
+          if (selectedValues.includes(record.organNo)) {
+            return true;
+          } else {
+            if (record.id) {
+              this.$confirm(
+                "鍒犻櫎鍣ㄥ畼鍒╃敤鏁版嵁鍚庡皢鏃犳硶鎭㈠锛屾偍纭鍒犻櫎璇ユ潯璁板綍鍚楋紵",
+                "鎻愮ず",
+                {
+                  confirmButtonText: "纭畾",
+                  cancelButtonText: "鍙栨秷",
+                  type: "warning"
+                }
+              )
+                .then(() => {
+                  this.utilizationData.records = this.utilizationData.records.filter(
+                    r => r.organNo !== record.organNo
+                  );
+                  this.$message.success("鍒犻櫎鎴愬姛");
+                })
+                .catch(() => {
+                  this.selectedOrgans.push(record.organNo);
+                });
+              return true;
+            } else {
+              return false;
+            }
+          }
+        }
+      );
+    },
+    // 鍖婚櫌閫夋嫨鍙樺寲
+    handleHospitalChange(row, hospitalNo) {
+      const hospital = this.hospitalList.find(
+        item => item.hospitalNo === hospitalNo
+      );
+      if (hospital) {
+        row.hospitalName = hospital.hospitalName;
+      }
+    },
+    // 缂栬緫鍒╃敤璁板綍
+    handleEditUtilization(row) {
+      const index = this.utilizationData.records.findIndex(
+        item => item.organNo === row.organNo
+      );
+      if (index !== -1) {
+        this.currentRecord = { ...row };
+        this.currentEditIndex = index;
+        this.editDialogVisible = true;
+      }
+    },
+    // 纭缂栬緫
+    handleEditConfirm() {
+      if (this.currentEditIndex !== -1) {
+        this.utilizationData.records[this.currentEditIndex] = {
+          ...this.currentRecord
+        };
+        this.$message.success("鍒╃敤璁板綍鏇存柊鎴愬姛");
+        this.editDialogVisible = false;
+      }
+    },
+    // 鍣ㄥ畼琛屾牱寮�
+    getOrganRowClassName({ row }) {
+      if (
+        !row.caseNo ||
+        !row.hospitalNo ||
+        !row.recipientName ||
+        !row.transplantTime
+      ) {
+        return "warning-row";
+      }
+      return "";
+    },
+    // 鑾峰彇鐘舵�佹爣绛剧被鍨�
+    getStatusTagType(status) {
+      const typeMap = {
+        completed: "success",
+        in_progress: "warning",
+        pending: "info"
+      };
+      return typeMap[status] || "info";
+    },
+    // 鑾峰彇鐘舵�佹枃鏈�
+    getStatusText(status) {
+      const textMap = {
+        completed: "宸插畬鎴�",
+        in_progress: "杩涜涓�",
+        pending: "寰呭鐞�"
+      };
+      return textMap[status] || "鏈煡";
+    },
+    // 鑾峰彇闅忚绫诲瀷鏍囩
+    getFollowupTypeTag(type) {
+      const typeMap = {
+        routine: "success",
+        emergency: "danger",
+        special: "warning"
+      };
+      return typeMap[type] || "info";
+    },
+    // 鑾峰彇闅忚绫诲瀷鏂囨湰
+    getFollowupTypeText(type) {
+      const textMap = {
+        routine: "甯歌闅忚",
+        emergency: "绱ф�ラ殢璁�",
+        special: "鐗规畩闅忚"
+      };
+      return textMap[type] || "鏈煡";
+    },
+    // 淇濆瓨鍩烘湰淇℃伅
+    handleSave() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.saveLoading = true;
+          const apiMethod = this.form.id
+            ? updateOrganUtilization
+            : addOrganUtilization;
+
+          apiMethod(this.form)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("淇濆瓨鎴愬姛");
+                if (!this.form.id) {
+                  this.form.id = response.data.id;
+                  this.$router.replace({
+                    query: { ...this.$route.query, id: this.form.id }
+                  });
+                }
+              }
+            })
+            .catch(error => {
+              console.error("淇濆瓨澶辫触:", error);
+              this.$message.error("淇濆瓨澶辫触");
+            })
+            .finally(() => {
+              this.saveLoading = false;
+            });
+        }
+      });
+    },
+    // 淇濆瓨鍒╃敤璁板綍
+    handleSaveUtilization() {
+      if (!this.form.id) {
+        this.$message.warning("璇峰厛淇濆瓨鍩烘湰淇℃伅");
+        return;
+      }
+
+      this.saveLoading = true;
+      saveUtilizationRecords(this.form.id, this.utilizationData.records)
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍒╃敤璁板綍淇濆瓨鎴愬姛");
+          }
+        })
+        .catch(error => {
+          console.error("淇濆瓨鍒╃敤璁板綍澶辫触:", error);
+          this.$message.error("淇濆瓨鍒╃敤璁板綍澶辫触");
+        })
+        .finally(() => {
+          this.saveLoading = false;
+        });
+    },
+    // 纭瀹屾垚鍒╃敤
+    handleConfirmUtilization() {
+      if (this.incompleteRecords > 0) {
+        this.$message.warning("璇峰厛瀹屽杽鎵�鏈夊埄鐢ㄨ褰曠殑淇℃伅");
+        return;
+      }
+
+      this.$confirm("纭瀹屾垚鍣ㄥ畼鍒╃敤鍚楋紵瀹屾垚鍚庡皢鏃犳硶淇敼鍒╃敤淇℃伅銆�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.confirmLoading = true;
+          this.form.utilizationStatus = "completed";
+          this.form.completionTime = new Date()
+            .toISOString()
+            .replace("T", " ")
+            .substring(0, 19);
+
+          updateOrganUtilization(this.form)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("鍣ㄥ畼鍒╃敤宸插畬鎴�");
+              }
+            })
+            .catch(error => {
+              console.error("纭鍒╃敤澶辫触:", error);
+              this.$message.error("纭鍒╃敤澶辫触");
+            })
+            .finally(() => {
+              this.confirmLoading = false;
+            });
+        })
+        .catch(() => {});
+    },
+    // 瀹屾垚鍒╃敤
+    handleComplete() {
+      this.handleConfirmUtilization();
+    },
+    // 鏂板闅忚璁板綍
+    handleAddFollowup() {
+      this.followupDialogTitle = "鏂板闅忚璁板綍";
+      this.isEditingFollowup = false;
+      this.currentFollowup = {
+        organNo: this.utilizationData.records.length > 0 ? this.utilizationData.records[0].organNo : "",
+        followupTime: new Date().toISOString().replace("T", " ").substring(0, 19),
+        followupType: "routine",
+        recipientCondition: "",
+        medicationSituation: "",
+        testResults: "",
+        nextFollowupTime: "",
+        followupDoctor: ""
+      };
+      this.followupDialogVisible = true;
+    },
+    // 鏌ョ湅闅忚璁板綍
+    handleViewFollowup(record) {
+      this.currentFollowup = { ...record };
+      this.followupDialogTitle = "鏌ョ湅闅忚璁板綍";
+      this.followupDialogVisible = true;
+    },
+    // 缂栬緫闅忚璁板綍
+    handleEditFollowup(record) {
+      this.followupDialogTitle = "缂栬緫闅忚璁板綍";
+      this.isEditingFollowup = true;
+      this.currentFollowup = { ...record };
+      this.followupDialogVisible = true;
+    },
+    // 鍒犻櫎闅忚璁板綍
+    handleDeleteFollowup(record) {
+      this.$confirm("纭畾瑕佸垹闄よ繖鏉¢殢璁胯褰曞悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          const index = this.followupData.records.findIndex(
+            item => item.id === record.id
+          );
+          if (index !== -1) {
+            this.followupData.records.splice(index, 1);
+            this.$message.success("闅忚璁板綍鍒犻櫎鎴愬姛");
+          }
+        })
+        .catch(() => {});
+    },
+    // 淇濆瓨闅忚璁板綍
+    handleSaveFollowup() {
+      if (!this.currentFollowup.organNo) {
+        this.$message.warning("璇烽�夋嫨鍣ㄥ畼");
+        return;
+      }
+
+      if (!this.currentFollowup.followupTime) {
+        this.$message.warning("璇烽�夋嫨闅忚鏃堕棿");
+        return;
+      }
+
+      this.saveLoading = true;
+
+      // 鑾峰彇鍣ㄥ畼鍚嶇О
+      const organRecord = this.utilizationData.records.find(
+        item => item.organNo === this.currentFollowup.organNo
+      );
+      const organName = organRecord ? organRecord.organName : "";
+
+      const followupData = {
+        ...this.currentFollowup,
+        organName: organName,
+        utilizationId: this.form.id
+      };
+
+      saveFollowupRecord(followupData)
+        .then(response => {
+          if (response.code === 200) {
+            if (this.isEditingFollowup) {
+              // 鏇存柊鐜版湁璁板綍
+              const index = this.followupData.records.findIndex(
+                item => item.id === this.currentFollowup.id
+              );
+              if (index !== -1) {
+                this.followupData.records[index] = response.data;
+              }
+            } else {
+              // 娣诲姞鏂拌褰�
+              this.followupData.records.push(response.data);
+            }
+            this.$message.success("闅忚璁板綍淇濆瓨鎴愬姛");
+            this.followupDialogVisible = false;
+          }
+        })
+        .catch(error => {
+          console.error("淇濆瓨闅忚璁板綍澶辫触:", error);
+          this.$message.error("淇濆瓨闅忚璁板綍澶辫触");
+        })
+        .finally(() => {
+          this.saveLoading = false;
+        });
+    },
+    // 涓婁紶闄勪欢
+    handleUploadAttachment() {
+      this.$message.info("闄勪欢涓婁紶鍔熻兘");
+    },
+    // 棰勮闄勪欢
+    handlePreviewAttachment(attachment) {
+      this.$message.info("闄勪欢棰勮鍔熻兘");
+    },
+    // 涓嬭浇闄勪欢
+    handleDownloadAttachment(attachment) {
+      this.$message.info("闄勪欢涓嬭浇鍔熻兘");
+    },
+    // 鍒犻櫎闄勪欢
+    handleRemoveAttachment(attachment) {
+      this.$confirm("纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+        })
+        .catch(() => {});
+    },
+    // 鑾峰彇鏂囦欢鍥炬爣
+    getFileIcon(fileName) {
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const iconMap = {
+        pdf: "el-icon-document",
+        doc: "el-icon-document",
+        docx: "el-icon-document",
+        xls: "el-icon-document",
+        xlsx: "el-icon-document",
+        jpg: "el-icon-picture",
+        jpeg: "el-icon-picture",
+        png: "el-icon-picture"
+      };
+      return iconMap[ext] || "el-icon-document";
+    },
+    // 鑾峰彇鏂囦欢绫诲瀷
+    getFileType(fileName) {
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const typeMap = {
+        pdf: "PDF",
+        doc: "DOC",
+        docx: "DOCX",
+        xls: "XLS",
+        xlsx: "XLSX",
+        jpg: "JPG",
+        jpeg: "JPEG",
+        png: "PNG"
+      };
+      return typeMap[ext] || ext.toUpperCase();
+    },
+    // 鏂囦欢澶у皬鏍煎紡鍖�
+    formatFileSize(size) {
+      if (size === 0) 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];
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time) {
+      if (!time) return "";
+      const date = new Date(time);
+      return `${date.getFullYear()}-${(date.getMonth() + 1)
+        .toString()
+        .padStart(2, "0")}-${date
+        .getDate()
+        .toString()
+        .padStart(2, "0")} ${date
+        .getHours()
+        .toString()
+        .padStart(2, "0")}:${date
+        .getMinutes()
+        .toString()
+        .padStart(2, "0")}`;
+    },
+    // 鎻愪氦褰掓。
+    handleSubmitArchive() {
+      this.$confirm("纭鎻愪氦褰掓。鍚楋紵褰掓。鍚庡皢鏃犳硶淇敼鏁版嵁銆�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.$message.success("鎻愪氦褰掓。鎴愬姛");
+        })
+        .catch(() => {});
+    },
+    // 鎾ら攢褰掓。
+    handleRevokeArchive() {
+      this.$confirm("纭鎾ら攢褰掓。鍚楋紵", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.$message.success("鎾ら攢褰掓。鎴愬姛");
+        })
+        .catch(() => {});
+    },
+    // 缁堟妗堜緥
+    handleTerminateCase() {
+      this.$confirm("纭缁堟妗堜緥鍚楋紵", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.$message.success("妗堜緥宸茬粓姝�");
+        })
+        .catch(() => {});
+    },
+    // 鎭㈠妗堜緥
+    handleRestoreCase() {
+      this.$confirm("纭鎭㈠妗堜緥鍚楋紵", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.$message.success("妗堜緥宸叉仮澶�");
+        })
+        .catch(() => {});
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.organ-utilization-detail {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.detail-card, .utilization-card, .recipient-card, .followup-card, .attachment-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  border: 1px solid #e4e7ed;
+}
+
+.detail-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+  line-height: 1.4;
+}
+/* 琛ㄦ牸鏁翠綋鏍峰紡 */
+:deep(.el-table) {
+  border-radius: 8px;
+  overflow: hidden;
+}
+:deep(.el-table th) {
+  background-color: #f5f7fa;
+  color: #606266;
+  font-weight: 600;
+}
+:deep(.el-table .cell) {
+  padding: 12px 8px;
+  line-height: 1.5;
+}
+
+/* 鏂戦┈绾硅〃鏍艰 */
+:deep(.el-table__row.warning-row) {
+  background-color: #fdf6ec;
+}
+:deep(.el-table__row.default-row) {
+  background-color: #f0f9ff;
+}
+
+/* 榧犳爣鎮仠鏁堟灉 */
+:deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
+  background-color: #f5f7fa !important;
+}
+
+/* 缁熻淇℃伅鏍峰紡 */
+.utilization-stats {
+  margin-top: 20px;
+  padding: 15px;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  border-radius: 8px;
+  color: white;
+}
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 10px;
+  text-align: center;
+}
+.stat-label {
+  font-size: 18px;
+  opacity: 0.9;
+  margin-bottom: 5px;
+}
+.stat-value {
+  font-size: 20px;
+  font-weight: bold;
+}
+/* 琛ㄥ崟鏍囩鍜岃緭鍏ユ鏍峰紡 */
+:deep(.el-form-item__label) {
+  font-weight: 500;
+  color: #606266;
+}
+:deep(.el-input__inner) {
+  border-radius: 4px;
+  transition: border-color 0.3s ease;
+}
+:deep(.el-input__inner:focus) {
+  border-color: #409EFF;
+  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+}
+
+/* 鎸夐挳鏍峰紡浼樺寲 */
+:deep(.el-button--primary) {
+  background: linear-gradient(135deg, #409EFF 0%, #3375e0 100%);
+  border: none;
+  border-radius: 4px;
+  transition: all 0.3s ease;
+}
+:deep(.el-button--primary:hover) {
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
+}
+
+/* 鏍囩椤垫牱寮� */
+:deep(.el-tabs__item) {
+  font-weight: 500;
+}
+:deep(.el-tabs__active-bar) {
+  background: linear-gradient(135deg, #409EFF 0%, #3375e0 100%);
+}
+/* 骞虫澘璁惧閫傞厤 */
+@media (max-width: 1024px) {
+  .organ-utilization-detail {
+    padding: 15px;
+  }
+  :deep(.el-col) {
+    margin-bottom: 10px;
+  }
+}
+
+/* 鎵嬫満璁惧閫傞厤 */
+@media (max-width: 768px) {
+  .organ-utilization-detail {
+    padding: 10px;
+  }
+  .detail-title {
+    font-size: 16px;
+  }
+  :deep(.el-table .cell) {
+    padding: 8px 4px;
+    font-size: 12px;
+  }
+  :deep(.el-form-item__label) {
+    font-size: 12px;
+  }
+}
+
+/* 瓒呭皬灞忓箷璁惧 */
+@media (max-width: 480px) {
+  .organ-utilization-detail {
+    padding: 5px;
+  }
+  :deep(.el-card__header) {
+    padding: 10px 15px;
+  }
+}
+/* 绌虹姸鎬佹牱寮� */
+.empty-utilization {
+  text-align: center;
+  padding: 40px 0;
+  color: #909399;
+  background: #fafafa;
+  border-radius: 4px;
+  margin: 20px 0;
+}
+
+/* 鍔犺浇鐘舵�� */
+:deep(.el-loading-mask) {
+  border-radius: 4px;
+}
+
+/* 鏂囦欢淇℃伅鏍峰紡 */
+.file-info {
+  display: flex;
+  align-items: center;
+  padding: 5px 0;
+}
+.file-info i {
+  font-size: 18px;
+  margin-right: 10px;
+}
+
+/* 鍔ㄧ敾鏁堟灉 */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+.fade-enter, .fade-leave-to {
+  opacity: 0;
+}
+</style>
diff --git a/src/views/business/OrganUtilization/index.vue b/src/views/business/OrganUtilization/index.vue
new file mode 100644
index 0000000..6b1941b
--- /dev/null
+++ b/src/views/business/OrganUtilization/index.vue
@@ -0,0 +1,377 @@
+<template>
+  <div class="organ-utilization-list">
+    <!-- 鏌ヨ鏉′欢 -->
+    <el-card class="search-card">
+      <el-form
+        :model="queryParams"
+        ref="queryForm"
+        :inline="true"
+        label-width="100px"
+      >
+        <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+          <el-input
+            v-model="queryParams.hospitalNo"
+            placeholder="璇疯緭鍏ヤ綇闄㈠彿"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+          <el-input
+            v-model="queryParams.donorName"
+            placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="鍒╃敤鐘舵��" prop="utilizationStatus">
+          <el-select
+            v-model="queryParams.utilizationStatus"
+            placeholder="璇烽�夋嫨鍒╃敤鐘舵��"
+            clearable
+            style="width: 200px"
+          >
+            <el-option label="宸插畬鎴�" value="completed" />
+            <el-option label="杩涜涓�" value="in_progress" />
+            <el-option label="寰呭鐞�" value="pending" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" @click="handleQuery"
+            >鎼滅储</el-button
+          >
+          <el-button icon="el-icon-refresh" @click="resetQuery">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 鎿嶄綔鎸夐挳 -->
+    <el-card class="tool-card">
+      <el-row :gutter="10">
+        <el-col :span="16">
+          <el-button type="primary" icon="el-icon-plus" @click="handleCreate"
+            >鏂板缓鍒╃敤</el-button
+          >
+          <el-button
+            type="success"
+            icon="el-icon-edit"
+            :disabled="single"
+            @click="handleUpdate"
+            >淇敼</el-button
+          >
+          <el-button
+            type="danger"
+            icon="el-icon-delete"
+            :disabled="multiple"
+            @click="handleDelete"
+            >鍒犻櫎</el-button
+          >
+        </el-col>
+        <el-col :span="8" style="text-align: right">
+          <el-tooltip content="鍒锋柊" placement="top">
+            <el-button icon="el-icon-refresh" circle @click="getList" />
+          </el-tooltip>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <el-card>
+      <el-table
+        v-loading="loading"
+        :data="organUtilizationList"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column
+          label="浣忛櫌鍙�"
+          align="center"
+          prop="hospitalNo"
+          width="120"
+        />
+        <el-table-column
+          label="鎹愮尞鑰呭鍚�"
+          align="center"
+          prop="donorName"
+          width="120"
+        />
+        <el-table-column label="鎬у埆" align="center" prop="gender" width="80">
+          <template slot-scope="scope">
+            <dict-tag
+              :options="dict.type.sys_user_sex"
+              :value="parseInt(scope.row.gender)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="骞撮緞" align="center" prop="age" width="80" />
+        <el-table-column
+          label="鐤剧梾璇婃柇"
+          align="center"
+          prop="diagnosis"
+          min-width="180"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="鍒╃敤鐘舵��"
+          align="center"
+          prop="utilizationStatus"
+          width="100"
+        >
+          <template slot-scope="scope">
+            <el-tag :type="getStatusTagType(scope.row.utilizationStatus)">
+              {{ getStatusText(scope.row.utilizationStatus) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鐧昏浜�"
+          align="center"
+          prop="registrant"
+          width="100"
+        />
+        <el-table-column
+          label="鐧昏鏃堕棿"
+          align="center"
+          prop="registrationTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.registrationTime
+                ? parseTime(scope.row.registrationTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鎿嶄綔"
+          align="center"
+          width="150"
+          class-name="small-padding fixed-width"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleView(scope.row)"
+              >璇︽儏</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdate(scope.row)"
+              >淇敼</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-delete"
+              style="color: #F56C6C"
+              @click="handleDelete(scope.row)"
+              >鍒犻櫎</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 鍒嗛〉缁勪欢 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { listOrganUtilization, delOrganUtilization } from "./organUtilization";
+import Pagination from "@/components/Pagination";
+
+export default {
+  name: "OrganUtilizationList",
+  components: { Pagination },
+  dicts: ["sys_user_sex"],
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 鍣ㄥ畼鍒╃敤琛ㄦ牸鏁版嵁
+      organUtilizationList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        hospitalNo: undefined,
+        donorName: undefined,
+        utilizationStatus: undefined
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 鏌ヨ鍣ㄥ畼鍒╃敤鍒楄〃
+    getList() {
+      this.loading = true;
+      listOrganUtilization(this.queryParams)
+        .then(response => {
+          if (response.code === 200) {
+            this.organUtilizationList = response.data.rows;
+            this.total = response.data.total;
+          } else {
+            this.$message.error("鑾峰彇鏁版嵁澶辫触");
+          }
+          this.loading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇鍣ㄥ畼鍒╃敤鍒楄〃澶辫触:", error);
+          this.loading = false;
+          this.$message.error("鑾峰彇鏁版嵁澶辫触");
+        });
+    },
+    // 鑾峰彇鐘舵�佹爣绛剧被鍨�
+    getStatusTagType(status) {
+      const typeMap = {
+        completed: "success",
+        in_progress: "warning",
+        pending: "info"
+      };
+      return typeMap[status] || "info";
+    },
+    // 鑾峰彇鐘舵�佹枃鏈�
+    getStatusText(status) {
+      const textMap = {
+        completed: "宸插畬鎴�",
+        in_progress: "杩涜涓�",
+        pending: "寰呭鐞�"
+      };
+      return textMap[status] || "鏈煡";
+    },
+    // 鎼滅储鎸夐挳鎿嶄綔
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    // 閲嶇疆鎸夐挳鎿嶄綔
+    resetQuery() {
+      this.$refs.queryForm.resetFields();
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    // 鏌ョ湅璇︽儏
+    handleView(row) {
+      this.$router.push({
+        path: "/case/organUtilizationInfo",
+        query: { id: row.id }
+      });
+    },
+    // 鏂板鎸夐挳鎿嶄綔
+    handleCreate() {
+      this.$router.push("/case/organUtilizationInfo");
+    },
+    // 淇敼鎸夐挳鎿嶄綔
+    handleUpdate(row) {
+      const id = row.id || this.ids[0];
+      this.$router.push({
+        path: "/case/organUtilizationInfo",
+        query: { id: id }
+      });
+    },
+    // 鍒犻櫎鎸夐挳鎿嶄綔
+    handleDelete(row) {
+      const ids = row.id ? [row.id] : this.ids;
+      this.$confirm("鏄惁纭鍒犻櫎閫変腑鐨勬暟鎹」锛�", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          return delOrganUtilization(ids);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍒犻櫎鎴愬姛");
+            this.getList();
+          }
+        })
+        .catch(() => {});
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time, pattern) {
+      if (!time) return "";
+      const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
+      let date;
+      if (typeof time === "object") {
+        date = time;
+      } else {
+        if (typeof time === "string" && /^[0-9]+$/.test(time)) {
+          time = parseInt(time);
+        }
+        if (typeof time === "number" && time.toString().length === 10) {
+          time = time * 1000;
+        }
+        date = new Date(time);
+      }
+      const formatObj = {
+        y: date.getFullYear(),
+        m: date.getMonth() + 1,
+        d: date.getDate(),
+        h: date.getHours(),
+        i: date.getMinutes(),
+        s: date.getSeconds(),
+        a: date.getDay()
+      };
+      const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+        let value = formatObj[key];
+        if (key === "a") {
+          return ["鏃�", "涓�", "浜�", "涓�", "鍥�", "浜�", "鍏�"][value];
+        }
+        if (result.length > 0 && value < 10) {
+          value = "0" + value;
+        }
+        return value || 0;
+      });
+      return time_str;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.organ-utilization-list {
+  padding: 20px;
+}
+
+.search-card {
+  margin-bottom: 20px;
+}
+
+.tool-card {
+  margin-bottom: 20px;
+}
+
+.fixed-width .el-button {
+  margin: 0 5px;
+}
+</style>
diff --git a/src/views/business/OrganUtilization/organUtilization.js b/src/views/business/OrganUtilization/organUtilization.js
new file mode 100644
index 0000000..5308a5e
--- /dev/null
+++ b/src/views/business/OrganUtilization/organUtilization.js
@@ -0,0 +1,439 @@
+// 妯℃嫙鍣ㄥ畼鍒╃敤鏁版嵁
+const mockOrganUtilizationData = [
+  {
+    id: 1,
+    hospitalNo: "D202312001",
+    caseNo: "C202312001",
+    donorName: "寮犱笁",
+    gender: "0",
+    age: 45,
+    diagnosis: "鑴戝浼�",
+    registrant: "鏉庡崗璋冨憳",
+    registrationTime: "2023-12-01 15:00:00",
+    createTime: "2023-12-01 10:00:00",
+    utilizationStatus: "completed",
+    completionTime: "2023-12-01 16:30:00",
+    isBodyDonation: "1",
+    receivingUnit: "鍖荤澶у瑙e墫鏁欑爺瀹�",
+    responsibleUserId: "L001",
+    coordinatedUserId1: "C001",
+    coordinatedUserId2: "C002"
+  },
+  {
+    id: 2,
+    hospitalNo: "D202312002",
+    caseNo: "C202312002",
+    donorName: "鏉庡洓",
+    gender: "1",
+    age: 38,
+    diagnosis: "蹇冭剰楠ゅ仠",
+    registrant: "寮犲崗璋冨憳",
+    registrationTime: "2023-12-02 10:00:00",
+    createTime: "2023-12-02 08:30:00",
+    utilizationStatus: "in_progress",
+    completionTime: "",
+    isBodyDonation: "0",
+    receivingUnit: "",
+    responsibleUserId: "",
+    coordinatedUserId1: "",
+    coordinatedUserId2: ""
+  },
+  {
+    id: 3,
+    hospitalNo: "D202312003",
+    caseNo: "C202312003",
+    donorName: "鐜嬩簲",
+    gender: "0",
+    age: 52,
+    diagnosis: "鑴戞姝�",
+    registrant: "璧靛崗璋冨憳",
+    registrationTime: "2023-12-03 17:20:00",
+    createTime: "2023-12-03 14:00:00",
+    utilizationStatus: "pending",
+    completionTime: "",
+    isBodyDonation: "0",
+    receivingUnit: "",
+    responsibleUserId: "",
+    coordinatedUserId1: "",
+    coordinatedUserId2: ""
+  }
+];
+
+// 妯℃嫙鍣ㄥ畼鍒╃敤璁板綍鏁版嵁
+const mockUtilizationRecordData = [
+  {
+    id: 1,
+    utilizationId: 1,
+    organName: "鑲濊剰",
+    organNo: "L001",
+    caseNo: "C202312001",
+    hospitalNo: "H1001",
+    hospitalName: "鍖椾含鍗忓拰鍖婚櫌",
+    recipientName: "鐜�",
+    transplantDoctor: "寮犲尰鐢�",
+    transplantTime: "2023-12-01 16:00:00",
+    transplantStatus: "1",
+    abandonReason: "",
+    recipientBirthDate: "1980-05-15",
+    recipientGender: "0",
+    transplantCenter: "鍖椾含鍗忓拰鍖婚櫌绉绘涓績",
+    location: "鍖椾含甯�",
+    originalDisease: "鑲濈‖鍖�",
+    testIndicators: "鑲濆姛鑳芥甯革紝琛�鍨嬪尮閰�"
+  },
+  {
+    id: 2,
+    utilizationId: 1,
+    organName: "鑲捐剰",
+    organNo: "K001",
+    caseNo: "C202312001",
+    hospitalNo: "H1002",
+    hospitalName: "涓婃捣鐟為噾鍖婚櫌",
+    recipientName: "鏉�",
+    transplantDoctor: "鐜嬪尰鐢�",
+    transplantTime: "2023-12-01 16:30:00",
+    transplantStatus: "1",
+    abandonReason: "",
+    recipientBirthDate: "1975-08-20",
+    recipientGender: "1",
+    transplantCenter: "涓婃捣鐟為噾鍖婚櫌绉绘涓績",
+    location: "涓婃捣甯�",
+    originalDisease: "灏挎瘨鐥�",
+    testIndicators: "鑲惧姛鑳芥甯革紝鍏嶇柅鍖归厤"
+  },
+  {
+    id: 3,
+    utilizationId: 1,
+    organName: "蹇冭剰",
+    organNo: "H001",
+    caseNo: "C202312001",
+    hospitalNo: "H1003",
+    hospitalName: "骞垮窞涓北鍖婚櫌",
+    recipientName: "闄�",
+    transplantDoctor: "鍒樺尰鐢�",
+    transplantTime: "2023-12-01 17:00:00",
+    transplantStatus: "1",
+    abandonReason: "",
+    recipientBirthDate: "1982-03-10",
+    recipientGender: "0",
+    transplantCenter: "骞垮窞涓北鍖婚櫌蹇冭剰涓績",
+    location: "骞垮窞甯�",
+    originalDisease: "蹇冭倢鐥�",
+    testIndicators: "蹇冨姛鑳芥甯革紝琛�鍨嬪尮閰�"
+  }
+];
+
+// 妯℃嫙闅忚璁板綍鏁版嵁
+const mockFollowupRecordData = [
+  {
+    id: 1,
+    utilizationId: 1,
+    organNo: "L001",
+    followupTime: "2024-01-01 10:00:00",
+    followupType: "routine",
+    recipientCondition: "鎭㈠鑹ソ锛岃倽鍔熻兘姝e父",
+    medicationSituation: "鍏嶇柅鎶戝埗鍓傝寰嬫湇鐢�",
+    testResults: "鑲濆姛鑳芥寚鏍囨甯革紝琛�鑽祿搴﹁揪鏍�",
+    nextFollowupTime: "2024-04-01",
+    followupDoctor: "寮犲尰鐢�",
+    attachment: "鑲濆姛鑳芥鏌ユ姤鍛�.pdf"
+  },
+  {
+    id: 2,
+    utilizationId: 1,
+    organNo: "K001",
+    followupTime: "2024-01-02 09:30:00",
+    followupType: "routine",
+    recipientCondition: "鑲惧姛鑳界ǔ瀹氾紝鏃犳帓鏂ュ弽搴�",
+    medicationSituation: "鎶楁帓鏂ヨ嵂鐗╂寜鏃舵湇鐢�",
+    testResults: "鑲岄厫姘村钩姝e父锛屽翱甯歌鏃犲紓甯�",
+    nextFollowupTime: "2024-04-02",
+    followupDoctor: "鐜嬪尰鐢�",
+    attachment: "鑲惧姛鑳介殢璁挎姤鍛�.pdf"
+  },
+  {
+    id: 3,
+    utilizationId: 1,
+    organNo: "H001",
+    followupTime: "2024-01-03 11:00:00",
+    followupType: "emergency",
+    recipientCondition: "鍑虹幇杞诲井鎺掓枼鍙嶅簲锛屽凡澶勭悊",
+    medicationSituation: "璋冩暣鍏嶇柅鎶戝埗鍓傚墏閲�",
+    testResults: "蹇冨姛鑳芥寚鏍囧熀鏈甯革紝闇�瀵嗗垏瑙傚療",
+    nextFollowupTime: "2024-01-10",
+    followupDoctor: "鍒樺尰鐢�",
+    attachment: "蹇冭剰绉绘闅忚璁板綍.pdf"
+  }
+];
+
+// 妯℃嫙鍖婚櫌鏁版嵁
+const mockHospitalData = [
+  { id: 1, hospitalNo: "H1001", hospitalName: "鍖椾含鍗忓拰鍖婚櫌", type: "4" },
+  { id: 2, hospitalNo: "H1002", hospitalName: "涓婃捣鐟為噾鍖婚櫌", type: "4" },
+  { id: 3, hospitalNo: "H1003", hospitalName: "骞垮窞涓北鍖婚櫌", type: "4" }
+];
+
+// 妯℃嫙璐熻矗浜烘暟鎹�
+const mockLeaderData = [
+  { reportNo: "L001", reportName: "寮犱富浠�" },
+  { reportNo: "L002", reportName: "鐜嬩富浠�" },
+  { reportNo: "L003", reportName: "鏉庝富浠�" }
+];
+
+// 妯℃嫙鍗忚皟鍛樻暟鎹�
+const mockCoordinatorData = [
+  { reportNo: "C001", reportName: "寮犲崗璋冨憳" },
+  { reportNo: "C002", reportName: "鏉庡崗璋冨憳" },
+  { reportNo: "C003", reportName: "鐜嬪崗璋冨憳" },
+  { reportNo: "C004", reportName: "璧靛崗璋冨憳" }
+];
+
+// 妯℃嫙API鍝嶅簲寤惰繜
+const delay = (ms = 500) => new Promise(resolve => setTimeout(resolve, ms));
+
+// 鏌ヨ鍣ㄥ畼鍒╃敤鍒楄〃
+export const listOrganUtilization = async (queryParams = {}) => {
+  await delay();
+
+  const {
+    pageNum = 1,
+    pageSize = 10,
+    hospitalNo,
+    donorName,
+    utilizationStatus
+  } = queryParams;
+
+  // 杩囨护鏁版嵁
+  let filteredData = mockOrganUtilizationData.filter(item => {
+    let match = true;
+
+    if (hospitalNo && !item.hospitalNo.includes(hospitalNo)) {
+      match = false;
+    }
+
+    if (donorName && !item.donorName.includes(donorName)) {
+      match = false;
+    }
+
+    if (utilizationStatus && item.utilizationStatus !== utilizationStatus) {
+      match = false;
+    }
+
+    return match;
+  });
+
+  // 鍒嗛〉
+  const startIndex = (pageNum - 1) * pageSize;
+  const endIndex = startIndex + parseInt(pageSize);
+  const paginatedData = filteredData.slice(startIndex, endIndex);
+
+  return {
+    code: 200,
+    message: "success",
+    data: {
+      rows: paginatedData,
+      total: filteredData.length,
+      pageNum: parseInt(pageNum),
+      pageSize: parseInt(pageSize)
+    }
+  };
+};
+
+// 鑾峰彇鍣ㄥ畼鍒╃敤璇︾粏淇℃伅
+export const getOrganUtilizationDetail = async (id) => {
+  await delay();
+
+  const detail = mockOrganUtilizationData.find(item => item.id == id);
+
+  if (detail) {
+    // 鑾峰彇鍒╃敤璁板綍
+    const utilizationRecords = mockUtilizationRecordData.filter(item => item.utilizationId == id);
+    // 鑾峰彇闅忚璁板綍
+    const followupRecords = mockFollowupRecordData.filter(item => item.utilizationId == id);
+
+    return {
+      code: 200,
+      message: "success",
+      data: {
+        ...detail,
+        utilizationRecords,
+        followupRecords
+      }
+    };
+  } else {
+    return {
+      code: 404,
+      message: "鍣ㄥ畼鍒╃敤璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鏂板鍣ㄥ畼鍒╃敤
+export const addOrganUtilization = async (data) => {
+  await delay();
+
+  const newId = Math.max(...mockOrganUtilizationData.map(item => item.id), 0) + 1;
+  const hospitalNo = `D${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(newId).padStart(3, '0')}`;
+  const caseNo = `C${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(newId).padStart(3, '0')}`;
+
+  const newRecord = {
+    ...data,
+    id: newId,
+    hospitalNo,
+    caseNo,
+    registrationTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+    createTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+  };
+
+  mockOrganUtilizationData.unshift(newRecord);
+
+  return {
+    code: 200,
+    message: "鏂板鎴愬姛",
+    data: newRecord
+  };
+};
+
+// 淇敼鍣ㄥ畼鍒╃敤
+export const updateOrganUtilization = async (data) => {
+  await delay();
+
+  const index = mockOrganUtilizationData.findIndex(item => item.id == data.id);
+
+  if (index !== -1) {
+    mockOrganUtilizationData[index] = {
+      ...mockOrganUtilizationData[index],
+      ...data,
+      updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+    };
+
+    return {
+      code: 200,
+      message: "淇敼鎴愬姛",
+      data: mockOrganUtilizationData[index]
+    };
+  } else {
+    return {
+      code: 404,
+      message: "鍣ㄥ畼鍒╃敤璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鍒犻櫎鍣ㄥ畼鍒╃敤
+export const delOrganUtilization = async (ids) => {
+  await delay();
+
+  const idArray = Array.isArray(ids) ? ids : [ids];
+
+  idArray.forEach(id => {
+    const index = mockOrganUtilizationData.findIndex(item => item.id == id);
+    if (index !== -1) {
+      mockOrganUtilizationData.splice(index, 1);
+    }
+  });
+
+  return {
+    code: 200,
+    message: "鍒犻櫎鎴愬姛"
+  };
+};
+
+// 淇濆瓨鍣ㄥ畼鍒╃敤璁板綍
+export const saveUtilizationRecords = async (utilizationId, records) => {
+  await delay();
+
+  // 鍒犻櫎璇ュ埄鐢↖D鐨勬墍鏈夎褰�
+  const existingIndexes = [];
+  mockUtilizationRecordData.forEach((item, index) => {
+    if (item.utilizationId == utilizationId) {
+      existingIndexes.push(index);
+    }
+  });
+
+  // 浠庡悗寰�鍓嶅垹闄ら伩鍏嶇储寮曢棶棰�
+  existingIndexes.reverse().forEach(index => {
+    mockUtilizationRecordData.splice(index, 1);
+  });
+
+  // 娣诲姞鏂拌褰�
+  records.forEach(record => {
+    const newId = Math.max(...mockUtilizationRecordData.map(item => item.id), 0) + 1;
+    mockUtilizationRecordData.push({
+      ...record,
+      id: newId,
+      utilizationId: utilizationId
+    });
+  });
+
+  return {
+    code: 200,
+    message: "淇濆瓨鎴愬姛",
+    data: records
+  };
+};
+
+// 淇濆瓨闅忚璁板綍
+export const saveFollowupRecord = async (record) => {
+  await delay();
+
+  const newId = Math.max(...mockFollowupRecordData.map(item => item.id), 0) + 1;
+  const newRecord = {
+    ...record,
+    id: newId
+  };
+
+  mockFollowupRecordData.push(newRecord);
+
+  return {
+    code: 200,
+    message: "闅忚璁板綍淇濆瓨鎴愬姛",
+    data: newRecord
+  };
+};
+
+// 鑾峰彇鍖婚櫌鍒楄〃
+export const getHospitalList = async () => {
+  await delay();
+
+  return {
+    code: 200,
+    message: "success",
+    data: mockHospitalData
+  };
+};
+
+// 鑾峰彇璐熻矗浜哄垪琛�
+export const getLeaderList = async () => {
+  await delay();
+
+  return {
+    code: 200,
+    message: "success",
+    data: mockLeaderData
+  };
+};
+
+// 鑾峰彇鍗忚皟鍛樺垪琛�
+export const getCoordinatorList = async () => {
+  await delay();
+
+  return {
+    code: 200,
+    message: "success",
+    data: mockCoordinatorData
+  };
+};
+
+export default {
+  listOrganUtilization,
+  getOrganUtilizationDetail,
+  addOrganUtilization,
+  updateOrganUtilization,
+  delOrganUtilization,
+  saveUtilizationRecords,
+  saveFollowupRecord,
+  getHospitalList,
+  getLeaderList,
+  getCoordinatorList
+};
diff --git a/src/views/business/affirm/mockConfirmationApi.js b/src/views/business/affirm/mockConfirmationApi.js
index d0d7626..e2057f1 100644
--- a/src/views/business/affirm/mockConfirmationApi.js
+++ b/src/views/business/affirm/mockConfirmationApi.js
@@ -116,7 +116,18 @@
     }, 300);
   });
 }
-
+// 鏇存柊鎹愮尞纭淇℃伅
+export function updateDeathJudgment(data) {
+  return new Promise((resolve) => {
+    setTimeout(() => {
+      const index = confirmationData.rows.findIndex(item => item.id === data.id);
+      if (index !== -1) {
+        confirmationData.rows[index] = { ...confirmationData.rows[index], ...data };
+      }
+      resolve({ code: 200, message: '鏇存柊鎴愬姛' });
+    }, 300);
+  });
+}
 // 鍒犻櫎鎹愮尞纭
 export function delConfirmation(ids) {
   return new Promise((resolve) => {
diff --git a/src/views/business/allocation/allocationInfo.vue b/src/views/business/allocation/allocationInfo.vue
new file mode 100644
index 0000000..fcda788
--- /dev/null
+++ b/src/views/business/allocation/allocationInfo.vue
@@ -0,0 +1,1014 @@
+<template>
+  <div class="organ-allocation-detail">
+    <!-- 鍩烘湰淇℃伅閮ㄥ垎 -->
+    <el-card class="detail-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鍣ㄥ畼鍒嗛厤鍩烘湰淇℃伅</span>
+        <div style="float: right;">
+          <el-button type="primary" @click="handleSave" :loading="saveLoading">
+            淇濆瓨
+          </el-button>
+          <el-button
+            type="success"
+            @click="handleAllocate"
+            :disabled="form.allocationStatus === 'allocated'"
+          >
+            纭鍒嗛厤
+          </el-button>
+        </div>
+      </div>
+
+      <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+              <el-input v-model="form.hospitalNo" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="妗堜緥缂栧彿" prop="caseNo">
+              <el-input v-model="form.caseNo" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+              <el-input v-model="form.donorName" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="鎬у埆" prop="gender">
+              <el-select v-model="form.gender" style="width: 100%">
+                <el-option label="鐢�" value="0" />
+                <el-option label="濂�" value="1" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <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="birthDate">
+              <el-date-picker
+                v-model="form.birthDate"
+                type="date"
+                value-format="yyyy-MM-dd"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐤剧梾璇婃柇" prop="diagnosis">
+              <el-input
+                type="textarea"
+                :rows="2"
+                v-model="form.diagnosis"
+                placeholder="璇疯緭鍏ョ柧鐥呰瘖鏂俊鎭�"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍒嗛厤鏃堕棿" prop="allocationTime">
+              <el-date-picker
+                v-model="form.allocationTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+                :disabled="form.allocationStatus !== 'allocated'"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐧昏浜�" prop="registrant">
+              <el-input v-model="form.registrant" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐧昏鏃堕棿" prop="registrationTime">
+              <el-date-picker
+                v-model="form.registrationTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                style="width: 100%"
+                readonly
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-card>
+
+    <!-- 鍣ㄥ畼鍒嗛厤璁板綍閮ㄥ垎 -->
+    <el-card class="allocation-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鍣ㄥ畼鍒嗛厤璁板綍</span>
+        <div style="float: right;">
+          <el-tag
+            :type="
+              form.allocationStatus === 'allocated' ? 'success' : 'warning'
+            "
+          >
+            {{ form.allocationStatus === "allocated" ? "宸插垎閰�" : "寰呭垎閰�" }}
+          </el-tag>
+        </div>
+      </div>
+
+      <el-form
+        ref="allocationForm"
+        :rules="allocationRules"
+        :model="allocationData"
+        label-position="right"
+      >
+        <el-row>
+          <el-col>
+            <el-form-item label-width="100px" label="鍒嗛厤鍣ㄥ畼">
+              <el-checkbox-group
+                v-model="selectedOrgans"
+                @change="handleOrganSelectionChange"
+              >
+                <el-checkbox
+                  v-for="organ in organDict"
+                  :key="organ.value"
+                  :label="organ.value"
+                  :disabled="form.allocationStatus === 'allocated'"
+                >
+                  {{ organ.label }}
+                </el-checkbox>
+              </el-checkbox-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col>
+            <el-form-item>
+              <el-table
+                :data="allocationData.records"
+                v-loading="loading"
+                border
+                style="width: 100%"
+                :row-class-name="getOrganRowClassName"
+              >
+                <el-table-column
+                  label="鍣ㄥ畼鍚嶇О"
+                  align="center"
+                  width="120"
+                  prop="organName"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.organName"
+                      placeholder="鍣ㄥ畼鍚嶇О"
+                      :disabled="true"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鍒嗛厤绯荤粺缂栧彿"
+                  align="center"
+                  width="150"
+                  prop="systemNo"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.systemNo"
+                      placeholder="鍒嗛厤绯荤粺缂栧彿"
+                      :disabled="form.allocationStatus === 'allocated'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鍒嗛厤鎺ユ敹鏃堕棿"
+                  align="center"
+                  width="180"
+                  prop="applicantTime"
+                >
+                  <template slot-scope="scope">
+                    <el-date-picker
+                      clearable
+                      size="small"
+                      style="width: 100%"
+                      v-model="scope.row.applicantTime"
+                      type="datetime"
+                      value-format="yyyy-MM-dd HH:mm:ss"
+                      placeholder="閫夋嫨鍒嗛厤鎺ユ敹鏃堕棿"
+                      :disabled="form.allocationStatus === 'allocated'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鍙椾綋濮撴皬"
+                  align="center"
+                  width="120"
+                  prop="recipientName"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      v-model="scope.row.recipientName"
+                      placeholder="鍙椾綋濮撴皬"
+                      :disabled="form.allocationStatus === 'allocated'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="绉绘鍖婚櫌"
+                  align="center"
+                  width="200"
+                  prop="transplantHospitalNo"
+                >
+                  <template slot-scope="scope">
+                    <el-select
+                      v-model="scope.row.transplantHospitalNo"
+                      placeholder="璇烽�夋嫨绉绘鍖婚櫌"
+                      style="width: 100%"
+                      :disabled="form.allocationStatus === 'allocated'"
+                      @change="handleHospitalChange(scope.row, $event)"
+                    >
+                      <el-option
+                        v-for="hospital in hospitalList"
+                        :key="hospital.hospitalNo"
+                        :label="hospital.hospitalName"
+                        :value="hospital.hospitalNo"
+                      />
+                    </el-select>
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="璇存槑"
+                  align="center"
+                  prop="reallocationReason"
+                  min-width="200"
+                >
+                  <template slot-scope="scope">
+                    <el-input
+                      type="textarea"
+                      clearable
+                      v-model="scope.row.reallocationReason"
+                      placeholder="璇疯緭鍏ヨ鏄�"
+                      :disabled="form.allocationStatus === 'allocated'"
+                    />
+                  </template>
+                </el-table-column>
+
+                <el-table-column
+                  label="鎿嶄綔"
+                  align="center"
+                  width="120"
+                  class-name="small-padding fixed-width"
+                  v-if="form.allocationStatus !== 'allocated'"
+                >
+                  <template slot-scope="scope">
+                    <el-button
+                      size="mini"
+                      type="text"
+                      icon="el-icon-copy-document"
+                      @click="handleRedistribution(scope.row)"
+                      :disabled="!scope.row.systemNo"
+                    >
+                      閲嶅垎閰�
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <!-- 鍒嗛厤缁熻淇℃伅 -->
+        <div class="allocation-stats" v-if="allocationData.records.length > 0">
+          <el-row :gutter="20">
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">宸插垎閰嶅櫒瀹�:</span>
+                <span class="stat-value"
+                  >{{ allocationData.records.length }} 涓�</span
+                >
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">寰呭畬鍠勪俊鎭�:</span>
+                <span class="stat-value">{{ incompleteRecords }} 涓�</span>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">娑夊強鍖婚櫌:</span>
+                <span class="stat-value">{{ uniqueHospitals }} 瀹�</span>
+              </div>
+            </el-col>
+            <el-col :span="6">
+              <div class="stat-item">
+                <span class="stat-label">鍒嗛厤鐘舵��:</span>
+                <span class="stat-value">
+                  <el-tag
+                    :type="
+                      form.allocationStatus === 'allocated'
+                        ? 'success'
+                        : 'warning'
+                    "
+                  >
+                    {{
+                      form.allocationStatus === "allocated"
+                        ? "宸插畬鎴�"
+                        : "杩涜涓�"
+                    }}
+                  </el-tag>
+                </span>
+              </div>
+            </el-col>
+          </el-row>
+        </div>
+
+        <div v-else class="empty-allocation">
+          <el-empty description="鏆傛棤鍒嗛厤璁板綍" :image-size="80">
+            <span>璇峰厛閫夋嫨瑕佸垎閰嶇殑鍣ㄥ畼</span>
+          </el-empty>
+        </div>
+      </el-form>
+
+      <div class="dialog-footer" v-if="form.allocationStatus !== 'allocated'">
+        <el-button
+          type="primary"
+          @click="handleSaveAllocation"
+          :loading="saveLoading"
+          :disabled="allocationData.records.length === 0"
+        >
+          淇濆瓨鍒嗛厤璁板綍
+        </el-button>
+        <el-button
+          type="success"
+          @click="handleConfirmAllocation"
+          :loading="confirmLoading"
+          :disabled="incompleteRecords > 0"
+        >
+          纭瀹屾垚鍒嗛厤
+        </el-button>
+      </div>
+    </el-card>
+
+    <!-- 闄勪欢绠$悊閮ㄥ垎 -->
+    <el-card class="attachment-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鐩稿叧闄勪欢</span>
+        <upload-attachment
+          :file-list="attachments"
+          @change="handleAttachmentChange"
+          :limit="10"
+          :accept="'.pdf,.jpg,.jpeg,.png,.doc,.docx'"
+        />
+      </div>
+
+      <div class="attachment-list">
+        <el-table :data="attachments" style="width: 100%">
+          <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
+            <template slot-scope="scope">
+              <div class="file-info">
+                <i
+                  :class="getFileIcon(scope.row.fileName)"
+                  style="margin-right: 8px; color: #409EFF;"
+                ></i>
+                <span>{{ scope.row.fileName }}</span>
+              </div>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="鏂囦欢绫诲瀷" width="100" 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="100" align="center">
+            <template slot-scope="scope">
+              <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="涓婁紶鏃堕棿" width="160" align="center">
+            <template slot-scope="scope">
+              <span>{{ parseTime(scope.row.uploadTime) }}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="鎿嶄綔" width="150" align="center">
+            <template slot-scope="scope">
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-view"
+                @click="handlePreviewAttachment(scope.row)"
+                >棰勮</el-button
+              >
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-download"
+                @click="handleDownloadAttachment(scope.row)"
+                >涓嬭浇</el-button
+              >
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-delete"
+                style="color: #F56C6C;"
+                @click="handleRemoveAttachment(scope.row)"
+                >鍒犻櫎</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-card>
+    <!-- 闄勪欢棰勮瀵硅瘽妗� -->
+    <attachment-preview
+      :visible="attachmentPreviewVisible"
+      :file-list="currentAttachmentList"
+      :title="attachmentPreviewTitle"
+      @close="attachmentPreviewVisible = false"
+    />
+    <!-- 閲嶅垎閰嶅璇濇 -->
+    <el-dialog
+      title="鍣ㄥ畼閲嶅垎閰�"
+      :visible.sync="redistributionDialogVisible"
+      width="500px"
+    >
+      <el-form :model="redistributionForm" label-width="100px">
+        <el-form-item label="鍘熷櫒瀹樹俊鎭�">
+          <el-input v-model="redistributionForm.organName" readonly />
+        </el-form-item>
+        <el-form-item label="閲嶅垎閰嶅師鍥�" prop="reason">
+          <el-input
+            type="textarea"
+            :rows="4"
+            v-model="redistributionForm.reason"
+            placeholder="璇疯緭鍏ラ噸鍒嗛厤鍘熷洜"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="redistributionDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleRedistributionConfirm"
+          >纭閲嶅垎閰�</el-button
+        >
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getOrganAllocationDetail,
+  updateOrganAllocation,
+  saveAllocationRecords,
+  getHospitalList,
+  getOrganDict
+} from "./organAllocation";
+import UploadAttachment from "@/components/UploadAttachment";
+import AttachmentPreview from "@/components/AttachmentPreview";
+export default {
+  name: "OrganAllocationDetail",
+  components: {
+    UploadAttachment,
+    AttachmentPreview,
+  },
+  data() {
+    return {
+      // 琛ㄥ崟鏁版嵁
+      form: {
+        id: undefined,
+        hospitalNo: "",
+        caseNo: "",
+        donorName: "",
+        gender: "",
+        age: "",
+        birthDate: "",
+        diagnosis: "",
+        allocationStatus: "pending",
+        allocationTime: "",
+        registrant: "",
+        registrationTime: ""
+      },
+      // 琛ㄥ崟楠岃瘉瑙勫垯
+      rules: {
+        donorName: [
+          { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+        ],
+        diagnosis: [
+          { required: true, message: "鐤剧梾璇婃柇涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+      },
+      // 鍒嗛厤璁板綍楠岃瘉瑙勫垯
+      allocationRules: {},
+      // 淇濆瓨鍔犺浇鐘舵��
+      saveLoading: false,
+      confirmLoading: false,
+      // 鍔犺浇鐘舵��
+      loading: false,
+      // 閫変腑鐨勫櫒瀹�
+      selectedOrgans: [],
+      // 鍣ㄥ畼瀛楀吀
+      organDict: [],
+      // 鍖婚櫌鍒楄〃
+      hospitalList: [],
+      // 鍒嗛厤璁板綍鏁版嵁
+      allocationData: {
+        records: []
+      },
+      // 闄勪欢鏁版嵁
+      attachments: [],
+      // 閲嶅垎閰嶅璇濇
+      redistributionDialogVisible: false,
+      redistributionForm: {
+        organName: "",
+        reason: ""
+      },
+      currentRedistributeRecord: null
+    };
+  },
+  computed: {
+    // 褰撳墠鐢ㄦ埛淇℃伅
+    currentUser() {
+      return JSON.parse(sessionStorage.getItem("user") || "{}");
+    },
+    // 涓嶅畬鏁寸殑璁板綍鏁伴噺
+    incompleteRecords() {
+      return this.allocationData.records.filter(
+        record =>
+          !record.systemNo ||
+          !record.applicantTime ||
+          !record.recipientName ||
+          !record.transplantHospitalNo
+      ).length;
+    },
+    // 鍞竴鍖婚櫌鏁伴噺
+    uniqueHospitals() {
+      const hospitals = this.allocationData.records
+        .map(record => record.transplantHospitalNo)
+        .filter(Boolean);
+      return new Set(hospitals).size;
+    }
+  },
+  created() {
+    const id = this.$route.query.id;
+    if (id) {
+      this.getDetail(id);
+    } else {
+      this.generateCaseNo();
+      this.form.registrant = this.currentUser.username || "褰撳墠鐢ㄦ埛";
+      this.form.registrationTime = new Date()
+        .toISOString()
+        .replace("T", " ")
+        .substring(0, 19);
+    }
+    this.getOrganDictionary();
+    this.getHospitalData();
+  },
+  methods: {
+    // 鐢熸垚妗堜緥缂栧彿
+    generateCaseNo() {
+      const timestamp = Date.now().toString();
+      this.form.hospitalNo = "D" + timestamp.slice(-6);
+      this.form.caseNo = "C" + timestamp.slice(-6);
+    },
+    // 鑾峰彇璇︽儏
+    getDetail(id) {
+      this.loading = true;
+      getOrganAllocationDetail(id)
+        .then(response => {
+          if (response.code === 200) {
+            this.form = response.data;
+            if (response.data.allocationRecords) {
+              this.allocationData.records = response.data.allocationRecords;
+              this.selectedOrgans = response.data.allocationRecords.map(
+                item => item.organNo
+              );
+            }
+          }
+          this.loading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇鍣ㄥ畼鍒嗛厤璇︽儏澶辫触:", error);
+          this.loading = false;
+          this.$message.error("鑾峰彇璇︽儏澶辫触");
+        });
+    },
+    // 鑾峰彇鍣ㄥ畼瀛楀吀
+    getOrganDictionary() {
+      getOrganDict().then(response => {
+        if (response.code === 200) {
+          this.organDict = response.data;
+        }
+      });
+    },
+    // 鑾峰彇鍖婚櫌鏁版嵁
+    getHospitalData() {
+      getHospitalList().then(response => {
+        if (response.code === 200) {
+          this.hospitalList = response.data;
+        }
+      });
+    },
+      handleAttachmentChange(fileList) {
+console.log(fileList,'娴嬭瘯');
+
+    },
+    // 鍣ㄥ畼閫夋嫨鐘舵�佸彉鍖�
+    handleOrganSelectionChange(selectedValues) {
+      const currentOrganNos = this.allocationData.records.map(
+        item => item.organNo
+      );
+
+      // 鏂板閫夋嫨鐨勫櫒瀹�
+      selectedValues.forEach(organValue => {
+        if (!currentOrganNos.includes(organValue)) {
+          const organInfo = this.organDict.find(
+            item => item.value === organValue
+          );
+          if (organInfo) {
+            this.allocationData.records.push({
+              organName: organInfo.label,
+              organNo: organValue,
+              id: null,
+              allocationId: this.form.id,
+              systemNo: "",
+              applicantTime: "",
+              recipientName: "",
+              transplantHospitalNo: "",
+              transplantHospitalName: "",
+              reallocationReason: "",
+              organState: 1
+            });
+          }
+        }
+      });
+
+      // 绉婚櫎鍙栨秷閫夋嫨鐨勫櫒瀹�
+      this.allocationData.records = this.allocationData.records.filter(
+        record => {
+          if (selectedValues.includes(record.organNo)) {
+            return true;
+          } else {
+            if (record.id) {
+              this.$confirm(
+                "鍒犻櫎鍣ㄥ畼鍒嗛厤鏁版嵁鍚庡皢鏃犳硶鎭㈠锛屾偍纭鍒犻櫎璇ユ潯璁板綍鍚楋紵",
+                "鎻愮ず",
+                {
+                  confirmButtonText: "纭畾",
+                  cancelButtonText: "鍙栨秷",
+                  type: "warning"
+                }
+              )
+                .then(() => {
+                  // 瀹為檯椤圭洰涓繖閲屽簲璇ヨ皟鐢ㄥ垹闄PI
+                  this.allocationData.records = this.allocationData.records.filter(
+                    r => r.organNo !== record.organNo
+                  );
+                  this.$message.success("鍒犻櫎鎴愬姛");
+                })
+                .catch(() => {
+                  this.selectedOrgans.push(record.organNo);
+                });
+              return true; // 绛夊緟鐢ㄦ埛纭
+            } else {
+              return false; // 鐩存帴鍒犻櫎鏂拌褰�
+            }
+          }
+        }
+      );
+    },
+    // 鍖婚櫌閫夋嫨鍙樺寲
+    handleHospitalChange(row, hospitalNo) {
+      const hospital = this.hospitalList.find(
+        item => item.hospitalNo === hospitalNo
+      );
+      if (hospital) {
+        row.transplantHospitalName = hospital.hospitalName;
+      }
+    },
+    // 閲嶅垎閰嶆搷浣�
+    handleRedistribution(row) {
+      this.currentRedistributeRecord = row;
+      this.redistributionForm.organName = row.organName;
+      this.redistributionForm.reason = row.reallocationReason || "";
+      this.redistributionDialogVisible = true;
+    },
+    // 纭閲嶅垎閰�
+    handleRedistributionConfirm() {
+      if (!this.redistributionForm.reason) {
+        this.$message.warning("璇疯緭鍏ラ噸鍒嗛厤鍘熷洜");
+        return;
+      }
+
+      if (this.currentRedistributeRecord) {
+        this.currentRedistributeRecord.reallocationReason = this.redistributionForm.reason;
+        this.$message.success("閲嶅垎閰嶅師鍥犲凡鏇存柊");
+        this.redistributionDialogVisible = false;
+      }
+    },
+    // 鍣ㄥ畼琛屾牱寮�
+    getOrganRowClassName({ row }) {
+      if (
+        !row.systemNo ||
+        !row.applicantTime ||
+        !row.recipientName ||
+        !row.transplantHospitalNo
+      ) {
+        return "warning-row";
+      }
+      return "";
+    },
+    // 淇濆瓨鍩烘湰淇℃伅
+    handleSave() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.saveLoading = true;
+          const apiMethod = this.form.id
+            ? updateOrganAllocation
+            : addOrganAllocation;
+
+          apiMethod(this.form)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("淇濆瓨鎴愬姛");
+                if (!this.form.id) {
+                  this.form.id = response.data.id;
+                  this.$router.replace({
+                    query: { ...this.$route.query, id: this.form.id }
+                  });
+                }
+              }
+            })
+            .catch(error => {
+              console.error("淇濆瓨澶辫触:", error);
+              this.$message.error("淇濆瓨澶辫触");
+            })
+            .finally(() => {
+              this.saveLoading = false;
+            });
+        }
+      });
+    },
+    // 淇濆瓨鍒嗛厤璁板綍
+    handleSaveAllocation() {
+      if (!this.form.id) {
+        this.$message.warning("璇峰厛淇濆瓨鍩烘湰淇℃伅");
+        return;
+      }
+
+      this.saveLoading = true;
+      saveAllocationRecords(this.form.id, this.allocationData.records)
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍒嗛厤璁板綍淇濆瓨鎴愬姛");
+          }
+        })
+        .catch(error => {
+          console.error("淇濆瓨鍒嗛厤璁板綍澶辫触:", error);
+          this.$message.error("淇濆瓨鍒嗛厤璁板綍澶辫触");
+        })
+        .finally(() => {
+          this.saveLoading = false;
+        });
+    },
+    // 纭瀹屾垚鍒嗛厤
+    handleConfirmAllocation() {
+      if (this.incompleteRecords > 0) {
+        this.$message.warning("璇峰厛瀹屽杽鎵�鏈夊垎閰嶈褰曠殑淇℃伅");
+        return;
+      }
+
+      this.$confirm("纭瀹屾垚鍣ㄥ畼鍒嗛厤鍚楋紵瀹屾垚鍚庡皢鏃犳硶淇敼鍒嗛厤淇℃伅銆�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.confirmLoading = true;
+          this.form.allocationStatus = "allocated";
+          this.form.allocationTime = new Date()
+            .toISOString()
+            .replace("T", " ")
+            .substring(0, 19);
+
+          updateOrganAllocation(this.form)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("鍣ㄥ畼鍒嗛厤宸插畬鎴�");
+              }
+            })
+            .catch(error => {
+              console.error("纭鍒嗛厤澶辫触:", error);
+              this.$message.error("纭鍒嗛厤澶辫触");
+            })
+            .finally(() => {
+              this.confirmLoading = false;
+            });
+        })
+        .catch(() => {});
+    },
+    // 涓婁紶闄勪欢
+    handleUploadAttachment() {
+      // 闄勪欢涓婁紶閫昏緫
+      this.$message.info("闄勪欢涓婁紶鍔熻兘");
+    },
+    // 棰勮闄勪欢
+    handlePreviewAttachment(attachment) {
+      // 闄勪欢棰勮閫昏緫
+      this.$message.info("闄勪欢棰勮鍔熻兘");
+    },
+    // 涓嬭浇闄勪欢
+    handleDownloadAttachment(attachment) {
+      // 闄勪欢涓嬭浇閫昏緫
+      this.$message.info("闄勪欢涓嬭浇鍔熻兘");
+    },
+    // 鍒犻櫎闄勪欢
+    handleRemoveAttachment(attachment) {
+      this.$confirm("纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+        })
+        .catch(() => {});
+    },
+    // 鑾峰彇鏂囦欢鍥炬爣
+    getFileIcon(fileName) {
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const iconMap = {
+        pdf: "el-icon-document",
+        doc: "el-icon-document",
+        docx: "el-icon-document",
+        xls: "el-icon-document",
+        xlsx: "el-icon-document",
+        jpg: "el-icon-picture",
+        jpeg: "el-icon-picture",
+        png: "el-icon-picture"
+      };
+      return iconMap[ext] || "el-icon-document";
+    },
+    // 鑾峰彇鏂囦欢绫诲瀷
+    getFileType(fileName) {
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const typeMap = {
+        pdf: "PDF",
+        doc: "DOC",
+        docx: "DOCX",
+        xls: "XLS",
+        xlsx: "XLSX",
+        jpg: "JPG",
+        jpeg: "JPEG",
+        png: "PNG"
+      };
+      return typeMap[ext] || ext.toUpperCase();
+    },
+    // 鏂囦欢澶у皬鏍煎紡鍖�
+    formatFileSize(size) {
+      if (size === 0) 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];
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time) {
+      if (!time) return "";
+      const date = new Date(time);
+      return `${date.getFullYear()}-${(date.getMonth() + 1)
+        .toString()
+        .padStart(2, "0")}-${date
+        .getDate()
+        .toString()
+        .padStart(2, "0")} ${date
+        .getHours()
+        .toString()
+        .padStart(2, "0")}:${date
+        .getMinutes()
+        .toString()
+        .padStart(2, "0")}`;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.organ-allocation-detail {
+  padding: 20px;
+  background-color: #f5f7fa;
+}
+
+.detail-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.allocation-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.attachment-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.detail-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+}
+
+/* 缁熻淇℃伅鏍峰紡 */
+.allocation-stats {
+  margin-top: 20px;
+  padding: 15px;
+  background: linear-gradient(135deg, #9eb7e5 0%, #53519c 100%);
+  border-radius: 8px;
+  color: white;
+  font-size: 18px;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 10px;
+}
+
+.stat-label {
+  /* font-size: 12px; */
+  opacity: 0.9;
+
+  /* color: #606266; */
+  margin-bottom: 5px;
+}
+
+.stat-value {
+  font-size: 20px;
+  font-weight: bold;
+  /* color: #303133; */
+}
+
+/* 绌虹姸鎬佹牱寮� */
+.empty-allocation {
+  text-align: center;
+  padding: 40px 0;
+  color: #909399;
+}
+
+/* 瀵硅瘽妗嗗簳閮ㄦ寜閽� */
+.dialog-footer {
+  margin-top: 20px;
+  text-align: center;
+  padding-top: 20px;
+  border-top: 1px solid #e4e7ed;
+}
+
+/* 琛ㄦ牸琛屾牱寮� */
+:deep(.warning-row) {
+  background-color: #fff7e6;
+}
+
+:deep(.warning-row:hover) {
+  background-color: #ffecc2;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+  .organ-allocation-detail {
+    padding: 10px;
+  }
+
+  .allocation-stats .el-col {
+    margin-bottom: 10px;
+  }
+}
+</style>
diff --git a/src/views/business/allocation/index.vue b/src/views/business/allocation/index.vue
new file mode 100644
index 0000000..72a80e7
--- /dev/null
+++ b/src/views/business/allocation/index.vue
@@ -0,0 +1,372 @@
+<template>
+  <div class="organ-allocation-list">
+    <!-- 鏌ヨ鏉′欢 -->
+    <el-card class="search-card">
+      <el-form
+        :model="queryParams"
+        ref="queryForm"
+        :inline="true"
+        label-width="100px"
+      >
+        <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+          <el-input
+            v-model="queryParams.hospitalNo"
+            placeholder="璇疯緭鍏ヤ綇闄㈠彿"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+          <el-input
+            v-model="queryParams.donorName"
+            placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="鍒嗛厤鐘舵��" prop="allocationStatus">
+          <el-select
+            v-model="queryParams.allocationStatus"
+            placeholder="璇烽�夋嫨鍒嗛厤鐘舵��"
+            clearable
+            style="width: 200px"
+          >
+            <el-option label="宸插垎閰�" value="allocated" />
+            <el-option label="寰呭垎閰�" value="pending" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" @click="handleQuery"
+            >鎼滅储</el-button
+          >
+          <el-button icon="el-icon-refresh" @click="resetQuery">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 鎿嶄綔鎸夐挳 -->
+    <el-card class="tool-card">
+      <el-row :gutter="10">
+        <el-col :span="16">
+          <el-button type="primary" icon="el-icon-plus" @click="handleCreate"
+            >鏂板缓鍒嗛厤</el-button
+          >
+          <el-button
+            type="success"
+            icon="el-icon-edit"
+            :disabled="single"
+            @click="handleUpdate"
+            >淇敼</el-button
+          >
+          <el-button
+            type="danger"
+            icon="el-icon-delete"
+            :disabled="multiple"
+            @click="handleDelete"
+            >鍒犻櫎</el-button
+          >
+        </el-col>
+        <el-col :span="8" style="text-align: right">
+          <el-tooltip content="鍒锋柊" placement="top">
+            <el-button icon="el-icon-refresh" circle @click="getList" />
+          </el-tooltip>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <el-card>
+      <el-table
+        v-loading="loading"
+        :data="organAllocationList"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column
+          label="浣忛櫌鍙�"
+          align="center"
+          prop="hospitalNo"
+          width="120"
+        />
+        <el-table-column
+          label="鎹愮尞鑰呭鍚�"
+          align="center"
+          prop="donorName"
+          width="120"
+        />
+        <el-table-column label="鎬у埆" align="center" prop="gender" width="80">
+          <template slot-scope="scope">
+            <dict-tag
+              :options="dict.type.sys_user_sex"
+              :value="parseInt(scope.row.gender)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="骞撮緞" align="center" prop="age" width="80" />
+        <el-table-column
+          label="鐤剧梾璇婃柇"
+          align="center"
+          prop="diagnosis"
+          min-width="180"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="鍒嗛厤鐘舵��"
+          align="center"
+          prop="allocationStatus"
+          width="100"
+        >
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.allocationStatus === 'allocated' ? 'success' : 'warning'">
+              {{ scope.row.allocationStatus === 'allocated' ? '宸插垎閰�' : '寰呭垎閰�' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鍒嗛厤鏃堕棿"
+          align="center"
+          prop="allocationTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.allocationTime
+                ? parseTime(scope.row.allocationTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鐧昏浜�"
+          align="center"
+          prop="registrant"
+          width="100"
+        />
+        <el-table-column
+          label="鐧昏鏃堕棿"
+          align="center"
+          prop="registrationTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.registrationTime
+                ? parseTime(scope.row.registrationTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鎿嶄綔"
+          align="center"
+          width="150"
+          class-name="small-padding fixed-width"
+        >
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleView(scope.row)"
+              >璇︽儏</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdate(scope.row)"
+              >淇敼</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-delete"
+              style="color: #F56C6C"
+              @click="handleDelete(scope.row)"
+              >鍒犻櫎</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 鍒嗛〉缁勪欢 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { listOrganAllocation, delOrganAllocation } from "./organAllocation";
+import Pagination from "@/components/Pagination";
+
+export default {
+  name: "OrganAllocationList",
+  components: { Pagination },
+  dicts: ["sys_user_sex"],
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 鍣ㄥ畼鍒嗛厤琛ㄦ牸鏁版嵁
+      organAllocationList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        hospitalNo: undefined,
+        donorName: undefined,
+        allocationStatus: undefined
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 鏌ヨ鍣ㄥ畼鍒嗛厤鍒楄〃
+    getList() {
+      this.loading = true;
+      listOrganAllocation(this.queryParams)
+        .then(response => {
+          if (response.code === 200) {
+            this.organAllocationList = response.data.rows;
+            this.total = response.data.total;
+          } else {
+            this.$message.error("鑾峰彇鏁版嵁澶辫触");
+          }
+          this.loading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇鍣ㄥ畼鍒嗛厤鍒楄〃澶辫触:", error);
+          this.loading = false;
+          this.$message.error("鑾峰彇鏁版嵁澶辫触");
+        });
+    },
+    // 鎼滅储鎸夐挳鎿嶄綔
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    // 閲嶇疆鎸夐挳鎿嶄綔
+    resetQuery() {
+      this.$refs.queryForm.resetFields();
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    // 鏌ョ湅璇︽儏
+    handleView(row) {
+      this.$router.push({
+        path: "/case/allocationInfo",
+        query: { id: row.id }
+      });
+    },
+    // 鏂板鎸夐挳鎿嶄綔
+    handleCreate() {
+      this.$router.push("/case/allocationInfo");
+    },
+    // 淇敼鎸夐挳鎿嶄綔
+    handleUpdate(row) {
+      const id = row.id || this.ids[0];
+      this.$router.push({
+        path: "/case/allocationInfo",
+        query: { id: id }
+      });
+    },
+    // 鍒犻櫎鎸夐挳鎿嶄綔
+    handleDelete(row) {
+      const ids = row.id ? [row.id] : this.ids;
+      this.$confirm("鏄惁纭鍒犻櫎閫変腑鐨勬暟鎹」锛�", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          return delOrganAllocation(ids);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍒犻櫎鎴愬姛");
+            this.getList();
+          }
+        })
+        .catch(() => {});
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time, pattern) {
+      if (!time) return "";
+      const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
+      let date;
+      if (typeof time === "object") {
+        date = time;
+      } else {
+        if (typeof time === "string" && /^[0-9]+$/.test(time)) {
+          time = parseInt(time);
+        }
+        if (typeof time === "number" && time.toString().length === 10) {
+          time = time * 1000;
+        }
+        date = new Date(time);
+      }
+      const formatObj = {
+        y: date.getFullYear(),
+        m: date.getMonth() + 1,
+        d: date.getDate(),
+        h: date.getHours(),
+        i: date.getMinutes(),
+        s: date.getSeconds(),
+        a: date.getDay()
+      };
+      const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+        let value = formatObj[key];
+        if (key === "a") {
+          return ["鏃�", "涓�", "浜�", "涓�", "鍥�", "浜�", "鍏�"][value];
+        }
+        if (result.length > 0 && value < 10) {
+          value = "0" + value;
+        }
+        return value || 0;
+      });
+      return time_str;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.organ-allocation-list {
+  padding: 20px;
+}
+
+.search-card {
+  margin-bottom: 20px;
+}
+
+.tool-card {
+  margin-bottom: 20px;
+}
+
+.fixed-width .el-button {
+  margin: 0 5px;
+}
+</style>
diff --git a/src/views/business/allocation/organAllocation.js b/src/views/business/allocation/organAllocation.js
new file mode 100644
index 0000000..dd879c1
--- /dev/null
+++ b/src/views/business/allocation/organAllocation.js
@@ -0,0 +1,329 @@
+// 妯℃嫙鍣ㄥ畼鍒嗛厤鏁版嵁
+const mockOrganAllocationData = [
+  {
+    id: 1,
+    hospitalNo: "D202312001",
+    caseNo: "C202312001",
+    donorName: "寮犱笁",
+    gender: "0",
+    age: 45,
+    birthDate: "1978-05-15",
+    diagnosis: "鑴戝浼�",
+    allocationStatus: "allocated",
+    allocationTime: "2023-12-01 16:30:00",
+    registrant: "鏉庡崗璋冨憳",
+    registrationTime: "2023-12-01 15:00:00",
+    createTime: "2023-12-01 10:00:00"
+  },
+  {
+    id: 2,
+    hospitalNo: "D202312002",
+    caseNo: "C202312002",
+    donorName: "鏉庡洓",
+    gender: "1",
+    age: 38,
+    birthDate: "1985-08-22",
+    diagnosis: "蹇冭剰楠ゅ仠",
+    allocationStatus: "allocated",
+    allocationTime: "2023-12-02 11:20:00",
+    registrant: "寮犲崗璋冨憳",
+    registrationTime: "2023-12-02 10:00:00",
+    createTime: "2023-12-02 08:30:00"
+  },
+  {
+    id: 3,
+    hospitalNo: "D202312003",
+    caseNo: "C202312003",
+    donorName: "鐜嬩簲",
+    gender: "0",
+    age: 52,
+    birthDate: "1971-03-10",
+    diagnosis: "鑴戞姝�",
+    allocationStatus: "pending",
+    allocationTime: "",
+    registrant: "璧靛崗璋冨憳",
+    registrationTime: "2023-12-03 17:20:00",
+    createTime: "2023-12-03 14:00:00"
+  }
+];
+
+// 妯℃嫙鍣ㄥ畼鍒嗛厤璁板綍鏁版嵁
+const mockAllocationRecordData = [
+  {
+    id: 1,
+    allocationId: 1,
+    organName: "鑲濊剰",
+    organNo: "L001",
+    caseNo: "C202312001",
+    systemNo: "AL202312001",
+    applicantTime: "2023-12-01 17:00:00",
+    recipientName: "鐜�",
+    transplantHospitalNo: "H1001",
+    transplantHospitalName: "鍖椾含鍗忓拰鍖婚櫌",
+    reallocationReason: "",
+    organState: 1
+  },
+  {
+    id: 2,
+    allocationId: 1,
+    organName: "鑲捐剰",
+    organNo: "K001",
+    caseNo: "C202312001",
+    systemNo: "AL202312002",
+    applicantTime: "2023-12-01 17:30:00",
+    recipientName: "鏉�",
+    transplantHospitalNo: "H1002",
+    transplantHospitalName: "涓婃捣鐟為噾鍖婚櫌",
+    reallocationReason: "",
+    organState: 1
+  },
+  {
+    id: 3,
+    allocationId: 1,
+    organName: "蹇冭剰",
+    organNo: "H001",
+    caseNo: "C202312001",
+    systemNo: "AL202312003",
+    applicantTime: "2023-12-01 18:00:00",
+    recipientName: "寮�",
+    transplantHospitalNo: "H1003",
+    transplantHospitalName: "骞垮窞涓北鍖婚櫌",
+    reallocationReason: "",
+    organState: 1
+  }
+];
+
+// 妯℃嫙鍖婚櫌鏁版嵁
+const mockHospitalData = [
+  { id: 1, hospitalNo: "H1001", hospitalName: "鍖椾含鍗忓拰鍖婚櫌", type: "4" },
+  { id: 2, hospitalNo: "H1002", hospitalName: "涓婃捣鐟為噾鍖婚櫌", type: "4" },
+  { id: 3, hospitalNo: "H1003", hospitalName: "骞垮窞涓北鍖婚櫌", type: "4" },
+  { id: 4, hospitalNo: "H1004", hospitalName: "姝︽眽鍚屾祹鍖婚櫌", type: "4" },
+  { id: 5, hospitalNo: "H1005", hospitalName: "鎴愰兘鍗庤タ鍖婚櫌", type: "4" }
+];
+
+// 妯℃嫙鍣ㄥ畼绫诲瀷瀛楀吀
+const mockOrganDict = [
+  { value: "L001", label: "鑲濊剰" },
+  { value: "K001", label: "鑲捐剰" },
+  { value: "H001", label: "蹇冭剰" },
+  { value: "L002", label: "鑲鸿剰" },
+  { value: "P001", label: "鑳拌吅" },
+  { value: "I001", label: "灏忚偁" },
+  { value: "C001", label: "瑙掕啘" }
+];
+
+// 妯℃嫙API鍝嶅簲寤惰繜
+const delay = (ms = 500) => new Promise(resolve => setTimeout(resolve, ms));
+
+// 鏌ヨ鍣ㄥ畼鍒嗛厤鍒楄〃
+export const listOrganAllocation = async (queryParams = {}) => {
+  await delay();
+
+  const {
+    pageNum = 1,
+    pageSize = 10,
+    hospitalNo,
+    donorName,
+    allocationStatus
+  } = queryParams;
+
+  // 杩囨护鏁版嵁
+  let filteredData = mockOrganAllocationData.filter(item => {
+    let match = true;
+
+    if (hospitalNo && !item.hospitalNo.includes(hospitalNo)) {
+      match = false;
+    }
+
+    if (donorName && !item.donorName.includes(donorName)) {
+      match = false;
+    }
+
+    if (allocationStatus && item.allocationStatus !== allocationStatus) {
+      match = false;
+    }
+
+    return match;
+  });
+
+  // 鍒嗛〉
+  const startIndex = (pageNum - 1) * pageSize;
+  const endIndex = startIndex + parseInt(pageSize);
+  const paginatedData = filteredData.slice(startIndex, endIndex);
+
+  return {
+    code: 200,
+    message: "success",
+    data: {
+      rows: paginatedData,
+      total: filteredData.length,
+      pageNum: parseInt(pageNum),
+      pageSize: parseInt(pageSize)
+    }
+  };
+};
+
+// 鑾峰彇鍣ㄥ畼鍒嗛厤璇︾粏淇℃伅
+export const getOrganAllocationDetail = async (id) => {
+  await delay();
+
+  const detail = mockOrganAllocationData.find(item => item.id == id);
+
+  if (detail) {
+    // 鑾峰彇鍒嗛厤璁板綍
+    const allocationRecords = mockAllocationRecordData.filter(item => item.allocationId == id);
+
+    return {
+      code: 200,
+      message: "success",
+      data: {
+        ...detail,
+        allocationRecords
+      }
+    };
+  } else {
+    return {
+      code: 404,
+      message: "鍣ㄥ畼鍒嗛厤璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鏂板鍣ㄥ畼鍒嗛厤
+export const addOrganAllocation = async (data) => {
+  await delay();
+
+  const newId = Math.max(...mockOrganAllocationData.map(item => item.id), 0) + 1;
+  const hospitalNo = `D${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(newId).padStart(3, '0')}`;
+  const caseNo = `C${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(newId).padStart(3, '0')}`;
+
+  const newRecord = {
+    ...data,
+    id: newId,
+    hospitalNo,
+    caseNo,
+    registrationTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+    createTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+  };
+
+  mockOrganAllocationData.unshift(newRecord);
+
+  return {
+    code: 200,
+    message: "鏂板鎴愬姛",
+    data: newRecord
+  };
+};
+
+// 淇敼鍣ㄥ畼鍒嗛厤
+export const updateOrganAllocation = async (data) => {
+  await delay();
+
+  const index = mockOrganAllocationData.findIndex(item => item.id == data.id);
+
+  if (index !== -1) {
+    mockOrganAllocationData[index] = {
+      ...mockOrganAllocationData[index],
+      ...data,
+      updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+    };
+
+    return {
+      code: 200,
+      message: "淇敼鎴愬姛",
+      data: mockOrganAllocationData[index]
+    };
+  } else {
+    return {
+      code: 404,
+      message: "鍣ㄥ畼鍒嗛厤璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鍒犻櫎鍣ㄥ畼鍒嗛厤
+export const delOrganAllocation = async (ids) => {
+  await delay();
+
+  const idArray = Array.isArray(ids) ? ids : [ids];
+
+  idArray.forEach(id => {
+    const index = mockOrganAllocationData.findIndex(item => item.id == id);
+    if (index !== -1) {
+      mockOrganAllocationData.splice(index, 1);
+    }
+  });
+
+  return {
+    code: 200,
+    message: "鍒犻櫎鎴愬姛"
+  };
+};
+
+// 淇濆瓨鍣ㄥ畼鍒嗛厤璁板綍
+export const saveAllocationRecords = async (allocationId, records) => {
+  await delay();
+
+  // 鍒犻櫎璇ュ垎閰岻D鐨勬墍鏈夎褰�
+  const existingIndexes = [];
+  mockAllocationRecordData.forEach((item, index) => {
+    if (item.allocationId == allocationId) {
+      existingIndexes.push(index);
+    }
+  });
+
+  // 浠庡悗寰�鍓嶅垹闄ら伩鍏嶇储寮曢棶棰�
+  existingIndexes.reverse().forEach(index => {
+    mockAllocationRecordData.splice(index, 1);
+  });
+
+  // 娣诲姞鏂拌褰�
+  records.forEach(record => {
+    const newId = Math.max(...mockAllocationRecordData.map(item => item.id), 0) + 1;
+    mockAllocationRecordData.push({
+      ...record,
+      id: newId,
+      allocationId: allocationId
+    });
+  });
+
+  return {
+    code: 200,
+    message: "淇濆瓨鎴愬姛",
+    data: records
+  };
+};
+
+// 鑾峰彇鍖婚櫌鍒楄〃
+export const getHospitalList = async () => {
+  await delay();
+
+  return {
+    code: 200,
+    message: "success",
+    data: mockHospitalData
+  };
+};
+
+// 鑾峰彇鍣ㄥ畼瀛楀吀
+export const getOrganDict = async () => {
+  await delay();
+
+  return {
+    code: 200,
+    message: "success",
+    data: mockOrganDict
+  };
+};
+
+export default {
+  listOrganAllocation,
+  getOrganAllocationDetail,
+  addOrganAllocation,
+  updateOrganAllocation,
+  delOrganAllocation,
+  saveAllocationRecords,
+  getHospitalList,
+  getOrganDict
+};
diff --git a/src/views/business/appear/caseDetail.vue b/src/views/business/appear/caseDetail.vue
index 05826f7..fb7c54c 100644
--- a/src/views/business/appear/caseDetail.vue
+++ b/src/views/business/appear/caseDetail.vue
@@ -3,40 +3,76 @@
     <el-tabs v-model="activeTab">
       <el-tab-pane label="鍩烘湰淇℃伅" name="basic">
         <el-descriptions :column="2" border>
-          <el-descriptions-item label="鎹愮尞缂栧彿">{{ caseData.donorNo }}</el-descriptions-item>
-          <el-descriptions-item label="鎹愮尞鑰呭鍚�">{{ caseData.donorName }}</el-descriptions-item>
+          <el-descriptions-item label="鎹愮尞缂栧彿">{{
+            caseData.donorNo
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鎹愮尞鑰呭鍚�">{{
+            caseData.donorName
+          }}</el-descriptions-item>
           <el-descriptions-item label="鎬у埆">
-            <dict-tag :options="genderOptions" :value="caseData.gender"/>
+            <dict-tag :options="genderOptions" :value="caseData.gender" />
           </el-descriptions-item>
-          <el-descriptions-item label="骞撮緞">{{ caseData.age }}宀�</el-descriptions-item>
+          <el-descriptions-item label="骞撮緞"
+            >{{ caseData.age }}宀�</el-descriptions-item
+          >
           <el-descriptions-item label="琛�鍨�">
-            <dict-tag :options="bloodTypeOptions" :value="caseData.bloodType"/>
+            <dict-tag :options="bloodTypeOptions" :value="caseData.bloodType" />
           </el-descriptions-item>
-          <el-descriptions-item label="璇佷欢鍙风爜">{{ caseData.idCardNo }}</el-descriptions-item>
-          <el-descriptions-item label="姘戞棌">{{ caseData.nation }}</el-descriptions-item>
-          <el-descriptions-item label="鑱旂郴鐢佃瘽">{{ caseData.phone }}</el-descriptions-item>
-          <el-descriptions-item label="浣忓潃" :span="2">{{ caseData.address }}</el-descriptions-item>
+          <el-descriptions-item label="璇佷欢鍙风爜">{{
+            caseData.idCardNo
+          }}</el-descriptions-item>
+          <el-descriptions-item label="姘戞棌">{{
+            caseData.nation
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鑱旂郴鐢佃瘽">{{
+            caseData.phone
+          }}</el-descriptions-item>
+          <el-descriptions-item label="浣忓潃" :span="2">{{
+            caseData.address
+          }}</el-descriptions-item>
         </el-descriptions>
       </el-tab-pane>
 
       <el-tab-pane label="鍖荤枟淇℃伅" name="medical">
         <el-descriptions :column="1" border>
-          <el-descriptions-item label="鐤剧梾璇婃柇">{{ caseData.diagnosis }}</el-descriptions-item>
-          <el-descriptions-item label="浣忛櫌鍙�">{{ caseData.inpatientNo }}</el-descriptions-item>
-          <el-descriptions-item label="鎵�鍦ㄧ瀹�">{{ caseData.departmentName }}</el-descriptions-item>
-          <el-descriptions-item label="涓绘不鍖荤敓">{{ caseData.doctorName }}</el-descriptions-item>
-          <el-descriptions-item label="浼犳煋鐥呮儏鍐�">{{ caseData.infectiousDisease || '鏃�' }}</el-descriptions-item>
-          <el-descriptions-item label="鍖荤枟璁板綍">{{ caseData.medicalRecord }}</el-descriptions-item>
+          <el-descriptions-item label="鐤剧梾璇婃柇">{{
+            caseData.diagnosis
+          }}</el-descriptions-item>
+          <el-descriptions-item label="浣忛櫌鍙�">{{
+            caseData.inpatientNo
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鎵�鍦ㄧ瀹�">{{
+            caseData.departmentName
+          }}</el-descriptions-item>
+          <el-descriptions-item label="涓绘不鍖荤敓">{{
+            caseData.doctorName
+          }}</el-descriptions-item>
+          <el-descriptions-item label="浼犳煋鐥呮儏鍐�">{{
+            caseData.infectiousDisease || "鏃�"
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鍖荤枟璁板綍">{{
+            caseData.medicalRecord
+          }}</el-descriptions-item>
         </el-descriptions>
       </el-tab-pane>
 
       <el-tab-pane label="鍖婚櫌淇℃伅" name="hospital">
         <el-descriptions :column="2" border>
-          <el-descriptions-item label="鍖婚櫌鍚嶇О">{{ caseData.hospitalName }}</el-descriptions-item>
-          <el-descriptions-item label="鍖婚櫌绾у埆">{{ caseData.hospitalLevel }}</el-descriptions-item>
-          <el-descriptions-item label="鑱旂郴浜�">{{ caseData.contactPerson }}</el-descriptions-item>
-          <el-descriptions-item label="鑱旂郴鐢佃瘽">{{ caseData.contactPhone }}</el-descriptions-item>
-          <el-descriptions-item label="鍖婚櫌鍦板潃" :span="2">{{ caseData.hospitalAddress }}</el-descriptions-item>
+          <el-descriptions-item label="鍖婚櫌鍚嶇О">{{
+            caseData.hospitalName
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鍖婚櫌绾у埆">{{
+            caseData.hospitalLevel
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鑱旂郴浜�">{{
+            caseData.contactPerson
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鑱旂郴鐢佃瘽">{{
+            caseData.contactPhone
+          }}</el-descriptions-item>
+          <el-descriptions-item label="鍖婚櫌鍦板潃" :span="2">{{
+            caseData.hospitalAddress
+          }}</el-descriptions-item>
         </el-descriptions>
       </el-tab-pane>
 
@@ -99,16 +135,26 @@
         </el-card>
       </el-tab-pane>
 
-      <el-tab-pane label="瀹℃壒淇℃伅" name="approval" v-if="caseData.status !== '0'">
+      <el-tab-pane
+        label="瀹℃壒淇℃伅"
+        name="approval"
+        v-if="caseData.status !== '0'"
+      >
         <el-descriptions :column="1" border>
           <el-descriptions-item label="瀹℃壒缁撴灉">
             <el-tag :type="caseData.status | statusFilter">
               {{ caseData.status | statusTextFilter }}
             </el-tag>
           </el-descriptions-item>
-          <el-descriptions-item label="瀹℃壒鏃堕棿">{{ caseData.approveTime }}</el-descriptions-item>
-          <el-descriptions-item label="瀹℃壒浜�">{{ caseData.approverName }}</el-descriptions-item>
-          <el-descriptions-item label="瀹℃壒鎰忚">{{ caseData.approveOpinion }}</el-descriptions-item>
+          <el-descriptions-item label="瀹℃壒鏃堕棿">{{
+            caseData.approveTime
+          }}</el-descriptions-item>
+          <el-descriptions-item label="瀹℃壒浜�">{{
+            caseData.approverName
+          }}</el-descriptions-item>
+          <el-descriptions-item label="瀹℃壒鎰忚">{{
+            caseData.approveOpinion
+          }}</el-descriptions-item>
         </el-descriptions>
       </el-tab-pane>
     </el-tabs>
@@ -252,24 +298,24 @@
   filters: {
     statusFilter(status) {
       const statusMap = {
-        '0': 'warning',
-        '1': 'success',
-        '2': 'danger'
+        "0": "warning",
+        "1": "success",
+        "2": "danger"
       };
       return statusMap[status];
     },
     statusTextFilter(status) {
       const statusMap = {
-        '0': '寰呭鎵�',
-        '1': '宸查�氳繃',
-        '2': '宸查┏鍥�'
+        "0": "寰呭鎵�",
+        "1": "宸查�氳繃",
+        "2": "宸查┏鍥�"
       };
       return statusMap[status];
     }
   },
   data() {
     return {
-      activeTab: 'basic',
+      activeTab: "basic",
       genderOptions: [
         { value: "0", label: "鐢�" },
         { value: "1", label: "濂�" }
@@ -333,12 +379,15 @@
   },
   methods: {
     handleClose() {
-      this.$emit('close');
+      this.$emit("close");
     },
 
     // 鑾峰彇鏂囦欢绫诲瀷
     getFileType(fileName) {
-      const extension = fileName.split('.').pop().toLowerCase();
+      const extension = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
       const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
       const pdfTypes = ["pdf"];
 
diff --git a/src/views/business/course/components/BaseStage.vue b/src/views/business/course/components/BaseStage.vue
new file mode 100644
index 0000000..a0457c7
--- /dev/null
+++ b/src/views/business/course/components/BaseStage.vue
@@ -0,0 +1,51 @@
+<template>
+  <div class="base-stage">
+    <slot name="header"></slot>
+    <div class="stage-content">
+      <slot></slot>
+    </div>
+    <slot name="footer"></slot>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'BaseStage',
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  methods: {
+    // 鏍煎紡鍖栨椂闂�
+    formatTime(time) {
+      if (!time) return '-';
+      return this.$dayjs(time).format('YYYY-MM-DD HH:mm');
+    },
+    // 鑾峰彇鐘舵�佹爣绛剧被鍨�
+    getStatusTag(status) {
+      const map = {
+        'completed': 'success',
+        'in_progress': 'warning',
+        'pending': 'info'
+      };
+      return map[status] || 'info';
+    }
+  }
+};
+</script>
+
+<style scoped>
+.base-stage {
+  padding: 0;
+}
+
+.stage-content {
+  min-height: 200px;
+}
+</style>
diff --git a/src/views/business/course/components/DeathJudgmentStage.vue b/src/views/business/course/components/DeathJudgmentStage.vue
new file mode 100644
index 0000000..f4d0e4b
--- /dev/null
+++ b/src/views/business/course/components/DeathJudgmentStage.vue
@@ -0,0 +1,206 @@
+<template>
+  <base-stage :stage-data="stageData" :case-info="caseInfo">
+    <template #header>
+      <el-alert
+        title="姝讳骸鍒ゅ畾闃舵"
+        :type="stageData.status === 'completed' ? 'success' : 'warning'"
+        :description="getAlertDescription()"
+        show-icon
+        :closable="false"
+      />
+    </template>
+
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <el-col :span="12">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鍒ゅ畾鍩烘湰淇℃伅</span>
+          </div>
+          <el-descriptions :column="1" border>
+            <el-descriptions-item label="鍒ゅ畾绫诲瀷">
+              <el-tag type="primary">鑴戞浜″垽瀹�</el-tag>
+            </el-descriptions-item>
+            <el-descriptions-item label="鍒ゅ畾鏃堕棿">
+              {{ formatTime(judgmentDetails.judgmentTime) }}
+            </el-descriptions-item>
+            <el-descriptions-item label="鍒ゅ畾鍖荤敓涓�">
+              {{ judgmentDetails.doctor1 }}
+            </el-descriptions-item>
+            <el-descriptions-item label="鍒ゅ畾鍖荤敓浜�">
+              {{ judgmentDetails.doctor2 }}
+            </el-descriptions-item>
+            <el-descriptions-item label="鍒ゅ畾缁撴灉">
+              <el-tag :type="judgmentDetails.result ? 'success' : 'warning'">
+                {{ judgmentDetails.result ? '鑴戞浜$‘璁�' : '鍒ゅ畾涓�' }}
+              </el-tag>
+            </el-descriptions-item>
+          </el-descriptions>
+        </el-card>
+      </el-col>
+
+      <el-col :span="12">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鍒ゅ畾娴佺▼璁板綍</span>
+          </div>
+          <el-steps direction="vertical" :active="judgmentSteps.active" space="100px">
+            <el-step
+              v-for="step in judgmentSteps.steps"
+              :key="step.title"
+              :title="step.title"
+              :description="step.description"
+              :status="step.status"
+            />
+          </el-steps>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>鍒ゅ畾璇︾粏璁板綍</span>
+      </div>
+      <el-table :data="judgmentRecords" border>
+        <el-table-column label="妫�鏌ラ」鐩�" prop="item" width="180" />
+        <el-table-column label="妫�鏌ユ柟娉�" prop="method" width="150" />
+        <el-table-column label="妫�鏌ョ粨鏋�" prop="result" width="120">
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.result === '绗﹀悎' ? 'success' : 'warning'">
+              {{ scope.row.result }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="妫�鏌ユ椂闂�" width="160">
+          <template slot-scope="scope">
+            {{ formatTime(scope.row.time) }}
+          </template>
+        </el-table-column>
+        <el-table-column label="妫�鏌ュ尰鐢�" prop="doctor" width="120" />
+        <el-table-column label="澶囨敞" prop="remark" min-width="200" />
+      </el-table>
+    </el-card>
+
+    <template #footer>
+      <div class="action-buttons" style="margin-top: 20px; text-align: center;">
+        <el-button type="primary" @click="handleViewCertificate">
+          鏌ョ湅姝讳骸璇佹槑
+        </el-button>
+        <el-button type="success" @click="handleConfirmJudgment">
+          纭鍒ゅ畾缁撴灉
+        </el-button>
+      </div>
+    </template>
+  </base-stage>
+</template>
+
+<script>
+import BaseStage from './BaseStage.vue';
+
+export default {
+  name: 'DeathJudgmentStage',
+  components: { BaseStage },
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      judgmentDetails: {
+        judgmentTime: '2023-12-03 09:15:00',
+        doctor1: '寮犱富浠�',
+        doctor2: '鐜嬪尰鐢�',
+        result: true,
+        certificateNo: 'SW20231203001'
+      },
+      judgmentSteps: {
+        active: 4,
+        steps: [
+          {
+            title: '鍒濇涓村簥妫�鏌�',
+            description: '瀹屾垚鑷富鍛煎惛娴嬭瘯',
+            status: 'finish'
+          },
+          {
+            title: '鑴戝共鍙嶅皠娴嬭瘯',
+            description: '鍚勯」鍙嶅皠娴嬭瘯瀹屾垚',
+            status: 'finish'
+          },
+          {
+            title: '纭鎬ф鏌�',
+            description: '鑴戠數鍥炬鏌ュ畬鎴�',
+            status: 'finish'
+          },
+          {
+            title: '鏈�缁堝垽瀹�',
+            description: '涓や綅鍖荤敓鐙珛鍒ゅ畾',
+            status: 'finish'
+          }
+        ]
+      },
+      judgmentRecords: [
+        {
+          item: '鑷富鍛煎惛娴嬭瘯',
+          method: '鍛煎惛鏆傚仠璇曢獙',
+          result: '绗﹀悎',
+          time: '2023-12-03 08:30:00',
+          doctor: '寮犱富浠�',
+          remark: '鏃犺嚜涓诲懠鍚�'
+        },
+        {
+          item: '鐬冲瓟瀵瑰厜鍙嶅皠',
+          method: '鍏夊埡婵�娴嬭瘯',
+          result: '绗﹀悎',
+          time: '2023-12-03 08:45:00',
+          doctor: '鐜嬪尰鐢�',
+          remark: '鐬冲瓟鍥哄畾锛屽鍏夊弽灏勬秷澶�'
+        },
+        {
+          item: '鑴戝共鍚璇卞彂鐢典綅',
+          method: 'BAEP妫�鏌�',
+          result: '绗﹀悎',
+          time: '2023-12-03 09:00:00',
+          doctor: '鏉庡尰鐢�',
+          remark: '鑴戝共鍔熻兘涓уけ'
+        }
+      ]
+    };
+  },
+  methods: {
+    getAlertDescription() {
+      if (this.stageData.status === 'completed') {
+        return '鑴戞浜″垽瀹氬凡瀹屾垚锛岀鍚堝櫒瀹樻崘鐚潯浠�';
+      } else if (this.stageData.status === 'in_progress') {
+        return '姝讳骸鍒ゅ畾娴佺▼姝e湪杩涜涓�';
+      }
+      return '绛夊緟寮�濮嬫浜″垽瀹氭祦绋�';
+    },
+    handleViewCertificate() {
+      this.$message.info('鏌ョ湅姝讳骸璇佹槑鍔熻兘');
+    },
+    handleConfirmJudgment() {
+      this.$confirm('纭姝讳骸鍒ゅ畾缁撴灉鍚楋紵', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.$message.success('姝讳骸鍒ゅ畾缁撴灉宸茬‘璁�');
+      });
+    }
+  }
+};
+</script>
+
+<style scoped>
+.action-buttons {
+  display: flex;
+  justify-content: center;
+  gap: 15px;
+  margin-top: 20px;
+}
+</style>
diff --git a/src/views/business/course/components/DonationConfirmStage.vue b/src/views/business/course/components/DonationConfirmStage.vue
new file mode 100644
index 0000000..d608417
--- /dev/null
+++ b/src/views/business/course/components/DonationConfirmStage.vue
@@ -0,0 +1,217 @@
+<template>
+  <base-stage :stage-data="stageData" :case-info="caseInfo">
+    <template #header>
+      <el-alert
+        :title="`鎹愮尞纭 - ${getStatusText()}`"
+        :type="getAlertType()"
+        :description="getAlertDescription()"
+        show-icon
+        :closable="false"
+      />
+    </template>
+
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>纭淇℃伅姒傝</span>
+          </div>
+          <div class="confirm-overview">
+            <div class="overview-item">
+              <span class="label">纭鐘舵��:</span>
+              <el-tag :type="getStatusTag(confirmationDetails.status)">
+                {{ getStatusText(confirmationDetails.status) }}
+              </el-tag>
+            </div>
+            <div class="overview-item">
+              <span class="label">纭鏃堕棿:</span>
+              <span>{{ formatTime(confirmationDetails.confirmTime) }}</span>
+            </div>
+            <div class="overview-item">
+              <span class="label">纭鏂瑰紡:</span>
+              <span>{{ confirmationDetails.method }}</span>
+            </div>
+            <div class="overview-item">
+              <span class="label">鍗忚皟鍛�:</span>
+              <span>{{ confirmationDetails.coordinator }}</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>瀹跺睘鍚屾剰鎯呭喌</span>
+          </div>
+          <el-descriptions :column="1" size="small">
+            <el-descriptions-item label="涓昏瀹跺睘">
+              {{ familyConsent.mainRelative }}
+            </el-descriptions-item>
+            <el-descriptions-item label="鍚屾剰鐘舵��">
+              <el-tag :type="familyConsent.consented ? 'success' : 'warning'">
+                {{ familyConsent.consented ? '宸插悓鎰�' : '寰呯‘璁�' }}
+              </el-tag>
+            </el-descriptions-item>
+            <el-descriptions-item label="绛惧瓧鏃堕棿">
+              {{ formatTime(familyConsent.signTime) }}
+            </el-descriptions-item>
+            <el-descriptions-item label="鍏崇郴璇佹槑">
+              {{ familyConsent.relationshipProof }}
+            </el-descriptions-item>
+          </el-descriptions>
+        </el-card>
+      </el-col>
+
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>娉曞緥鏂囦欢</span>
+          </div>
+          <div class="document-list">
+            <div v-for="doc in legalDocuments" :key="doc.name" class="document-item">
+              <div class="doc-info">
+                <i :class="doc.icon" style="color: #409EFF; margin-right: 8px;"></i>
+                <span>{{ doc.name }}</span>
+              </div>
+              <el-tag :type="doc.status === 'completed' ? 'success' : 'warning'" size="small">
+                {{ doc.status === 'completed' ? '宸茬缃�' : '寰呯缃�' }}
+              </el-tag>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>鎹愮尞鎰忔効纭涔�</span>
+      </div>
+      <div class="consent-content">
+        <p>鏈汉/瀹跺睘纭锛屽湪鍏呭垎浜嗚В鍣ㄥ畼鎹愮尞鐨勭浉鍏充俊鎭悗锛岃嚜鎰垮悓鎰忚繘琛屽櫒瀹樻崘鐚��</p>
+        <el-divider />
+        <el-descriptions :column="2" border>
+          <el-descriptions-item label="鎹愮尞鑰呭鍚�">{{ caseInfo.donorName }}</el-descriptions-item>
+          <el-descriptions-item label="鎹愮尞鑰呰韩浠借瘉鍙�">{{ confirmationDetails.idNumber }}</el-descriptions-item>
+          <el-descriptions-item label="鎹愮尞鍣ㄥ畼绫诲瀷">{{ confirmationDetails.organs }}</el-descriptions-item>
+          <el-descriptions-item label="鎹愮尞鐢ㄩ��">{{ confirmationDetails.purpose }}</el-descriptions-item>
+          <el-descriptions-item label="绛惧瓧浜�">{{ familyConsent.mainRelative }}</el-descriptions-item>
+          <el-descriptions-item label="绛惧瓧鏃ユ湡">{{ formatTime(familyConsent.signTime) }}</el-descriptions-item>
+        </el-descriptions>
+      </div>
+    </el-card>
+  </base-stage>
+</template>
+
+<script>
+import BaseStage from './BaseStage.vue';
+
+export default {
+  name: 'DonationConfirmStage',
+  components: { BaseStage },
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      confirmationDetails: {
+        status: 'completed',
+        confirmTime: '2023-12-03 11:00:00',
+        method: '瀹跺睘涔﹂潰鍚屾剰',
+        coordinator: '璧靛崗璋冨憳',
+        idNumber: '110101199001011234',
+        organs: '蹇冭剰銆佽倽鑴忋�佽偩鑴忋�佽鑶�',
+        purpose: '涓村簥绉绘'
+      },
+      familyConsent: {
+        mainRelative: '寮犱笁鐖朵翰',
+        consented: true,
+        signTime: '2023-12-03 10:45:00',
+        relationshipProof: '鎴峰彛鏈叧绯昏瘉鏄�'
+      },
+      legalDocuments: [
+        { name: '鍣ㄥ畼鎹愮尞鍚屾剰涔�', icon: 'el-icon-document', status: 'completed' },
+        { name: '瀹跺睘鍏崇郴璇佹槑', icon: 'el-icon-document', status: 'completed' },
+        { name: '鍖荤枟鍏嶈矗澹版槑', icon: 'el-icon-document', status: 'completed' },
+        { name: '闅愮淇濇姢鍗忚', icon: 'el-icon-document', status: 'completed' }
+      ]
+    };
+  },
+  methods: {
+    getStatusText() {
+      const status = this.stageData.status;
+      return status === 'completed' ? '宸插畬鎴�' :
+             status === 'in_progress' ? '杩涜涓�' : '鏈紑濮�';
+    },
+    getAlertType() {
+      const status = this.stageData.status;
+      return status === 'completed' ? 'success' :
+             status === 'in_progress' ? 'warning' : 'info';
+    },
+    getAlertDescription() {
+      const status = this.stageData.status;
+      return status === 'completed' ? '鎹愮尞纭娴佺▼宸插畬鎴愶紝鎵�鏈夋硶寰嬫枃浠跺凡绛剧讲' :
+             status === 'in_progress' ? '鎹愮尞纭娴佺▼姝e湪杩涜涓�' : '绛夊緟寮�濮嬫崘鐚‘璁ゆ祦绋�';
+    },
+    getStatusTag(status) {
+      const map = {
+        'completed': 'success',
+        'in_progress': 'warning',
+        'pending': 'info'
+      };
+      return map[status] || 'info';
+    }
+  }
+};
+</script>
+
+<style scoped>
+.confirm-overview {
+  padding: 10px 0;
+}
+
+.overview-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding: 8px 0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.overview-item .label {
+  color: #606266;
+  font-weight: 500;
+}
+
+.document-list {
+  padding: 10px 0;
+}
+
+.document-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+  padding: 8px 12px;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+}
+
+.doc-info {
+  display: flex;
+  align-items: center;
+}
+
+.consent-content {
+  padding: 20px;
+  line-height: 1.6;
+}
+</style>
diff --git a/src/views/business/course/components/DonorMaintenanceStage.vue b/src/views/business/course/components/DonorMaintenanceStage.vue
new file mode 100644
index 0000000..a7e82a9
--- /dev/null
+++ b/src/views/business/course/components/DonorMaintenanceStage.vue
@@ -0,0 +1,156 @@
+<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>
+      <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">
+          <template slot-scope="scope">
+            {{ formatTime(scope.row.time) }}
+          </template>
+        </el-table-column>
+        <el-table-column label="鐘舵��" width="100">
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.status === 'completed' ? 'success' : 'warning'">
+              {{ scope.row.status === 'completed' ? '宸插畬鎴�' : '杩涜涓�' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+  </base-stage>
+</template>
+
+<script>
+import BaseStage from './BaseStage.vue';
+
+export default {
+  name: 'DonorMaintenanceStage',
+  components: { BaseStage },
+  dicts: ['sys_user_sex'],
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  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'
+        }
+      ],
+      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'
+        }
+      ]
+    };
+  }
+};
+</script>
+
+<style scoped>
+.card-header {
+  font-weight: 600;
+  color: #303133;
+}
+
+.info-card, .timeline-card {
+  height: 100%;
+}
+</style>
diff --git a/src/views/business/course/components/EthicalReviewStage.vue b/src/views/business/course/components/EthicalReviewStage.vue
new file mode 100644
index 0000000..47e4877
--- /dev/null
+++ b/src/views/business/course/components/EthicalReviewStage.vue
@@ -0,0 +1,206 @@
+<template>
+  <base-stage :stage-data="stageData" :case-info="caseInfo">
+    <template #header>
+      <el-alert
+        title="浼︾悊瀹℃煡闃舵"
+        :type="getAlertType()"
+        :description="getAlertDescription()"
+        show-icon
+        :closable="false"
+      />
+    </template>
+
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <el-col :span="12">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>瀹℃煡濮斿憳浼氫俊鎭�</span>
+          </div>
+          <el-descriptions :column="1" border>
+            <el-descriptions-item label="濮斿憳浼氬悕绉�">
+              {{ reviewCommittee.name }}
+            </el-descriptions-item>
+            <el-descriptions-item label="瀹℃煡浼氳鏃堕棿">
+              {{ formatTime(reviewCommittee.meetingTime) }}
+            </el-descriptions-item>
+            <el-descriptions-item label="鍙備細濮斿憳">
+              {{ reviewCommittee.members.length }} 浜�
+            </el-descriptions-item>
+            <el-descriptions-item label="瀹℃煡缁撹">
+              <el-tag :type="reviewCommittee.conclusion ? 'success' : 'warning'">
+                {{ reviewCommittee.conclusion ? '瀹℃煡閫氳繃' : '瀹℃煡涓�' }}
+              </el-tag>
+            </el-descriptions-item>
+            <el-descriptions-item label="涓诲腑绛惧瓧">
+              {{ reviewCommittee.chairman }}
+            </el-descriptions-item>
+          </el-descriptions>
+        </el-card>
+      </el-col>
+
+      <el-col :span="12">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>瀹℃煡娴佺▼杩涘害</span>
+          </div>
+          <el-steps direction="vertical" :active="reviewProgress.active" space="80px">
+            <el-step
+              v-for="step in reviewProgress.steps"
+              :key="step.title"
+              :title="step.title"
+              :description="step.description"
+              :status="step.status"
+            />
+          </el-steps>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>濮斿憳瀹℃煡鎰忚</span>
+      </div>
+      <el-table :data="reviewComments" border>
+        <el-table-column label="濮斿憳濮撳悕" prop="memberName" width="120" />
+        <el-table-column label="涓撲笟棰嗗煙" prop="specialty" width="120" />
+        <el-table-column label="瀹℃煡鎰忚" prop="comment" min-width="200" />
+        <el-table-column label="鎶曠エ缁撴灉" width="100">
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.vote === '鍚屾剰' ? 'success' : 'danger'">
+              {{ scope.row.vote }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="瀹℃煡鏃堕棿" width="160">
+          <template slot-scope="scope">
+            {{ formatTime(scope.row.reviewTime) }}
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>瀹℃煡鍐宠鏂囦欢</span>
+        <el-button type="primary" size="small" @click="handleViewResolution">
+          鏌ョ湅鍐宠鏂囦欢
+        </el-button>
+      </div>
+      <div class="resolution-content">
+        <p><strong>浼︾悊瀹℃煡鍐宠锛�</strong></p>
+        <p>{{ resolutionContent }}</p>
+        <el-divider />
+        <div class="signature-area">
+          <p>浼︾悊濮斿憳浼氫富甯細{{ reviewCommittee.chairman }}</p>
+          <p>鏃ユ湡锛歿{ formatTime(reviewCommittee.meetingTime) }}</p>
+        </div>
+      </div>
+    </el-card>
+  </base-stage>
+</template>
+
+<script>
+import BaseStage from './BaseStage.vue';
+
+export default {
+  name: 'EthicalReviewStage',
+  components: { BaseStage },
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      reviewCommittee: {
+        name: '鍖婚櫌浼︾悊瀹℃煡濮斿憳浼�',
+        meetingTime: '2023-12-03 15:20:00',
+        members: ['寮犳暀鎺�', '鏉庝富浠�', '鐜嬪尰鐢�', '璧靛鍛�', '閽变笓瀹�'],
+        conclusion: true,
+        chairman: '寮犳暀鎺�'
+      },
+      reviewProgress: {
+        active: 4,
+        steps: [
+          {
+            title: '鏉愭枡鍒濆',
+            description: '鐢宠鏉愭枡瀹屾暣鎬у鏌�',
+            status: 'finish'
+          },
+          {
+            title: '濮斿憳璇勫',
+            description: '鍚勫鍛樼嫭绔嬪鏌�',
+            status: 'finish'
+          },
+          {
+            title: '浼氳璁ㄨ',
+            description: '濮斿憳浼氶泦浣撹璁�',
+            status: 'finish'
+          },
+          {
+            title: '褰㈡垚鍐宠',
+            description: '鎶曠エ褰㈡垚鏈�缁堝喅璁�',
+            status: 'finish'
+          }
+        ]
+      },
+      reviewComments: [
+        {
+          memberName: '寮犳暀鎺�',
+          specialty: '鍖诲浼︾悊',
+          comment: '鎹愮尞绋嬪簭绗﹀悎浼︾悊瑙勮寖锛屽悓鎰忛�氳繃',
+          vote: '鍚屾剰',
+          reviewTime: '2023-12-03 14:30:00'
+        },
+        {
+          memberName: '鏉庝富浠�',
+          specialty: '涓村簥鍖诲',
+          comment: '鍖荤枟绋嬪簭瑙勮寖锛屾棤浼︾悊闂',
+          vote: '鍚屾剰',
+          reviewTime: '2023-12-03 14:45:00'
+        },
+        {
+          memberName: '鐜嬪尰鐢�',
+          specialty: '娉曞緥鍖诲',
+          comment: '娉曞緥鏂囦欢榻愬叏锛岀▼搴忓悎娉�',
+          vote: '鍚屾剰',
+          reviewTime: '2023-12-03 15:00:00'
+        }
+      ],
+      resolutionContent: '缁忎鸡鐞嗗鏌ュ鍛樹細瀹℃煡锛岃鍣ㄥ畼鎹愮尞妗堜緥绗﹀悎鍖诲浼︾悊瑕佹眰锛屾崘鐚▼搴忚鑼冿紝瀹跺睘鎰忔効鐪熷疄鏈夋晥锛屽悓鎰忚繘琛屽櫒瀹樻崘鐚��'
+    };
+  },
+  methods: {
+    getAlertType() {
+      const status = this.stageData.status;
+      return status === 'completed' ? 'success' :
+             status === 'in_progress' ? 'warning' : 'info';
+    },
+    getAlertDescription() {
+      const status = this.stageData.status;
+      return status === 'completed' ? '浼︾悊瀹℃煡宸查�氳繃锛屽彲浠ヨ繘琛屽櫒瀹樺垎閰�' :
+             status === 'in_progress' ? '浼︾悊瀹℃煡娴佺▼姝e湪杩涜涓�' : '绛夊緟寮�濮嬩鸡鐞嗗鏌ユ祦绋�';
+    },
+    handleViewResolution() {
+      this.$message.info('鏌ョ湅浼︾悊瀹℃煡鍐宠鏂囦欢鍔熻兘');
+    }
+  }
+};
+</script>
+
+<style scoped>
+.resolution-content {
+  padding: 20px;
+  line-height: 1.8;
+}
+
+.signature-area {
+  text-align: right;
+  margin-top: 30px;
+}
+</style>
diff --git a/src/views/business/course/components/MedicalAssessmentStage.vue b/src/views/business/course/components/MedicalAssessmentStage.vue
new file mode 100644
index 0000000..ece6b8f
--- /dev/null
+++ b/src/views/business/course/components/MedicalAssessmentStage.vue
@@ -0,0 +1,208 @@
+<template>
+  <base-stage :stage-data="stageData" :case-info="caseInfo">
+    <template #header>
+      <el-alert
+        :title="alertTitle"
+        :type="alertType"
+        :description="alertDescription"
+        show-icon
+        :closable="false"
+      />
+    </template>
+
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>璇勪及姒傚喌</span>
+          </div>
+          <div class="assessment-stats">
+            <div class="stat-item">
+              <span class="stat-label">璇勪及鐘舵��:</span>
+              <el-tag :type="getStatusTag(stageData.status)">
+                {{ getStatusText(stageData.status) }}
+              </el-tag>
+            </div>
+            <div class="stat-item">
+              <span class="stat-label">璇勪及鍖荤敓:</span>
+              <span>{{ stageData.operator || '寰呭垎閰�' }}</span>
+            </div>
+            <div class="stat-item">
+              <span class="stat-label">寮�濮嬫椂闂�:</span>
+              <span>{{ formatTime(stageData.updateTime) }}</span>
+            </div>
+            <div class="stat-item">
+              <span class="stat-label">瀹屾垚鏃堕棿:</span>
+              <span>{{ formatTime(stageData.completeTime) || '-' }}</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="16">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>璇勪及椤圭洰杩涘害</span>
+          </div>
+          <div class="progress-list">
+            <div v-for="item in assessmentItems" :key="item.name" class="progress-item">
+              <div class="progress-info">
+                <span class="item-name">{{ item.name }}</span>
+                <span class="item-status">
+                  <el-tag :type="item.status === 'completed' ? 'success' : 'warning'" size="small">
+                    {{ item.status === 'completed' ? '宸插畬鎴�' : '寰呰瘎浼�' }}
+                  </el-tag>
+                </span>
+              </div>
+              <el-progress
+                :percentage="item.status === 'completed' ? 100 : 0"
+                :show-text="false"
+                :status="item.status === 'completed' ? 'success' : 'exception'"
+              />
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>璇勪及璇︽儏璁板綍</span>
+        <el-button type="primary" size="small" @click="handleViewReport">
+          鏌ョ湅璇勪及鎶ュ憡
+        </el-button>
+      </div>
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="鐢熺悊鎸囨爣璇勪及">
+          {{ assessmentDetails.physiological || '寰呰瘎浼�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鍣ㄥ畼鍔熻兘璇勪及">
+          {{ assessmentDetails.organFunction || '寰呰瘎浼�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鎰熸煋鎬х柧鐥呯瓫鏌�">
+          {{ assessmentDetails.infectionScreening || '寰呯瓫鏌�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鎭舵�ц偪鐦ょ瓫鏌�">
+          {{ assessmentDetails.cancerScreening || '寰呯瓫鏌�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="璇勪及缁撹">
+          <el-tag :type="assessmentDetails.conclusion ? 'success' : 'warning'">
+            {{ assessmentDetails.conclusion || '璇勪及涓�' }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="璇勪及鍖荤敓鎰忚">
+          {{ assessmentDetails.doctorOpinion || '寰呭~鍐�' }}
+        </el-descriptions-item>
+      </el-descriptions>
+    </el-card>
+  </base-stage>
+</template>
+
+<script>
+import BaseStage from './BaseStage.vue';
+
+export default {
+  name: 'MedicalAssessmentStage',
+  components: { BaseStage },
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  computed: {
+    alertTitle() {
+      const status = this.stageData.status;
+      return status === 'completed' ? '鍖诲璇勪及瀹屾垚' :
+             status === 'in_progress' ? '鍖诲璇勪及杩涜涓�' : '寰呭紑濮嬪尰瀛﹁瘎浼�';
+    },
+    alertType() {
+      const status = this.stageData.status;
+      return status === 'completed' ? 'success' :
+             status === 'in_progress' ? 'warning' : 'info';
+    },
+    alertDescription() {
+      const status = this.stageData.status;
+      return status === 'completed' ? '鎵�鏈夊尰瀛﹁瘎浼伴」鐩凡瀹屾垚锛屼緵鑰呯鍚堟崘鐚潯浠�' :
+             status === 'in_progress' ? '鍖诲璇勪及姝e湪杩涜涓紝璇峰叧娉ㄨ瘎浼拌繘搴�' : '绛夊緟寮�濮嬪尰瀛﹁瘎浼版祦绋�';
+    }
+  },
+  data() {
+    return {
+      assessmentItems: [
+        { name: '鐢熺悊鎸囨爣璇勪及', status: 'completed' },
+        { name: '鍣ㄥ畼鍔熻兘璇勪及', status: 'completed' },
+        { name: '鎰熸煋鎬х柧鐥呯瓫鏌�', status: 'completed' },
+        { name: '鎭舵�ц偪鐦ょ瓫鏌�', status: 'completed' },
+        { name: '閬椾紶鎬х柧鐥呯瓫鏌�', status: 'completed' },
+        { name: '蹇冪悊鐘舵�佽瘎浼�', status: 'completed' }
+      ],
+      assessmentDetails: {
+        physiological: '鍚勯」鐢熺悊鎸囨爣姝e父锛岀鍚堟崘鐚姹�',
+        organFunction: '涓昏鍣ㄥ畼鍔熻兘鑹ソ锛屾棤绂佸繉鐥�',
+        infectionScreening: '浼犳煋鐥呯瓫鏌ュ潎涓洪槾鎬�',
+        cancerScreening: '鏃犳伓鎬ц偪鐦よ抗璞�',
+        conclusion: '閫傚悎鍣ㄥ畼鎹愮尞',
+        doctorOpinion: '渚涜�呰韩浣撶姸鍐佃壇濂斤紝绗﹀悎鎹愮尞鍖诲鏍囧噯'
+      }
+    };
+  },
+  methods: {
+    getStatusText(status) {
+      const map = {
+        'completed': '宸插畬鎴�',
+        'in_progress': '杩涜涓�',
+        'pending': '鏈紑濮�'
+      };
+      return map[status] || '鏈煡';
+    },
+    handleViewReport() {
+      this.$message.info('鏌ョ湅鍖诲璇勪及鎶ュ憡鍔熻兘');
+    }
+  }
+};
+</script>
+
+<style scoped>
+.assessment-stats {
+  padding: 10px 0;
+}
+
+.stat-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding: 8px 0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.stat-label {
+  color: #606266;
+  font-weight: 500;
+}
+
+.progress-list {
+  padding: 10px 0;
+}
+
+.progress-item {
+  margin-bottom: 15px;
+}
+
+.progress-info {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.item-name {
+  color: #606266;
+  font-size: 14px;
+}
+</style>
diff --git a/src/views/business/course/components/OrganAllocationStage.vue b/src/views/business/course/components/OrganAllocationStage.vue
new file mode 100644
index 0000000..8bc58b5
--- /dev/null
+++ b/src/views/business/course/components/OrganAllocationStage.vue
@@ -0,0 +1,447 @@
+<template>
+  <base-stage :stage-data="stageData" :case-info="caseInfo">
+    <template #header>
+      <el-alert
+        :title="`鍣ㄥ畼鍒嗛厤 - ${getStatusText()}`"
+        :type="getAlertType()"
+        :description="getAlertDescription()"
+        show-icon
+        :closable="false"
+      />
+    </template>
+
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鍒嗛厤姒傚喌</span>
+          </div>
+          <div class="allocation-stats">
+            <div class="stat-item">
+              <span class="label">寰呭垎閰嶅櫒瀹�:</span>
+              <span class="value">{{ allocationStats.totalOrgans }} 涓�</span>
+            </div>
+            <div class="stat-item">
+              <span class="label">宸插垎閰嶅櫒瀹�:</span>
+              <span class="value">{{ allocationStats.allocatedOrgans }} 涓�</span>
+            </div>
+            <div class="stat-item">
+              <span class="label">鍒嗛厤绯荤粺:</span>
+              <span class="value">{{ allocationStats.system }}</span>
+            </div>
+            <div class="stat-item">
+              <span class="label">鍖归厤鎴愬姛鐜�:</span>
+              <el-progress
+                :percentage="allocationStats.matchRate"
+                :status="allocationStats.matchRate > 80 ? 'success' : 'warning'"
+              />
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鍒嗛厤鏃堕棿绐楀彛</span>
+          </div>
+          <div class="time-window">
+            <div class="time-item">
+              <span class="label">鍒嗛厤寮�濮�:</span>
+              <span>{{ formatTime(allocationDetails.startTime) }}</span>
+            </div>
+            <div class="time-item">
+              <span class="label">棰勮瀹屾垚:</span>
+              <span>{{ formatTime(allocationDetails.estimatedEndTime) }}</span>
+            </div>
+            <div class="time-item">
+              <span class="label">鍣ㄥ畼鑰愬彈鏃堕棿:</span>
+              <span>{{ allocationDetails.toleranceTime }}</span>
+            </div>
+            <div class="time-item">
+              <span class="label">鍓╀綑鏃堕棿:</span>
+              <el-tag :type="getTimeRemainingType()">
+                {{ allocationDetails.timeRemaining }}
+              </el-tag>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鍒嗛厤浼樺厛绾�</span>
+          </div>
+          <el-steps direction="vertical" :active="prioritySteps.active">
+            <el-step
+              v-for="step in prioritySteps.steps"
+              :key="step.title"
+              :title="step.title"
+              :description="step.description"
+              :status="step.status"
+            />
+          </el-steps>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>鍣ㄥ畼鍒嗛厤璇︽儏</span>
+        <el-button type="primary" size="small" @click="handleStartAllocation">
+          鍚姩鑷姩鍒嗛厤
+        </el-button>
+      </div>
+      <el-table :data="organAllocationData" border>
+        <el-table-column label="鍣ㄥ畼鍚嶇О" prop="organName" width="120" align="center" />
+        <el-table-column label="鍣ㄥ畼鐘舵��" width="100" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="getOrganStatusTag(scope.row.status)" size="small">
+              {{ scope.row.status }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍖归厤鍙椾綋" prop="recipient" width="150" />
+        <el-table-column label="琛�鍨嬪尮閰�" width="100" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.bloodMatch ? 'success' : 'warning'">
+              {{ scope.row.bloodMatch ? '鍖归厤' : '寰呭尮閰�' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="缁勭粐閰嶅瀷" width="100" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.tissueMatch ? 'success' : 'warning'">
+              {{ scope.row.tissueMatch ? '鍚堟牸' : '寰呮娴�' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="绉绘鍖婚櫌" prop="hospital" min-width="200" />
+        <el-table-column label="鍒嗛厤鏃堕棿" width="160" align="center">
+          <template slot-scope="scope">
+            {{ scope.row.allocationTime || '寰呭垎閰�' }}
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" width="120" align="center">
+          <template slot-scope="scope">
+            <el-button type="text" size="small" @click="handleViewMatch(scope.row)">
+              鏌ョ湅鍖归厤
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>鍒嗛厤绠楁硶缁撴灉</span>
+      </div>
+      <div class="algorithm-results">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <div class="result-item">
+              <h4>鍖归厤璇勫垎鎺掑悕</h4>
+              <el-table :data="matchRanking" border size="small">
+                <el-table-column label="鎺掑悕" width="60" align="center">
+                  <template slot-scope="scope">
+                    {{ scope.$index + 1 }}
+                  </template>
+                </el-table-column>
+                <el-table-column label="鍙椾綋缂栧彿" prop="recipientNo" width="100" />
+                <el-table-column label="鍖归厤鍒嗘暟" prop="matchScore" width="100">
+                  <template slot-scope="scope">
+                    <el-rate
+                      v-model="scope.row.matchScore"
+                      disabled
+                      show-score
+                      text-color="#ff9900"
+                      score-template="{value} 鍒�"
+                    />
+                  </template>
+                </el-table-column>
+                <el-table-column label="鎺ㄨ崘鍣ㄥ畼" prop="recommendedOrgan" />
+              </el-table>
+            </div>
+          </el-col>
+          <el-col :span="12">
+            <div class="result-item">
+              <h4>鍒嗛厤鍥犵礌鏉冮噸</h4>
+              <div class="weight-distribution">
+                <div v-for="factor in allocationFactors" :key="factor.name" class="factor-item">
+                  <span class="factor-name">{{ factor.name }}</span>
+                  <el-progress
+                    :percentage="factor.weight"
+                    :show-text="false"
+                    :color="factor.color"
+                  />
+                  <span class="factor-percent">{{ factor.weight }}%</span>
+                </div>
+              </div>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </el-card>
+
+    <template #footer>
+      <div class="action-buttons" style="margin-top: 20px; text-align: center;">
+        <el-button type="primary" @click="handleAutoAllocation">
+          鏅鸿兘鍒嗛厤
+        </el-button>
+        <el-button type="success" @click="handleConfirmAllocation">
+          纭鍒嗛厤缁撴灉
+        </el-button>
+        <el-button type="warning" @click="handleManualAdjust">
+          鎵嬪姩璋冩暣
+        </el-button>
+      </div>
+    </template>
+  </base-stage>
+</template>
+
+<script>
+import BaseStage from './BaseStage.vue';
+
+export default {
+  name: 'OrganAllocationStage',
+  components: { BaseStage },
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      allocationStats: {
+        totalOrgans: 3,
+        allocatedOrgans: 0,
+        system: '涓浗浜轰綋鍣ㄥ畼鍒嗛厤涓庡叡浜绠楁満绯荤粺',
+        matchRate: 0
+      },
+      allocationDetails: {
+        startTime: '2023-12-04 10:00:00',
+        estimatedEndTime: '2023-12-04 12:00:00',
+        toleranceTime: '鑲濊剰:12灏忔椂,鑲捐剰:24灏忔椂,蹇冭剰:8灏忔椂,鑲鸿剰:12灏忔椂',
+        timeRemaining: '2灏忔椂'
+      },
+      prioritySteps: {
+        active: 3,
+        steps: [
+          {
+            title: '鐥呮儏鍗遍噸浼樺厛',
+            description: '鏍规嵁鎮h�呯梾鎯呭嵄閲嶇▼搴﹀垎閰峓1](@ref)',
+            status: 'finish'
+          },
+          {
+            title: '缁勭粐閰嶅瀷浼樺厛',
+            description: '缁勭粐閰嶅瀷鍖归厤搴﹂珮鐨勬偅鑰呬紭鍏�',
+            status: 'finish'
+          },
+          {
+            title: '琛�鍨嬬浉鍚屼紭鍏�',
+            description: '琛�鍨嬪尮閰嶇殑鎮h�呬紭鍏堣�冭檻',
+            status: 'finish'
+          },
+          {
+            title: '鍎跨鍖归厤浼樺厛',
+            description: '鍎跨鎮h�呬韩鏈変紭鍏堝垎閰嶆潈',
+            status: 'wait'
+          }
+        ]
+      },
+      organAllocationData: [
+        {
+          organName: '鑲濊剰',
+          status: '寰呭垎閰�',
+          recipient: '',
+          bloodMatch: false,
+          tissueMatch: false,
+          hospital: '',
+          allocationTime: ''
+        },
+        {
+          organName: '鑲捐剰',
+          status: '寰呭垎閰�',
+          recipient: '',
+          bloodMatch: false,
+          tissueMatch: false,
+          hospital: '',
+          allocationTime: ''
+        },
+        {
+          organName: '蹇冭剰',
+          status: '寰呭垎閰�',
+          recipient: '',
+          bloodMatch: false,
+          tissueMatch: false,
+          hospital: '',
+          allocationTime: ''
+        }
+      ],
+      matchRanking: [
+        {
+          recipientNo: 'R202312001',
+          matchScore: 4.8,
+          recommendedOrgan: '鑲濊剰'
+        },
+        {
+          recipientNo: 'R202312002',
+          matchScore: 4.5,
+          recommendedOrgan: '鑲捐剰'
+        },
+        {
+          recipientNo: 'R202312003',
+          matchScore: 4.3,
+          recommendedOrgan: '蹇冭剰'
+        }
+      ],
+      allocationFactors: [
+        { name: '鐥呮儏鍗遍噸绋嬪害', weight: 35, color: '#f56c6c' },
+        { name: '缁勭粐閰嶅瀷鍖归厤', weight: 25, color: '#e6a23c' },
+        { name: '绛夊緟鏃堕棿', weight: 15, color: '#5cb87a' },
+        { name: '鍦扮悊鍥犵礌', weight: 10, color: '#6f7ad3' },
+        { name: '骞撮緞鍥犵礌', weight: 15, color: '#8e44ad' }
+      ]
+    };
+  },
+  methods: {
+    getStatusText() {
+      const status = this.stageData.status;
+      return status === 'completed' ? '宸插畬鎴�' :
+             status === 'in_progress' ? '杩涜涓�' : '鏈紑濮�';
+    },
+    getAlertType() {
+      const status = this.stageData.status;
+      return status === 'completed' ? 'success' :
+             status === 'in_progress' ? 'warning' : 'info';
+    },
+    getAlertDescription() {
+      const status = this.stageData.status;
+      if (status === 'completed') {
+        return '鍣ㄥ畼鍒嗛厤宸插畬鎴愶紝鎵�鏈夊櫒瀹樺潎宸叉垚鍔熷尮閰嶅彈浣�';
+      } else if (status === 'in_progress') {
+        return '鍣ㄥ畼鍒嗛厤杩涜涓紝绯荤粺姝e湪鑷姩鍖归厤鏈�浣冲彈浣�';
+      }
+      return '绛夊緟寮�濮嬪櫒瀹樺垎閰嶆祦绋�';
+    },
+    getOrganStatusTag(status) {
+      const map = {
+        '宸插垎閰�': 'success',
+        '鍒嗛厤涓�': 'warning',
+        '寰呭垎閰�': 'info'
+      };
+      return map[status] || 'info';
+    },
+    getTimeRemainingType() {
+      return this.allocationDetails.timeRemaining.includes('灏忔椂') ? 'success' : 'danger';
+    },
+    handleStartAllocation() {
+      this.$confirm('纭鍚姩鑷姩鍣ㄥ畼鍒嗛厤鍚楋紵', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.$message.success('宸插惎鍔ㄨ嚜鍔ㄥ垎閰嶇畻娉�');
+        // 妯℃嫙鍒嗛厤杩囩▼
+        this.allocationStats.allocatedOrgans = 3;
+        this.allocationStats.matchRate = 95;
+        this.organAllocationData.forEach(organ => {
+          organ.status = '宸插垎閰�';
+          organ.allocationTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
+        });
+      });
+    },
+    handleAutoAllocation() {
+      this.$message.info('鎵ц鏅鸿兘鍒嗛厤绠楁硶');
+    },
+    handleConfirmAllocation() {
+      this.$confirm('纭鏈�缁堝垎閰嶇粨鏋滃悧锛�', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'success'
+      }).then(() => {
+        this.$message.success('鍣ㄥ畼鍒嗛厤缁撴灉宸茬‘璁�');
+      });
+    },
+    handleManualAdjust() {
+      this.$message.info('杩涘叆鎵嬪姩璋冩暣妯″紡');
+    },
+    handleViewMatch(row) {
+      this.$message.info(`鏌ョ湅${row.organName}鐨勫尮閰嶈鎯卄);
+    }
+  }
+};
+</script>
+
+<style scoped>
+.allocation-stats, .time-window {
+  padding: 10px 0;
+}
+
+.stat-item, .time-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding: 8px 0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.stat-item .label, .time-item .label {
+  color: #606266;
+  font-weight: 500;
+  min-width: 100px;
+}
+
+.stat-item .value {
+  font-weight: 600;
+  color: #409EFF;
+}
+
+.algorithm-results {
+  padding: 15px 0;
+}
+
+.result-item {
+  margin-bottom: 20px;
+}
+
+.result-item h4 {
+  margin-bottom: 15px;
+  color: #303133;
+}
+
+.weight-distribution {
+  padding: 10px 0;
+}
+
+.factor-item {
+  display: flex;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.factor-name {
+  width: 120px;
+  color: #606266;
+  font-size: 14px;
+}
+
+.factor-item .el-progress {
+  flex: 1;
+  margin: 0 15px;
+}
+
+.factor-percent {
+  width: 40px;
+  text-align: right;
+  color: #909399;
+  font-size: 12px;
+}
+</style>
diff --git a/src/views/business/course/components/OrganProcurementStage.vue b/src/views/business/course/components/OrganProcurementStage.vue
new file mode 100644
index 0000000..1b8a555
--- /dev/null
+++ b/src/views/business/course/components/OrganProcurementStage.vue
@@ -0,0 +1,499 @@
+<template>
+  <base-stage :stage-data="stageData" :case-info="caseInfo">
+    <template #header>
+      <el-alert
+        :title="`鍣ㄥ畼鑾峰彇 - ${getStatusText()}`"
+        :type="getAlertType()"
+        :description="getAlertDescription()"
+        show-icon
+        :closable="false"
+      />
+    </template>
+
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鑾峰彇鎵嬫湳淇℃伅</span>
+          </div>
+          <el-descriptions :column="1" border size="small">
+            <el-descriptions-item label="鎵嬫湳鏃堕棿">
+              {{ formatTime(procurementDetails.surgeryTime) }}
+            </el-descriptions-item>
+            <el-descriptions-item label="鎵嬫湳鍦扮偣">
+              {{ procurementDetails.location }}
+            </el-descriptions-item>
+            <el-descriptions-item label="涓诲垁鍖荤敓">
+              {{ procurementDetails.surgeon }}
+            </el-descriptions-item>
+            <el-descriptions-item label="楹婚唹鍖荤敓">
+              {{ procurementDetails.anesthesiologist }}
+            </el-descriptions-item>
+            <el-descriptions-item label="鎵嬫湳鐘舵��">
+              <el-tag :type="procurementDetails.status === 'completed' ? 'success' : 'warning'">
+                {{ procurementDetails.status === 'completed' ? '宸插畬鎴�' : '杩涜涓�' }}
+              </el-tag>
+            </el-descriptions-item>
+          </el-descriptions>
+        </el-card>
+      </el-col>
+
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鍣ㄥ畼鑾峰彇缁熻</span>
+          </div>
+          <div class="procurement-stats">
+            <div class="stat-item">
+              <span class="label">璁″垝鑾峰彇:</span>
+              <span class="value">{{ procurementStats.planned }} 涓�</span>
+            </div>
+            <div class="stat-item">
+              <span class="label">瀹為檯鑾峰彇:</span>
+              <span class="value">{{ procurementStats.actual }} 涓�</span>
+            </div>
+            <div class="stat-item">
+              <span class="label">鑾峰彇鎴愬姛鐜�:</span>
+              <el-progress
+                :percentage="procurementStats.successRate"
+                :status="procurementStats.successRate > 90 ? 'success' : 'warning'"
+              />
+            </div>
+            <div class="stat-item">
+              <span class="label">璐ㄩ噺璇勪及:</span>
+              <el-rate
+                v-model="procurementStats.qualityRating"
+                disabled
+                show-score
+                text-color="#ff9900"
+                score-template="{value} 鏄�"
+              />
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="8">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>淇濆瓨涓庤繍杈�</span>
+          </div>
+          <div class="preservation-info">
+            <div class="info-item">
+              <span class="label">淇濆瓨鏂瑰紡:</span>
+              <span>{{ preservationDetails.method }}</span>
+            </div>
+            <div class="info-item">
+              <span class="label">淇濆瓨娓╁害:</span>
+              <span>{{ preservationDetails.temperature }}</span>
+            </div>
+            <div class="info-item">
+              <span class="label">鐏屾敞娑�:</span>
+              <span>{{ preservationDetails.perfusionSolution }}</span>
+            </div>
+            <div class="info-item">
+              <span class="label">棰勮瀛樻椿鏃堕棿:</span>
+              <el-tag :type="getSurvivalTimeType()">
+                {{ preservationDetails.survivalTime }}
+              </el-tag>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>鍣ㄥ畼鑾峰彇璇︽儏</span>
+        <el-button type="primary" size="small" @click="handleStartProcurement">
+          寮�濮嬭幏鍙栨墜鏈�
+        </el-button>
+      </div>
+      <el-table :data="organProcurementData" border>
+        <el-table-column label="鍣ㄥ畼鍚嶇О" prop="organName" width="120" align="center" />
+        <el-table-column label="鑾峰彇鐘舵��" width="100" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="getProcurementStatusTag(scope.row.status)">
+              {{ scope.row.status }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鑾峰彇鏃堕棿" width="160" align="center">
+          <template slot-scope="scope">
+            {{ formatTime(scope.row.procurementTime) || '-' }}
+          </template>
+        </el-table-column>
+        <el-table-column label="閲嶉噺(g)" prop="weight" width="100" align="center" />
+        <el-table-column label="璐ㄩ噺璇勪及" width="120" align="center">
+          <template slot-scope="scope">
+            <el-rate
+              v-model="scope.row.qualityScore"
+              disabled
+              show-score
+              text-color="#ff9900"
+              score-template="{value}"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="鐏屾敞鎯呭喌" width="100" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.perfusionStatus ? 'success' : 'warning'">
+              {{ scope.row.perfusionStatus ? '宸插畬鎴�' : '寰呯亴娉�' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="淇濆瓨鏂瑰紡" prop="preservationMethod" width="120" />
+        <el-table-column label="鎿嶄綔" width="150" align="center">
+          <template slot-scope="scope">
+            <el-button type="text" size="small" @click="handleViewOrgan(scope.row)">
+              鏌ョ湅璇︽儏
+            </el-button>
+            <el-button
+              v-if="scope.row.status !== '宸茶幏鍙�'"
+              type="text"
+              size="small"
+              @click="handleRecordProcurement(scope.row)"
+            >
+              璁板綍鑾峰彇
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>鎵嬫湳璁板綍涓庡奖鍍�</span>
+      </div>
+      <el-tabs v-model="activeMedicalTab">
+        <el-tab-pane label="鎵嬫湳璁板綍" name="surgeryRecord">
+          <div class="surgery-record">
+            <el-timeline>
+              <el-timeline-item
+                v-for="record in surgeryRecords"
+                :key="record.time"
+                :timestamp="formatTime(record.time)"
+                :type="record.type"
+                :icon="record.icon"
+              >
+                <p>{{ record.content }}</p>
+                <div v-if="record.images && record.images.length > 0" class="record-images">
+                  <el-image
+                    v-for="(img, index) in record.images"
+                    :key="index"
+                    :src="img"
+                    :preview-src-list="record.images"
+                    style="width: 100px; height: 100px; margin-right: 10px;"
+                  />
+                </div>
+              </el-timeline-item>
+            </el-timeline>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane label="鍣ㄥ畼褰卞儚" name="organImages">
+          <div class="organ-images">
+            <el-row :gutter="15">
+              <el-col v-for="organ in organImages" :key="organ.name" :span="8">
+                <el-card shadow="hover">
+                  <div slot="header" class="image-header">
+                    <span>{{ organ.name }}</span>
+                  </div>
+                  <el-image
+                    :src="organ.image"
+                    :preview-src-list="[organ.image]"
+                    fit="cover"
+                    style="width: 100%; height: 200px;"
+                  />
+                  <div style="padding: 10px;">
+                    <p>{{ organ.description }}</p>
+                    <el-tag size="small">{{ organ.status }}</el-tag>
+                  </div>
+                </el-card>
+              </el-col>
+            </el-row>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane label="璐ㄩ噺妫�娴嬫姤鍛�" name="qualityReport">
+          <div class="quality-report">
+            <el-table :data="qualityReports" border>
+              <el-table-column label="妫�娴嬮」鐩�" prop="item" width="150" />
+              <el-table-column label="妫�娴嬬粨鏋�" prop="result" width="120">
+                <template slot-scope="scope">
+                  <el-tag :type="scope.row.pass ? 'success' : 'danger'">
+                    {{ scope.row.pass ? '鍚堟牸' : '涓嶅悎鏍�' }}
+                  </el-tag>
+                </template>
+              </el-table-column>
+              <el-table-column label="鍙傝�冭寖鍥�" prop="reference" width="120" />
+              <el-table-column label="妫�娴嬪��" prop="value" width="100" />
+              <el-table-column label="妫�娴嬫椂闂�" width="160">
+                <template slot-scope="scope">
+                  {{ formatTime(scope.row.testTime) }}
+                </template>
+              </el-table-column>
+              <el-table-column label="妫�娴嬪尰鐢�" prop="doctor" width="120" />
+            </el-table>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+
+    <template #footer>
+      <div class="action-buttons" style="margin-top: 20px; text-align: center;">
+        <el-button type="primary" @click="handleCompleteProcurement">
+          瀹屾垚鍣ㄥ畼鑾峰彇
+        </el-button>
+        <el-button type="success" @click="handleGenerateReport">
+          鐢熸垚鑾峰彇鎶ュ憡
+        </el-button>
+        <el-button type="warning" @click="handleUploadEvidence">
+          涓婁紶鎵嬫湳璇佹嵁
+        </el-button>
+      </div>
+    </template>
+  </base-stage>
+</template>
+
+<script>
+import BaseStage from './BaseStage.vue';
+
+export default {
+  name: 'OrganProcurementStage',
+  components: { BaseStage },
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      activeMedicalTab: 'surgeryRecord',
+      procurementDetails: {
+        surgeryTime: '2023-12-04 14:00:00',
+        location: '鎵嬫湳瀹や竴鍙�',
+        surgeon: '寮犱富浠�',
+        anesthesiologist: '鐜嬪尰鐢�',
+        status: 'in_progress'
+      },
+      procurementStats: {
+        planned: 3,
+        actual: 0,
+        successRate: 0,
+        qualityRating: 0
+      },
+      preservationDetails: {
+        method: '浣庢俯鏈烘鐏屾敞[9](@ref)',
+        temperature: '4掳C',
+        perfusionSolution: 'UW淇濆瓨娑�',
+        survivalTime: '鑲濊剰12灏忔椂[1](@ref)'
+      },
+      organProcurementData: [
+        {
+          organName: '鑲濊剰',
+          status: '鑾峰彇涓�',
+          procurementTime: '',
+          weight: 1500,
+          qualityScore: 0,
+          perfusionStatus: false,
+          preservationMethod: '浣庢俯淇濆瓨'
+        },
+        {
+          organName: '鑲捐剰',
+          status: '寰呰幏鍙�',
+          procurementTime: '',
+          weight: 0,
+          qualityScore: 0,
+          perfusionStatus: false,
+          preservationMethod: ''
+        },
+        {
+          organName: '蹇冭剰',
+          status: '寰呰幏鍙�',
+          procurementTime: '',
+          weight: 0,
+          qualityScore: 0,
+          perfusionStatus: false,
+          preservationMethod: ''
+        }
+      ],
+      surgeryRecords: [
+        {
+          time: '2023-12-04 14:00:00',
+          content: '鎵嬫湳寮�濮嬶紝鎮h�呬綋浣嶆憜鏀撅紝娑堟瘨閾哄肪',
+          type: 'primary',
+          icon: 'el-icon-video-play'
+        },
+        {
+          time: '2023-12-04 14:30:00',
+          content: '寮�鑵规墜鏈紝鏆撮湶鑵硅厰鍣ㄥ畼',
+          type: 'success',
+          icon: 'el-icon-scissors'
+        },
+        {
+          time: '2023-12-04 15:00:00',
+          content: '鑲濊剰娓哥锛岃绠¤В鍓栧垎绂�',
+          type: 'warning',
+          icon: 'el-icon-medal'
+        }
+      ],
+      organImages: [
+        {
+          name: '鑲濊剰',
+          image: '/images/liver-procurement.jpg',
+          description: '鑾峰彇鐨勮倽鑴忓櫒瀹橈紝褰㈡�佸畬鏁�',
+          status: '璐ㄩ噺鑹ソ'
+        }
+      ],
+      qualityReports: [
+        {
+          item: '鑲濆姛鑳介叾瀛�',
+          result: true,
+          reference: '<40 U/L',
+          value: '35 U/L',
+          testTime: '2023-12-04 16:00:00',
+          doctor: '鏉庢楠屽笀'
+        },
+        {
+          item: '缁勭粐瀹屾暣鎬�',
+          result: true,
+          reference: '瀹屾暣',
+          value: '瀹屾暣',
+          testTime: '2023-12-04 16:15:00',
+          doctor: '寮犵梾鐞嗗笀'
+        }
+      ]
+    };
+  },
+  methods: {
+    getStatusText() {
+      const status = this.stageData.status;
+      return status === 'completed' ? '宸插畬鎴�' :
+             status === 'in_progress' ? '杩涜涓�' : '鏈紑濮�';
+    },
+    getAlertType() {
+      const status = this.stageData.status;
+      return status === 'completed' ? 'success' :
+             status === 'in_progress' ? 'warning' : 'info';
+    },
+    getAlertDescription() {
+      const status = this.stageData.status;
+      if (status === 'completed') {
+        return '鍣ㄥ畼鑾峰彇鎵嬫湳宸插畬鎴愶紝鎵�鏈夊櫒瀹樺潎宸叉垚鍔熻幏鍙栧苟淇濆瓨';
+      } else if (status === 'in_progress') {
+        return '鍣ㄥ畼鑾峰彇鎵嬫湳杩涜涓紝璇峰瘑鍒囧叧娉ㄦ墜鏈繘灞�';
+      }
+      return '绛夊緟寮�濮嬪櫒瀹樿幏鍙栨墜鏈�';
+    },
+    getProcurementStatusTag(status) {
+      const map = {
+        '宸茶幏鍙�': 'success',
+        '鑾峰彇涓�': 'warning',
+        '寰呰幏鍙�': 'info'
+      };
+      return map[status] || 'info';
+    },
+    getSurvivalTimeType() {
+      return this.preservationDetails.survivalTime.includes('灏忔椂') ? 'success' : 'danger';
+    },
+    handleStartProcurement() {
+      this.$confirm('纭寮�濮嬪櫒瀹樿幏鍙栨墜鏈悧锛�', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.$message.success('鍣ㄥ畼鑾峰彇鎵嬫湳宸插紑濮�');
+      });
+    },
+    handleRecordProcurement(row) {
+      this.$prompt('璇疯緭鍏ュ櫒瀹橀噸閲�(g)', '璁板綍鍣ㄥ畼鑾峰彇', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        inputPattern: /^\d+$/,
+        inputErrorMessage: '璇疯緭鍏ユ湁鏁堢殑閲嶉噺鏁板瓧'
+      }).then(({ value }) => {
+        row.status = '宸茶幏鍙�';
+        row.procurementTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
+        row.weight = parseInt(value);
+        row.qualityScore = 4.5;
+        row.perfusionStatus = true;
+
+        this.procurementStats.actual++;
+        this.procurementStats.successRate = Math.round(
+          (this.procurementStats.actual / this.procurementStats.planned) * 100
+        );
+        this.procurementStats.qualityRating = 4.2;
+
+        this.$message.success(`${row.organName}鑾峰彇璁板綍宸蹭繚瀛榒);
+      });
+    },
+    handleViewOrgan(row) {
+      this.$message.info(`鏌ョ湅${row.organName}鐨勮缁嗕俊鎭痐);
+    },
+    handleCompleteProcurement() {
+      this.$confirm('纭瀹屾垚鎵�鏈夊櫒瀹樿幏鍙栧悧锛�', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'success'
+      }).then(() => {
+        this.$message.success('鍣ㄥ畼鑾峰彇闃舵宸插畬鎴�');
+      });
+    },
+    handleGenerateReport() {
+      this.$message.info('鐢熸垚鍣ㄥ畼鑾峰彇鎶ュ憡');
+    },
+    handleUploadEvidence() {
+      this.$message.info('涓婁紶鎵嬫湳璇佹嵁鏉愭枡');
+    }
+  }
+};
+</script>
+
+<style scoped>
+.procurement-stats, .preservation-info {
+  padding: 10px 0;
+}
+
+.stat-item, .info-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding: 8px 0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.stat-item .label, .info-item .label {
+  color: #606266;
+  font-weight: 500;
+  min-width: 100px;
+}
+
+.stat-item .value {
+  font-weight: 600;
+  color: #409EFF;
+}
+
+.surgery-record {
+  padding: 20px;
+}
+
+.record-images {
+  margin-top: 10px;
+}
+
+.image-header {
+  font-weight: 600;
+  color: #303133;
+}
+
+.quality-report {
+  padding: 10px 0;
+}
+</style>
diff --git a/src/views/business/course/components/OrganUtilizationStage.vue b/src/views/business/course/components/OrganUtilizationStage.vue
new file mode 100644
index 0000000..95fbb77
--- /dev/null
+++ b/src/views/business/course/components/OrganUtilizationStage.vue
@@ -0,0 +1,812 @@
+<template>
+  <base-stage :stage-data="stageData" :case-info="caseInfo">
+    <!-- 澶撮儴璀﹀憡淇℃伅 -->
+    <template #header>
+      <el-alert
+        :title="`鍣ㄥ畼鍒╃敤 - ${getStatusText()}`"
+        :type="getAlertType()"
+        :description="getAlertDescription()"
+        show-icon
+        :closable="false"
+      />
+    </template>
+
+    <!-- 缁熻姒傝琛� -->
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <el-col :span="6">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鍒╃敤姒傚喌</span>
+          </div>
+          <div class="utilization-overview">
+            <div class="overview-item">
+              <div class="overview-icon" style="color: #67C23A;">
+                <i class="el-icon-success"></i>
+              </div>
+              <div class="overview-content">
+                <div class="value">{{ utilizationStats.transplanted }}</div>
+                <div class="label">宸茬Щ妞嶅櫒瀹�</div>
+              </div>
+            </div>
+            <div class="overview-item">
+              <div class="overview-icon" style="color: #E6A23C;">
+                <i class="el-icon-time"></i>
+              </div>
+              <div class="overview-content">
+                <div class="value">{{ utilizationStats.inProgress }}</div>
+                <div class="label">绉绘涓�</div>
+              </div>
+            </div>
+            <div class="overview-item">
+              <div class="overview-icon" style="color: #F56C6C;">
+                <i class="el-icon-warning"></i>
+              </div>
+              <div class="overview-content">
+                <div class="value">{{ utilizationStats.failed }}</div>
+                <div class="label">绉绘澶辫触</div>
+              </div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="6">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鎴愬姛鐜囩粺璁�</span>
+          </div>
+          <div class="success-stats">
+            <div class="success-item">
+              <span class="label">绉绘鎴愬姛鐜�:</span>
+              <el-progress
+                :percentage="utilizationStats.successRate"
+                :status="utilizationStats.successRate > 85 ? 'success' : 'warning'"
+              />
+            </div>
+            <div class="success-item">
+              <span class="label">鍣ㄥ畼鍒╃敤鐜�:</span>
+              <el-progress
+                :percentage="utilizationStats.utilizationRate"
+                status="success"
+              />
+            </div>
+            <div class="success-item">
+              <span class="label">鎮h�呭瓨娲荤巼:</span>
+              <el-progress
+                :percentage="utilizationStats.survivalRate"
+                status="success"
+              />
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="6">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鏃堕棿璺熻釜</span>
+          </div>
+          <div class="time-tracking">
+            <div class="time-item">
+              <span class="label">鑾峰彇鍒扮Щ妞�:</span>
+              <span class="value">{{ timeTracking.procurementToTransplant }}</span>
+            </div>
+            <div class="time-item">
+              <span class="label">鍐风己琛�鏃堕棿:</span>
+              <span class="value">{{ timeTracking.coldIschemiaTime }}</span>
+            </div>
+            <div class="time-item">
+              <span class="label">鎵嬫湳鏃堕暱:</span>
+              <span class="value">{{ timeTracking.surgeryDuration }}</span>
+            </div>
+            <div class="time-item">
+              <span class="label">ICU鍋滅暀:</span>
+              <span class="value">{{ timeTracking.icuStay }}</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <el-col :span="6">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>璐ㄩ噺璇勪及</span>
+          </div>
+          <div class="quality-assessment">
+            <div class="quality-item">
+              <span class="label">鍣ㄥ畼璐ㄩ噺璇勫垎:</span>
+              <el-rate
+                v-model="qualityStats.organQuality"
+                disabled
+                show-score
+                text-color="#ff9900"
+                score-template="{value}"
+              />
+            </div>
+            <div class="quality-item">
+              <span class="label">鎵嬫湳璐ㄩ噺:</span>
+              <el-rate
+                v-model="qualityStats.surgeryQuality"
+                disabled
+                show-score
+                text-color="#ff9900"
+                score-template="{value}"
+              />
+            </div>
+            <div class="quality-item">
+              <span class="label">闅忚瀹屾垚鐜�:</span>
+              <el-progress
+                :percentage="qualityStats.followupCompletionRate"
+                status="success"
+              />
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 鏁版嵁鍙鍖栭儴鍒� -->
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <!-- 鍣ㄥ畼鍒╃敤鍒嗗竷鍥� -->
+      <el-col :span="12">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>鍣ㄥ畼鍒╃敤鍒嗗竷</span>
+            <el-radio-group v-model="chartView" size="small" @change="updateCharts">
+              <el-radio-button label="bar">鏌辩姸鍥�</el-radio-button>
+              <el-radio-button label="pie">楗煎浘</el-radio-button>
+            </el-radio-group>
+          </div>
+          <div class="chart-container">
+            <div ref="organDistributionChart" style="width: 100%; height: 300px;"></div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <!-- 鎴愬姛鐜囪秼鍔垮浘 -->
+      <el-col :span="12">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>绉绘鎴愬姛鐜囪秼鍔�</span>
+          </div>
+          <div class="chart-container">
+            <div ref="successTrendChart" style="width: 100%; height: 300px;"></div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-row :gutter="20" style="margin-top: 20px;">
+      <!-- 闅忚鏁版嵁缁熻 -->
+      <el-col :span="12">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>闅忚鏁版嵁缁熻</span>
+          </div>
+          <div class="chart-container">
+            <div ref="followupStatsChart" style="width: 100%; height: 300px;"></div>
+          </div>
+        </el-card>
+      </el-col>
+
+      <!-- 骞跺彂鐥囧垎鏋� -->
+      <el-col :span="12">
+        <el-card>
+          <div slot="header" class="card-header">
+            <span>骞跺彂鐥囧垎鏋�</span>
+          </div>
+          <div class="chart-container">
+            <div ref="complicationChart" style="width: 100%; height: 300px;"></div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 璇︾粏鏁版嵁琛ㄦ牸 -->
+    <el-card style="margin-top: 20px;">
+      <div slot="header" class="card-header">
+        <span>鍣ㄥ畼鍒╃敤璇︽儏</span>
+        <el-button type="primary" size="small" @click="exportData">
+          瀵煎嚭鏁版嵁
+        </el-button>
+      </div>
+
+      <el-table :data="organUtilizationData" v-loading="loading" border>
+        <el-table-column label="鍣ㄥ畼鍚嶇О" prop="organName" width="120" align="center" />
+        <el-table-column label="绉绘鐘舵��" width="100" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="getTransplantStatusTag(scope.row.status)">
+              {{ scope.row.status }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍙椾綋淇℃伅" width="150">
+          <template slot-scope="scope">
+            <div>{{ scope.row.recipientName }}</div>
+            <div style="font-size: 12px; color: #909399;">{{ scope.row.recipientAge }}宀�/{{ scope.row.recipientGender }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="绉绘鍖婚櫌" prop="hospital" min-width="180" />
+        <el-table-column label="绉绘鏃堕棿" width="160" align="center">
+          <template slot-scope="scope">
+            {{ formatTime(scope.row.transplantTime) }}
+          </template>
+        </el-table-column>
+        <el-table-column label="闅忚娆℃暟" width="100" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.followupCount > 0 ? 'success' : 'info'">
+              {{ scope.row.followupCount }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="褰撳墠鐘舵��" width="120" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="getRecipientStatusTag(scope.row.recipientStatus)">
+              {{ scope.row.recipientStatus }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鎿嶄綔" width="150" align="center">
+          <template slot-scope="scope">
+            <el-button type="text" size="small" @click="handleViewDetails(scope.row)">
+              鏌ョ湅璇︽儏
+            </el-button>
+            <el-button type="text" size="small" @click="handleAddFollowup(scope.row)">
+              娣诲姞闅忚
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <!-- 琛屽姩鎸夐挳 -->
+    <template #footer>
+      <div class="action-buttons" style="margin-top: 20px; text-align: center;">
+        <el-button type="primary" @click="handleGenerateReport">
+          鐢熸垚鍒╃敤鎶ュ憡
+        </el-button>
+        <el-button type="success" @click="handleCompleteUtilization">
+          瀹屾垚鍣ㄥ畼鍒╃敤
+        </el-button>
+        <el-button type="warning" @click="handleStatistics">
+          缁熻鏁版嵁鍒嗘瀽
+        </el-button>
+      </div>
+    </template>
+  </base-stage>
+</template>
+
+<script>
+import BaseStage from './BaseStage.vue';
+import * as echarts from 'echarts';
+
+export default {
+  name: 'OrganUtilizationStage',
+  components: { BaseStage },
+  props: {
+    stageData: {
+      type: Object,
+      default: () => ({})
+    },
+    caseInfo: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data() {
+    return {
+      chartView: 'bar',
+      loading: false,
+      utilizationStats: {
+        transplanted: 3,
+        inProgress: 0,
+        failed: 0,
+        successRate: 95,
+        utilizationRate: 100,
+        survivalRate: 92
+      },
+      timeTracking: {
+        procurementToTransplant: '4.5灏忔椂',
+        coldIschemiaTime: '鑲濊剰:6h,鑲捐剰:8h,蹇冭剰:3h',
+        surgeryDuration: '鑲濊剰:4h,鑲捐剰:3h,蹇冭剰:5h',
+        icuStay: '鑲濊剰:3澶�,鑲捐剰:2澶�,蹇冭剰:5澶�'
+      },
+      qualityStats: {
+        organQuality: 4.5,
+        surgeryQuality: 4.8,
+        followupCompletionRate: 85
+      },
+      organUtilizationData: [
+        {
+          organName: '鑲濊剰',
+          status: '绉绘鎴愬姛',
+          recipientName: '鐜嬪厛鐢�',
+          recipientAge: 45,
+          recipientGender: '鐢�',
+          hospital: '鍖椾含鍗忓拰鍖婚櫌绉绘涓績',
+          transplantTime: '2023-12-04 16:00:00',
+          followupCount: 3,
+          recipientStatus: '鎭㈠鑹ソ'
+        },
+        {
+          organName: '鑲捐剰',
+          status: '绉绘鎴愬姛',
+          recipientName: '鏉庡コ澹�',
+          recipientAge: 38,
+          recipientGender: '濂�',
+          hospital: '涓婃捣鐟為噾鍖婚櫌绉绘涓績',
+          transplantTime: '2023-12-04 17:30:00',
+          followupCount: 2,
+          recipientStatus: '绋冲畾鎭㈠'
+        },
+        {
+          organName: '蹇冭剰',
+          status: '绉绘鎴愬姛',
+          recipientName: '闄堝厛鐢�',
+          recipientAge: 52,
+          recipientGender: '鐢�',
+          hospital: '骞垮窞涓北鍖婚櫌蹇冭剰涓績',
+          transplantTime: '2023-12-04 18:15:00',
+          followupCount: 1,
+          recipientStatus: '瀵嗗垏瑙傚療'
+        }
+      ],
+      // 鍥捐〃瀹炰緥
+      organDistributionChart: null,
+      successTrendChart: null,
+      followupStatsChart: null,
+      complicationChart: null
+    };
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.initCharts();
+    });
+  },
+  beforeDestroy() {
+    // 閿�姣佸浘琛ㄥ疄渚�
+    if (this.organDistributionChart) {
+      this.organDistributionChart.dispose();
+    }
+    if (this.successTrendChart) {
+      this.successTrendChart.dispose();
+    }
+    if (this.followupStatsChart) {
+      this.followupStatsChart.dispose();
+    }
+    if (this.complicationChart) {
+      this.complicationChart.dispose();
+    }
+  },
+  methods: {
+    // 鍒濆鍖栧浘琛�
+    initCharts() {
+      this.initOrganDistributionChart();
+      this.initSuccessTrendChart();
+      this.initFollowupStatsChart();
+      this.initComplicationChart();
+    },
+
+    // 鍒濆鍖栧櫒瀹樺垎甯冨浘琛�
+    initOrganDistributionChart() {
+      this.organDistributionChart = echarts.init(this.$refs.organDistributionChart);
+      const option = {
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b}: {c} ({d}%)'
+        },
+        legend: {
+          orient: 'vertical',
+          right: 10,
+          top: 'center',
+          data: ['鑲濊剰', '鑲捐剰', '蹇冭剰', '鑲鸿剰', '瑙掕啘', '鍏朵粬']
+        },
+        series: [
+          {
+            name: '鍣ㄥ畼鍒╃敤',
+            type: 'pie',
+            radius: ['50%', '70%'],
+            avoidLabelOverlap: false,
+            label: {
+              show: false,
+              position: 'center'
+            },
+            emphasis: {
+              label: {
+                show: true,
+                fontSize: '18',
+                fontWeight: 'bold'
+              }
+            },
+            labelLine: {
+              show: false
+            },
+            data: [
+              { value: 35, name: '鑲濊剰' },
+              { value: 30, name: '鑲捐剰' },
+              { value: 15, name: '蹇冭剰' },
+              { value: 10, name: '鑲鸿剰' },
+              { value: 8, name: '瑙掕啘' },
+              { value: 2, name: '鍏朵粬' }
+            ]
+          }
+        ]
+      };
+      this.organDistributionChart.setOption(option);
+    },
+
+    // 鍒濆鍖栨垚鍔熺巼瓒嬪娍鍥捐〃
+    initSuccessTrendChart() {
+      this.successTrendChart = echarts.init(this.$refs.successTrendChart);
+      const option = {
+        tooltip: {
+          trigger: 'axis'
+        },
+        legend: {
+          data: ['鑲濊剰绉绘', '鑲捐剰绉绘', '蹇冭剰绉绘', '骞冲潎鎴愬姛鐜�']
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          boundaryGap: false,
+          data: ['1鏈�', '2鏈�', '3鏈�', '4鏈�', '5鏈�', '6鏈�', '7鏈�']
+        },
+        yAxis: {
+          type: 'value',
+          min: 80,
+          max: 100
+        },
+        series: [
+          {
+            name: '鑲濊剰绉绘',
+            type: 'line',
+            smooth: true,
+            data: [92, 93, 94, 95, 96, 95, 96]
+          },
+          {
+            name: '鑲捐剰绉绘',
+            type: 'line',
+            smooth: true,
+            data: [94, 95, 95, 96, 95, 96, 97]
+          },
+          {
+            name: '蹇冭剰绉绘',
+            type: 'line',
+            smooth: true,
+            data: [88, 89, 90, 91, 92, 91, 92]
+          },
+          {
+            name: '骞冲潎鎴愬姛鐜�',
+            type: 'line',
+            smooth: true,
+            lineStyle: {
+              type: 'dashed'
+            },
+            data: [91.3, 92.3, 93, 94, 94.3, 94, 95]
+          }
+        ]
+      };
+      this.successTrendChart.setOption(option);
+    },
+
+    // 鍒濆鍖栭殢璁跨粺璁″浘琛�
+    initFollowupStatsChart() {
+      this.followupStatsChart = echarts.init(this.$refs.followupStatsChart);
+      const option = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        legend: {
+          data: ['璁″垝闅忚', '宸插畬鎴�', '閫炬湡鏈畬鎴�']
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'value'
+        },
+        yAxis: {
+          type: 'category',
+          data: ['1涓湀', '3涓湀', '6涓湀', '1骞�', '2骞�', '5骞�']
+        },
+        series: [
+          {
+            name: '璁″垝闅忚',
+            type: 'bar',
+            stack: 'total',
+            label: {
+              show: true
+            },
+            emphasis: {
+              focus: 'series'
+            },
+            data: [120, 132, 101, 134, 90, 60]
+          },
+          {
+            name: '宸插畬鎴�',
+            type: 'bar',
+            stack: 'total',
+            label: {
+              show: true
+            },
+            emphasis: {
+              focus: 'series'
+            },
+            data: [115, 125, 95, 120, 85, 55]
+          },
+          {
+            name: '閫炬湡鏈畬鎴�',
+            type: 'bar',
+            stack: 'total',
+            label: {
+              show: true
+            },
+            emphasis: {
+              focus: 'series'
+            },
+            data: [5, 7, 6, 14, 5, 5]
+          }
+        ]
+      };
+      this.followupStatsChart.setOption(option);
+    },
+
+    // 鍒濆鍖栧苟鍙戠棁鍒嗘瀽鍥捐〃
+    initComplicationChart() {
+      this.complicationChart = echarts.init(this.$refs.complicationChart);
+      const option = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        radar: {
+          indicator: [
+            { name: '鎰熸煋椋庨櫓', max: 100 },
+            { name: '鎺掓枼鍙嶅簲', max: 100 },
+            { name: '琛�绠″苟鍙戠棁', max: 100 },
+            { name: '鑳嗛亾骞跺彂鐥�', max: 100 },
+            { name: '浠h阿寮傚父', max: 100 },
+            { name: '鍏朵粬骞跺彂鐥�', max: 100 }
+          ]
+        },
+        series: [
+          {
+            type: 'radar',
+            data: [
+              {
+                value: [85, 90, 78, 82, 75, 70],
+                name: '鑲濊剰绉绘',
+                areaStyle: {}
+              },
+              {
+                value: [78, 85, 72, 65, 80, 68],
+                name: '鑲捐剰绉绘',
+                areaStyle: {}
+              },
+              {
+                value: [90, 88, 85, 60, 82, 75],
+                name: '蹇冭剰绉绘',
+                areaStyle: {}
+              }
+            ]
+          }
+        ]
+      };
+      this.complicationChart.setOption(option);
+    },
+
+    // 鏇存柊鍥捐〃瑙嗗浘
+    updateCharts() {
+      if (this.chartView === 'bar') {
+        this.updateToBarChart();
+      } else {
+        this.initOrganDistributionChart(); // 鍒囧洖楗煎浘
+      }
+    },
+
+    // 鏇存柊涓烘煴鐘跺浘
+    updateToBarChart() {
+      const option = {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          data: ['鑲濊剰', '鑲捐剰', '蹇冭剰', '鑲鸿剰', '瑙掕啘', '鍏朵粬']
+        },
+        yAxis: {
+          type: 'value',
+          name: '鏁伴噺'
+        },
+        series: [
+          {
+            name: '鍣ㄥ畼鍒╃敤鏁伴噺',
+            type: 'bar',
+            data: [35, 30, 15, 10, 8, 2],
+            itemStyle: {
+              color: function(params) {
+                const colorList = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272'];
+                return colorList[params.dataIndex];
+              }
+            }
+          }
+        ]
+      };
+      this.organDistributionChart.setOption(option);
+    },
+
+    // 鑾峰彇鐘舵�佹枃鏈�
+    getStatusText() {
+      const status = this.stageData.status;
+      return status === 'completed' ? '宸插畬鎴�' :
+             status === 'in_progress' ? '杩涜涓�' : '鏈紑濮�';
+    },
+
+    // 鑾峰彇璀﹀憡绫诲瀷
+    getAlertType() {
+      const status = this.stageData.status;
+      return status === 'completed' ? 'success' :
+             status === 'in_progress' ? 'warning' : 'info';
+    },
+
+    // 鑾峰彇璀﹀憡鎻忚堪
+    getAlertDescription() {
+      const status = this.stageData.status;
+      if (status === 'completed') {
+        return '鍣ㄥ畼鍒╃敤闃舵宸插畬鎴愶紝鎵�鏈夊櫒瀹樺潎宸叉垚鍔熺Щ妞嶅苟寮�濮嬮殢璁�';
+      } else if (status === 'in_progress') {
+        return '鍣ㄥ畼鍒╃敤杩涜涓紝绉绘鎵嬫湳宸插畬鎴愶紝姝e湪杩涜鏈悗闅忚';
+      }
+      return '绛夊緟寮�濮嬪櫒瀹樺埄鐢ㄦ祦绋�';
+    },
+
+    // 鑾峰彇绉绘鐘舵�佹爣绛�
+    getTransplantStatusTag(status) {
+      const map = {
+        '绉绘鎴愬姛': 'success',
+        '绉绘涓�': 'warning',
+        '绉绘澶辫触': 'danger'
+      };
+      return map[status] || 'info';
+    },
+
+    // 鑾峰彇鍙椾綋鐘舵�佹爣绛�
+    getRecipientStatusTag(status) {
+      const map = {
+        '鎭㈠鑹ソ': 'success',
+        '绋冲畾鎭㈠': 'warning',
+        '瀵嗗垏瑙傚療': 'danger'
+      };
+      return map[status] || 'info';
+    },
+
+    // 鏌ョ湅璇︽儏
+    handleViewDetails(row) {
+      this.$message.info(`鏌ョ湅${row.organName}绉绘璇︽儏`);
+    },
+
+    // 娣诲姞闅忚
+    handleAddFollowup(row) {
+      this.$message.info(`涓�${row.recipientName}娣诲姞闅忚璁板綍`);
+    },
+
+    // 鐢熸垚鎶ュ憡
+    handleGenerateReport() {
+      this.$message.info('鐢熸垚鍣ㄥ畼鍒╃敤鍒嗘瀽鎶ュ憡');
+    },
+
+    // 瀹屾垚鍒╃敤
+    handleCompleteUtilization() {
+      this.$confirm('纭瀹屾垚鍣ㄥ畼鍒╃敤闃舵鍚楋紵', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'success'
+      }).then(() => {
+        this.$message.success('鍣ㄥ畼鍒╃敤闃舵宸插畬鎴�');
+      });
+    },
+
+    // 缁熻鏁版嵁鍒嗘瀽
+    handleStatistics() {
+      this.$message.info('鎵撳紑缁熻鍒嗘瀽闈㈡澘');
+    },
+
+    // 瀵煎嚭鏁版嵁
+    exportData() {
+      this.$message.info('瀵煎嚭鍣ㄥ畼鍒╃敤鏁版嵁');
+    }
+  }
+};
+</script>
+
+<style scoped>
+.utilization-overview {
+  padding: 10px 0;
+}
+
+.overview-item {
+  display: flex;
+  align-items: center;
+  margin-bottom: 15px;
+  padding: 8px 0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.overview-icon {
+  font-size: 24px;
+  margin-right: 15px;
+}
+
+.overview-content .value {
+  font-size: 24px;
+  font-weight: bold;
+  color: #303133;
+}
+
+.overview-content .label {
+  font-size: 12px;
+  color: #909399;
+}
+
+.success-stats, .time-tracking, .quality-assessment {
+  padding: 10px 0;
+}
+
+.success-item, .time-item, .quality-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.success-item .label, .time-item .label, .quality-item .label {
+  color: #606266;
+  font-size: 14px;
+  min-width: 80px;
+}
+
+.time-item .value {
+  font-weight: 600;
+  color: #409EFF;
+}
+
+.chart-container {
+  position: relative;
+  min-height: 300px;
+}
+
+.action-buttons {
+  display: flex;
+  justify-content: center;
+  gap: 15px;
+  margin-top: 20px;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+</style>
diff --git a/src/views/business/course/donationProcess.js b/src/views/business/course/donationProcess.js
new file mode 100644
index 0000000..a70096e
--- /dev/null
+++ b/src/views/business/course/donationProcess.js
@@ -0,0 +1,453 @@
+// 妯℃嫙鎹愮尞杩涚▼鏁版嵁
+const mockDonationProcessData = {
+  caseInfo: {
+    id: '202312001',
+    caseNo: 'C202312001',
+    hospitalNo: 'D202312001',
+    donorName: '寮犱笁',
+    gender: '0',
+    age: 45,
+    bloodType: 'A',
+    diagnosis: '鑴戝浼�',
+    status: 'in_progress',
+    createTime: '2023-12-01 08:00:00',
+    registrant: '鏉庡崗璋冨憳',
+    currentStage: 'organ_allocation',
+    // 鏂板鍩烘湰淇℃伅
+    height: 175,
+    weight: 70,
+    bloodPressure: '120/80',
+    contactPerson: '寮犵埗',
+    contactPhone: '13800138000',
+    hospital: '鍖椾含鍗忓拰鍖婚櫌',
+    department: '绁炵粡澶栫',
+    attendingDoctor: '鐜嬩富浠�'
+  },
+  processStages: [
+    {
+      key: 'donor_maintenance',
+      name: '渚涜�呯淮鎶�',
+      status: 'completed',
+      completeTime: '2023-12-01 10:00:00',
+      updateTime: '2023-12-01 10:00:00',
+      operator: '寮犲尰鐢�',
+      details: {
+        maintenanceRecords: 5,
+        lastCheckup: '2023-12-01 09:30:00',
+        vitalSigns: {
+          heartRate: 75,
+          bloodPressure: '118/76',
+          temperature: 36.5,
+          oxygenSaturation: 98
+        },
+        medications: [
+          { name: '澶氬反鑳�', dosage: '5渭g/kg/min', time: '2023-12-01 08:00:00' },
+          { name: '鐢橀湶閱�', dosage: '125ml', time: '2023-12-01 09:00:00' }
+        ],
+        labResults: {
+          wbc: 8.5,
+          hgb: 12.5,
+          plt: 250,
+          na: 140,
+          k: 4.0
+        }
+      }
+    },
+    {
+      key: 'medical_assessment',
+      name: '鍖诲璇勪及',
+      status: 'completed',
+      completeTime: '2023-12-02 14:30:00',
+      updateTime: '2023-12-02 14:30:00',
+      operator: '鏉庝富浠�',
+      details: {
+        assessmentItems: [
+          { name: '绁炵粡绯荤粺璇勪及', result: '鑴戞浜$‘璁�', status: 'completed' },
+          { name: '蹇冭绠$郴缁熻瘎浼�', result: '鍔熻兘姝e父', status: 'completed' },
+          { name: '鍛煎惛绯荤粺璇勪及', result: '鍛煎惛鏈虹淮鎸�', status: 'completed' },
+          { name: '鑲濊偩鍔熻兘璇勪及', result: '鍔熻兘鑹ソ', status: 'completed' },
+          { name: '鎰熸煋鎬х柧鐥呯瓫鏌�', result: '闃存��', status: 'completed' }
+        ],
+        imagingResults: {
+          ctBrain: '鑴戞按鑲匡紝鑴戝共鍙嶅皠娑堝け',
+          chestXRay: '鍙岃偤娓呮櫚',
+          abdominalUS: '鑲濊儐鑳拌劸鏈寮傚父'
+        },
+        conclusion: '绗﹀悎鍣ㄥ畼鎹愮尞鍖诲鏍囧噯',
+        contraindications: '鏃犵粷瀵圭蹇岀棁'
+      }
+    },
+    {
+      key: 'death_judgment',
+      name: '姝讳骸鍒ゅ畾',
+      status: 'completed',
+      completeTime: '2023-12-03 09:15:00',
+      updateTime: '2023-12-03 09:15:00',
+      operator: '鐜嬪尰鐢�',
+      details: {
+        judgmentType: '鑴戞浜″垽瀹�',
+        judgmentTime: '2023-12-03 09:00:00',
+        doctors: ['寮犱富浠�', '鐜嬪尰鐢�'],
+        testResults: [
+          { test: '鑷富鍛煎惛娴嬭瘯', result: '鏃犺嚜涓诲懠鍚�', time: '2023-12-03 08:30:00' },
+          { test: '鐬冲瓟瀵瑰厜鍙嶅皠', result: '鍙嶅皠娑堝け', time: '2023-12-03 08:45:00' },
+          { test: '鑴戝共鍚璇卞彂鐢典綅', result: '鑴戝共鍔熻兘涓уけ', time: '2023-12-03 09:00:00' }
+        ],
+        certificateNo: 'SW20231203001',
+        legalDocuments: ['姝讳骸璇佹槑涔�', '鑴戞浜″垽瀹氫功']
+      }
+    },
+    {
+      key: 'donation_confirm',
+      name: '鎹愮尞纭',
+      status: 'completed',
+      completeTime: '2023-12-03 11:00:00',
+      updateTime: '2023-12-03 11:00:00',
+      operator: '璧靛崗璋冨憳',
+      details: {
+        familyConsent: {
+          mainRelative: '寮犵埗',
+          relationship: '鐖跺瓙',
+          consentTime: '2023-12-03 10:45:00',
+          consentForm: '宸茬缃�',
+          witness: '鏉庢姢澹�'
+        },
+        donationType: '澶氬櫒瀹樻崘鐚�',
+        organs: ['鑲濊剰', '鑲捐剰', '蹇冭剰', '瑙掕啘'],
+        legalDocuments: [
+          '鍣ㄥ畼鎹愮尞鍚屾剰涔�',
+          '瀹跺睘鍏崇郴璇佹槑',
+          '鍖荤枟鍏嶈矗澹版槑'
+        ],
+        coordinator: '璧靛崗璋冨憳',
+        confirmationTime: '2023-12-03 11:00:00'
+      }
+    },
+    {
+      key: 'ethical_review',
+      name: '浼︾悊瀹℃煡',
+      status: 'completed',
+      completeTime: '2023-12-03 15:20:00',
+      updateTime: '2023-12-03 15:20:00',
+      operator: '浼︾悊濮斿憳浼�',
+      details: {
+        committee: '鍖婚櫌浼︾悊瀹℃煡濮斿憳浼�',
+        meetingTime: '2023-12-03 14:00:00',
+        members: ['寮犳暀鎺�', '鏉庝富浠�', '鐜嬪尰鐢�', '璧靛鍛�', '閽变笓瀹�'],
+        reviewItems: [
+          { item: '鎹愮尞鎰忔効鐪熷疄鎬�', result: '纭鐪熷疄', vote: '鍏ㄧエ閫氳繃' },
+          { item: '鍖诲璇勪及鍑嗙‘鎬�', result: '纭鍑嗙‘', vote: '鍏ㄧエ閫氳繃' },
+          { item: '娉曞緥鏂囦欢瀹屾暣鎬�', result: '纭瀹屾暣', vote: '鍏ㄧエ閫氳繃' }
+        ],
+        conclusion: '绗﹀悎浼︾悊瑕佹眰锛屽悓鎰忚繘琛屽櫒瀹樻崘鐚�',
+        resolutionNo: 'LL20231203001'
+      }
+    },
+    {
+      key: 'organ_allocation',
+      name: '鍣ㄥ畼鍒嗛厤',
+      status: 'in_progress',
+      updateTime: '2023-12-04 10:00:00',
+      operator: '鍒嗛厤绯荤粺',
+      details: {
+        allocationStartTime: '2023-12-04 09:00:00',
+        allocationSystem: '涓浗浜轰綋鍣ㄥ畼鍒嗛厤涓庡叡浜绠楁満绯荤粺',
+        organs: [
+          {
+            organ: '鑲濊剰',
+            status: '鍒嗛厤涓�',
+            matchScore: 95,
+            recommendedRecipient: '鐜嬪厛鐢�',
+            recipientAge: 45,
+            recipientBloodType: 'A',
+            hospital: '鍖椾含鍗忓拰鍖婚櫌',
+            urgency: '绱ф��'
+          },
+          {
+            organ: '鑲捐剰',
+            status: '鍖归厤瀹屾垚',
+            matchScore: 92,
+            recommendedRecipient: '鏉庡コ澹�',
+            recipientAge: 38,
+            recipientBloodType: 'A',
+            hospital: '涓婃捣鐟為噾鍖婚櫌',
+            urgency: '楂�'
+          },
+          {
+            organ: '蹇冭剰',
+            status: '寰呭垎閰�',
+            matchScore: 88,
+            recommendedRecipient: '闄堝厛鐢�',
+            recipientAge: 52,
+            recipientBloodType: 'O',
+            hospital: '骞垮窞涓北鍖婚櫌',
+            urgency: '绱ф��'
+          }
+        ],
+        allocationFactors: [
+          { factor: '鐥呮儏鍗遍噸绋嬪害', weight: 35 },
+          { factor: '缁勭粐閰嶅瀷鍖归厤', weight: 25 },
+          { factor: '绛夊緟鏃堕棿', weight: 15 },
+          { factor: '鍦扮悊鍥犵礌', weight: 10 },
+          { factor: '骞撮緞鍥犵礌', weight: 15 }
+        ]
+      }
+    },
+    {
+      key: 'organ_procurement',
+      name: '鍣ㄥ畼鑾峰彇',
+      status: 'pending',
+      updateTime: '2023-12-03 16:00:00',
+      operator: '寰呭垎閰�',
+      details: {
+        scheduledTime: '2023-12-04 14:00:00',
+        operationRoom: '鎵嬫湳瀹や竴鍙�',
+        surgicalTeam: {
+          surgeon: '寰呭垎閰�',
+          assistant: '寰呭垎閰�',
+          anesthesiologist: '寰呭垎閰�',
+          nurse: '寰呭垎閰�'
+        },
+        preservationPlan: {
+          method: '浣庢俯鏈烘鐏屾敞',
+          solution: 'UW淇濆瓨娑�',
+          temperature: '4掳C'
+        },
+        organs: [
+          {
+            organ: '鑲濊剰',
+            planned: true,
+            preservation: '寰呭噯澶�',
+            estimatedTime: '4灏忔椂'
+          },
+          {
+            organ: '鑲捐剰',
+            planned: true,
+            preservation: '寰呭噯澶�',
+            estimatedTime: '3灏忔椂'
+          },
+          {
+            organ: '蹇冭剰',
+            planned: true,
+            preservation: '寰呭噯澶�',
+            estimatedTime: '5灏忔椂'
+          }
+        ]
+      }
+    },
+    {
+      key: 'organ_utilization',
+      name: '鍣ㄥ畼鍒╃敤',
+      status: 'pending',
+      updateTime: '2023-12-03 16:00:00',
+      operator: '寰呭垎閰�',
+      details: {
+        transplantCenters: [
+          {
+            hospital: '鍖椾含鍗忓拰鍖婚櫌',
+            organ: '鑲濊剰',
+            recipient: '鐜嬪厛鐢�',
+            scheduledTime: '2023-12-04 18:00:00',
+            surgicalTeam: '寰呯‘璁�'
+          },
+          {
+            hospital: '涓婃捣鐟為噾鍖婚櫌',
+            organ: '鑲捐剰',
+            recipient: '鏉庡コ澹�',
+            scheduledTime: '2023-12-04 19:00:00',
+            surgicalTeam: '寰呯‘璁�'
+          }
+        ],
+        followupPlan: {
+          frequency: '鏈悗1涓湀銆�3涓湀銆�6涓湀銆�1骞�',
+          items: ['鑲濆姛鑳芥鏌�', '鍏嶇柅鎶戝埗鍓傛祿搴�', '褰卞儚瀛︽鏌�'],
+          coordinator: '寰呭垎閰�'
+        },
+        qualityMetrics: {
+          expectedSurvivalRate: 92,
+          complicationRisk: '涓瓑',
+          successRate: 95
+        }
+      }
+    }
+  ],
+  // 鏂板鏃堕棿绾夸簨浠�
+  timelineEvents: [
+    {
+      time: '2023-12-01 08:00:00',
+      event: '妗堜緥鐧昏',
+      operator: '鏉庡崗璋冨憳',
+      description: '鎹愮尞妗堜緥姝e紡鐧昏鍚姩'
+    },
+    {
+      time: '2023-12-01 10:00:00',
+      event: '渚涜�呯淮鎶ゅ畬鎴�',
+      operator: '寮犲尰鐢�',
+      description: '瀹屾垚渚涜�呯敓鍛戒綋寰佺淮鎶ゅ拰鍖荤枟绠$悊'
+    },
+    {
+      time: '2023-12-02 14:30:00',
+      event: '鍖诲璇勪及瀹屾垚',
+      operator: '鏉庝富浠�',
+      description: '鍏ㄩ潰鍖诲璇勪及纭绗﹀悎鎹愮尞鏍囧噯'
+    },
+    {
+      time: '2023-12-03 09:15:00',
+      event: '姝讳骸鍒ゅ畾瀹屾垚',
+      operator: '鐜嬪尰鐢�',
+      description: '鑴戞浜″垽瀹氱▼搴忓畬鎴�'
+    },
+    {
+      time: '2023-12-03 11:00:00',
+      event: '鎹愮尞纭瀹屾垚',
+      operator: '璧靛崗璋冨憳',
+      description: '瀹跺睘绛剧讲鎹愮尞鍚屾剰涔�'
+    },
+    {
+      time: '2023-12-03 15:20:00',
+      event: '浼︾悊瀹℃煡閫氳繃',
+      operator: '浼︾悊濮斿憳浼�',
+      description: '浼︾悊瀹℃煡濮斿憳浼氬叏绁ㄩ�氳繃'
+    }
+  ],
+  // 鏂板缁熻淇℃伅
+  statistics: {
+    totalStages: 8,
+    completedStages: 5,
+    completionRate: 62.5,
+    timeElapsed: '2澶�6灏忔椂',
+    estimatedCompletion: '2023-12-04 20:00:00',
+    organsToDonate: 4,
+    potentialRecipients: 3
+  }
+};
+
+// 鑾峰彇鎹愮尞杩涚▼璇︽儏
+export const getDonationProcessDetail = async (caseId) => {
+  await new Promise(resolve => setTimeout(resolve, 500));
+
+  // 妯℃嫙鏍规嵁caseId杩斿洖涓嶅悓鏁版嵁
+  const data = JSON.parse(JSON.stringify(mockDonationProcessData));
+  data.caseInfo.id = caseId;
+
+  return {
+    code: 200,
+    message: 'success',
+    data: data
+  };
+};
+
+// 鏇存柊闃舵鐘舵��
+export const updateStageStatus = async (caseId, stageKey, status) => {
+  await new Promise(resolve => setTimeout(resolve, 300));
+
+  // 妯℃嫙鏇存柊閫昏緫
+  const stage = mockDonationProcessData.processStages.find(s => s.key === stageKey);
+  if (stage) {
+    stage.status = status;
+    stage.updateTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
+
+    if (status === 'completed') {
+      stage.completeTime = stage.updateTime;
+    }
+  }
+
+  return {
+    code: 200,
+    message: '闃舵鐘舵�佹洿鏂版垚鍔�',
+    data: {
+      caseId,
+      stageKey,
+      status,
+      updateTime: stage.updateTime
+    }
+  };
+};
+
+// 鑾峰彇闃舵璇︽儏
+export const getStageDetail = async (caseId, stageKey) => {
+  await new Promise(resolve => setTimeout(resolve, 200));
+
+  const stage = mockDonationProcessData.processStages.find(s => s.key === stageKey);
+  if (!stage) {
+    return {
+      code: 404,
+      message: '闃舵涓嶅瓨鍦�',
+      data: null
+    };
+  }
+
+  return {
+    code: 200,
+    message: 'success',
+    data: stage
+  };
+};
+
+// 鑾峰彇鏃堕棿绾夸簨浠�
+export const getTimelineEvents = async (caseId) => {
+  await new Promise(resolve => setTimeout(resolve, 150));
+
+  return {
+    code: 200,
+    message: 'success',
+    data: mockDonationProcessData.timelineEvents
+  };
+};
+
+// 鑾峰彇妗堜緥缁熻淇℃伅
+export const getCaseStatistics = async (caseId) => {
+  await new Promise(resolve => setTimeout(resolve, 100));
+
+  return {
+    code: 200,
+    message: 'success',
+    data: mockDonationProcessData.statistics
+  };
+};
+
+// 鎻愪氦闃舵瀹℃牳
+export const submitStageReview = async (caseId, stageKey, reviewData) => {
+  await new Promise(resolve => setTimeout(resolve, 400));
+
+  return {
+    code: 200,
+    message: '瀹℃牳鎻愪氦鎴愬姛',
+    data: {
+      caseId,
+      stageKey,
+      reviewId: `REV${Date.now()}`,
+      submitTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+      ...reviewData
+    }
+  };
+};
+
+// 涓婁紶闃舵鏂囦欢
+export const uploadStageFile = async (caseId, stageKey, fileInfo) => {
+  await new Promise(resolve => setTimeout(resolve, 500));
+
+  return {
+    code: 200,
+    message: '鏂囦欢涓婁紶鎴愬姛',
+    data: {
+      caseId,
+      stageKey,
+      fileId: `FILE${Date.now()}`,
+      fileName: fileInfo.name,
+      fileSize: fileInfo.size,
+      uploadTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+      url: `/files/${caseId}/${stageKey}/${fileInfo.name}`
+    }
+  };
+};
+
+export default {
+  getDonationProcessDetail,
+  updateStageStatus,
+  getStageDetail,
+  getTimelineEvents,
+  getCaseStatistics,
+  submitStageReview,
+  uploadStageFile
+};
diff --git a/src/views/business/course/index.vue b/src/views/business/course/index.vue
new file mode 100644
index 0000000..db767b5
--- /dev/null
+++ b/src/views/business/course/index.vue
@@ -0,0 +1,677 @@
+<template>
+  <div class="donation-process-detail">
+    <el-card class="process-card">
+      <div class="process-container">
+        <!-- 宸︿晶鏃堕棿绾� -->
+        <div class="timeline-section">
+          <div class="section-header">
+            <h3>鎹愮尞杩涚▼鏃堕棿绾�</h3>
+            <el-tag :type="getOverallStatusTag(caseInfo.status)">
+              {{ getStatusText(caseInfo.status) }}
+            </el-tag>
+          </div>
+
+          <div class="timeline-container">
+            <div
+              v-for="stage in processStages"
+              :key="stage.key"
+              class="timeline-item"
+              :class="{
+                'active': activeStage === stage.key,
+                'completed': stage.status === 'completed',
+                'in-progress': stage.status === 'in_progress',
+                'pending': stage.status === 'pending'
+              }"
+              @click="handleStageClick(stage)"
+            >
+              <div class="timeline-marker">
+                <i v-if="stage.status === 'completed'" class="el-icon-check"></i>
+                <i v-else-if="stage.status === 'in_progress'" class="el-icon-loading"></i>
+                <i v-else class="el-icon-time"></i>
+              </div>
+
+              <div class="timeline-content">
+                <div class="stage-header">
+                  <span class="stage-name">{{ stage.name }}</span>
+                  <el-tag
+                    size="small"
+                    :type="getStageStatusTag(stage.status)"
+                  >
+                    {{ getStageStatusText(stage.status) }}
+                  </el-tag>
+                </div>
+
+                <div class="stage-info">
+                  <div v-if="stage.completeTime" class="time-info">
+                    <span>瀹屾垚鏃堕棿: {{ formatTime(stage.completeTime) }}</span>
+                  </div>
+                  <div v-if="stage.updateTime" class="time-info">
+                    <span>鏈�杩戞洿鏂�: {{ formatTime(stage.updateTime) }}</span>
+                  </div>
+                  <div v-if="stage.operator" class="operator-info">
+                    <span>璐熻矗浜�: {{ stage.operator }}</span>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+
+        <!-- 鍙充晶鍐呭鍖哄煙 -->
+        <div class="content-section">
+          <!-- 妗堜緥鍩烘湰淇℃伅 -->
+          <div class="basic-info-section">
+            <div class="section-header">
+              <h3>妗堜緥鍩烘湰淇℃伅</h3>
+              <el-button
+                type="primary"
+                size="small"
+                @click="handleEditBasicInfo"
+              >
+                缂栬緫淇℃伅
+              </el-button>
+            </div>
+
+            <el-descriptions :column="2" border>
+              <el-descriptions-item label="妗堜緥缂栧彿">
+                {{ caseInfo.caseNo }}
+              </el-descriptions-item>
+              <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="琛�鍨�">
+                <dict-tag
+                  :options="dict.type.sys_BloodType"
+                  :value="caseInfo.bloodType"
+                />
+              </el-descriptions-item>
+              <el-descriptions-item label="鐤剧梾璇婃柇">
+                {{ caseInfo.diagnosis }}
+              </el-descriptions-item>
+              <el-descriptions-item label="妗堜緥鐘舵��">
+                <el-tag :type="getOverallStatusTag(caseInfo.status)">
+                  {{ getStatusText(caseInfo.status) }}
+                </el-tag>
+              </el-descriptions-item>
+              <el-descriptions-item label="鍒涘缓鏃堕棿">
+                {{ formatTime(caseInfo.createTime) }}
+              </el-descriptions-item>
+              <el-descriptions-item label="鐧昏浜�">
+                {{ caseInfo.registrant }}
+              </el-descriptions-item>
+              <el-descriptions-item label="褰撳墠闃舵">
+                {{ getCurrentStageName() }}
+              </el-descriptions-item>
+            </el-descriptions>
+          </div>
+
+          <!-- 闃舵璇︽儏鍐呭 -->
+          <div class="stage-detail-section">
+            <div class="section-header">
+              <h3>{{ activeStageName }} - 闃舵璇︽儏</h3>
+              <div class="stage-actions">
+                <el-button
+                  v-if="activeStageData.status !== 'completed'"
+                  type="success"
+                  size="small"
+                  @click="handleCompleteStage"
+                >
+                  瀹屾垚闃舵
+                </el-button>
+                <el-button
+                  type="primary"
+                  size="small"
+                  @click="handleViewDetail"
+                >
+                  鏌ョ湅璇︽儏
+                </el-button>
+                <el-button
+                  v-if="activeStageData.status === 'completed'"
+                  type="warning"
+                  size="small"
+                  @click="handleModifyStage"
+                >
+                  淇敼淇℃伅
+                </el-button>
+              </div>
+            </div>
+
+            <!-- 鍔ㄦ�侀樁娈靛唴瀹� -->
+            <div class="stage-content">
+              <component
+                :is="getStageComponent()"
+                :stageData="activeStageData"
+                :caseInfo="caseInfo"
+              />
+            </div>
+          </div>
+        </div>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { getDonationProcessDetail } from './donationProcess';
+import DonorMaintenanceStage from './components/DonorMaintenanceStage';
+import MedicalAssessmentStage from './components/MedicalAssessmentStage';
+import DeathJudgmentStage from './components/DeathJudgmentStage';
+import DonationConfirmStage from './components/DonationConfirmStage';
+import EthicalReviewStage from './components/EthicalReviewStage';
+import OrganAllocationStage from './components/OrganAllocationStage';
+import OrganProcurementStage from './components/OrganProcurementStage';
+import OrganUtilizationStage from './components/OrganUtilizationStage';
+import dayjs from "dayjs";
+
+export default {
+  name: 'DonationProcessDetail',
+  components: {
+    DonorMaintenanceStage,
+    MedicalAssessmentStage,
+    DeathJudgmentStage,
+    DonationConfirmStage,
+    EthicalReviewStage,
+    OrganAllocationStage,
+    OrganProcurementStage,
+    OrganUtilizationStage
+  },
+  dicts: ['sys_user_sex', 'sys_BloodType', 'sys_0_1'],
+  data() {
+    return {
+      caseId: null,
+      caseInfo: {
+        id: '',
+        caseNo: '',
+        hospitalNo: '',
+        donorName: '',
+        gender: '',
+        age: '',
+        bloodType: '',
+        diagnosis: '',
+        status: 'in_progress',
+        createTime: '',
+        registrant: '',
+        currentStage: 'donor_maintenance'
+      },
+      processStages: [
+        {
+          key: 'donor_maintenance',
+          name: '渚涜�呯淮鎶�',
+          status: 'completed',
+          completeTime: '2023-12-01 10:00:00',
+          updateTime: '2023-12-01 10:00:00',
+          operator: '寮犲尰鐢�'
+        },
+        {
+          key: 'medical_assessment',
+          name: '鍖诲璇勪及',
+          status: 'completed',
+          completeTime: '2023-12-02 14:30:00',
+          updateTime: '2023-12-02 14:30:00',
+          operator: '鏉庝富浠�'
+        },
+        {
+          key: 'death_judgment',
+          name: '姝讳骸鍒ゅ畾',
+          status: 'completed',
+          completeTime: '2023-12-03 09:15:00',
+          updateTime: '2023-12-03 09:15:00',
+          operator: '鐜嬪尰鐢�'
+        },
+        {
+          key: 'donation_confirm',
+          name: '鎹愮尞纭',
+          status: 'completed',
+          completeTime: '2023-12-03 11:00:00',
+          updateTime: '2023-12-03 11:00:00',
+          operator: '璧靛崗璋冨憳'
+        },
+        {
+          key: 'ethical_review',
+          name: '浼︾悊瀹℃煡',
+          status: 'completed',
+          completeTime: '2023-12-03 15:20:00',
+          updateTime: '2023-12-03 15:20:00',
+          operator: '浼︾悊濮斿憳浼�'
+        },
+        {
+          key: 'organ_allocation',
+          name: '鍣ㄥ畼鍒嗛厤',
+          status: 'in_progress',
+          updateTime: '2023-12-04 10:00:00',
+          operator: '鍒嗛厤绯荤粺'
+        },
+        {
+          key: 'organ_procurement',
+          name: '鍣ㄥ畼鑾峰彇',
+          status: 'pending',
+          operator: '寰呭垎閰�'
+        },
+        {
+          key: 'organ_utilization',
+          name: '鍣ㄥ畼鍒╃敤',
+          status: 'pending',
+          operator: '寰呭垎閰�'
+        }
+      ],
+      activeStage: 'organ_allocation',
+      activeStageName: '鍣ㄥ畼鍒嗛厤',
+      activeStageData: {},
+      loading: false
+    };
+  },
+  computed: {
+
+  },
+  created() {
+    this.caseId = this.$route.query.id;
+    if (this.caseId) {
+      this.getDetail();
+    } else {
+      this.generateMockData();
+    }
+    this.setActiveStage(this.activeStage);
+  },
+  methods: {
+       getStageComponent() {
+      const componentMap = {
+        'donor_maintenance': 'DonorMaintenanceStage',
+        'medical_assessment': 'MedicalAssessmentStage',
+        'death_judgment': 'DeathJudgmentStage',
+        'donation_confirm': 'DonationConfirmStage',
+        'ethical_review': 'EthicalReviewStage',
+        'organ_allocation': 'OrganAllocationStage',
+        'organ_procurement': 'OrganProcurementStage',
+        'organ_utilization': 'OrganUtilizationStage'
+      };
+      return componentMap[this.activeStage];
+    },
+    // 鑾峰彇璇︽儏鏁版嵁
+    async getDetail() {
+      this.loading = true;
+      try {
+        const response = await getDonationProcessDetail(this.caseId);
+        if (response.code === 200) {
+          this.caseInfo = response.data.caseInfo;
+          this.processStages = response.data.processStages;
+          this.setActiveStage(response.data.currentStage);
+        }
+      } catch (error) {
+        console.error('鑾峰彇鎹愮尞杩涚▼璇︽儏澶辫触:', error);
+        this.$message.error('鑾峰彇璇︽儏澶辫触');
+      } finally {
+        this.loading = false;
+      }
+    },
+    // 鐢熸垚妯℃嫙鏁版嵁
+    generateMockData() {
+      this.caseInfo = {
+        id: '202312001',
+        caseNo: 'C202312001',
+        hospitalNo: 'D202312001',
+        donorName: '寮犱笁',
+        gender: '0',
+        age: 45,
+        bloodType: 'A',
+        diagnosis: '鑴戝浼�',
+        status: 'in_progress',
+        createTime: '2023-12-01 08:00:00',
+        registrant: '鏉庡崗璋冨憳',
+        currentStage: 'organ_allocation'
+      };
+    },
+    // 璁剧疆褰撳墠婵�娲婚樁娈�
+    setActiveStage(stageKey) {
+      this.activeStage = stageKey;
+      const stage = this.processStages.find(s => s.key === stageKey);
+      if (stage) {
+        this.activeStageName = stage.name;
+        this.activeStageData = stage;
+      }
+    },
+    // 澶勭悊闃舵鐐瑰嚮
+    handleStageClick(stage) {
+      if (stage.status !== 'pending') {
+        this.setActiveStage(stage.key);
+      } else {
+        this.$message.warning('璇ラ樁娈靛皻鏈紑濮嬶紝鏃犳硶鏌ョ湅璇︽儏');
+      }
+    },
+    // 鑾峰彇闃舵鐘舵�佹爣绛剧被鍨�
+    getStageStatusTag(status) {
+      const map = {
+        'completed': 'success',
+        'in_progress': 'warning',
+        'pending': 'info'
+      };
+      return map[status] || 'info';
+    },
+    // 鑾峰彇闃舵鐘舵�佹枃鏈�
+    getStageStatusText(status) {
+      const map = {
+        'completed': '宸插畬鎴�',
+        'in_progress': '杩涜涓�',
+        'pending': '鏈紑濮�'
+      };
+      return map[status] || '鏈煡';
+    },
+    // 鑾峰彇鏁翠綋鐘舵�佹爣绛剧被鍨�
+    getOverallStatusTag(status) {
+      const map = {
+        'completed': 'success',
+        'in_progress': 'warning',
+        'pending': 'info',
+        'terminated': 'danger'
+      };
+      return map[status] || 'info';
+    },
+    // 鑾峰彇鏁翠綋鐘舵�佹枃鏈�
+    getStatusText(status) {
+      const map = {
+        'completed': '宸插畬鎴�',
+        'in_progress': '杩涜涓�',
+        'pending': '鏈紑濮�',
+        'terminated': '宸茬粓姝�'
+      };
+      return map[status] || '鏈煡';
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    formatTime(time) {
+      if (!time) return '-';
+      return dayjs(time).format('YYYY-MM-DD HH:mm');
+    },
+
+    // 鑾峰彇褰撳墠闃舵鍚嶇О
+    getCurrentStageName() {
+      const currentStage = this.processStages.find(
+        stage => stage.status === 'in_progress'
+      );
+      return currentStage ? currentStage.name : '宸插畬鎴�';
+    },
+    // 缂栬緫鍩烘湰淇℃伅
+    handleEditBasicInfo() {
+      this.$message.info('缂栬緫鍩烘湰淇℃伅鍔熻兘');
+    },
+    // 瀹屾垚闃舵
+    handleCompleteStage() {
+      this.$confirm(`纭畾瑕佸畬鎴愩��${this.activeStageName}銆戦樁娈靛悧锛焋, '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        // 鏇存柊褰撳墠闃舵鐘舵��
+        const currentIndex = this.processStages.findIndex(
+          stage => stage.key === this.activeStage
+        );
+
+        if (currentIndex !== -1) {
+          this.processStages[currentIndex].status = 'completed';
+          this.processStages[currentIndex].completeTime = new Date().toISOString();
+
+          // 婵�娲讳笅涓�涓樁娈�
+          if (currentIndex < this.processStages.length - 1) {
+            this.processStages[currentIndex + 1].status = 'in_progress';
+            this.setActiveStage(this.processStages[currentIndex + 1].key);
+          } else {
+            this.caseInfo.status = 'completed';
+          }
+
+          this.$message.success('闃舵宸插畬鎴�');
+        }
+      });
+    },
+    // 鏌ョ湅璇︽儏
+    handleViewDetail() {
+      const routeMap = {
+        'donor_maintenance': '/case/donorMaintenance/detail',
+        'medical_assessment': '/case/medicalAssessment/detail',
+        'death_judgment': '/case/deathJudgment/detail',
+        'donation_confirm': '/case/donationConfirm/detail',
+        'ethical_review': '/case/ethicalReview/detail',
+        'organ_allocation': '/case/organAllocation/detail',
+        'organ_procurement': '/case/organProcurement/detail',
+        'organ_utilization': '/case/organUtilization/detail'
+      };
+
+      const route = routeMap[this.activeStage];
+      if (route) {
+        this.$router.push({
+          path: route,
+          query: { id: this.caseId }
+        });
+      }
+    },
+    // 淇敼闃舵淇℃伅
+    handleModifyStage() {
+      this.$message.info(`淇敼${this.activeStageName}淇℃伅鍔熻兘`);
+    }
+  }
+};
+</script>
+
+<style scoped>
+.donation-process-detail {
+  padding: 20px;
+  background-color: #f5f7fa;
+  min-height: 100vh;
+}
+
+.process-card {
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.process-container {
+  display: flex;
+  min-height: 800px;
+  gap: 20px;
+}
+
+/* 宸︿晶鏃堕棿绾挎牱寮� */
+.timeline-section {
+  flex: 0 0 300px;
+  background: white;
+  border-radius: 6px;
+  padding: 20px;
+  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding-bottom: 15px;
+  border-bottom: 1px solid #e4e7ed;
+}
+
+.section-header h3 {
+  margin: 0;
+  color: #303133;
+  font-size: 16px;
+}
+
+.timeline-container {
+  display: flex;
+  flex-direction: column;
+  gap: 15px;
+}
+
+.timeline-item {
+  display: flex;
+  align-items: flex-start;
+  padding: 15px;
+  border-radius: 6px;
+  cursor: pointer;
+  transition: all 0.3s ease;
+  border: 1px solid #e4e7ed;
+}
+
+.timeline-item:hover {
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  transform: translateY(-1px);
+}
+
+.timeline-item.active {
+  border-color: #409EFF;
+  background-color: #f0f9ff;
+}
+
+.timeline-item.completed {
+  border-color: #67C23A;
+  background-color: #f0f9e8;
+}
+
+.timeline-item.in-progress {
+  border-color: #E6A23C;
+  background-color: #fdf6ec;
+}
+
+.timeline-item.pending {
+  border-color: #909399;
+  background-color: #f4f4f5;
+}
+
+.timeline-marker {
+  flex: 0 0 40px;
+  height: 40px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 15px;
+  font-size: 18px;
+  color: white;
+}
+
+.timeline-item.completed .timeline-marker {
+  background-color: #67C23A;
+}
+
+.timeline-item.in-progress .timeline-marker {
+  background-color: #E6A23C;
+}
+
+.timeline-item.pending .timeline-marker {
+  background-color: #909399;
+}
+
+.timeline-content {
+  flex: 1;
+}
+
+.stage-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.stage-name {
+  font-weight: 600;
+  color: #303133;
+  font-size: 14px;
+}
+
+.stage-info {
+  font-size: 12px;
+  color: #606266;
+}
+
+.time-info, .operator-info {
+  margin-bottom: 4px;
+}
+
+/* 鍙充晶鍐呭鍖哄煙鏍峰紡 */
+.content-section {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+}
+
+.basic-info-section,
+.stage-detail-section {
+  background: white;
+  border-radius: 6px;
+  padding: 20px;
+  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
+}
+
+.stage-actions {
+  display: flex;
+  gap: 10px;
+}
+
+.stage-content {
+  margin-top: 20px;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 1200px) {
+  .process-container {
+    flex-direction: column;
+  }
+
+  .timeline-section {
+    flex: none;
+    margin-bottom: 20px;
+  }
+}
+
+@media (max-width: 768px) {
+  .donation-process-detail {
+    padding: 10px;
+  }
+
+  .process-container {
+    gap: 15px;
+  }
+
+  .timeline-section,
+  .basic-info-section,
+  .stage-detail-section {
+    padding: 15px;
+  }
+
+  .section-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 10px;
+  }
+
+  .stage-actions {
+    flex-wrap: wrap;
+  }
+}
+
+/* 鍔ㄧ敾鏁堟灉 */
+.timeline-item {
+  transition: all 0.3s ease;
+}
+
+.timeline-item:hover {
+  transform: translateY(-2px);
+}
+
+/* 杩涘害鏉℃牱寮忎紭鍖� */
+:deep(.el-progress-bar) {
+  padding-right: 0;
+}
+
+:deep(.el-progress__text) {
+  font-size: 12px;
+}
+</style>
diff --git a/src/views/business/decide/DecideInfo.vue b/src/views/business/decide/DecideInfo.vue
new file mode 100644
index 0000000..927d786
--- /dev/null
+++ b/src/views/business/decide/DecideInfo.vue
@@ -0,0 +1,653 @@
+<template>
+  <div class="death-judgment-detail">
+    <el-card class="detail-card">
+      <!-- 鍩虹淇℃伅 -->
+      <div slot="header" class="clearfix">
+        <span class="detail-title">姝讳骸鍒ゅ畾鍩烘湰淇℃伅</span>
+        <el-button
+          v-if="isEdit"
+          type="primary"
+          style="float: right; padding: 3px 0"
+          @click="handleSave"
+          :loading="saveLoading"
+        >
+          淇濆瓨淇℃伅
+        </el-button>
+      </div>
+
+      <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="妗堜緥缂栧彿" prop="hospitalNo">
+              <el-input
+                v-model="form.hospitalNo"
+                :readonly="!isEdit"
+                placeholder="鑷姩鐢熸垚 D+鏁板瓧"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+              <el-input v-model="form.donorName" :readonly="!isEdit" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎬у埆" prop="gender">
+              <el-select
+                v-model="form.gender"
+                :disabled="!isEdit"
+                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" :readonly="!isEdit" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鐤剧梾璇婃柇" prop="diagnosis">
+              <el-input v-model="form.diagnosis" :readonly="!isEdit" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="姝讳骸鍘熷洜" prop="deathReason">
+              <el-select
+                v-model="form.deathReason"
+                :disabled="!isEdit"
+                style="width: 100%"
+              >
+                <el-option label="鑴戞浜�" value="brain_death" />
+                <el-option label="蹇冩浜�" value="heart_death" />
+                <el-option label="鍏朵粬" value="other" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <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%"
+                :disabled="!isEdit"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鍒ゅ畾鍖荤敓" prop="judgmentDoctor">
+              <el-input v-model="form.judgmentDoctor" :readonly="!isEdit" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鐧昏浜�" prop="registrant">
+              <el-input v-model="form.registrant" :readonly="!isEdit" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item label="姝讳骸鍒ゅ畾璇存槑" prop="judgmentDescription">
+          <el-input
+            type="textarea"
+            :rows="3"
+            v-model="form.judgmentDescription"
+            :readonly="!isEdit"
+            placeholder="璇︾粏璁板綍姝讳骸鍒ゅ畾杩囩▼鍜屼緷鎹�"
+          />
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 璇勪及琛ㄩ檮浠� -->
+    <el-card class="attachment-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">姝讳骸鍒ゅ畾璇勪及琛ㄩ檮浠�</span>
+        <el-button
+          v-if="isEdit"
+          type="primary"
+          size="mini"
+          @click="openUploadDialog"
+          :loading="uploadLoading"
+        >
+          涓婁紶闄勪欢
+        </el-button>
+      </div>
+
+      <!-- 闄勪欢绫诲瀷閫夐」鍗� -->
+      <el-tabs v-model="activeAttachmentType" type="card">
+        <el-tab-pane
+          v-for="type in attachmentTypes"
+          :key="type.value"
+          :label="type.label"
+          :name="type.value"
+        >
+          <div class="attachment-upload-section">
+            <div class="upload-header">
+              <span class="upload-title">{{ type.label }}</span>
+              <el-tooltip content="鐐瑰嚮涓婁紶璇ョ被鍨嬭瘎浼拌〃" placement="top">
+                <el-button
+                  size="mini"
+                  type="primary"
+                  icon="el-icon-plus"
+                  @click="openUploadDialog(type.value)"
+                  :disabled="!isEdit"
+                >
+                  娣诲姞璇勪及琛�
+                </el-button>
+              </el-tooltip>
+            </div>
+
+            <!-- 闄勪欢鍒楄〃 -->
+            <el-table
+              :data="getAttachmentsByType(type.value)"
+              v-loading="attachmentLoading"
+              style="width: 100%; margin-top: 15px;"
+            >
+              <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
+                <template slot-scope="scope">
+                  <div class="file-info">
+                    <i
+                      class="el-icon-document"
+                      style="margin-right: 8px; color: #409EFF;"
+                    ></i>
+                    <span>{{ scope.row.fileName }}</span>
+                  </div>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="鏂囦欢绫诲瀷" width="100" 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="100" align="center">
+                <template slot-scope="scope">
+                  <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="涓婁紶鏃堕棿" width="160" align="center">
+                <template slot-scope="scope">
+                  <span>{{ parseTime(scope.row.uploadTime) }}</span>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="涓婁紶浜�" width="100" align="center">
+                <template slot-scope="scope">
+                  <span>{{ scope.row.uploader }}</span>
+                </template>
+              </el-table-column>
+
+              <el-table-column
+                label="鎿嶄綔"
+                width="180"
+                align="center"
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    size="mini"
+                    type="text"
+                    icon="el-icon-view"
+                    @click="handlePreview(scope.row)"
+                    >棰勮</el-button
+                  >
+                  <el-button
+                    size="mini"
+                    type="text"
+                    icon="el-icon-download"
+                    @click="handleDownload(scope.row)"
+                    >涓嬭浇</el-button
+                  >
+                  <el-button
+                    v-if="isEdit"
+                    size="mini"
+                    type="text"
+                    icon="el-icon-delete"
+                    style="color: #F56C6C;"
+                    @click="handleRemoveAttachment(scope.row)"
+                    >鍒犻櫎</el-button
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+
+            <div
+              v-if="getAttachmentsByType(type.value).length === 0"
+              class="empty-attachment"
+            >
+              <el-empty description="鏆傛棤璇勪及琛ㄩ檮浠�" :image-size="80"></el-empty>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+
+    <!-- 涓婁紶瀵硅瘽妗� -->
+    <el-dialog
+      :title="`涓婁紶${getCurrentTypeLabel}璇勪及琛╜"
+      :visible.sync="uploadDialogVisible"
+      width="500px"
+      :close-on-click-modal="false"
+    >
+      <el-upload
+        ref="uploadRef"
+        class="upload-demo"
+        drag
+        action="#"
+        multiple
+        :file-list="tempFileList"
+        :before-upload="beforeUpload"
+        :on-change="handleFileChange"
+        :on-remove="handleTempRemove"
+        :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銆亁ls銆亁lsx鏍煎紡鏂囦欢锛屽崟涓枃浠朵笉瓒呰繃10MB
+        </div>
+      </el-upload>
+
+      <div 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>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getDeathJudgmentDetail, updateDeathJudgment } from "./mockDeathJudgmentApi";
+
+export default {
+  name: "DeathJudgmentDetail",
+  data() {
+    return {
+      // 鏄惁缂栬緫妯″紡
+      isEdit: false,
+      // 淇濆瓨鍔犺浇鐘舵��
+      saveLoading: false,
+      // 琛ㄥ崟鏁版嵁
+      form: {
+        id: undefined,
+        hospitalNo: "",
+        donorName: "",
+        gender: "",
+        age: "",
+        diagnosis: "",
+        deathReason: "",
+        deathTime: "",
+        judgmentDoctor: "",
+        judgmentDescription: "",
+        registrant: "",
+        registrationTime: ""
+      },
+      // 琛ㄥ崟楠岃瘉瑙勫垯
+      rules: {
+        donorName: [
+          { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+        ],
+        deathReason: [
+          { required: true, message: "姝讳骸鍘熷洜涓嶈兘涓虹┖", trigger: "change" }
+        ],
+        deathTime: [
+          { required: true, message: "姝讳骸鏃堕棿涓嶈兘涓虹┖", trigger: "change" }
+        ],
+        judgmentDoctor: [
+          { required: true, message: "鍒ゅ畾鍖荤敓涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+      },
+      // 闄勪欢鐩稿叧鏁版嵁
+      activeAttachmentType: "1",
+      attachmentLoading: false,
+      uploadDialogVisible: false,
+      uploadLoading: false,
+      tempFileList: [],
+      currentUploadType: "",
+
+      // 璇勪及琛ㄧ被鍨嬪畾涔�
+      attachmentTypes: [
+        { value: "1", label: "鑴戞浜″垽瀹氳〃" },
+        { value: "2", label: "鑴戠數鍥捐瘎浼拌〃" },
+        { value: "3", label: "鐭綔浼忔湡浣撴劅璇卞彂鐢典綅璇勪及琛�" },
+        { value: "4", label: "缁忛澶氭櫘鍕掕秴澹拌瘎浼拌褰�" },
+        { value: "5", label: "鍗仴濮旇剳鎹熶激璐ㄦ帶涓績 - 涓村簥缁煎悎璇勪及琛�" },
+        { value: "6", label: "UW璇勫垎琛�" },
+        { value: "7", label: "蹇冩浜″垽瀹氳〃" }
+      ],
+
+      // 闄勪欢鍒楄〃鏁版嵁
+      attachmentList: []
+    };
+  },
+  computed: {
+    getCurrentTypeLabel() {
+      const type = this.attachmentTypes.find(
+        t => t.value === this.currentUploadType
+      );
+      return type ? type.label : "";
+    }
+  },
+  created() {
+    const id = this.$route.query.id;
+    this.isEdit = this.$route.path.includes('/edit') || this.$route.path.includes('/add');
+    if (id && !this.$route.path.includes('/add')) {
+      this.getDetail(id);
+    } else if (this.$route.path.includes('/add')) {
+      this.generateHospitalNo();
+    }
+    this.getAttachmentList();
+  },
+  methods: {
+    // 鐢熸垚妗堜緥缂栧彿
+    generateHospitalNo() {
+      // 妯℃嫙鐢熸垚妗堜緥缂栧彿锛欴 + 鏃堕棿鎴冲悗6浣�
+      const timestamp = Date.now().toString();
+      this.form.hospitalNo = 'D' + timestamp.slice(-6);
+    },
+    // 鑾峰彇璇︽儏
+    getDetail(id) {
+      getDeathJudgmentDetail(id).then(response => {
+        if (response.code === 200) {
+          this.form = response.data;
+        }
+      });
+    },
+    // 鑾峰彇闄勪欢鍒楄〃
+    getAttachmentList() {
+      this.attachmentLoading = true;
+      // 妯℃嫙闄勪欢鏁版嵁 - 瀹為檯椤圭洰涓粠鎺ュ彛鑾峰彇
+      setTimeout(() => {
+        this.attachmentList = [
+          {
+            id: 1,
+            type: "1",
+            typeName: "鑴戞浜″垽瀹氳〃",
+            fileName: "鑴戞浜″垽瀹氳〃_202312001.pdf",
+            fileSize: 2548321,
+            uploadTime: "2023-12-01 10:30:00",
+            uploader: "寮犲尰鐢�",
+            fileUrl: "/attachments/brain_death_1.pdf"
+          },
+          {
+            id: 2,
+            type: "2",
+            typeName: "鑴戠數鍥捐瘎浼拌〃",
+            fileName: "鑴戠數鍥捐瘎浼拌〃_202312001.docx",
+            fileSize: 512345,
+            uploadTime: "2023-12-01 14:20:00",
+            uploader: "鏉庡尰鐢�",
+            fileUrl: "/attachments/eeg_1.docx"
+          }
+        ];
+        this.attachmentLoading = false;
+      }, 500);
+    },
+    // 鏍规嵁绫诲瀷鑾峰彇闄勪欢
+    getAttachmentsByType(type) {
+      return this.attachmentList.filter(item => item.type === type);
+    },
+    // 鑾峰彇鏂囦欢绫诲瀷
+    getFileType(fileName) {
+      const ext = fileName.split('.').pop().toLowerCase();
+      const typeMap = {
+        'pdf': 'PDF',
+        'doc': 'DOC',
+        'docx': 'DOCX',
+        'xls': 'XLS',
+        'xlsx': 'XLSX',
+        'jpg': 'JPG',
+        'jpeg': 'JPEG',
+        'png': 'PNG'
+      };
+      return typeMap[ext] || ext.toUpperCase();
+    },
+    // 鎵撳紑涓婁紶瀵硅瘽妗�
+    openUploadDialog(type = null) {
+      this.currentUploadType = type || this.activeAttachmentType;
+      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',
+        'application/vnd.ms-excel',
+        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+      ];
+
+      const maxSize = 10 * 1024 * 1024; // 10MB
+
+      // 鏍¢獙鏂囦欢绫诲瀷
+      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') ||
+                      file.name.endsWith('.xls') ||
+                      file.name.endsWith('.xlsx');
+
+      if (!isTypeOk) {
+        this.$message.error('鏂囦欢鏍煎紡涓嶆敮鎸侊紝璇蜂笂浼爌df銆乯pg銆乸ng銆乨oc銆乨ocx銆亁ls鎴杧lsx鏍煎紡鏂囦欢');
+        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;
+    },
+    // 鎻愪氦涓婁紶
+    async submitUpload() {
+      if (this.tempFileList.length === 0) {
+        this.$message.warning('璇峰厛閫夋嫨瑕佷笂浼犵殑鏂囦欢');
+        return;
+      }
+
+      this.uploadLoading = true;
+
+      try {
+        // 妯℃嫙涓婁紶杩囩▼ - 瀹為檯椤圭洰涓皟鐢ㄤ笂浼犳帴鍙�
+        for (const file of this.tempFileList) {
+          const newAttachment = {
+            id: Date.now() + Math.random(),
+            type: this.currentUploadType,
+            typeName: this.getCurrentTypeLabel,
+            fileName: file.name,
+            fileSize: file.size,
+            uploadTime: new Date().toISOString(),
+            uploader: '褰撳墠鐢ㄦ埛',
+            fileUrl: URL.createObjectURL(file.raw)
+          };
+
+          this.attachmentList.push(newAttachment);
+        }
+
+        this.$message.success('鏂囦欢涓婁紶鎴愬姛');
+        this.uploadDialogVisible = false;
+        this.tempFileList = [];
+      } catch (error) {
+        this.$message.error('鏂囦欢涓婁紶澶辫触');
+        console.error('涓婁紶澶辫触:', error);
+      } finally {
+        this.uploadLoading = false;
+      }
+    },
+    // 鍒犻櫎闄勪欢
+    handleRemoveAttachment(attachment) {
+      this.$confirm('纭畾瑕佸垹闄よ繖涓瘎浼拌〃闄勪欢鍚楋紵', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        const index = this.attachmentList.findIndex(item => item.id === attachment.id);
+        if (index !== -1) {
+          this.attachmentList.splice(index, 1);
+          this.$message.success('璇勪及琛ㄥ垹闄ゆ垚鍔�');
+        }
+      }).catch(() => {});
+    },
+    // 棰勮闄勪欢
+    handlePreview(attachment) {
+      if (attachment.fileName.endsWith('.pdf')) {
+        window.open(attachment.fileUrl, '_blank');
+      } else if (attachment.fileName.match(/\.(jpg|jpeg|png)$/i)) {
+        this.$alert(`<img src="${attachment.fileUrl}" style="max-width: 100%;" alt="${attachment.fileName}">`,
+          '鍥剧墖棰勮', {
+            dangerouslyUseHTMLString: true,
+            customClass: 'image-preview-dialog'
+          });
+      } else {
+        this.$message.info('璇ユ枃浠剁被鍨嬫殏涓嶆敮鎸佸湪绾块瑙堬紝璇蜂笅杞藉悗鏌ョ湅');
+      }
+    },
+    // 涓嬭浇闄勪欢
+    handleDownload(attachment) {
+      // 瀹為檯椤圭洰涓皟鐢ㄤ笅杞芥帴鍙�
+      const link = document.createElement('a');
+      link.href = attachment.fileUrl;
+      link.download = attachment.fileName;
+      link.click();
+      this.$message.success(`寮�濮嬩笅杞�: ${attachment.fileName}`);
+    },
+    // 淇濆瓨淇℃伅
+    handleSave() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.saveLoading = true;
+
+          // 妯℃嫙淇濆瓨杩囩▼
+          updateDeathJudgment(this.form)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success('淇濆瓨鎴愬姛');
+                if (this.$route.path.includes('/add')) {
+                  this.$router.push('/case/deathJudgment');
+                } else {
+                  this.isEdit = false;
+                }
+              }
+            })
+            .catch(error => {
+              console.error('淇濆瓨澶辫触:', error);
+              this.$message.error('淇濆瓨澶辫触');
+            })
+            .finally(() => {
+              this.saveLoading = false;
+            });
+        }
+      });
+    },
+    // 鏂囦欢澶у皬鏍煎紡鍖�
+    formatFileSize(size) {
+      if (size === 0) 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];
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time) {
+      if (!time) return '';
+      const date = new Date(time);
+      return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.death-judgment-detail {
+  padding: 20px;
+}
+
+.detail-card {
+  margin-bottom: 20px;
+}
+
+.attachment-card {
+  margin-bottom: 20px;
+}
+
+.detail-title {
+  font-size: 16px;
+  font-weight: bold;
+}
+
+.attachment-upload-section {
+  padding: 10px;
+}
+
+.upload-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.upload-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: #303133;
+}
+
+.file-info {
+  display: flex;
+  align-items: center;
+}
+
+.empty-attachment {
+  text-align: center;
+  padding: 40px 0;
+  color: #909399;
+}
+
+/* 鍥剧墖棰勮瀵硅瘽妗嗘牱寮� */
+:deep(.image-preview-dialog) {
+  width: auto;
+  max-width: 90vw;
+}
+
+:deep(.image-preview-dialog .el-message-box__content) {
+  text-align: center;
+}
+</style>
diff --git a/src/views/business/decide/index.vue b/src/views/business/decide/index.vue
new file mode 100644
index 0000000..a285ce9
--- /dev/null
+++ b/src/views/business/decide/index.vue
@@ -0,0 +1,437 @@
+<template>
+  <div class="death-judgment-list">
+    <!-- 鏌ヨ鏉′欢 -->
+    <el-card class="search-card">
+      <el-form
+        :model="queryParams"
+        ref="queryForm"
+        :inline="true"
+        label-width="100px"
+      >
+        <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+          <el-input
+            v-model="queryParams.hospitalNo"
+            placeholder="璇疯緭鍏ヤ綇闄㈠彿"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+          <el-input
+            v-model="queryParams.donorName"
+            placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="姝讳骸鍘熷洜" prop="deathReason">
+          <el-select
+            v-model="queryParams.deathReason"
+            placeholder="璇烽�夋嫨姝讳骸鍘熷洜"
+            clearable
+            style="width: 200px"
+          >
+            <el-option label="鑴戞浜�" value="brain_death" />
+            <el-option label="蹇冩浜�" value="heart_death" />
+            <el-option label="鍏朵粬" value="other" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="姝讳骸鏃堕棿鑼冨洿" prop="deathTimeRange">
+          <el-date-picker
+            v-model="queryParams.deathTimeRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="yyyy-MM-dd"
+            style="width: 240px"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" @click="handleQuery"
+            >鎼滅储</el-button
+          >
+          <el-button icon="el-icon-refresh" @click="resetQuery">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 鎿嶄綔鎸夐挳 -->
+    <el-card class="tool-card">
+      <el-row :gutter="10">
+        <el-col :span="16">
+          <el-button type="primary" icon="el-icon-plus" @click="handleCreate"
+            >鏂板缓姝讳骸鍒ゅ畾</el-button
+          >
+          <el-button
+            type="success"
+            icon="el-icon-edit"
+            :disabled="single"
+            @click="handleUpdate"
+            >淇敼</el-button
+          >
+          <el-button
+            type="danger"
+            icon="el-icon-delete"
+            :disabled="multiple"
+            @click="handleDelete"
+            >鍒犻櫎</el-button
+          >
+          <el-button
+            type="warning"
+            icon="el-icon-download"
+            @click="handleExport"
+            >瀵煎嚭</el-button
+          >
+        </el-col>
+        <el-col :span="8" style="text-align: right">
+          <el-tooltip content="鍒锋柊" placement="top">
+            <el-button icon="el-icon-refresh" circle @click="getList" />
+          </el-tooltip>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <el-card>
+      <el-table
+        v-loading="loading"
+        :data="deathJudgmentList"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column
+          label="浣忛櫌鍙�"
+          align="center"
+          prop="hospitalNo"
+          width="120"
+        />
+        <el-table-column
+          label="鎹愮尞鑰呭鍚�"
+          align="center"
+          prop="donorName"
+          width="120"
+        />
+        <el-table-column label="鎬у埆" align="center" prop="gender" width="80">
+          <template slot-scope="scope">
+            <dict-tag
+              :options="dict.type.sys_user_sex"
+              :value="parseInt(scope.row.gender)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="骞撮緞" align="center" prop="age" width="80" />
+        <el-table-column
+          label="鐤剧梾璇婃柇"
+          align="center"
+          prop="diagnosis"
+          min-width="180"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="姝讳骸鍘熷洜"
+          align="center"
+          prop="deathReason"
+          width="120"
+        >
+          <template slot-scope="scope">
+            <el-tag :type="reasonFilter(scope.row.deathReason)">
+              {{ reasonTextFilter(scope.row.deathReason) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="姝讳骸鏃堕棿"
+          align="center"
+          prop="deathTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.deathTime
+                ? parseTime(scope.row.deathTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鍒ゅ畾鍖荤敓"
+          align="center"
+          prop="judgmentDoctor"
+          width="120"
+        />
+        <el-table-column
+          label="鐧昏鏃堕棿"
+          align="center"
+          prop="registrationTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.registrationTime
+                ? parseTime(scope.row.registrationTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鐧昏浜�"
+          align="center"
+          prop="registrant"
+          width="100"
+        />
+        <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-view"
+              @click="handleView(scope.row)"
+              >璇︽儏</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdate(scope.row)"
+              >淇敼</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-delete"
+              style="color: #F56C6C"
+              @click="handleDelete(scope.row)"
+              >鍒犻櫎</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 鍒嗛〉缁勪欢 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { listDeathJudgment, delDeathJudgment, exportDeathJudgment } from "./mockDeathJudgmentApi";
+import Pagination from "@/components/Pagination";
+
+export default {
+  name: "DeathJudgmentList",
+  components: { Pagination },
+  dicts: ["sys_user_sex"],
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 姝讳骸鍒ゅ畾琛ㄦ牸鏁版嵁
+      deathJudgmentList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        hospitalNo: undefined,
+        donorName: undefined,
+        deathReason: undefined,
+        deathTimeRange: []
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 姝讳骸鍘熷洜杩囨护鍣�
+    reasonFilter(reason) {
+      const reasonMap = {
+        "brain_death": "primary", // 鑴戞浜�
+        "heart_death": "danger", // 蹇冩浜�
+        "other": "info" // 鍏朵粬
+      };
+      return reasonMap[reason] || "info";
+    },
+    reasonTextFilter(reason) {
+      const reasonMap = {
+        "brain_death": "鑴戞浜�",
+        "heart_death": "蹇冩浜�",
+        "other": "鍏朵粬"
+      };
+      return reasonMap[reason] || "鏈煡";
+    },
+    // 鏌ヨ姝讳骸鍒ゅ畾鍒楄〃
+    getList() {
+      this.loading = true;
+      listDeathJudgment(this.queryParams)
+        .then(response => {
+          if (response.code === 200) {
+            this.deathJudgmentList = response.data.rows;
+            this.total = response.data.total;
+          } else {
+            this.$message.error("鑾峰彇鏁版嵁澶辫触");
+          }
+          this.loading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇姝讳骸鍒ゅ畾鍒楄〃澶辫触:", error);
+          this.loading = false;
+          this.$message.error("鑾峰彇鏁版嵁澶辫触");
+        });
+    },
+    // 鎼滅储鎸夐挳鎿嶄綔
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    // 閲嶇疆鎸夐挳鎿嶄綔
+    resetQuery() {
+      this.$refs.queryForm.resetFields();
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    // 鏌ョ湅璇︽儏
+    handleView(row) {
+      this.$router.push({
+        path: "/case/DecideInfo",
+        query: { id: row.id }
+      });
+    },
+    // 鏂板鎸夐挳鎿嶄綔
+    handleCreate() {
+      this.$router.push("/case/DecideInfo");
+    },
+    // 淇敼鎸夐挳鎿嶄綔
+    handleUpdate(row) {
+      const id = row.id || this.ids[0];
+      this.$router.push({
+        path: "/case/DecideInfo",
+        query: { id: id }
+      });
+    },
+    // 鍒犻櫎鎸夐挳鎿嶄綔
+    handleDelete(row) {
+      const ids = row.id ? [row.id] : this.ids;
+      this.$confirm("鏄惁纭鍒犻櫎閫変腑鐨勬暟鎹」锛�", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          return delDeathJudgment(ids);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍒犻櫎鎴愬姛");
+            this.getList();
+          }
+        })
+        .catch(() => {});
+    },
+    // 瀵煎嚭鎸夐挳鎿嶄綔
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm("鏄惁纭瀵煎嚭鎵�鏈夋浜″垽瀹氭暟鎹紵", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.loading = true;
+          return exportDeathJudgment(queryParams);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("瀵煎嚭鎴愬姛");
+            // 瀹為檯椤圭洰涓繖閲屽鐞嗘枃浠朵笅杞�
+          }
+          this.loading = false;
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time, pattern) {
+      if (!time) return "";
+      const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
+      let date;
+      if (typeof time === "object") {
+        date = time;
+      } else {
+        if (typeof time === "string" && /^[0-9]+$/.test(time)) {
+          time = parseInt(time);
+        }
+        if (typeof time === "number" && time.toString().length === 10) {
+          time = time * 1000;
+        }
+        date = new Date(time);
+      }
+      const formatObj = {
+        y: date.getFullYear(),
+        m: date.getMonth() + 1,
+        d: date.getDate(),
+        h: date.getHours(),
+        i: date.getMinutes(),
+        s: date.getSeconds(),
+        a: date.getDay()
+      };
+      const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+        let value = formatObj[key];
+        if (key === "a") {
+          return ["鏃�", "涓�", "浜�", "涓�", "鍥�", "浜�", "鍏�"][value];
+        }
+        if (result.length > 0 && value < 10) {
+          value = "0" + value;
+        }
+        return value || 0;
+      });
+      return time_str;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.death-judgment-list {
+  padding: 20px;
+}
+
+.search-card {
+  margin-bottom: 20px;
+}
+
+.tool-card {
+  margin-bottom: 20px;
+}
+
+.fixed-width .el-button {
+  margin: 0 5px;
+}
+</style>
diff --git a/src/views/business/decide/mockDeathJudgmentApi.js b/src/views/business/decide/mockDeathJudgmentApi.js
new file mode 100644
index 0000000..6fd13c9
--- /dev/null
+++ b/src/views/business/decide/mockDeathJudgmentApi.js
@@ -0,0 +1,391 @@
+// 妯℃嫙姝讳骸鍒ゅ畾鏁版嵁
+const mockDeathJudgmentData = [
+  {
+    id: 1,
+    hospitalNo: "D202312001",
+    donorName: "寮犱笁",
+    gender: "0",
+    age: 45,
+    diagnosis: "鑴戝浼�",
+    deathReason: "brain_death",
+    deathTime: "2023-12-01 14:30:00",
+    judgmentDoctor: "鐜嬪尰鐢�",
+    judgmentDescription: "缁忚繃澶氭鑴戞浜″垽瀹氾紝绗﹀悎鑴戞浜′复搴婅瘖鏂爣鍑�",
+    registrant: "鏉庡崗璋冨憳",
+    registrationTime: "2023-12-01 15:00:00",
+    createTime: "2023-12-01 10:00:00"
+  },
+  {
+    id: 2,
+    hospitalNo: "D202312002",
+    donorName: "鏉庡洓",
+    gender: "1",
+    age: 38,
+    diagnosis: "蹇冭剰楠ゅ仠",
+    deathReason: "heart_death",
+    deathTime: "2023-12-02 09:15:00",
+    judgmentDoctor: "鍒樺尰鐢�",
+    judgmentDescription: "蹇冩浜″垽瀹氾紝蹇冪數鍥惧憟鐩寸嚎锛屾棤鑷富鍛煎惛",
+    registrant: "寮犲崗璋冨憳",
+    registrationTime: "2023-12-02 10:00:00",
+    createTime: "2023-12-02 08:30:00"
+  },
+  {
+    id: 3,
+    hospitalNo: "D202312003",
+    donorName: "鐜嬩簲",
+    gender: "0",
+    age: 52,
+    diagnosis: "鑴戞姝�",
+    deathReason: "brain_death",
+    deathTime: "2023-12-03 16:45:00",
+    judgmentDoctor: "闄堝尰鐢�",
+    judgmentDescription: "鑴戝共鍔熻兘瀹屽叏涓уけ锛岀鍚堣剳姝讳骸鏍囧噯",
+    registrant: "璧靛崗璋冨憳",
+    registrationTime: "2023-12-03 17:20:00",
+    createTime: "2023-12-03 14:00:00"
+  },
+  {
+    id: 4,
+    hospitalNo: "D202312004",
+    donorName: "璧靛叚",
+    gender: "1",
+    age: 29,
+    diagnosis: "澶氬彂浼�",
+    deathReason: "other",
+    deathTime: "2023-12-04 11:20:00",
+    judgmentDoctor: "瀛欏尰鐢�",
+    judgmentDescription: "鍒涗激鎬т紤鍏嬪鑷村鍣ㄥ畼鍔熻兘琛扮",
+    registrant: "閽卞崗璋冨憳",
+    registrationTime: "2023-12-04 12:00:00",
+    createTime: "2023-12-04 09:45:00"
+  },
+  {
+    id: 5,
+    hospitalNo: "D202312005",
+    donorName: "瀛欎竷",
+    gender: "0",
+    age: 61,
+    diagnosis: "鑴戣偪鐦�",
+    deathReason: "brain_death",
+    deathTime: "2023-12-05 13:10:00",
+    judgmentDoctor: "鍛ㄥ尰鐢�",
+    judgmentDescription: "棰呭唴鍘嬪楂樺鑷磋剳鐤濆舰鎴�",
+    registrant: "鍚村崗璋冨憳",
+    registrationTime: "2023-12-05 13:45:00",
+    createTime: "2023-12-05 10:30:00"
+  }
+];
+
+// 妯℃嫙闄勪欢鏁版嵁
+const mockAttachmentData = [
+  {
+    id: 1,
+    judgmentId: 1,
+    type: "1",
+    typeName: "鑴戞浜″垽瀹氳〃",
+    fileName: "鑴戞浜″垽瀹氳〃_202312001.pdf",
+    fileSize: 2548321,
+    uploadTime: "2023-12-01 14:35:00",
+    uploader: "鐜嬪尰鐢�",
+    fileUrl: "/attachments/brain_death_1.pdf"
+  },
+  {
+    id: 2,
+    judgmentId: 1,
+    type: "2",
+    typeName: "鑴戠數鍥捐瘎浼拌〃",
+    fileName: "鑴戠數鍥捐瘎浼拌〃_202312001.docx",
+    fileSize: 512345,
+    uploadTime: "2023-12-01 15:20:00",
+    uploader: "鏉庡尰鐢�",
+    fileUrl: "/attachments/eeg_1.docx"
+  },
+  {
+    id: 3,
+    judgmentId: 2,
+    type: "7",
+    typeName: "蹇冩浜″垽瀹氳〃",
+    fileName: "蹇冩浜″垽瀹氳〃_202312002.pdf",
+    fileSize: 1892345,
+    uploadTime: "2023-12-02 09:30:00",
+    uploader: "鍒樺尰鐢�",
+    fileUrl: "/attachments/heart_death_2.pdf"
+  },
+  {
+    id: 4,
+    judgmentId: 3,
+    type: "1",
+    typeName: "鑴戞浜″垽瀹氳〃",
+    fileName: "鑴戞浜″垽瀹氳〃_202312003.pdf",
+    fileSize: 3124567,
+    uploadTime: "2023-12-03 17:00:00",
+    uploader: "闄堝尰鐢�",
+    fileUrl: "/attachments/brain_death_3.pdf"
+  },
+  {
+    id: 5,
+    judgmentId: 3,
+    type: "4",
+    typeName: "缁忛澶氭櫘鍕掕秴澹拌瘎浼拌褰�",
+    fileName: "缁忛澶氭櫘鍕抇202312003.xlsx",
+    fileSize: 845672,
+    uploadTime: "2023-12-03 17:15:00",
+    uploader: "寮犳妧甯�",
+    fileUrl: "/attachments/tcd_3.xlsx"
+  }
+];
+
+// 妯℃嫙API鍝嶅簲寤惰繜
+const delay = (ms = 500) => new Promise(resolve => setTimeout(resolve, ms));
+
+// 鏌ヨ姝讳骸鍒ゅ畾鍒楄〃
+export const listDeathJudgment = async (queryParams = {}) => {
+  await delay();
+
+  const {
+    pageNum = 1,
+    pageSize = 10,
+    hospitalNo,
+    donorName,
+    deathReason,
+    deathTimeRange = []
+  } = queryParams;
+
+  // 杩囨护鏁版嵁
+  let filteredData = mockDeathJudgmentData.filter(item => {
+    let match = true;
+
+    if (hospitalNo && !item.hospitalNo.includes(hospitalNo)) {
+      match = false;
+    }
+
+    if (donorName && !item.donorName.includes(donorName)) {
+      match = false;
+    }
+
+    if (deathReason && item.deathReason !== deathReason) {
+      match = false;
+    }
+
+    if (deathTimeRange.length === 2) {
+      const deathTime = new Date(item.deathTime);
+      const startTime = new Date(deathTimeRange[0]);
+      const endTime = new Date(deathTimeRange[1]);
+      endTime.setDate(endTime.getDate() + 1);
+
+      if (deathTime < startTime || deathTime >= endTime) {
+        match = false;
+      }
+    }
+
+    return match;
+  });
+
+  // 鍒嗛〉
+  const startIndex = (pageNum - 1) * pageSize;
+  const endIndex = startIndex + parseInt(pageSize);
+  const paginatedData = filteredData.slice(startIndex, endIndex);
+
+  return {
+    code: 200,
+    message: "success",
+    data: {
+      rows: paginatedData,
+      total: filteredData.length,
+      pageNum: parseInt(pageNum),
+      pageSize: parseInt(pageSize)
+    }
+  };
+};
+
+// 鑾峰彇姝讳骸鍒ゅ畾璇︾粏淇℃伅
+export const getDeathJudgmentDetail = async (id) => {
+  await delay();
+
+  const detail = mockDeathJudgmentData.find(item => item.id == id);
+
+  if (detail) {
+    // 鑾峰彇璇ュ垽瀹氬搴旂殑闄勪欢
+    const attachments = mockAttachmentData.filter(item => item.judgmentId == id);
+
+    return {
+      code: 200,
+      message: "success",
+      data: {
+        ...detail,
+        attachments
+      }
+    };
+  } else {
+    return {
+      code: 404,
+      message: "姝讳骸鍒ゅ畾璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鏂板姝讳骸鍒ゅ畾
+export const addDeathJudgment = async (data) => {
+  await delay();
+
+  const newId = Math.max(...mockDeathJudgmentData.map(item => item.id)) + 1;
+  const hospitalNo = `D${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(newId).padStart(3, '0')}`;
+
+  const newRecord = {
+    ...data,
+    id: newId,
+    hospitalNo,
+    registrationTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+    createTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+  };
+
+  // 妯℃嫙娣诲姞鍒版暟鎹�
+  mockDeathJudgmentData.unshift(newRecord);
+
+  return {
+    code: 200,
+    message: "鏂板鎴愬姛",
+    data: newRecord
+  };
+};
+
+// 淇敼姝讳骸鍒ゅ畾
+export const updateDeathJudgment = async (data) => {
+  await delay();
+
+  const index = mockDeathJudgmentData.findIndex(item => item.id == data.id);
+
+  if (index !== -1) {
+    mockDeathJudgmentData[index] = {
+      ...mockDeathJudgmentData[index],
+      ...data,
+      updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+    };
+
+    return {
+      code: 200,
+      message: "淇敼鎴愬姛",
+      data: mockDeathJudgmentData[index]
+    };
+  } else {
+    return {
+      code: 404,
+      message: "姝讳骸鍒ゅ畾璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鍒犻櫎姝讳骸鍒ゅ畾
+export const delDeathJudgment = async (ids) => {
+  await delay();
+
+  const idArray = Array.isArray(ids) ? ids : [ids];
+
+  idArray.forEach(id => {
+    const index = mockDeathJudgmentData.findIndex(item => item.id == id);
+    if (index !== -1) {
+      mockDeathJudgmentData.splice(index, 1);
+
+      // 鍚屾椂鍒犻櫎瀵瑰簲鐨勯檮浠惰褰�
+      const attachmentIndex = mockAttachmentData.findIndex(item => item.judgmentId == id);
+      while (attachmentIndex !== -1) {
+        mockAttachmentData.splice(attachmentIndex, 1);
+      }
+    }
+  });
+
+  return {
+    code: 200,
+    message: "鍒犻櫎鎴愬姛"
+  };
+};
+
+// 瀵煎嚭姝讳骸鍒ゅ畾
+export const exportDeathJudgment = async (queryParams) => {
+  await delay(1000);
+
+  // 妯℃嫙瀵煎嚭鍔熻兘
+  const { data } = await listDeathJudgment(queryParams);
+
+  return {
+    code: 200,
+    message: "瀵煎嚭鎴愬姛",
+    data: {
+      fileName: `姝讳骸鍒ゅ畾鏁版嵁_${new Date().getTime()}.xlsx`,
+      downloadUrl: "/api/export/deathJudgment"
+    }
+  };
+};
+
+// 闄勪欢鐩稿叧API
+export const uploadAttachment = async (file, judgmentId, type) => {
+  await delay(1500);
+
+  const newAttachment = {
+    id: Math.max(...mockAttachmentData.map(item => item.id), 0) + 1,
+    judgmentId: parseInt(judgmentId),
+    type: type,
+    typeName: getTypeName(type),
+    fileName: file.name,
+    fileSize: file.size,
+    uploadTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+    uploader: "褰撳墠鐢ㄦ埛",
+    fileUrl: URL.createObjectURL(file)
+  };
+
+  mockAttachmentData.push(newAttachment);
+
+  return {
+    code: 200,
+    message: "涓婁紶鎴愬姛",
+    data: newAttachment
+  };
+};
+
+export const deleteAttachment = async (attachmentId) => {
+  await delay();
+
+  const index = mockAttachmentData.findIndex(item => item.id == attachmentId);
+
+  if (index !== -1) {
+    mockAttachmentData.splice(index, 1);
+
+    return {
+      code: 200,
+      message: "鍒犻櫎鎴愬姛"
+    };
+  } else {
+    return {
+      code: 404,
+      message: "闄勪欢涓嶅瓨鍦�"
+    };
+  }
+};
+
+export const getAttachments = async (judgmentId) => {
+  await delay();
+
+  const attachments = mockAttachmentData.filter(item => item.judgmentId == judgmentId);
+
+  return {
+    code: 200,
+    message: "success",
+    data: attachments
+  };
+};
+
+// 杈呭姪鍑芥暟
+function getTypeName(type) {
+  const typeMap = {
+    "1": "鑴戞浜″垽瀹氳〃",
+    "2": "鑴戠數鍥捐瘎浼拌〃",
+    "3": "鐭綔浼忔湡浣撴劅璇卞彂鐢典綅璇勪及琛�",
+    "4": "缁忛澶氭櫘鍕掕秴澹拌瘎浼拌褰�",
+    "5": "鍗仴濮旇剳鎹熶激璐ㄦ帶涓績 - 涓村簥缁煎悎璇勪及琛�",
+    "6": "UW璇勫垎琛�",
+    "7": "蹇冩浜″垽瀹氳〃"
+  };
+
+  return typeMap[type] || "鏈煡绫诲瀷";
+}
diff --git a/src/views/business/ethicalReview/ethicalReviewInfo.vue b/src/views/business/ethicalReview/ethicalReviewInfo.vue
new file mode 100644
index 0000000..d505029
--- /dev/null
+++ b/src/views/business/ethicalReview/ethicalReviewInfo.vue
@@ -0,0 +1,1526 @@
+<template>
+  <div class="ethics-review-detail">
+    <el-card class="detail-card">
+      <!-- 鍩虹淇℃伅 -->
+      <div slot="header" class="clearfix">
+        <span class="detail-title">浼︾悊瀹℃煡鍩烘湰淇℃伅</span>
+        <div style="float: right;">
+          <el-button type="primary" @click="handleSave" :loading="saveLoading">
+            淇濆瓨
+          </el-button>
+
+          <el-button
+            type="warning"
+            @click="handleEndReview"
+            :disabled="form.ethicsConclusion === 'terminated'"
+          >
+            缁撴潫瀹℃煡
+          </el-button>
+        </div>
+      </div>
+
+      <el-form :model="form" ref="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+              <el-input v-model="form.hospitalNo" readonly />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+              <el-input v-model="form.donorName" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="鎬у埆" prop="gender">
+              <el-select v-model="form.gender" 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="16">
+            <el-form-item label="鐤剧梾璇婃柇" prop="diagnosis">
+              <el-input v-model="form.diagnosis" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="浼︾悊缁撹" prop="ethicsConclusion">
+              <el-select v-model="form.ethicsConclusion" style="width: 100%">
+                <el-option label="瀹℃煡涓�" value="reviewing" />
+                <el-option label="鍚屾剰" value="approved" />
+                <el-option
+                  label="淇敼鍚庡悓鎰�"
+                  value="approved_with_modifications"
+                />
+                <el-option label="淇敼鍚庨噸瀹�" value="re-review" />
+                <el-option label="涓嶅悓鎰�" value="disapproved" />
+                <el-option label="缁堟瀹℃煡" value="terminated" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="瀹℃煡鏃堕棿" prop="reviewTime">
+              <el-date-picker
+                v-model="form.reviewTime"
+                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="registrant">
+              <el-input v-model="form.registrant" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="浼︾悊鎰忚" prop="ethicsOpinion">
+              <el-input
+                type="textarea"
+                :rows="3"
+                v-model="form.ethicsOpinion"
+                placeholder="璇疯緭鍏ヤ鸡鐞嗗鏌ユ剰瑙�"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-form-item label="鐧昏鏃堕棿" prop="registrationTime">
+          <el-date-picker
+            v-model="form.registrationTime"
+            type="datetime"
+            value-format="yyyy-MM-dd HH:mm:ss"
+            style="width: 100%"
+          />
+        </el-form-item>
+      </el-form>
+    </el-card>
+    <!-- 闄勪欢涓婁紶 -->
+    <el-card class="attachment-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title">鐩稿叧闄勪欢</span>
+        <el-button type="primary" size="mini" @click="handleUploadAttachment">
+          涓婁紶闄勪欢
+        </el-button>
+      </div>
+
+      <el-table :data="attachments" style="width: 100%">
+        <el-table-column label="鏂囦欢鍚嶇О" min-width="200">
+          <template slot-scope="scope">
+            <div class="file-info">
+              <i
+                class="el-icon-document"
+                style="margin-right: 8px; color: #409EFF;"
+              ></i>
+              <span>{{ scope.row.fileName }}</span>
+            </div>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鏂囦欢绫诲瀷" width="100" 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="100" align="center">
+          <template slot-scope="scope">
+            <span>{{ formatFileSize(scope.row.fileSize) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="涓婁紶鏃堕棿" width="160" align="center">
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.uploadTime) }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="涓婁紶浜�" width="100" align="center">
+          <template slot-scope="scope">
+            <span>{{ scope.row.uploader }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鎿嶄綔" width="120" align="center">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handlePreviewAttachment(scope.row)"
+              >棰勮</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-download"
+              @click="handleDownloadAttachment(scope.row)"
+              >涓嬭浇</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+    <!-- 涓撳瀹℃煡鎯呭喌 -->
+    <el-card class="expert-card">
+      <div slot="header" class="clearfix">
+        <span class="detail-title"
+          >涓撳瀹℃煡鎯呭喌 (18浣嶆櫘閫氫笓瀹� + 1浣嶄富浠讳笓瀹�)</span
+        >
+        <div style="float: right;">
+          <el-button
+            size="mini"
+            type="primary"
+            @click="handleSendToNormalExperts"
+            :disabled="!canSendToNormalExperts"
+          >
+            鍙戦�佹櫘閫氫笓瀹�
+          </el-button>
+          <el-button
+            size="mini"
+            type="success"
+            @click="handleSendToChiefExpert"
+            :disabled="!canSendToChiefExpert"
+          >
+            鍙戦�佷富浠讳笓瀹�
+          </el-button>
+          <el-button
+            size="mini"
+            type="warning"
+            @click="handleBatchSend"
+            :disabled="!canBatchSend"
+          >
+            鎵归噺鍙戦��
+          </el-button>
+        </div>
+      </div>
+ <!-- 涓撳缁熻淇℃伅 -->
+      <div
+        class="expert-stats"
+        style="margin-top: 20px; padding: 15px; background: #f5f7fa; border-radius: 4px;"
+      >
+        <el-row :gutter="20">
+          <el-col :span="6">
+            <div class="stat-item">
+              <span class="stat-label">鏅�氫笓瀹跺凡鍚屾剰:</span>
+              <span class="stat-value">{{ approvedNormalExperts }}/18</span>
+            </div>
+          </el-col>
+          <el-col :span="6">
+            <div class="stat-item">
+              <span class="stat-label">涓讳换涓撳鐘舵��:</span>
+              <span class="stat-value">{{ chiefExpertStatus }}</span>
+            </div>
+          </el-col>
+          <el-col :span="6">
+            <div class="stat-item">
+              <span class="stat-label">鎬诲畬鎴愯繘搴�:</span>
+              <span class="stat-value">{{ completionRate }}%</span>
+            </div>
+          </el-col>
+          <el-col :span="6">
+            <div class="stat-item">
+              <span class="stat-label">瀹℃煡缁撴灉:</span>
+              <span class="stat-value">
+                <el-tag :type="overallConclusionFilter">
+                  {{ overallConclusionText }}
+                </el-tag>
+              </span>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+      <!-- 涓撳瀹℃煡琛ㄦ牸 -->
+      <el-table
+        :data="expertReviews"
+        v-loading="expertLoading"
+        style="width: 100%"
+        heiht="300"
+        :row-class-name="getExpertRowClassName"
+      >
+        <el-table-column label="搴忓彿" width="60" align="center" type="index" />
+
+        <el-table-column
+          label="涓撳濮撳悕"
+          width="120"
+          align="center"
+          fixed="left"
+        >
+          <template slot-scope="scope">
+            <span>{{ scope.row.expertName }}</span>
+            <el-tag
+              v-if="scope.row.isChief"
+              size="mini"
+              type="danger"
+              style="margin-left: 5px;"
+              >涓讳换</el-tag
+            >
+          </template>
+        </el-table-column>
+
+        <el-table-column label="涓撳绫诲瀷" width="100" align="center">
+          <template slot-scope="scope">
+            <span :class="scope.row.isChief ? 'chief-expert' : 'normal-expert'">
+              {{ scope.row.isChief ? "涓讳换涓撳" : "鏅�氫笓瀹�" }}
+            </span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="瀹℃煡鐘舵��" width="100" align="center">
+          <template slot-scope="scope">
+            <el-tag :type="statusFilter(scope.row.reviewStatus)" size="small">
+              {{ statusTextFilter(scope.row.reviewStatus) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="涓撳缁撹" width="120" align="center">
+          <template slot-scope="scope">
+            <el-tag
+              v-if="scope.row.expertConclusion"
+              :type="conclusionFilter(scope.row.expertConclusion)"
+              size="small"
+            >
+              {{ conclusionTextFilter(scope.row.expertConclusion) }}
+            </el-tag>
+            <span v-else class="no-data">-</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="瀹℃煡鎰忚" min-width="200" show-overflow-tooltip>
+          <template slot-scope="scope">
+            <span :class="{ 'expert-opinion': scope.row.expertOpinion }">
+              {{ scope.row.expertOpinion || "鏆傛棤鎰忚" }}
+            </span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="瀹℃煡鏃堕棿" width="160" align="center">
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.reviewTime ? parseTime(scope.row.reviewTime) : "鏈鏌�"
+            }}</span>
+          </template>
+        </el-table-column>
+
+        <el-table-column label="鎿嶄綔" width="180" align="center" fixed="right">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-s-promotion"
+              @click="handleSendToExpert(scope.row)"
+              :disabled="scope.row.reviewStatus === 'submitted'"
+              :class="{ 'sent-button': scope.row.reviewStatus === 'submitted' }"
+            >
+              {{ scope.row.reviewStatus === "submitted" ? "宸插彂閫�" : "鍙戦��" }}
+            </el-button>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleEditExpertReview(scope.row)"
+              :disabled="scope.row.reviewStatus !== 'submitted'"
+            >
+              缂栬緫
+            </el-button>
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-view"
+              @click="handleViewExpertReview(scope.row)"
+            >
+              璇︽儏
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+
+    </el-card>
+
+    <!-- 鍙戦�佷笓瀹跺璇濇 -->
+    <el-dialog
+      title="鍙戦�佷笓瀹跺鏌�"
+      :visible.sync="sendDialogVisible"
+      width="500px"
+    >
+      <el-form :model="sendForm" ref="sendForm" label-width="100px">
+        <el-form-item label="涓撳绫诲瀷" prop="expertType">
+          <el-radio-group v-model="sendForm.expertType">
+            <el-radio label="normal">鏅�氫笓瀹�</el-radio>
+            <el-radio label="chief">涓讳换涓撳</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item
+          label="閫夋嫨涓撳"
+          prop="expertIds"
+          v-if="sendForm.expertType === 'normal'"
+        >
+          <el-select
+            v-model="sendForm.expertIds"
+            multiple
+            placeholder="璇烽�夋嫨涓撳"
+            style="width: 100%"
+          >
+            <el-option
+              v-for="expert in availableExperts"
+              :key="expert.id"
+              :label="expert.name"
+              :value="expert.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鍙戦�佸唴瀹�" prop="content">
+          <el-input
+            type="textarea"
+            :rows="4"
+            v-model="sendForm.content"
+            placeholder="璇疯緭鍏ュ彂閫佺粰涓撳鐨勫鏌ュ唴瀹硅鏄�"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="sendDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleSendConfirm"
+          >纭鍙戦��</el-button
+        >
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import {
+  getEthicsReviewDetail,
+  updateEthicsReview,
+  sendExpertReview,
+  endEthicsReview,
+  uploadAttachment,
+  deleteAttachment,
+  getAttachments
+} from "./ethicsReview";
+
+export default {
+  name: "EthicsReviewDetail",
+  data() {
+    return {
+      // 琛ㄥ崟鏁版嵁
+      form: {
+        id: undefined,
+        hospitalNo: "",
+        donorName: "",
+        gender: "",
+        age: "",
+        diagnosis: "",
+        ethicsConclusion: "reviewing",
+        ethicsOpinion: "",
+        reviewTime: "",
+        registrant: "",
+        registrationTime: new Date()
+          .toISOString()
+          .replace("T", " ")
+          .substring(0, 19)
+      },
+      // 琛ㄥ崟楠岃瘉瑙勫垯
+      rules: {
+        donorName: [
+          { required: true, message: "鎹愮尞鑰呭鍚嶄笉鑳戒负绌�", trigger: "blur" }
+        ],
+        ethicsConclusion: [
+          { required: true, message: "浼︾悊缁撹涓嶈兘涓虹┖", trigger: "change" }
+        ],
+        reviewTime: [
+          { required: true, message: "瀹℃煡鏃堕棿涓嶈兘涓虹┖", trigger: "change" }
+        ]
+      },
+      // 淇濆瓨鍔犺浇鐘舵��
+      saveLoading: false,
+
+      // 闄勪欢鏁版嵁
+      attachments: [],
+      expertReviews: [
+        // 鏅�氫笓瀹讹紙18浣嶏級- 鍒濆鐘舵�佷负鐢宠涓�
+        {
+          id: 1,
+          expertName: "寮犳暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 2,
+          expertName: "鏉庢暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 3,
+          expertName: "鐜嬫暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 4,
+          expertName: "鍒樻暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 5,
+          expertName: "闄堟暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 6,
+          expertName: "鏉ㄦ暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 7,
+          expertName: "榛勬暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 8,
+          expertName: "璧垫暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 9,
+          expertName: "鍛ㄦ暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 10,
+          expertName: "鍚存暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 11,
+          expertName: "寰愭暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 12,
+          expertName: "瀛欐暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 13,
+          expertName: "鏈辨暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 14,
+          expertName: "椹暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 15,
+          expertName: "鑳℃暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 16,
+          expertName: "鏋楁暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 17,
+          expertName: "閮暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        {
+          id: 18,
+          expertName: "浣曟暀鎺�",
+          isChief: false,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        },
+        // 涓讳换涓撳锛�1浣嶏級
+        {
+          id: 19,
+          expertName: "涓讳换涓撳",
+          isChief: true,
+          reviewStatus: "applying",
+          expertConclusion: "",
+          expertOpinion: "",
+          reviewTime: ""
+        }
+      ],
+      expertLoading: false,
+      attachmentLoading: false,
+      // 鍙戦�佸璇濇
+      sendDialogVisible: false,
+      sendForm: {
+        expertType: "normal",
+        expertIds: [],
+        content: ""
+      },
+      // 涓婁紶鐩稿叧
+      uploadDialogVisible: false,
+      uploadLoading: false,
+      tempFileList: [],
+      // 鍙敤涓撳鍒楄〃
+      availableExperts: [
+        { id: 1, name: "寮犳暀鎺�", type: "normal" },
+        { id: 2, name: "鏉庢暀鎺�", type: "normal" },
+        { id: 3, name: "鐜嬫暀鎺�", type: "normal" },
+        { id: 4, name: "璧典富浠�", type: "chief" }
+      ]
+    };
+  },
+  computed: {
+    // 璁$畻灞炴�э細鏅�氫笓瀹跺悓鎰忔暟閲�
+    approvedNormalExperts() {
+      return this.expertReviews.filter(
+        expert => !expert.isChief && expert.expertConclusion === "approved"
+      ).length;
+    },
+    // 璁$畻灞炴�э細涓讳换涓撳鐘舵��
+    chiefExpertStatus() {
+      const chiefExpert = this.expertReviews.find(expert => expert.isChief);
+      return chiefExpert
+        ? this.statusTextFilter(chiefExpert.reviewStatus)
+        : "鏈垎閰�";
+    },
+    // 璁$畻灞炴�э細瀹屾垚杩涘害
+    completionRate() {
+      const totalExperts = this.expertReviews.length;
+      const completedExperts = this.expertReviews.filter(
+        expert => expert.reviewStatus === "submitted"
+      ).length;
+      return totalExperts > 0
+        ? Math.round((completedExperts / totalExperts) * 100)
+        : 0;
+    },
+    // 璁$畻灞炴�э細鎬讳綋缁撹
+    overallConclusionText() {
+      if (this.approvedNormalExperts >= 12) {
+        return "閫氳繃";
+      } else if (this.approvedNormalExperts >= 9) {
+        return "淇敼鍚庨�氳繃";
+      } else {
+        return "涓嶉�氳繃";
+      }
+    },
+    overallConclusionFilter() {
+      if (this.approvedNormalExperts >= 12) {
+        return "success";
+      } else if (this.approvedNormalExperts >= 9) {
+        return "warning";
+      } else {
+        return "danger";
+      }
+    },
+    // 鏄惁鍙互鍙戦�佺粰鏅�氫笓瀹�
+    canSendToNormalExperts() {
+      return (
+        this.expertReviews.filter(
+          expert => !expert.isChief && expert.reviewStatus === "applying"
+        ).length > 0
+      );
+    },
+    // 鏄惁鍙互鍙戦�佺粰涓讳换涓撳锛堥渶瑕佽嚦灏�12涓櫘閫氫笓瀹跺悓鎰忥級
+    canSendToChiefExpert() {
+      return (
+        this.approvedNormalExperts >= 12 &&
+        this.expertReviews.filter(
+          expert => expert.isChief && expert.reviewStatus === "applying"
+        ).length > 0
+      );
+    },
+    // 鏄惁鍙互鎵归噺鍙戦��
+    canBatchSend() {
+      return (
+        this.expertReviews.filter(expert => expert.reviewStatus === "applying")
+          .length > 0
+      );
+    },
+    // 鏄惁鍙互鍙戦�佷笓瀹跺鏌�
+    canSendToExperts() {
+      return this.form.id && this.form.ethicsConclusion === "reviewing";
+    },
+    // 褰撳墠鐢ㄦ埛淇℃伅
+    currentUser() {
+      return JSON.parse(sessionStorage.getItem("user") || "{}");
+    }
+  },
+  created() {
+    const id = this.$route.query.id;
+    if (id) {
+      this.getDetail(id);
+      this.getAttachments(id);
+      // 涓嶅啀闇�瑕佷粠鎺ュ彛鑾峰彇涓撳鍒楄〃锛屼娇鐢ㄥ浐瀹氱殑expertReviews鏁版嵁
+    } else if (this.$route.path.includes("/add")) {
+      this.generateHospitalNo();
+      this.form.registrant = this.currentUser.username || "褰撳墠鐢ㄦ埛";
+    }
+  },
+  methods: {
+    // 鐢熸垚浣忛櫌鍙�
+    generateHospitalNo() {
+      const timestamp = Date.now().toString();
+      this.form.hospitalNo = "D" + timestamp.slice(-6);
+    },
+    getExpertRowClassName({ row }) {
+      return row.isChief ? "chief-expert-row" : "normal-expert-row";
+    },
+    // 鑾峰彇璇︽儏
+    getDetail(id) {
+      getEthicsReviewDetail(id)
+        .then(response => {
+          if (response.code === 200) {
+            this.form = response.data;
+          }
+        })
+        .catch(error => {
+          console.error("鑾峰彇浼︾悊瀹℃煡璇︽儏澶辫触:", error);
+          this.$message.error("鑾峰彇璇︽儏澶辫触");
+        });
+    },
+
+    // 鑾峰彇涓撳瀹℃煡鍒楄〃
+    getExpertReviews(ethicsReviewId) {
+      this.expertLoading = true;
+      // 妯℃嫙鏁版嵁 - 瀹為檯椤圭洰涓粠鎺ュ彛鑾峰彇
+      setTimeout(() => {
+        this.expertReviews = [
+          // 鏅�氫笓瀹讹紙18浣嶏級
+          {
+            id: 1,
+            expertName: "寮犳暀鎺�",
+            isChief: false,
+            reviewStatus: "submitted",
+            expertConclusion: "approved",
+            expertOpinion: "绗﹀悎浼︾悊瑕佹眰",
+            reviewTime: "2023-12-01 10:30:00"
+          },
+          {
+            id: 2,
+            expertName: "鏉庢暀鎺�",
+            isChief: false,
+            reviewStatus: "submitted",
+            expertConclusion: "approved",
+            expertOpinion: "鏂规璁捐鍚堢悊",
+            reviewTime: "2023-12-01 11:20:00"
+          },
+          {
+            id: 3,
+            expertName: "鐜嬫暀鎺�",
+            isChief: false,
+            reviewStatus: "applying",
+            expertConclusion: "",
+            expertOpinion: "",
+            reviewTime: ""
+          },
+          // 涓讳换涓撳锛�1浣嶏級
+          {
+            id: 19,
+            expertName: "璧典富浠�",
+            isChief: true,
+            reviewStatus: "applying",
+            expertConclusion: "",
+            expertOpinion: "",
+            reviewTime: ""
+          }
+        ];
+        this.expertLoading = false;
+      }, 500);
+    },
+
+    // 鑾峰彇闄勪欢鍒楄〃
+    getAttachments(ethicsReviewId) {
+      this.attachmentLoading = true;
+      getAttachments(ethicsReviewId)
+        .then(response => {
+          if (response.code === 200) {
+            this.attachments = response.data;
+          }
+          this.attachmentLoading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇闄勪欢鍒楄〃澶辫触:", error);
+          this.attachmentLoading = false;
+        });
+    },
+
+    // 鐘舵�佽繃婊ゅ櫒
+    statusFilter(status) {
+      const statusMap = {
+        applying: "info",
+        submitted: "success"
+      };
+      return statusMap[status] || "info";
+    },
+
+    statusTextFilter(status) {
+      const statusMap = {
+        applying: "鐢宠涓�",
+        submitted: "宸叉彁浜�"
+      };
+      return statusMap[status] || "鏈煡";
+    },
+
+    // 缁撹杩囨护鍣�
+    conclusionFilter(conclusion) {
+      const conclusionMap = {
+        approved: "success",
+        approved_with_modifications: "warning",
+        disapproved: "danger"
+      };
+      return conclusionMap[conclusion] || "info";
+    },
+
+    conclusionTextFilter(conclusion) {
+      const conclusionMap = {
+        approved: "鍚屾剰",
+        approved_with_modifications: "淇敼鍚庡悓鎰�",
+        disapproved: "涓嶅悓鎰�"
+      };
+      return conclusionMap[conclusion] || "鏈煡";
+    },
+
+    // 淇濆瓨淇℃伅
+    handleSave() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.saveLoading = true;
+          const apiMethod = this.form.id ? updateEthicsReview : addEthicsReview;
+
+          apiMethod(this.form)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("淇濆瓨鎴愬姛");
+                if (!this.form.id) {
+                  this.form.id = response.data.id;
+                  this.$router.replace({
+                    query: { ...this.$route.query, id: this.form.id }
+                  });
+                }
+              }
+            })
+            .catch(error => {
+              console.error("淇濆瓨澶辫触:", error);
+              this.$message.error("淇濆瓨澶辫触");
+            })
+            .finally(() => {
+              this.saveLoading = false;
+            });
+        }
+      });
+    },
+
+    // 鍙戦�佷笓瀹跺鏌�
+    handleSendToExperts() {
+      this.sendDialogVisible = true;
+    },
+
+    // 鍙戦�佺粰鏅�氫笓瀹�
+    handleSendToNormalExperts() {
+      const normalExperts = this.expertReviews.filter(
+        expert => !expert.isChief && expert.reviewStatus === "applying"
+      );
+      this.sendForm.expertIds = normalExperts.map(expert => expert.id);
+      this.sendForm.expertType = "normal";
+      this.sendDialogVisible = true;
+    },
+
+    // 鍙戦�佺粰涓讳换涓撳
+    handleSendToChiefExpert() {
+      const chiefExpert = this.expertReviews.find(
+        expert => expert.isChief && expert.reviewStatus === "applying"
+      );
+      if (chiefExpert) {
+        this.sendForm.expertIds = [chiefExpert.id];
+        this.sendForm.expertType = "chief";
+        this.sendDialogVisible = true;
+      }
+    },
+
+    // 鎵归噺鍙戦��
+    handleBatchSend() {
+      const applyingExperts = this.expertReviews.filter(
+        expert => expert.reviewStatus === "applying"
+      );
+      this.sendForm.expertIds = applyingExperts.map(expert => expert.id);
+      this.sendForm.expertType = "batch";
+      this.sendDialogVisible = true;
+    },
+
+    // 鍙戦�佺粰鍗曚釜涓撳
+    handleSendToExpert(expert) {
+      this.sendForm.expertIds = [expert.id];
+      this.sendForm.expertType = expert.isChief ? "chief" : "normal";
+      this.sendDialogVisible = true;
+    },
+
+    // 纭鍙戦��
+    handleSendConfirm() {
+      if (this.sendForm.expertIds.length === 0) {
+        this.$message.warning("璇烽�夋嫨瑕佸彂閫佺殑涓撳");
+        return;
+      }
+
+      sendExpertReview({
+        ethicsReviewId: this.form.id,
+        expertIds: this.sendForm.expertIds,
+        content: this.sendForm.content
+      })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍙戦�佹垚鍔�");
+            this.sendDialogVisible = false;
+            this.getExpertReviews(this.form.id);
+            this.sendForm = {
+              expertType: "normal",
+              expertIds: [],
+              content: ""
+            };
+          }
+        })
+        .catch(error => {
+          console.error("鍙戦�佸け璐�:", error);
+          this.$message.error("鍙戦�佸け璐�");
+        });
+    },
+
+    // 缁撴潫瀹℃煡
+    handleEndReview() {
+      this.$confirm(
+        "纭畾瑕佺粨鏉熸湰娆′鸡鐞嗗鏌ュ悧锛熺粨鏉熷悗灏嗘棤娉曚慨鏀逛笓瀹跺鏌ョ粨鏋溿��",
+        "鎻愮ず",
+        {
+          confirmButtonText: "纭畾",
+          cancelButtonText: "鍙栨秷",
+          type: "warning"
+        }
+      )
+        .then(() => {
+          endEthicsReview(this.form.id)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("瀹℃煡宸茬粨鏉�");
+                this.form.ethicsConclusion = "terminated";
+              }
+            })
+            .catch(error => {
+              console.error("缁撴潫瀹℃煡澶辫触:", error);
+              this.$message.error("缁撴潫瀹℃煡澶辫触");
+            });
+        })
+        .catch(() => {});
+    },
+
+    // 缂栬緫涓撳瀹℃煡
+    handleEditExpertReview(expert) {
+      this.$prompt("璇疯緭鍏ュ鏌ユ剰瑙�", "缂栬緫涓撳瀹℃煡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        inputValue: expert.expertOpinion || "",
+        inputValidator: value => {
+          if (!value || value.trim() === "") {
+            return "瀹℃煡鎰忚涓嶈兘涓虹┖";
+          }
+          return true;
+        }
+      })
+        .then(({ value }) => {
+          // 妯℃嫙鏇存柊涓撳瀹℃煡
+          const index = this.expertReviews.findIndex(e => e.id === expert.id);
+          if (index !== -1) {
+            this.expertReviews[index].expertOpinion = value;
+            this.$message.success("瀹℃煡鎰忚宸叉洿鏂�");
+          }
+        })
+        .catch(() => {});
+    },
+
+    // 鏌ョ湅涓撳瀹℃煡璇︽儏
+    handleViewExpertReview(expert) {
+      this.$alert(
+        `
+        <div>
+          <p><strong>涓撳濮撳悕锛�</strong>${expert.expertName}</p>
+          <p><strong>涓撳绫诲瀷锛�</strong>${
+            expert.isChief ? "涓讳换涓撳" : "鏅�氫笓瀹�"
+          }</p>
+          <p><strong>瀹℃煡鐘舵�侊細</strong>${this.statusTextFilter(
+            expert.reviewStatus
+          )}</p>
+          <p><strong>涓撳缁撹锛�</strong>${
+            expert.expertConclusion
+              ? this.conclusionTextFilter(expert.expertConclusion)
+              : "鏈彁浜�"
+          }</p>
+          <p><strong>瀹℃煡鎰忚锛�</strong>${expert.expertOpinion || "鏃�"}</p>
+          <p><strong>瀹℃煡鏃堕棿锛�</strong>${expert.reviewTime || "鏈鏌�"}</p>
+        </div>
+      `,
+        "涓撳瀹℃煡璇︽儏",
+        {
+          dangerouslyUseHTMLString: true,
+          customClass: "expert-review-detail-dialog"
+        }
+      );
+    },
+
+    // 涓婁紶闄勪欢
+    handleUploadAttachment() {
+      this.uploadDialogVisible = true;
+    },
+
+    // 涓婁紶鍓嶆牎楠�
+    beforeUpload(file) {
+      const allowedTypes = [
+        "application/pdf",
+        "image/jpeg",
+        "image/png",
+        "application/msword",
+        "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+        "application/vnd.ms-excel",
+        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+      ];
+
+      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") ||
+        file.name.endsWith(".xls") ||
+        file.name.endsWith(".xlsx");
+
+      if (!isTypeOk) {
+        this.$message.error("鏂囦欢鏍煎紡涓嶆敮鎸�");
+        return false;
+      }
+
+      if (file.size > maxSize) {
+        this.$message.error("鏂囦欢澶у皬涓嶈兘瓒呰繃10MB");
+        return false;
+      }
+
+      return true;
+    },
+
+    // 鏂囦欢閫夋嫨鍙樺寲
+    handleFileChange(file, fileList) {
+      this.tempFileList = fileList;
+    },
+
+    // 鎻愪氦涓婁紶
+    submitUpload() {
+      if (this.tempFileList.length === 0) {
+        this.$message.warning("璇峰厛閫夋嫨瑕佷笂浼犵殑鏂囦欢");
+        return;
+      }
+
+      this.uploadLoading = true;
+
+      const uploadPromises = this.tempFileList.map(file => {
+        const formData = new FormData();
+        formData.append("file", file.raw);
+        formData.append("ethicsReviewId", this.form.id);
+
+        return uploadAttachment(formData);
+      });
+
+      Promise.all(uploadPromises)
+        .then(responses => {
+          this.$message.success("鏂囦欢涓婁紶鎴愬姛");
+          this.uploadDialogVisible = false;
+          this.tempFileList = [];
+          this.getAttachments(this.form.id);
+        })
+        .catch(error => {
+          console.error("涓婁紶澶辫触:", error);
+          this.$message.error("鏂囦欢涓婁紶澶辫触");
+        })
+        .finally(() => {
+          this.uploadLoading = false;
+        });
+    },
+
+    // 棰勮闄勪欢
+    handlePreviewAttachment(attachment) {
+      if (attachment.fileName.endsWith(".pdf")) {
+        window.open(attachment.fileUrl, "_blank");
+      } else if (attachment.fileName.match(/\.(jpg|jpeg|png)$/i)) {
+        this.$alert(
+          `<img src="${attachment.fileUrl}" style="max-width: 100%;" alt="${attachment.fileName}">`,
+          "鍥剧墖棰勮",
+          {
+            dangerouslyUseHTMLString: true,
+            customClass: "image-preview-dialog"
+          }
+        );
+      } else {
+        this.$message.info("璇ユ枃浠剁被鍨嬫殏涓嶆敮鎸佸湪绾块瑙堬紝璇蜂笅杞藉悗鏌ョ湅");
+      }
+    },
+
+    // 涓嬭浇闄勪欢
+    handleDownloadAttachment(attachment) {
+      const link = document.createElement("a");
+      link.href = attachment.fileUrl;
+      link.download = attachment.fileName;
+      link.click();
+      this.$message.success(`寮�濮嬩笅杞�: ${attachment.fileName}`);
+    },
+
+    // 鍒犻櫎闄勪欢
+    handleRemoveAttachment(attachment) {
+      this.$confirm("纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          deleteAttachment(attachment.id)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success("闄勪欢鍒犻櫎鎴愬姛");
+                this.getAttachments(this.form.id);
+              }
+            })
+            .catch(error => {
+              console.error("鍒犻櫎闄勪欢澶辫触:", error);
+              this.$message.error("鍒犻櫎闄勪欢澶辫触");
+            });
+        })
+        .catch(() => {});
+    },
+
+    // 鑾峰彇鏂囦欢绫诲瀷
+    getFileType(fileName) {
+      const ext = fileName
+        .split(".")
+        .pop()
+        .toLowerCase();
+      const typeMap = {
+        pdf: "PDF",
+        doc: "DOC",
+        docx: "DOCX",
+        xls: "XLS",
+        xlsx: "XLSX",
+        jpg: "JPG",
+        jpeg: "JPEG",
+        png: "PNG"
+      };
+      return typeMap[ext] || ext.toUpperCase();
+    },
+
+    // 鏂囦欢澶у皬鏍煎紡鍖�
+    formatFileSize(size) {
+      if (size === 0) 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];
+    },
+
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time) {
+      if (!time) return "";
+      const date = new Date(time);
+      return `${date.getFullYear()}-${(date.getMonth() + 1)
+        .toString()
+        .padStart(2, "0")}-${date
+        .getDate()
+        .toString()
+        .padStart(2, "0")} ${date
+        .getHours()
+        .toString()
+        .padStart(2, "0")}:${date
+        .getMinutes()
+        .toString()
+        .padStart(2, "0")}`;
+    }
+  }
+};
+</script>
+<style scoped>
+.ethics-review-detail {
+  padding: 20px;
+  background-color: #f5f7fa;
+}
+
+.detail-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.expert-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.attachment-card {
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.detail-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+}
+
+.expert-stats {
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  color: rgb(43, 181, 245);
+  border-radius: 8px;
+  margin-bottom: 20px;
+}
+
+.stat-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 10px;
+}
+
+.stat-label {
+  font-size: 12px;
+  opacity: 0.9;
+  margin-bottom: 5px;
+}
+
+.stat-value {
+  font-size: 18px;
+  font-weight: bold;
+}
+
+.upload-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding: 10px;
+  background-color: #f8f9fa;
+  border-radius: 4px;
+}
+
+.upload-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: #303133;
+}
+
+.file-info {
+  display: flex;
+  align-items: center;
+}
+
+.empty-attachment {
+  text-align: center;
+  padding: 40px 0;
+  color: #909399;
+}
+
+/* 琛ㄥ崟鏍峰紡浼樺寲 */
+:deep(.el-form-item__label) {
+  font-weight: 500;
+}
+
+:deep(.el-input__inner) {
+  border-radius: 4px;
+}
+
+:deep(.el-textarea__inner) {
+  border-radius: 4px;
+  resize: vertical;
+}
+
+/* 琛ㄦ牸鏍峰紡浼樺寲 */
+:deep(.el-table) {
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+:deep(.el-table th) {
+  background-color: #f5f7fa;
+  color: #606266;
+  font-weight: 500;
+}
+
+:deep(.el-table .cell) {
+  padding: 8px 12px;
+}
+
+/* 鎸夐挳鏍峰紡浼樺寲 */
+:deep(.el-button--primary) {
+  background: linear-gradient(135deg, #409eff 0%, #3375e0 100%);
+  border: none;
+  border-radius: 4px;
+}
+
+:deep(.el-button--success) {
+  background: linear-gradient(135deg, #67c23a 0%, #529b2f 100%);
+  border: none;
+  border-radius: 4px;
+}
+
+:deep(.el-button--warning) {
+  background: linear-gradient(135deg, #e6a23c 0%, #d18c2a 100%);
+  border: none;
+  border-radius: 4px;
+}
+
+:deep(.el-button--danger) {
+  background: linear-gradient(135deg, #f56c6c 0%, #e05b5b 100%);
+  border: none;
+  border-radius: 4px;
+}
+
+/* 鏍囩鏍峰紡 */
+:deep(.el-tag) {
+  border-radius: 12px;
+  border: none;
+  font-weight: 500;
+}
+
+/* 瀵硅瘽妗嗘牱寮忎紭鍖� */
+:deep(.el-dialog) {
+  border-radius: 8px;
+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+}
+
+:deep(.el-dialog__header) {
+  background: linear-gradient(135deg, #f5f7fa 0%, #e4e7ed 100%);
+  border-bottom: 1px solid #e4e7ed;
+  padding: 15px 20px;
+}
+
+:deep(.el-dialog__title) {
+  font-weight: 600;
+  color: #303133;
+}
+
+/* 涓婁紶缁勪欢鏍峰紡 */
+:deep(.el-upload-dragger) {
+  border: 2px dashed #dcdfe6;
+  border-radius: 6px;
+  background-color: #fafafa;
+  transition: all 0.3s ease;
+}
+
+:deep(.el-upload-dragger:hover) {
+  border-color: #409eff;
+  background-color: #f0f7ff;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+  .ethics-review-detail {
+    padding: 10px;
+  }
+
+  .expert-stats .el-col {
+    margin-bottom: 10px;
+  }
+
+  .upload-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 10px;
+  }
+}
+
+/* 鍔ㄧ敾鏁堟灉 */
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+
+.fade-enter,
+.fade-leave-to {
+  opacity: 0;
+}
+
+/* 鍔犺浇鐘舵�� */
+.loading-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 200px;
+}
+/* 涓撳绫诲瀷鏍峰紡 */
+.normal-expert {
+  color: #409eff;
+  font-weight: 500;
+}
+
+.chief-expert {
+  color: #f56c6c;
+  font-weight: 600;
+}
+
+/* 涓撳琛屾牱寮� */
+:deep(.normal-expert-row) {
+  background-color: #fafafa;
+}
+
+:deep(.chief-expert-row) {
+  background-color: #fff7e6;
+}
+
+:deep(.normal-expert-row:hover) {
+  background-color: #f0f7ff;
+}
+
+:deep(.chief-expert-row:hover) {
+  background-color: #ffecc2;
+}
+
+/* 鏃犳暟鎹牱寮� */
+.no-data {
+  color: #909399;
+  font-style: italic;
+}
+
+/* 涓撳鎰忚鏍峰紡 */
+.expert-opinion {
+  color: #303133;
+  line-height: 1.5;
+}
+
+/* 宸插彂閫佹寜閽牱寮� */
+.sent-button {
+  color: #67c23a !important;
+}
+
+/* 琛ㄦ牸琛屾偓鍋滄晥鏋� */
+:deep(.el-table__row:hover) {
+  transform: translateY(-1px);
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  transition: all 0.3s ease;
+}
+/* 鑷畾涔夋粴鍔ㄦ潯 */
+:deep(::-webkit-scrollbar) {
+  width: 6px;
+  height: 6px;
+}
+
+:deep(::-webkit-scrollbar-track) {
+  background: #f1f1f1;
+  border-radius: 3px;
+}
+
+:deep(::-webkit-scrollbar-thumb) {
+  background: #c1c1c1;
+  border-radius: 3px;
+}
+
+:deep(::-webkit-scrollbar-thumb:hover) {
+  background: #a8a8a8;
+}
+
+/* 涓撳瀹℃煡琛ㄦ牸鐗规畩鏍峰紡 */
+.expert-table-special :deep(.el-table__row) {
+  transition: all 0.3s ease;
+}
+
+.expert-table-special :deep(.el-table__row:hover) {
+  background-color: #f0f7ff;
+  transform: translateY(-1px);
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+/* 涓讳换涓撳琛岄珮浜� */
+:deep(.chief-expert-row) {
+  background-color: #fff7e6 !important;
+}
+
+:deep(.chief-expert-row:hover) {
+  background-color: #ffecc2 !important;
+}
+</style>
diff --git a/src/views/business/ethicalReview/ethicsReview.js b/src/views/business/ethicalReview/ethicsReview.js
new file mode 100644
index 0000000..3c38792
--- /dev/null
+++ b/src/views/business/ethicalReview/ethicsReview.js
@@ -0,0 +1,392 @@
+// 妯℃嫙浼︾悊瀹℃煡鏁版嵁
+const mockEthicsReviewData = [
+  {
+    id: 1,
+    hospitalNo: "D202312001",
+    donorName: "寮犱笁",
+    gender: "0",
+    age: 45,
+    diagnosis: "鑴戝浼�",
+    ethicsConclusion: "reviewing",
+    ethicsOpinion: "璇ョ梾渚嬬鍚堝櫒瀹樻崘鐚鸡鐞嗗鏌ュ熀鏈姹傦紝寤鸿鎻愪氦涓撳濮斿憳浼氬璁�",
+    reviewTime: "2023-12-01 14:30:00",
+    judgmentDoctor: "鐜嬪尰鐢�",
+    judgmentDescription: "缁忚繃澶氭鑴戞浜″垽瀹氾紝绗﹀悎鑴戞浜′复搴婅瘖鏂爣鍑�",
+    registrant: "鏉庡崗璋冨憳",
+    registrationTime: "2023-12-01 15:00:00",
+    createTime: "2023-12-01 10:00:00"
+  },
+  {
+    id: 2,
+    hospitalNo: "D202312002",
+    donorName: "鏉庡洓",
+    gender: "1",
+    age: 38,
+    diagnosis: "蹇冭剰楠ゅ仠",
+    ethicsConclusion: "approved",
+    ethicsOpinion: "瀹跺睘鎰忔効鏄庣‘锛屽尰鐤楃▼搴忓悎瑙勶紝鍚屾剰杩涜鍣ㄥ畼鎹愮尞",
+    reviewTime: "2023-12-02 09:15:00",
+    judgmentDoctor: "鍒樺尰鐢�",
+    judgmentDescription: "蹇冩浜″垽瀹氾紝蹇冪數鍥惧憟鐩寸嚎锛屾棤鑷富鍛煎惛",
+    registrant: "寮犲崗璋冨憳",
+    registrationTime: "2023-12-02 10:00:00",
+    createTime: "2023-12-02 08:30:00"
+  }
+];
+
+// 妯℃嫙涓撳瀹℃煡鏁版嵁
+const mockExpertReviewData = [
+  {
+    id: 1,
+    ethicsReviewId: 1,
+    expertName: "寮犳暀鎺�",
+    isChief: false,
+    reviewStatus: "submitted",
+    expertConclusion: "approved",
+    expertOpinion: "鐥呬緥璧勬枡瀹屾暣锛岀鍚堜鸡鐞嗗鏌ヨ姹�",
+    reviewTime: "2023-12-01 16:30:00"
+  },
+  {
+    id: 2,
+    ethicsReviewId: 1,
+    expertName: "鏉庢暀鎺�",
+    isChief: false,
+    reviewStatus: "submitted",
+    expertConclusion: "approved",
+    expertOpinion: "鎹愮尞娴佺▼瑙勮寖锛屽悓鎰忓鏌�",
+    reviewTime: "2023-12-01 17:20:00"
+  },
+  {
+    id: 19,
+    ethicsReviewId: 1,
+    expertName: "璧典富浠�",
+    isChief: true,
+    reviewStatus: "applying",
+    expertConclusion: "",
+    expertOpinion: "",
+    reviewTime: ""
+  }
+];
+
+// 妯℃嫙闄勪欢鏁版嵁
+const mockAttachmentData = [
+  {
+    id: 1,
+    ethicsReviewId: 1,
+    fileName: "浼︾悊瀹℃煡鐢宠琛�.pdf",
+    fileSize: 2048576,
+    uploadTime: "2023-12-01 09:30:00",
+    uploader: "寮犲尰鐢�",
+    fileUrl: "/attachments/ethics_application_1.pdf"
+  },
+  {
+    id: 2,
+    ethicsReviewId: 1,
+    fileName: "涓撳璇勫鎰忚姹囨��.docx",
+    fileSize: 512345,
+    uploadTime: "2023-12-01 14:20:00",
+    uploader: "鏉庡尰鐢�",
+    fileUrl: "/attachments/expert_review_1.docx"
+  }
+];
+
+// 妯℃嫙API鍝嶅簲寤惰繜
+const delay = (ms = 500) => new Promise(resolve => setTimeout(resolve, ms));
+
+// 鏌ヨ浼︾悊瀹℃煡鍒楄〃
+export const listEthicsReview = async (queryParams = {}) => {
+  await delay();
+
+  const {
+    pageNum = 1,
+    pageSize = 10,
+    hospitalNo,
+    donorName,
+    ethicsConclusion,
+    reviewTimeRange = []
+  } = queryParams;
+
+  // 杩囨护鏁版嵁
+  let filteredData = mockEthicsReviewData.filter(item => {
+    let match = true;
+
+    if (hospitalNo && !item.hospitalNo.includes(hospitalNo)) {
+      match = false;
+    }
+
+    if (donorName && !item.donorName.includes(donorName)) {
+      match = false;
+    }
+
+    if (ethicsConclusion && item.ethicsConclusion !== ethicsConclusion) {
+      match = false;
+    }
+
+    if (reviewTimeRange.length === 2) {
+      const reviewTime = new Date(item.reviewTime);
+      const startTime = new Date(reviewTimeRange[0]);
+      const endTime = new Date(reviewTimeRange[1]);
+      endTime.setDate(endTime.getDate() + 1);
+
+      if (reviewTime < startTime || reviewTime >= endTime) {
+        match = false;
+      }
+    }
+
+    return match;
+  });
+
+  // 鍒嗛〉
+  const startIndex = (pageNum - 1) * pageSize;
+  const endIndex = startIndex + parseInt(pageSize);
+  const paginatedData = filteredData.slice(startIndex, endIndex);
+
+  return {
+    code: 200,
+    message: "success",
+    data: {
+      rows: paginatedData,
+      total: filteredData.length,
+      pageNum: parseInt(pageNum),
+      pageSize: parseInt(pageSize)
+    }
+  };
+};
+
+// 鑾峰彇浼︾悊瀹℃煡璇︾粏淇℃伅
+export const getEthicsReviewDetail = async (id) => {
+  await delay();
+
+  const detail = mockEthicsReviewData.find(item => item.id == id);
+
+  if (detail) {
+    return {
+      code: 200,
+      message: "success",
+      data: detail
+    };
+  } else {
+    return {
+      code: 404,
+      message: "浼︾悊瀹℃煡璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鏂板浼︾悊瀹℃煡
+export const addEthicsReview = async (data) => {
+  await delay();
+
+  const newId = Math.max(...mockEthicsReviewData.map(item => item.id), 0) + 1;
+  const hospitalNo = `D${new Date().getFullYear()}${String(new Date().getMonth() + 1).padStart(2, '0')}${String(newId).padStart(3, '0')}`;
+
+  const newRecord = {
+    ...data,
+    id: newId,
+    hospitalNo,
+    registrationTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+    createTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+  };
+
+  mockEthicsReviewData.unshift(newRecord);
+
+  return {
+    code: 200,
+    message: "鏂板鎴愬姛",
+    data: newRecord
+  };
+};
+
+// 淇敼浼︾悊瀹℃煡
+export const updateEthicsReview = async (data) => {
+  await delay();
+
+  const index = mockEthicsReviewData.findIndex(item => item.id == data.id);
+
+  if (index !== -1) {
+    mockEthicsReviewData[index] = {
+      ...mockEthicsReviewData[index],
+      ...data,
+      updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
+    };
+
+    return {
+      code: 200,
+      message: "淇敼鎴愬姛",
+      data: mockEthicsReviewData[index]
+    };
+  } else {
+    return {
+      code: 404,
+      message: "浼︾悊瀹℃煡璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 鍒犻櫎浼︾悊瀹℃煡
+export const delEthicsReview = async (ids) => {
+  await delay();
+
+  const idArray = Array.isArray(ids) ? ids : [ids];
+
+  idArray.forEach(id => {
+    const index = mockEthicsReviewData.findIndex(item => item.id == id);
+    if (index !== -1) {
+      mockEthicsReviewData.splice(index, 1);
+    }
+  });
+
+  return {
+    code: 200,
+    message: "鍒犻櫎鎴愬姛"
+  };
+};
+
+// 缁撴潫浼︾悊瀹℃煡
+export const endEthicsReview = async (id) => {
+  await delay();
+
+  const index = mockEthicsReviewData.findIndex(item => item.id == id);
+
+  if (index !== -1) {
+    mockEthicsReviewData[index].ethicsConclusion = 'terminated';
+    mockEthicsReviewData[index].reviewTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
+
+    return {
+      code: 200,
+      message: "瀹℃煡宸茬粨鏉�",
+      data: mockEthicsReviewData[index]
+    };
+  } else {
+    return {
+      code: 404,
+      message: "浼︾悊瀹℃煡璁板綍涓嶅瓨鍦�"
+    };
+  }
+};
+
+// 瀵煎嚭浼︾悊瀹℃煡
+export const exportEthicsReview = async (queryParams) => {
+  await delay(1000);
+
+  const { data } = await listEthicsReview(queryParams);
+
+  return {
+    code: 200,
+    message: "瀵煎嚭鎴愬姛",
+    data: {
+      fileName: `浼︾悊瀹℃煡鏁版嵁_${new Date().getTime()}.xlsx`,
+      downloadUrl: "/api/export/ethicsReview"
+    }
+  };
+};
+
+// 鑾峰彇涓撳瀹℃煡鍒楄〃
+export const getExpertReviews = async (ethicsReviewId) => {
+  await delay();
+
+  const reviews = mockExpertReviewData.filter(item => item.ethicsReviewId == ethicsReviewId);
+
+  return {
+    code: 200,
+    message: "success",
+    data: reviews
+  };
+};
+
+// 鍙戦�佷笓瀹跺鏌�
+export const sendExpertReview = async (data) => {
+  await delay(1500);
+
+  const { ethicsReviewId, expertIds, content } = data;
+
+  // 妯℃嫙鍙戦�佺煭淇$粰涓撳
+  expertIds.forEach(expertId => {
+    const expert = mockExpertReviewData.find(item => item.id === expertId);
+    if (expert) {
+      expert.reviewStatus = 'submitted';
+      expert.reviewTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
+    }
+  });
+
+  return {
+    code: 200,
+    message: "涓撳瀹℃煡閭�璇峰彂閫佹垚鍔�",
+    data: {
+      sentCount: expertIds.length,
+      content: content
+    }
+  };
+};
+
+// 鑾峰彇闄勪欢鍒楄〃
+export const getAttachments = async (ethicsReviewId) => {
+  await delay();
+
+  const attachments = mockAttachmentData.filter(item => item.ethicsReviewId == ethicsReviewId);
+
+  return {
+    code: 200,
+    message: "success",
+    data: attachments
+  };
+};
+
+// 涓婁紶闄勪欢
+export const uploadAttachment = async (formData) => {
+  await delay(2000);
+
+  const newAttachment = {
+    id: Math.max(...mockAttachmentData.map(item => item.id), 0) + 1,
+    ethicsReviewId: parseInt(formData.get('ethicsReviewId')),
+    fileName: `闄勪欢_${new Date().getTime()}.pdf`,
+    fileSize: 1024000,
+    uploadTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
+    uploader: "褰撳墠鐢ㄦ埛",
+    fileUrl: `/attachments/ethics_${formData.get('ethicsReviewId')}_${new Date().getTime()}.pdf`
+  };
+
+  mockAttachmentData.push(newAttachment);
+
+  return {
+    code: 200,
+    message: "涓婁紶鎴愬姛",
+    data: newAttachment
+  };
+};
+
+// 鍒犻櫎闄勪欢
+export const deleteAttachment = async (attachmentId) => {
+  await delay();
+
+  const index = mockAttachmentData.findIndex(item => item.id == attachmentId);
+
+  if (index !== -1) {
+    mockAttachmentData.splice(index, 1);
+
+    return {
+      code: 200,
+      message: "鍒犻櫎鎴愬姛"
+    };
+  } else {
+    return {
+      code: 404,
+      message: "闄勪欢涓嶅瓨鍦�"
+    };
+  }
+};
+
+export default {
+  listEthicsReview,
+  getEthicsReviewDetail,
+  addEthicsReview,
+  updateEthicsReview,
+  delEthicsReview,
+  endEthicsReview,
+  exportEthicsReview,
+  getExpertReviews,
+  sendExpertReview,
+  getAttachments,
+  uploadAttachment,
+  deleteAttachment
+};
diff --git a/src/views/business/ethicalReview/index.vue b/src/views/business/ethicalReview/index.vue
new file mode 100644
index 0000000..f1e75a8
--- /dev/null
+++ b/src/views/business/ethicalReview/index.vue
@@ -0,0 +1,480 @@
+<template>
+  <div class="ethics-review-list">
+    <!-- 鏌ヨ鏉′欢 -->
+    <el-card class="search-card">
+      <el-form
+        :model="queryParams"
+        ref="queryForm"
+        :inline="true"
+        label-width="100px"
+      >
+        <el-form-item label="浣忛櫌鍙�" prop="hospitalNo">
+          <el-input
+            v-model="queryParams.hospitalNo"
+            placeholder="璇疯緭鍏ヤ綇闄㈠彿"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="鎹愮尞鑰呭鍚�" prop="donorName">
+          <el-input
+            v-model="queryParams.donorName"
+            placeholder="璇疯緭鍏ユ崘鐚�呭鍚�"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="浼︾悊缁撹" prop="ethicsConclusion">
+          <el-select
+            v-model="queryParams.ethicsConclusion"
+            placeholder="璇烽�夋嫨浼︾悊缁撹"
+            clearable
+            style="width: 200px"
+          >
+            <el-option label="瀹℃煡涓�" value="reviewing" />
+            <el-option label="鍚屾剰" value="approved" />
+            <el-option label="淇敼鍚庡悓鎰�" value="approved_with_modifications" />
+            <el-option label="淇敼鍚庨噸瀹�" value="re-review" />
+            <el-option label="涓嶅悓鎰�" value="disapproved" />
+            <el-option label="缁堟瀹℃煡" value="terminated" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="瀹℃煡鏃堕棿鑼冨洿" prop="reviewTimeRange">
+          <el-date-picker
+            v-model="queryParams.reviewTimeRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="yyyy-MM-dd"
+            style="width: 240px"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" @click="handleQuery"
+            >鎼滅储</el-button
+          >
+          <el-button icon="el-icon-refresh" @click="resetQuery">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 鎿嶄綔鎸夐挳 -->
+    <el-card class="tool-card">
+      <el-row :gutter="10">
+        <el-col :span="16">
+          <el-button type="primary" icon="el-icon-plus" @click="handleCreate"
+            >鏂板缓瀹℃煡</el-button
+          >
+          <el-button
+            type="success"
+            icon="el-icon-edit"
+            :disabled="single"
+            @click="handleUpdate"
+            >淇敼</el-button
+          >
+          <el-button
+            type="danger"
+            icon="el-icon-delete"
+            :disabled="multiple"
+            @click="handleDelete"
+            >鍒犻櫎</el-button
+          >
+          <el-button
+            type="warning"
+            icon="el-icon-download"
+            @click="handleExport"
+            >瀵煎嚭</el-button
+          >
+          <el-button
+            type="info"
+            icon="el-icon-check"
+            :disabled="multiple"
+            @click="handleEndReview"
+            >缁撴潫瀹℃煡</el-button
+          >
+        </el-col>
+        <el-col :span="8" style="text-align: right">
+          <el-tooltip content="鍒锋柊" placement="top">
+            <el-button icon="el-icon-refresh" circle @click="getList" />
+          </el-tooltip>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <el-card>
+      <el-table
+        v-loading="loading"
+        :data="ethicsReviewList"
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column
+          label="浣忛櫌鍙�"
+          align="center"
+          prop="hospitalNo"
+          width="120"
+        />
+        <el-table-column
+          label="鎹愮尞鑰呭鍚�"
+          align="center"
+          prop="donorName"
+          width="120"
+        />
+        <el-table-column label="鎬у埆" align="center" prop="gender" width="80">
+          <template slot-scope="scope">
+            <dict-tag
+              :options="dict.type.sys_user_sex"
+              :value="parseInt(scope.row.gender)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="骞撮緞" align="center" prop="age" width="80" />
+        <el-table-column
+          label="鐤剧梾璇婃柇"
+          align="center"
+          prop="diagnosis"
+          min-width="180"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="浼︾悊缁撹"
+          align="center"
+          prop="ethicsConclusion"
+          width="120"
+        >
+          <template slot-scope="scope">
+            <el-tag :type="conclusionFilter(scope.row.ethicsConclusion)">
+              {{ conclusionTextFilter(scope.row.ethicsConclusion) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="浼︾悊鎰忚"
+          align="center"
+          prop="ethicsOpinion"
+          min-width="200"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="瀹℃煡鏃堕棿"
+          align="center"
+          prop="reviewTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.reviewTime
+                ? parseTime(scope.row.reviewTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鐧昏鏃堕棿"
+          align="center"
+          prop="registrationTime"
+          width="160"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.registrationTime
+                ? parseTime(scope.row.registrationTime, "{y}-{m}-{d} {h}:{i}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="鐧昏浜�"
+          align="center"
+          prop="registrant"
+          width="100"
+        />
+        <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-view"
+              @click="handleView(scope.row)"
+              >璇︽儏</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click="handleUpdate(scope.row)"
+              >淇敼</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-check"
+              @click="handleEndReview(scope.row)"
+              :disabled="scope.row.ethicsConclusion === 'terminated'"
+              >缁撴潫</el-button
+            >
+            <el-button
+              size="mini"
+              type="text"
+              icon="el-icon-delete"
+              style="color: #F56C6C"
+              @click="handleDelete(scope.row)"
+              >鍒犻櫎</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 鍒嗛〉缁勪欢 -->
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        :page.sync="queryParams.pageNum"
+        :limit.sync="queryParams.pageSize"
+        @pagination="getList"
+      />
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { listEthicsReview, delEthicsReview, exportEthicsReview, endEthicsReview } from "./ethicsReview";
+import Pagination from "@/components/Pagination";
+
+export default {
+  name: "EthicsReviewList",
+  components: { Pagination },
+  dicts: ["sys_user_sex"],
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 浼︾悊瀹℃煡琛ㄦ牸鏁版嵁
+      ethicsReviewList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        hospitalNo: undefined,
+        donorName: undefined,
+        ethicsConclusion: undefined,
+        reviewTimeRange: []
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 浼︾悊缁撹杩囨护鍣�
+    conclusionFilter(conclusion) {
+      const conclusionMap = {
+        "reviewing": "warning", // 瀹℃煡涓�
+        "approved": "success", // 鍚屾剰
+        "approved_with_modifications": "primary", // 淇敼鍚庡悓鎰�
+        "re-review": "info", // 淇敼鍚庨噸瀹�
+        "disapproved": "danger", // 涓嶅悓鎰�
+        "terminated": "info" // 缁堟瀹℃煡
+      };
+      return conclusionMap[conclusion] || "info";
+    },
+    conclusionTextFilter(conclusion) {
+      const conclusionMap = {
+        "reviewing": "瀹℃煡涓�",
+        "approved": "鍚屾剰",
+        "approved_with_modifications": "淇敼鍚庡悓鎰�",
+        "re-review": "淇敼鍚庨噸瀹�",
+        "disapproved": "涓嶅悓鎰�",
+        "terminated": "缁堟瀹℃煡"
+      };
+      return conclusionMap[conclusion] || "鏈煡";
+    },
+    // 鏌ヨ浼︾悊瀹℃煡鍒楄〃
+    getList() {
+      this.loading = true;
+      listEthicsReview(this.queryParams)
+        .then(response => {
+          if (response.code === 200) {
+            this.ethicsReviewList = response.data.rows;
+            this.total = response.data.total;
+          } else {
+            this.$message.error("鑾峰彇鏁版嵁澶辫触");
+          }
+          this.loading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇浼︾悊瀹℃煡鍒楄〃澶辫触:", error);
+          this.loading = false;
+          this.$message.error("鑾峰彇鏁版嵁澶辫触");
+        });
+    },
+    // 鎼滅储鎸夐挳鎿嶄綔
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    // 閲嶇疆鎸夐挳鎿嶄綔
+    resetQuery() {
+      this.$refs.queryForm.resetFields();
+      this.handleQuery();
+    },
+    // 澶氶�夋閫変腑鏁版嵁
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id);
+      this.single = selection.length !== 1;
+      this.multiple = !selection.length;
+    },
+    // 鏌ョ湅璇︽儏
+    handleView(row) {
+      this.$router.push({
+        path: "/case/ethicalReviewInfo",
+        query: { id: row.id }
+      });
+    },
+    // 鏂板鎸夐挳鎿嶄綔
+    handleCreate() {
+      this.$router.push("/case/ethicalReviewInfo");
+    },
+    // 淇敼鎸夐挳鎿嶄綔
+    handleUpdate(row) {
+      const id = row.id || this.ids[0];
+      this.$router.push({
+        path: "/case/ethicalReviewInfo",
+        query: { id: id }
+      });
+    },
+    // 鍒犻櫎鎸夐挳鎿嶄綔
+    handleDelete(row) {
+      const ids = row.id ? [row.id] : this.ids;
+      this.$confirm("鏄惁纭鍒犻櫎閫変腑鐨勬暟鎹」锛�", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          return delEthicsReview(ids);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍒犻櫎鎴愬姛");
+            this.getList();
+          }
+        })
+        .catch(() => {});
+    },
+    // 缁撴潫瀹℃煡鎿嶄綔
+    handleEndReview(row) {
+      const ids = row.id ? [row.id] : this.ids;
+      this.$confirm("鏄惁纭缁撴潫閫変腑鐨勫鏌ラ」鐩紵", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          return endEthicsReview(ids);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("瀹℃煡宸茬粨鏉�");
+            this.getList();
+          }
+        })
+        .catch(() => {});
+    },
+    // 瀵煎嚭鎸夐挳鎿嶄綔
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm("鏄惁纭瀵煎嚭鎵�鏈変鸡鐞嗗鏌ユ暟鎹紵", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.loading = true;
+          return exportEthicsReview(queryParams);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("瀵煎嚭鎴愬姛");
+          }
+          this.loading = false;
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time, pattern) {
+      if (!time) return "";
+      const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}";
+      let date;
+      if (typeof time === "object") {
+        date = time;
+      } else {
+        if (typeof time === "string" && /^[0-9]+$/.test(time)) {
+          time = parseInt(time);
+        }
+        if (typeof time === "number" && time.toString().length === 10) {
+          time = time * 1000;
+        }
+        date = new Date(time);
+      }
+      const formatObj = {
+        y: date.getFullYear(),
+        m: date.getMonth() + 1,
+        d: date.getDate(),
+        h: date.getHours(),
+        i: date.getMinutes(),
+        s: date.getSeconds(),
+        a: date.getDay()
+      };
+      const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+        let value = formatObj[key];
+        if (key === "a") {
+          return ["鏃�", "涓�", "浜�", "涓�", "鍥�", "浜�", "鍏�"][value];
+        }
+        if (result.length > 0 && value < 10) {
+          value = "0" + value;
+        }
+        return value || 0;
+      });
+      return time_str;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.ethics-review-list {
+  padding: 20px;
+}
+
+.search-card {
+  margin-bottom: 20px;
+}
+
+.tool-card {
+  margin-bottom: 20px;
+}
+
+.fixed-width .el-button {
+  margin: 0 5px;
+}
+</style>
diff --git a/src/views/business/maintain/components/BloodRoutinePanel.vue b/src/views/business/maintain/components/BloodRoutinePanel.vue
new file mode 100644
index 0000000..a43e2fd
--- /dev/null
+++ b/src/views/business/maintain/components/BloodRoutinePanel.vue
@@ -0,0 +1,693 @@
+<template>
+  <div class="medical-panel">
+    <div class="panel-header">
+      <h3>琛�甯歌璁板綍琛�</h3>
+      <div class="panel-actions">
+        <el-button
+          v-if="isEditing"
+          type="primary"
+          size="small"
+          @click="addColumn"
+          icon="el-icon-plus"
+        >
+          鏂板璁板綍鍒�
+        </el-button>
+        <el-tooltip content="鍒锋柊琛ㄦ牸甯冨眬" placement="top">
+          <el-button
+            size="small"
+            @click="forceTableLayout"
+            icon="el-icon-refresh"
+          >
+            鍒锋柊甯冨眬
+          </el-button>
+        </el-tooltip>
+      </div>
+    </div>
+
+    <el-table
+      :data="tableData"
+      border
+      style="width: 100%"
+      class="medical-table"
+      v-fit-columns
+      :key="tableKey"
+      @header-dragend="handleHeaderDragEnd"
+      v-loading="tableLoading"
+    >
+      <el-table-column
+        prop="itemName"
+        label="妫�娴嬮」鐩�"
+        width="200"
+        fixed
+        class-name="leave-alone"
+      >
+        <template #default="scope">
+          <div class="item-name-cell">
+            <span :class="{'required-item': scope.row.required}">
+              {{ scope.row.itemName }}
+            </span>
+            <el-tooltip
+              v-if="scope.row.reference"
+              :content="`鍙傝�冭寖鍥�: ${scope.row.reference}`"
+              placement="top"
+            >
+              <i class="el-icon-info reference-icon"></i>
+            </el-tooltip>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column
+        v-for="(col, index) in dynamicColumns"
+        :key="col.key"
+        :label="col.label"
+        :min-width="140"
+        :resizable="isEditing"
+        header-align="center"
+        align="center"
+      >
+        <template #default="scope">
+          <div class="cell-content-wrapper">
+            <el-input
+              v-if="isEditing"
+              v-model="scope.row.values[index]"
+              size="small"
+              :placeholder="getPlaceholder(scope.row)"
+              @blur="handleValueChange(scope.row, index)"
+              class="value-input"
+              :title="scope.row.values[index]"
+            />
+            <div v-else class="value-display-container">
+              <span class="value-text" :title="scope.row.values[index]">
+                {{ scope.row.values[index] || '-' }}
+              </span>
+              <span v-if="scope.row.values[index] && scope.row.unit" class="unit-text">
+                {{ scope.row.unit }}
+              </span>
+            </div>
+            <div v-if="scope.row.reference && scope.row.values[index]" class="validation-indicator">
+              <i
+                v-if="isValueValid(scope.row, scope.row.values[index])"
+                class="el-icon-success valid-icon"
+                title="鏁板�煎湪姝e父鑼冨洿鍐�"
+              ></i>
+              <i
+                v-else
+                class="el-icon-warning invalid-icon"
+                title="鏁板�艰秴鍑烘甯歌寖鍥�"
+              ></i>
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+
+      <!-- <el-table-column
+        v-if="isEditing"
+        label="鎿嶄綔"
+        width="120"
+        fixed="right"
+        class-name="leave-alone"
+      >
+        <template #default>
+          <el-button link type="primary" @click="addColumn" size="small">
+            鏂板鍒�
+          </el-button>
+        </template>
+      </el-table-column> -->
+    </el-table>
+
+    <!-- 缁熻淇℃伅 -->
+    <div v-if="showStatistics" class="statistics-section">
+      <el-card shadow="never">
+        <div class="stats-content">
+          <span class="stats-title">鏁版嵁缁熻:</span>
+          <span class="stats-item">鎬昏褰曟暟: {{ dynamicColumns.length }} 涓椂闂寸偣</span>
+          <span class="stats-item">宸插~鍐�: {{ filledCount }} 椤�</span>
+          <span class="stats-item">瀹屾垚搴�: {{ completionRate }}%</span>
+        </div>
+      </el-card>
+    </div>
+
+    <!-- 闄勪欢涓婁紶鍖哄煙 -->
+    <div class="attachment-section">
+      <div class="attachment-header">
+        <i class="el-icon-paperclip"></i>
+        <span class="attachment-title">闄勪欢涓婁紶</span>
+        <span class="attachment-tip">鏀寔涓婁紶妫�楠屾姤鍛婂崟绛夋枃浠� (鏈�澶�10涓�)</span>
+      </div>
+      <upload-attachment
+        :file-list="attachments"
+        @change="handleAttachmentChange"
+        :limit="10"
+        :accept="'.pdf,.jpg,.jpeg,.png,.doc,.docx'"
+      />
+    </div>
+
+    <!-- 鍒楃紪杈戝璇濇 -->
+    <el-dialog
+      :title="`${editingColumnIndex !== null ? '缂栬緫' : '鏂板'}鏃堕棿鐐筦"
+      :visible.sync="columnDialogVisible"
+      width="450px"
+      @closed="handleDialogClosed"
+    >
+      <el-form
+        :model="columnForm"
+        label-width="80px"
+        ref="columnForm"
+        :rules="columnRules"
+      >
+        <el-form-item label="鏃ユ湡" prop="date">
+          <el-date-picker
+            v-model="columnForm.date"
+            type="date"
+            placeholder="閫夋嫨鏃ユ湡"
+            value-format="yyyy-MM-dd"
+            style="width: 100%"
+            :disabled-date="disableFutureDates"
+          />
+        </el-form-item>
+        <el-form-item label="鏃堕棿" prop="time">
+          <el-time-picker
+            v-model="columnForm.time"
+            placeholder="閫夋嫨鏃堕棿"
+            value-format="HH:mm"
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input
+            v-model="columnForm.remark"
+            type="textarea"
+            :rows="2"
+            placeholder="鍙�夊~鍐欐椂闂寸偣澶囨敞淇℃伅"
+            maxlength="100"
+            show-word-limit
+          />
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="columnDialogVisible = false">鍙栨秷</el-button>
+        <el-button
+          v-if="editingColumnIndex !== null"
+          type="danger"
+          @click="handleDeleteColumn"
+        >
+          鍒犻櫎
+        </el-button>
+        <el-button type="primary" @click="confirmAddColumn" :loading="saveLoading">
+          纭畾
+        </el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import UploadAttachment from "@/components/UploadAttachment";
+
+export default {
+  name: 'BloodRoutinePanel',
+  components: {
+    UploadAttachment,
+  },
+  props: {
+    isEditing: {
+      type: Boolean,
+      default: false
+    },
+    initialData: {
+      type: Array,
+      default: () => []
+    },
+    showStatistics: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      tableData: [],
+      dynamicColumns: [
+        {
+          label: '2024-12-27\n08:00',
+          key: 'time1',
+          date: '2024-12-27',
+          time: '08:00',
+          remark: '鏅ㄨ捣妫�娴�'
+        }
+      ],
+      attachments: [],
+      columnDialogVisible: false,
+      columnForm: {
+        date: '',
+        time: '',
+        remark: ''
+      },
+      editingColumnIndex: null,
+      tableKey: 0,
+      tableLoading: false,
+      saveLoading: false,
+      columnRules: {
+        date: [
+          { required: true, message: '璇烽�夋嫨鏃ユ湡', trigger: 'change' }
+        ],
+        time: [
+          { required: true, message: '璇烽�夋嫨鏃堕棿', trigger: 'change' }
+        ]
+      }
+    };
+  },
+  computed: {
+    filledCount() {
+      let count = 0;
+      this.tableData.forEach(row => {
+        row.values.forEach(value => {
+          if (value && value.toString().trim() !== '') {
+            count++;
+          }
+        });
+      });
+      return count;
+    },
+    completionRate() {
+      const total = this.tableData.length * this.dynamicColumns.length;
+      return total > 0 ? Math.round((this.filledCount / total) * 100) : 0;
+    }
+  },
+  watch: {
+    isEditing(newVal) {
+      if (!newVal) {
+        this.$emit('data-change', {
+          type: 'blood_routine',
+          data: this.tableData,
+          columns: this.dynamicColumns,
+          attachments: this.attachments
+        });
+      }
+      this.$nextTick(() => {
+        this.forceTableLayout();
+      });
+    },
+    dynamicColumns: {
+      handler() {
+        this.$nextTick(() => {
+          this.forceTableLayout();
+        });
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  methods: {
+    initTableData() {
+      const medicalItems = [
+        {
+          itemName: 'WBC',
+          unit: '脳10鈦�/L',
+          required: true,
+          reference: '3.5-9.5',
+          min: 3.5,
+          max: 9.5,
+          type: 'number'
+        },
+        {
+          itemName: 'NEUT%',
+          unit: '%',
+          required: true,
+          reference: '40-75',
+          min: 40,
+          max: 75,
+          type: 'number'
+        },
+        {
+          itemName: 'Hb',
+          unit: 'g/L',
+          required: true,
+          reference: '130-175',
+          min: 130,
+          max: 175,
+          type: 'number'
+        },
+        {
+          itemName: '琛�灏忔澘',
+          unit: '脳10鈦�/L',
+          required: true,
+          reference: '125-350',
+          min: 125,
+          max: 350,
+          type: 'number'
+        }
+      ];
+
+      this.tableData = medicalItems.map(item => ({
+        ...item,
+        values: new Array(this.dynamicColumns.length).fill('')
+      }));
+    },
+
+    getPlaceholder(row) {
+      return row.reference ? `鍙傝��: ${row.reference}` : '璇疯緭鍏ユ暟鍊�';
+    },
+
+    isValueValid(row, value) {
+      if (!value || !row.min || !row.max) return true;
+      const numValue = parseFloat(value);
+      return !isNaN(numValue) && numValue >= row.min && numValue <= row.max;
+    },
+
+    addColumn() {
+      this.editingColumnIndex = null;
+      this.columnForm = {
+        date: new Date().toISOString().split('T')[0],
+        time: '08:00',
+        remark: ''
+      };
+      this.columnDialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.columnForm && this.$refs.columnForm.clearValidate();
+      });
+    },
+
+    editColumn(index) {
+      this.editingColumnIndex = index;
+      const column = this.dynamicColumns[index];
+      this.columnForm = {
+        date: column.date,
+        time: column.time,
+        remark: column.remark || ''
+      };
+      this.columnDialogVisible = true;
+    },
+
+    confirmAddColumn() {
+      this.$refs.columnForm.validate((valid) => {
+        if (!valid) {
+          this.$message.warning('璇峰畬鍠勬椂闂寸偣淇℃伅');
+          return;
+        }
+
+        this.saveLoading = true;
+
+        if (this.editingColumnIndex !== null) {
+          // 缂栬緫鐜版湁鍒�
+          const column = this.dynamicColumns[this.editingColumnIndex];
+          column.label = `${this.columnForm.date}\n${this.columnForm.time}`;
+          column.date = this.columnForm.date;
+          column.time = this.columnForm.time;
+          column.remark = this.columnForm.remark;
+          this.$message.success('鏃堕棿鐐逛慨鏀规垚鍔�');
+        } else {
+          // 鏂板鍒�
+          const newIndex = this.dynamicColumns.length + 1;
+          const newColumn = {
+            label: `${this.columnForm.date}\n${this.columnForm.time}`,
+            key: `time${Date.now()}`,
+            date: this.columnForm.date,
+            time: this.columnForm.time,
+            remark: this.columnForm.remark
+          };
+
+          this.dynamicColumns.push(newColumn);
+          this.tableData.forEach(row => {
+            row.values.push('');
+          });
+          this.$message.success('鏃堕棿鐐规坊鍔犳垚鍔�');
+        }
+
+        this.columnDialogVisible = false;
+        this.saveLoading = false;
+        this.tableKey += 1;
+      });
+    },
+
+    handleDeleteColumn() {
+      if (this.editingColumnIndex !== null) {
+        this.$confirm('纭畾瑕佸垹闄よ繖涓椂闂寸偣鍚楋紵', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          this.dynamicColumns.splice(this.editingColumnIndex, 1);
+          this.tableData.forEach(row => {
+            row.values.splice(this.editingColumnIndex, 1);
+          });
+          this.columnDialogVisible = false;
+          this.tableKey += 1;
+          this.$message.success('鏃堕棿鐐瑰垹闄ゆ垚鍔�');
+        });
+      }
+    },
+
+    handleDialogClosed() {
+      this.editingColumnIndex = null;
+      this.columnForm = {
+        date: '',
+        time: '',
+        remark: ''
+      };
+      this.$refs.columnForm && this.$refs.columnForm.clearValidate();
+    },
+
+    disableFutureDates(time) {
+      return time.getTime() > Date.now();
+    },
+
+    handleValueChange(row, columnIndex) {
+      this.$emit('data-change', {
+        type: 'blood_routine',
+        data: this.tableData,
+        columns: this.dynamicColumns
+      });
+    },
+
+    handleAttachmentChange(fileList) {
+      this.attachments = fileList;
+      this.$emit('attachment-change', {
+        type: 'blood_routine',
+        attachments: fileList
+      });
+    },
+
+    forceTableLayout() {
+      this.$nextTick(() => {
+        const table = this.$el.querySelector('.el-table');
+        if (table) {
+          window.dispatchEvent(new Event('resize'));
+        }
+      });
+    },
+
+    handleHeaderDragEnd() {
+      this.forceTableLayout();
+    },
+
+    exportData() {
+      return {
+        tableData: this.tableData,
+        columns: this.dynamicColumns,
+        statistics: {
+          filledCount: this.filledCount,
+          completionRate: this.completionRate,
+          totalColumns: this.dynamicColumns.length
+        },
+        exportTime: new Date().toISOString(),
+        attachments: this.attachments
+      };
+    }
+  },
+  mounted() {
+    this.initTableData();
+  }
+};
+</script>
+
+<style scoped>
+.medical-panel {
+  padding: 20px;
+  background: #fff;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.panel-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 24px;
+  padding-bottom: 16px;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.panel-header h3 {
+  margin: 0;
+  color: #303133;
+  font-size: 20px;
+  font-weight: 600;
+}
+
+.panel-actions {
+  display: flex;
+  gap: 12px;
+  align-items: center;
+}
+
+.medical-table {
+  margin-bottom: 24px;
+  border-radius: 4px;
+  overflow: hidden;
+}
+
+.medical-table ::v-deep .el-table__body-wrapper {
+  overflow-x: auto;
+}
+
+.item-name-cell {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.reference-icon {
+  color: #909399;
+  font-size: 14px;
+  cursor: help;
+  margin-left: 8px;
+}
+
+.required-item::before {
+  content: "*";
+  color: #f56c6c;
+  margin-right: 4px;
+}
+
+.cell-content-wrapper {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 8px;
+  min-height: 32px;
+}
+
+.value-input {
+  flex: 1;
+  min-width: 80px;
+}
+
+.value-display-container {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+}
+
+.value-text {
+  font-weight: 500;
+  color: #303133;
+  max-width: 80px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.unit-text {
+  color: #909399;
+  font-size: 12px;
+  flex-shrink: 0;
+}
+
+.validation-indicator {
+  flex-shrink: 0;
+}
+
+.valid-icon {
+  color: #67c23a;
+  font-size: 14px;
+}
+
+.invalid-icon {
+  color: #e6a23c;
+  font-size: 14px;
+}
+
+.statistics-section {
+  margin-bottom: 20px;
+}
+
+.stats-content {
+  display: flex;
+  gap: 20px;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.stats-title {
+  font-weight: 600;
+  color: #303133;
+}
+
+.stats-item {
+  color: #606266;
+  font-size: 14px;
+}
+
+.attachment-section {
+  margin-top: 24px;
+  padding: 20px;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+  background: #fafafa;
+}
+
+.attachment-header {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  margin-bottom: 16px;
+}
+
+.attachment-title {
+  font-weight: 600;
+  color: #409eff;
+}
+
+.attachment-tip {
+  font-size: 12px;
+  color: #909399;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+  .medical-panel {
+    padding: 12px;
+  }
+
+  .panel-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+  }
+
+  .panel-actions {
+    width: 100%;
+    justify-content: flex-end;
+  }
+
+  .stats-content {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 8px;
+  }
+
+  .cell-content-wrapper {
+    flex-direction: column;
+    gap: 4px;
+  }
+}
+
+/* 鍔ㄧ敾鏁堟灉 */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.3s;
+}
+.fade-enter, .fade-leave-to {
+  opacity: 0;
+}
+</style>
diff --git a/src/views/business/maintain/components/LiverKidneyPanel.vue b/src/views/business/maintain/components/LiverKidneyPanel.vue
new file mode 100644
index 0000000..a485fed
--- /dev/null
+++ b/src/views/business/maintain/components/LiverKidneyPanel.vue
@@ -0,0 +1,492 @@
+<template>
+  <div class="medical-panel">
+    <div class="panel-header">
+      <h3>鑲濆姛鑳借偩鍔熻兘璁板綍琛�</h3>
+      <el-button
+        v-if="isEditing"
+        type="primary"
+        size="small"
+        @click="addColumn"
+        icon="el-icon-plus"
+      >
+        鏂板璁板綍鍒�
+      </el-button>
+    </div>
+
+    <el-table
+      :data="tableData"
+      border
+      style="width: 100%"
+      class="medical-table"
+      :key="tableKey"
+      v-fit-columns
+      @header-dragend="handleHeaderDragEnd"
+    >
+      <el-table-column
+        prop="itemName"
+        label="妫�娴嬮」鐩�"
+        width="200"
+        fixed
+        class-name="leave-alone"
+      >
+        <template #default="scope">
+          <span :class="{'required-item': scope.row.required}">
+            {{ scope.row.itemName }}
+          </span>
+        </template>
+      </el-table-column>
+
+      <el-table-column
+        v-for="(col, index) in dynamicColumns"
+        :key="col.key"
+        :label="col.label"
+        :min-width="120"
+        :resizable="isEditing"
+      >
+        <template #default="scope">
+          <div class="cell-content">
+            <el-input
+              v-if="isEditing"
+              v-model="scope.row.values[index]"
+              size="small"
+              :placeholder="`璇疯緭鍏�${scope.row.unit ? scope.row.unit : '鏁板��'}`"
+              @blur="handleValueChange(scope.row, index)"
+              class="value-input"
+            />
+            <span v-else class="value-display">
+              {{ scope.row.values[index] || '-' }}
+              <span v-if="scope.row.values[index] && scope.row.unit" class="unit">
+                {{ scope.row.unit }}
+              </span>
+            </span>
+            <span v-if="scope.row.reference" class="reference-range">
+              ({{ scope.row.reference }})
+            </span>
+          </div>
+        </template>
+      </el-table-column>
+
+
+    </el-table>
+
+    <!-- 闄勪欢涓婁紶鍖哄煙 -->
+    <div class="attachment-section">
+      <div class="attachment-title">
+        <i class="el-icon-paperclip"></i>
+        闄勪欢涓婁紶
+        <span class="attachment-tip">鏀寔涓婁紶妫�楠屾姤鍛婂崟绛夋枃浠�</span>
+      </div>
+      <upload-attachment
+        :file-list="attachments"
+        @change="handleAttachmentChange"
+        :limit="10"
+        :accept="'.pdf,.jpg,.jpeg,.png,.doc,.docx'"
+      />
+    </div>
+
+    <!-- 鍒楃紪杈戝璇濇 -->
+    <el-dialog
+      title="缂栬緫鏃堕棿鐐�"
+      :visible.sync="columnDialogVisible"
+      width="400px"
+      @closed="handleDialogClosed"
+    >
+      <el-form :model="columnForm" label-width="80px" ref="columnForm">
+        <el-form-item
+          label="鏃ユ湡"
+          prop="date"
+          :rules="[{ required: true, message: '璇烽�夋嫨鏃ユ湡', trigger: 'change' }]"
+        >
+          <el-date-picker
+            v-model="columnForm.date"
+            type="date"
+            placeholder="閫夋嫨鏃ユ湡"
+            value-format="yyyy-MM-dd"
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item
+          label="鏃堕棿"
+          prop="time"
+          :rules="[{ required: true, message: '璇烽�夋嫨鏃堕棿', trigger: 'change' }]"
+        >
+          <el-time-picker
+            v-model="columnForm.time"
+            placeholder="閫夋嫨鏃堕棿"
+            value-format="HH:mm"
+            style="width: 100%"
+          />
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="columnDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="confirmAddColumn">纭畾</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import UploadAttachment from "@/components/UploadAttachment";
+
+export default {
+  name: 'LiverKidneyPanel',
+  components: {
+    UploadAttachment,
+  },
+  props: {
+    isEditing: {
+      type: Boolean,
+      default: false
+    },
+    initialData: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      tableData: [],
+      dynamicColumns: [
+        {
+          label: '2024-12-27\n08:00',
+          key: 'time1',
+          date: '2024-12-27',
+          time: '08:00'
+        },
+        {
+          label: '2024-12-27\n14:00',
+          key: 'time2',
+          date: '2024-12-27',
+          time: '14:00'
+        }
+      ],
+      attachments: [],
+      columnDialogVisible: false,
+      columnForm: {
+        date: '',
+        time: ''
+      },
+      tableKey: 0 // 鐢ㄤ簬寮哄埗閲嶆柊娓叉煋琛ㄦ牸
+    };
+  },
+  watch: {
+    isEditing(newVal) {
+      if (!newVal) {
+        // 淇濆瓨鏁版嵁
+        this.$emit('data-change', {
+          type: 'liver_kidney',
+          data: this.tableData,
+          columns: this.dynamicColumns,
+          attachments: this.attachments
+        });
+      }
+      // 缂栬緫妯″紡鍒囨崲鏃堕噸鏂拌绠楀垪瀹�
+      this.$nextTick(() => {
+        this.forceTableLayout();
+      });
+    },
+    dynamicColumns: {
+      handler() {
+        // 鍒楀彉鍖栨椂閲嶆柊璁$畻甯冨眬
+        this.$nextTick(() => {
+          this.forceTableLayout();
+        });
+      },
+      deep: true
+    }
+  },
+  methods: {
+    initTableData() {
+      const medicalItems = [
+        {
+          itemName: '琛�閽�',
+          unit: 'mmol/L',
+          required: true,
+          reference: '135-145'
+        },
+        {
+          itemName: '琛�閽�',
+          unit: 'mmol/L',
+          required: true,
+          reference: '3.5-5.5'
+        },
+        {
+          itemName: 'BUN',
+          unit: 'mg/dL',
+          required: true,
+          reference: '<20'
+        },
+        {
+          itemName: '鑲岄厫',
+          unit: '渭mol/L',
+          required: true,
+          reference: '<100'
+        },
+        {
+          itemName: '鎬昏儐绾㈢礌',
+          unit: '渭mol/L',
+          required: true,
+          reference: '<21'
+        },
+        {
+          itemName: 'ALT',
+          unit: 'U/L',
+          required: true,
+          reference: '<50'
+        },
+        {
+          itemName: 'AST',
+          unit: 'U/L',
+          required: true,
+          reference: '<40'
+        },
+        {
+          itemName: 'GGT',
+          unit: 'U/L',
+          required: true,
+          reference: '<57'
+        },
+        {
+          itemName: 'ALP',
+          unit: 'U/L',
+          required: true,
+          reference: '<120'
+        },
+        {
+          itemName: 'PT',
+          unit: '绉�',
+          required: true,
+          reference: '9.4-12.5'
+        },
+        {
+          itemName: 'INR',
+          unit: '',
+          required: true,
+          reference: '0.85-1.15'
+        }
+      ];
+
+      this.tableData = medicalItems.map(item => ({
+        ...item,
+        values: new Array(this.dynamicColumns.length).fill('')
+      }));
+    },
+
+    addColumn() {
+      this.columnForm = {
+        date: new Date().toISOString().split('T')[0],
+        time: '08:00'
+      };
+      this.columnDialogVisible = true;
+    },
+
+    confirmAddColumn() {
+      this.$refs.columnForm.validate((valid) => {
+        if (!valid) {
+          this.$message.warning('璇峰畬鍠勬椂闂寸偣淇℃伅');
+          return;
+        }
+
+        const newIndex = this.dynamicColumns.length + 1;
+        const newColumn = {
+          label: `${this.columnForm.date}\n${this.columnForm.time}`,
+          key: `time${newIndex}`,
+          date: this.columnForm.date,
+          time: this.columnForm.time
+        };
+
+        this.dynamicColumns.push(newColumn);
+
+        // 涓烘墍鏈夎鏂板涓�涓┖鍊�
+        this.tableData.forEach(row => {
+          row.values.push('');
+        });
+
+        this.columnDialogVisible = false;
+        this.$message.success('鏃堕棿鐐规坊鍔犳垚鍔�');
+
+        // 寮哄埗琛ㄦ牸閲嶆柊娓叉煋
+        this.tableKey += 1;
+      });
+    },
+
+    handleDialogClosed() {
+      this.columnForm = {
+        date: '',
+        time: ''
+      };
+      this.$refs.columnForm && this.$refs.columnForm.clearValidate();
+    },
+
+    handleValueChange(row, columnIndex) {
+      this.$emit('data-change', {
+        type: 'liver_kidney',
+        data: this.tableData,
+        columns: this.dynamicColumns
+      });
+    },
+
+    handleAttachmentChange(fileList) {
+      this.attachments = fileList;
+      this.$emit('attachment-change', {
+        type: 'liver_kidney',
+        attachments: fileList
+      });
+    },
+
+    // 寮哄埗琛ㄦ牸閲嶆柊甯冨眬[1,3](@ref)
+    forceTableLayout() {
+      this.$nextTick(() => {
+        const table = this.$el.querySelector('.el-table');
+        if (table && table.querySelector('colgroup')) {
+          // 瑙﹀彂琛ㄦ牸閲嶆柊璁$畻甯冨眬
+          this.$nextTick(() => {
+            window.dispatchEvent(new Event('resize'));
+          });
+        }
+      });
+    },
+
+    handleHeaderDragEnd() {
+      // 鍒楀鎷栨嫿缁撴潫鍚庨噸鏂拌绠楀竷灞�
+      this.forceTableLayout();
+    },
+
+    exportData() {
+      return {
+        tableData: this.tableData,
+        columns: this.dynamicColumns,
+        exportTime: new Date().toISOString(),
+        attachments: this.attachments
+      };
+    }
+  },
+  mounted() {
+    this.initTableData();
+    // 鍒濆娓叉煋鍚庤绠楀垪瀹�
+    this.$nextTick(() => {
+      this.forceTableLayout();
+    });
+  }
+};
+</script>
+
+<style scoped>
+.medical-panel {
+  padding: 20px;
+  background: #fff;
+  border-radius: 4px;
+  overflow: hidden;
+}
+
+.panel-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding-bottom: 15px;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.panel-header h3 {
+  margin: 0;
+  color: #303133;
+  font-size: 18px;
+  font-weight: 600;
+}
+
+.medical-table {
+  margin-bottom: 30px;
+  min-width: 100%;
+}
+
+.medical-table ::v-deep .el-table__body-wrapper {
+  overflow-x: auto;
+}
+
+.cell-content {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  min-height: 32px;
+}
+
+.value-input {
+  flex: 1;
+  margin-right: 8px;
+}
+
+.value-display {
+  font-weight: 500;
+  color: #303133;
+}
+
+.unit {
+  color: #909399;
+  font-size: 12px;
+  margin-left: 4px;
+}
+
+.reference-range {
+  color: #67c23a;
+  font-size: 12px;
+  font-style: italic;
+  margin-left: 8px;
+}
+
+.required-item::before {
+  content: "*";
+  color: #f56c6c;
+  margin-right: 4px;
+}
+
+.attachment-section {
+  margin-top: 30px;
+  padding: 20px;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+  background: #fafafa;
+}
+
+.attachment-title {
+  font-weight: bold;
+  margin-bottom: 15px;
+  color: #409eff;
+  display: flex;
+  align-items: center;
+}
+
+.attachment-tip {
+  font-size: 12px;
+  color: #909399;
+  margin-left: 10px;
+  font-weight: normal;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+  .medical-panel {
+    padding: 10px;
+  }
+
+  .panel-header {
+    flex-direction: column;
+    align-items: flex-start;
+  }
+
+  .panel-header h3 {
+    margin-bottom: 10px;
+  }
+
+  .cell-content {
+    flex-direction: column;
+    align-items: flex-start;
+  }
+
+  .reference-range {
+    margin-left: 0;
+    margin-top: 4px;
+  }
+}
+</style>
diff --git a/src/views/business/maintain/components/UrineRoutinePanel.vue b/src/views/business/maintain/components/UrineRoutinePanel.vue
new file mode 100644
index 0000000..4d62072
--- /dev/null
+++ b/src/views/business/maintain/components/UrineRoutinePanel.vue
@@ -0,0 +1,751 @@
+<template>
+  <div class="medical-panel">
+    <div class="panel-header">
+      <h3>灏垮父瑙勮褰曡〃</h3>
+      <div class="panel-actions">
+        <el-button
+          v-if="isEditing"
+          type="primary"
+          size="small"
+          @click="addColumn"
+          icon="el-icon-plus"
+        >
+          鏂板璁板綍鍒�
+        </el-button>
+        <el-tooltip content="鍒锋柊琛ㄦ牸甯冨眬" placement="top">
+          <el-button
+            size="small"
+            @click="forceTableLayout"
+            icon="el-icon-refresh"
+          >
+            鍒锋柊甯冨眬
+          </el-button>
+        </el-tooltip>
+      </div>
+    </div>
+
+    <el-table
+      :data="tableData"
+      border
+      style="width: 100%"
+      class="medical-table"
+      v-fit-columns
+      :key="tableKey"
+      @header-dragend="handleHeaderDragEnd"
+      v-loading="tableLoading"
+    >
+      <el-table-column
+        prop="itemName"
+        label="妫�娴嬮」鐩�"
+        width="220"
+        fixed
+        class-name="leave-alone"
+      >
+        <template #default="scope">
+          <div class="item-name-cell">
+            <span :class="{'required-item': scope.row.required}">
+              {{ scope.row.itemName }}
+            </span>
+            <el-tooltip
+              v-if="scope.row.reference"
+              :content="`鍙傝�冭寖鍥�: ${scope.row.reference}`"
+              placement="top"
+            >
+              <i class="el-icon-info reference-icon"></i>
+            </el-tooltip>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column
+        v-for="(col, index) in dynamicColumns"
+        :key="col.key"
+        :label="col.label"
+        :min-width="160"
+        :resizable="isEditing"
+        header-align="center"
+        align="center"
+      >
+        <template #default="scope">
+          <div class="cell-content-wrapper">
+            <template v-if="scope.row.type === 'select'">
+              <el-select
+                v-if="isEditing"
+                v-model="scope.row.values[index]"
+                placeholder="璇烽�夋嫨"
+                size="small"
+                style="width: 100%"
+                @change="handleValueChange(scope.row, index)"
+                :title="getSelectLabel(scope.row, index)"
+              >
+                <el-option
+                  v-for="option in scope.row.options"
+                  :key="option.value"
+                  :label="option.label"
+                  :value="option.value"
+                />
+              </el-select>
+              <span v-else class="value-text" :title="getSelectLabel(scope.row, index)">
+                {{ getSelectLabel(scope.row, index) || '-' }}
+              </span>
+            </template>
+
+            <template v-else>
+              <el-input
+                v-if="isEditing"
+                v-model="scope.row.values[index]"
+                size="small"
+                :placeholder="scope.row.placeholder || '璇疯緭鍏�'"
+                @blur="handleValueChange(scope.row, index)"
+                class="value-input"
+                :title="scope.row.values[index]"
+              />
+              <div v-else class="value-display-container">
+                <span class="value-text" :title="scope.row.values[index]">
+                  {{ scope.row.values[index] || '-' }}
+                </span>
+                <span v-if="scope.row.values[index] && scope.row.unit" class="unit-text">
+                  {{ scope.row.unit }}
+                </span>
+              </div>
+            </template>
+          </div>
+        </template>
+      </el-table-column>
+
+      <!-- <el-table-column
+        v-if="isEditing"
+        label="鎿嶄綔"
+        width="120"
+        fixed="right"
+        class-name="leave-alone"
+      >
+        <template #default>
+          <el-button link type="primary" @click="addColumn" size="small">
+            鏂板鍒�
+          </el-button>
+        </template>
+      </el-table-column> -->
+    </el-table>
+
+    <!-- 缁熻淇℃伅 -->
+    <div v-if="showStatistics" class="statistics-section">
+      <el-card shadow="never">
+        <div class="stats-content">
+          <span class="stats-title">鏁版嵁缁熻:</span>
+          <span class="stats-item">鎬昏褰曟暟: {{ dynamicColumns.length }} 涓椂闂寸偣</span>
+          <span class="stats-item">宸插~鍐�: {{ filledCount }} 椤�</span>
+          <span class="stats-item">瀹屾垚搴�: {{ completionRate }}%</span>
+        </div>
+      </el-card>
+    </div>
+
+    <!-- 闄勪欢涓婁紶鍖哄煙 -->
+    <div class="attachment-section">
+      <div class="attachment-header">
+        <i class="el-icon-paperclip"></i>
+        <span class="attachment-title">闄勪欢涓婁紶</span>
+        <span class="attachment-tip">鏀寔涓婁紶灏垮父瑙勬楠屾姤鍛婂崟绛夋枃浠� (鏈�澶�10涓�)</span>
+      </div>
+      <upload-attachment
+        :file-list="attachments"
+        @change="handleAttachmentChange"
+        :limit="10"
+        :accept="'.pdf,.jpg,.jpeg,.png,.doc,.docx'"
+      />
+    </div>
+
+    <!-- 鍒楃紪杈戝璇濇 -->
+    <el-dialog
+      :title="`${editingColumnIndex !== null ? '缂栬緫' : '鏂板'}鏃堕棿鐐筦"
+      :visible.sync="columnDialogVisible"
+      width="450px"
+      @closed="handleDialogClosed"
+    >
+      <el-form
+        :model="columnForm"
+        label-width="80px"
+        ref="columnForm"
+        :rules="columnRules"
+      >
+        <el-form-item label="鏃ユ湡" prop="date">
+          <el-date-picker
+            v-model="columnForm.date"
+            type="date"
+            placeholder="閫夋嫨鏃ユ湡"
+            value-format="yyyy-MM-dd"
+            style="width: 100%"
+            :disabled-date="disableFutureDates"
+          />
+        </el-form-item>
+        <el-form-item label="鏃堕棿" prop="time">
+          <el-time-picker
+            v-model="columnForm.time"
+            placeholder="閫夋嫨鏃堕棿"
+            value-format="HH:mm"
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input
+            v-model="columnForm.remark"
+            type="textarea"
+            :rows="2"
+            placeholder="鍙�夊~鍐欐椂闂寸偣澶囨敞淇℃伅"
+            maxlength="100"
+            show-word-limit
+          />
+        </el-form-item>
+      </el-form>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="columnDialogVisible = false">鍙栨秷</el-button>
+        <el-button
+          v-if="editingColumnIndex !== null"
+          type="danger"
+          @click="handleDeleteColumn"
+        >
+          鍒犻櫎
+        </el-button>
+        <el-button type="primary" @click="confirmAddColumn" :loading="saveLoading">
+          纭畾
+        </el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import UploadAttachment from "@/components/UploadAttachment";
+
+export default {
+  name: 'UrineRoutinePanel',
+  components: {
+    UploadAttachment,
+  },
+  props: {
+    isEditing: {
+      type: Boolean,
+      default: false
+    },
+    initialData: {
+      type: Array,
+      default: () => []
+    },
+    showStatistics: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      tableData: [],
+      dynamicColumns: [
+        {
+          label: '2024-12-27\n08:00',
+          key: 'time1',
+          date: '2024-12-27',
+          time: '08:00',
+          remark: '鏅ㄥ翱妫�娴�'
+        }
+      ],
+      attachments: [],
+      columnDialogVisible: false,
+      columnForm: {
+        date: '',
+        time: '',
+        remark: ''
+      },
+      editingColumnIndex: null,
+      tableKey: 0,
+      tableLoading: false,
+      saveLoading: false,
+      columnRules: {
+        date: [
+          { required: true, message: '璇烽�夋嫨鏃ユ湡', trigger: 'change' }
+        ],
+        time: [
+          { required: true, message: '璇烽�夋嫨鏃堕棿', trigger: 'change' }
+        ]
+      }
+    };
+  },
+  computed: {
+    filledCount() {
+      let count = 0;
+      this.tableData.forEach(row => {
+        row.values.forEach(value => {
+          if (value && value.toString().trim() !== '') {
+            count++;
+          }
+        });
+      });
+      return count;
+    },
+    completionRate() {
+      const total = this.tableData.length * this.dynamicColumns.length;
+      return total > 0 ? Math.round((this.filledCount / total) * 100) : 0;
+    }
+  },
+  watch: {
+    isEditing(newVal) {
+      if (!newVal) {
+        this.$emit('data-change', {
+          type: 'urine_routine',
+          data: this.tableData,
+          columns: this.dynamicColumns,
+          attachments: this.attachments
+        });
+      }
+      this.$nextTick(() => {
+        this.forceTableLayout();
+      });
+    },
+    dynamicColumns: {
+      handler() {
+        this.$nextTick(() => {
+          this.forceTableLayout();
+        });
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  methods: {
+    initTableData() {
+      const medicalItems = [
+
+        {
+          itemName: '灏块噺',
+          type: 'number',
+          required: true,
+          unit: 'ml/h',
+          reference: '姝e父鑼冨洿瑙嗘儏鍐佃�屽畾'
+        },
+        {
+          itemName: '棰滆壊',
+          type: 'select',
+          required: true,
+          options: [
+            { value: '娣¢粍鑹�', label: '娣¢粍鑹�' },
+            { value: '榛勮壊', label: '榛勮壊' },
+            { value: '娣遍粍鑹�', label: '娣遍粍鑹�' },
+            { value: '绾㈣壊', label: '绾㈣壊' },
+            { value: '鐧借壊', label: '鐧借壊' },
+            { value: '鍏朵粬', label: '鍏朵粬' }
+          ]
+        },
+        {
+          itemName: '澶栬',
+          type: 'select',
+          required: false,
+          options: [
+            { value: '娓呬寒', label: '娓呬寒' },
+            { value: '寰祳', label: '寰祳' },
+            { value: '娴戞祳', label: '娴戞祳' },
+            { value: '娌夋穩', label: '娌夋穩' },
+            { value: '鍏朵粬', label: '鍏朵粬' }
+          ]
+        },
+        {
+          itemName: '灏胯泲鐧�',
+          type: 'select',
+          required: true,
+          options: [
+            { value: '-', label: '闃存��(-)' },
+            { value: '卤', label: '寰噺(卤)' },
+            { value: '+', label: '闃虫��(+)' },
+            { value: '++', label: '闃虫��(++)' },
+            { value: '+++', label: '闃虫��(+++)' }
+          ],
+          reference: '姝e父涓洪槾鎬�(-)'
+        },
+        {
+          itemName: 'pH鍊�',
+          type: 'number',
+          required: true,
+          placeholder: '4.5-8.0',
+          unit: '',
+          reference: '4.5-8.0',
+          min: 4.5,
+          max: 8.0
+        },
+        {
+          itemName: '鐧界粏鑳�',
+          type: 'select',
+          required: true,
+          options: [
+            { value: '-', label: '闃存��(-)' },
+            { value: '+', label: '闃虫��(+)' },
+            { value: '++', label: '闃虫��(++)' },
+            { value: '+++', label: '闃虫��(+++)' }
+          ],
+          reference: '姝e父涓洪槾鎬�(-)'
+        },
+        {
+          itemName: '绾㈢粏鑳�',
+          type: 'number',
+          required: true,
+          unit: '/渭L',
+          reference: '0-9.2',
+          min: 0,
+          max: 9.2
+        },
+        {
+          itemName: '缁嗚弻',
+          type: 'number',
+          required: true,
+          unit: '/渭L',
+          reference: '0-385',
+          min: 0,
+          max: 385
+        }
+      ];
+
+      this.tableData = medicalItems.map(item => ({
+        ...item,
+        values: new Array(this.dynamicColumns.length).fill('')
+      }));
+    },
+
+    getSelectLabel(row, columnIndex) {
+      if (!row.options || !row.values[columnIndex]) return row.values[columnIndex];
+      const option = row.options.find(opt => opt.value === row.values[columnIndex]);
+      return option ? option.label : row.values[columnIndex];
+    },
+
+    addColumn() {
+      this.editingColumnIndex = null;
+      this.columnForm = {
+        date: new Date().toISOString().split('T')[0],
+        time: '08:00',
+        remark: ''
+      };
+      this.columnDialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.columnForm && this.$refs.columnForm.clearValidate();
+      });
+    },
+
+    editColumn(index) {
+      this.editingColumnIndex = index;
+      const column = this.dynamicColumns[index];
+      this.columnForm = {
+        date: column.date,
+        time: column.time,
+        remark: column.remark || ''
+      };
+      this.columnDialogVisible = true;
+    },
+
+    confirmAddColumn() {
+      this.$refs.columnForm.validate((valid) => {
+        if (!valid) {
+          this.$message.warning('璇峰畬鍠勬椂闂寸偣淇℃伅');
+          return;
+        }
+
+        this.saveLoading = true;
+
+        if (this.editingColumnIndex !== null) {
+          // 缂栬緫鐜版湁鍒�
+          const column = this.dynamicColumns[this.editingColumnIndex];
+          column.label = `${this.columnForm.date}\n${this.columnForm.time}`;
+          column.date = this.columnForm.date;
+          column.time = this.columnForm.time;
+          column.remark = this.columnForm.remark;
+          this.$message.success('鏃堕棿鐐逛慨鏀规垚鍔�');
+        } else {
+          // 鏂板鍒�
+          const newIndex = this.dynamicColumns.length + 1;
+          const newColumn = {
+            label: `${this.columnForm.date}\n${this.columnForm.time}`,
+            key: `time${Date.now()}`,
+            date: this.columnForm.date,
+            time: this.columnForm.time,
+            remark: this.columnForm.remark
+          };
+
+          this.dynamicColumns.push(newColumn);
+          this.tableData.forEach(row => {
+            row.values.push('');
+          });
+          this.$message.success('鏃堕棿鐐规坊鍔犳垚鍔�');
+        }
+
+        this.columnDialogVisible = false;
+        this.saveLoading = false;
+        this.tableKey += 1;
+      });
+    },
+
+    handleDeleteColumn() {
+      if (this.editingColumnIndex !== null) {
+        this.$confirm('纭畾瑕佸垹闄よ繖涓椂闂寸偣鍚楋紵', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          this.dynamicColumns.splice(this.editingColumnIndex, 1);
+          this.tableData.forEach(row => {
+            row.values.splice(this.editingColumnIndex, 1);
+          });
+          this.columnDialogVisible = false;
+          this.tableKey += 1;
+          this.$message.success('鏃堕棿鐐瑰垹闄ゆ垚鍔�');
+        });
+      }
+    },
+
+    handleDialogClosed() {
+      this.editingColumnIndex = null;
+      this.columnForm = {
+        date: '',
+        time: '',
+        remark: ''
+      };
+      this.$refs.columnForm && this.$refs.columnForm.clearValidate();
+    },
+
+    disableFutureDates(time) {
+      return time.getTime() > Date.now();
+    },
+
+    handleValueChange(row, columnIndex) {
+      this.$emit('data-change', {
+        type: 'urine_routine',
+        data: this.tableData,
+        columns: this.dynamicColumns
+      });
+    },
+
+    handleAttachmentChange(fileList) {
+      this.attachments = fileList;
+      this.$emit('attachment-change', {
+        type: 'urine_routine',
+        attachments: fileList
+      });
+    },
+
+    forceTableLayout() {
+      this.$nextTick(() => {
+        const table = this.$el.querySelector('.el-table');
+        if (table) {
+          window.dispatchEvent(new Event('resize'));
+        }
+      });
+    },
+
+    handleHeaderDragEnd() {
+      this.forceTableLayout();
+    },
+
+    exportData() {
+      return {
+        tableData: this.tableData,
+        columns: this.dynamicColumns,
+        statistics: {
+          filledCount: this.filledCount,
+          completionRate: this.completionRate,
+          totalColumns: this.dynamicColumns.length
+        },
+        exportTime: new Date().toISOString(),
+        attachments: this.attachments
+      };
+    }
+  },
+  mounted() {
+    this.initTableData();
+  }
+};
+</script>
+
+<style scoped>
+.medical-panel {
+  padding: 20px;
+  background: #fff;
+  border-radius: 8px;
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+}
+
+.panel-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 24px;
+  padding-bottom: 16px;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.panel-header h3 {
+  margin: 0;
+  color: #303133;
+  font-size: 20px;
+  font-weight: 600;
+}
+
+.panel-actions {
+  display: flex;
+  gap: 12px;
+  align-items: center;
+}
+
+.medical-table {
+  margin-bottom: 24px;
+  border-radius: 4px;
+  overflow: hidden;
+}
+
+.medical-table ::v-deep .el-table__body-wrapper {
+  overflow-x: auto;
+}
+
+.item-name-cell {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.reference-icon {
+  color: #909399;
+  font-size: 14px;
+  cursor: help;
+  margin-left: 8px;
+}
+
+.required-item::before {
+  content: "*";
+  color: #f56c6c;
+  margin-right: 4px;
+}
+
+.cell-content-wrapper {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 8px;
+  min-height: 32px;
+}
+
+.value-input {
+  flex: 1;
+  min-width: 80px;
+}
+
+.value-display-container {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+}
+
+.value-text {
+  font-weight: 500;
+  color: #303133;
+  max-width: 80px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.unit-text {
+  color: #909399;
+  font-size: 12px;
+  flex-shrink: 0;
+}
+
+.validation-indicator {
+  flex-shrink: 0;
+}
+
+.valid-icon {
+  color: #67c23a;
+  font-size: 14px;
+}
+
+.invalid-icon {
+  color: #e6a23c;
+  font-size: 14px;
+}
+
+.statistics-section {
+  margin-bottom: 20px;
+}
+
+.stats-content {
+  display: flex;
+  gap: 20px;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.stats-title {
+  font-weight: 600;
+  color: #303133;
+}
+
+.stats-item {
+  color: #606266;
+  font-size: 14px;
+}
+
+.attachment-section {
+  margin-top: 24px;
+  padding: 20px;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+  background: #fafafa;
+}
+
+.attachment-header {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  margin-bottom: 16px;
+}
+
+.attachment-title {
+  font-weight: 600;
+  color: #409eff;
+}
+
+.attachment-tip {
+  font-size: 12px;
+  color: #909399;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+  .medical-panel {
+    padding: 12px;
+  }
+
+  .panel-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+  }
+
+  .panel-actions {
+    width: 100%;
+    justify-content: flex-end;
+  }
+
+  .stats-content {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 8px;
+  }
+
+  .cell-content-wrapper {
+    flex-direction: column;
+    gap: 4px;
+  }
+}
+
+/* 鍔ㄧ敾鏁堟灉 */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.3s;
+}
+.fade-enter, .fade-leave-to {
+  opacity: 0;
+}
+</style>
diff --git a/src/views/business/maintain/maintainInfo.vue b/src/views/business/maintain/maintainInfo.vue
index 3f88144..3bfd5bb 100644
--- a/src/views/business/maintain/maintainInfo.vue
+++ b/src/views/business/maintain/maintainInfo.vue
@@ -28,7 +28,11 @@
           </el-col>
           <el-col :span="8">
             <el-form-item label="鎬у埆" prop="gender">
-              <el-select v-model="form.gender" :disabled="!isEdit" style="width: 100%">
+              <el-select
+                v-model="form.gender"
+                :disabled="!isEdit"
+                style="width: 100%"
+              >
                 <el-option label="鐢�" value="0" />
                 <el-option label="濂�" value="1" />
               </el-select>
@@ -57,7 +61,11 @@
         <el-row :gutter="20">
           <el-col :span="8">
             <el-form-item label="鎮h�呯姸鎬�" prop="patientStatus">
-              <el-select v-model="form.patientStatus" :disabled="!isEdit" style="width: 100%">
+              <el-select
+                v-model="form.patientStatus"
+                :disabled="!isEdit"
+                style="width: 100%"
+              >
                 <el-option label="DCD" value="1" />
                 <el-option label="DBD" value="2" />
                 <el-option label="DBCD" value="3" />
@@ -67,7 +75,11 @@
             </el-form-item>
           </el-col>
           <el-col :span="8">
-            <el-form-item label="鏈畬鎴愬師鍥�" prop="incompleteReason" v-if="form.patientStatus === '5'">
+            <el-form-item
+              label="鏈畬鎴愬師鍥�"
+              prop="incompleteReason"
+              v-if="form.patientStatus === '5'"
+            >
               <el-input
                 v-model="form.incompleteReason"
                 :readonly="!isEdit"
@@ -110,7 +122,11 @@
         <el-row :gutter="20">
           <el-col :span="8">
             <el-form-item label="琛�鍨�" prop="bloodType">
-              <el-select v-model="form.bloodType" :disabled="!isEdit" style="width: 100%">
+              <el-select
+                v-model="form.bloodType"
+                :disabled="!isEdit"
+                style="width: 100%"
+              >
                 <el-option label="A鍨�" value="A" />
                 <el-option label="B鍨�" value="B" />
                 <el-option label="O鍨�" value="O" />
@@ -120,7 +136,11 @@
           </el-col>
           <el-col :span="8">
             <el-form-item label="RH鍥犲瓙" prop="rhFactor">
-              <el-select v-model="form.rhFactor" :disabled="!isEdit" style="width: 100%">
+              <el-select
+                v-model="form.rhFactor"
+                :disabled="!isEdit"
+                style="width: 100%"
+              >
                 <el-option label="闃虫��" value="positive" />
                 <el-option label="闃存��" value="negative" />
               </el-select>
@@ -139,75 +159,146 @@
         </el-form-item>
       </el-form>
     </el-card>
-
-    <!-- 鍩瑰吇缁撴灉璁板綍 -->
- <!-- 鍩瑰吇缁撴灉璁板綍 -->
-    <el-card class="culture-card">
+    <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"
-          icon="el-icon-plus"
-          @click="handleAddCulture"
+          @click="toggleEditMode"
+          style="float: right;"
         >
-          鏂板鍩瑰吇璁板綍
+          {{ isEdit ? "瀹屾垚缂栬緫" : "寮�濮嬬紪杈�" }}
         </el-button>
       </div>
 
-      <el-table :data="cultureList" v-loading="cultureLoading">
-        <el-table-column label="鍩瑰吇绫诲瀷" align="center" prop="cultureType" width="120">
-          <template slot-scope="scope">
-            <dict-tag :options="cultureTypeOptions" :value="scope.row.cultureType" />
-          </template>
-        </el-table-column>
-        <el-table-column label="閲囨牱鏃堕棿" align="center" prop="sampleTime" width="160" />
-        <el-table-column label="鍩瑰吇缁撴灉" align="center" prop="result" width="100">
-          <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" prop="bacteria" width="120" />
-        <el-table-column label="鑽晱缁撴灉" align="center" prop="drugSensitivity" min-width="150" show-overflow-tooltip />
-        <el-table-column label="妫�娴嬫満鏋�" align="center" prop="testingInstitution" width="120" />
-        <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="handleEditCulture(scope.row)"
-            >缂栬緫</el-button>
-            <el-button
-              size="mini"
-              type="text"
-              icon="el-icon-delete"
-              style="color: #F56C6C;"
-              @click="handleDeleteCulture(scope.row)"
-            >鍒犻櫎</el-button>
-            <el-button
-              size="mini"
-              type="text"
-              icon="el-icon-view"
-              @click="handleViewCulture(scope.row)"
-            >璇︽儏</el-button>
-          </template>
-        </el-table-column>
-      </el-table>
+      <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>
 
-      <!-- 鍒嗛〉缁勪欢 -->
-      <pagination
-        v-show="cultureTotal > 0"
-        :total="cultureTotal"
-        :page.sync="cultureQueryParams.pageNum"
-        :limit.sync="cultureQueryParams.pageSize"
-        @pagination="getCultureList"
-      />
+            <el-table :data="cultureList" v-loading="cultureLoading">
+              <el-table-column
+                label="鍩瑰吇绫诲瀷"
+                align="center"
+                prop="cultureType"
+              >
+                <!-- <template slot-scope="scope">
+            <dict-tag
+              :options="cultureTypeOptions"
+              :value="scope.row.cultureType"
+            />
+          </template> -->
+              </el-table-column>
+              <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>
+
+            <pagination
+              v-show="cultureTotal > 0"
+              :total="cultureTotal"
+              :page.sync="cultureQueryParams.pageNum"
+              :limit.sync="cultureQueryParams.pageSize"
+              @pagination="getCultureList"
+            />
+          </el-card>
+        </el-tab-pane>
+
+        <!-- 鑲濆姛鑳借偩鍔熻兘 -->
+        <el-tab-pane label="鑲濆姛鑳借偩鍔熻兘" name="liverKidney">
+          <liver-kidney-panel
+            ref="liverKidney"
+            :is-editing="isEdit && activeTab === 'liverKidney'"
+            @data-change="handleLiverKidneyDataChange"
+          />
+        </el-tab-pane>
+
+        <!-- 琛�甯歌 -->
+        <el-tab-pane label="琛�甯歌" name="bloodRoutine">
+          <blood-routine-panel
+            ref="bloodRoutine"
+            :is-editing="isEdit && activeTab === 'bloodRoutine'"
+            @data-change="handleBloodRoutineDataChange"
+          />
+        </el-tab-pane>
+
+        <!-- 灏垮父瑙� -->
+        <el-tab-pane label="灏垮父瑙�" name="urineRoutine">
+          <urine-routine-panel
+            ref="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>
@@ -222,40 +313,63 @@
       </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="temperature"  />
-        <el-table-column label="蹇冪巼(娆�/鍒�)" align="center" prop="heartRate"  />
-        <el-table-column label="琛�鍘�(mmHg)" align="center" prop="bloodPressure" width="160" />
-        <el-table-column label="鍛煎惛(娆�/鍒�)" align="center" prop="respirationRate"  />
-        <el-table-column label="琛�姘чケ鍜屽害(%)" align="center" prop="oxygenSaturation" width="160" />
-        <el-table-column label="灏块噺(ml/h)" align="center" prop="urineOutput"  />
-        <el-table-column label="鎿嶄綔" align="center" width="200" class-name="small-padding fixed-width">
+        <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"
-              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>
-            <el-button
-              size="mini"
-              type="text"
-              icon="el-icon-view"
-              @click="handleViewRecord(scope.row)"
-            >璇︽儏</el-button>
+              @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"
+        >
+          <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
+          >
         </el-table-column>
       </el-table>
 
-      <!-- 鍒嗛〉缁勪欢 -->
       <pagination
         v-show="recordTotal > 0"
         :total="recordTotal"
@@ -264,7 +378,6 @@
         @pagination="getRecordList"
       />
     </el-card>
-
     <!-- 鍩瑰吇璁板綍缂栬緫瀵硅瘽妗� -->
     <el-dialog
       :title="cultureDialogTitle"
@@ -272,16 +385,25 @@
       width="700px"
       :close-on-click-modal="false"
     >
-      <el-form :model="cultureForm" ref="cultureForm" :rules="cultureRules" label-width="120px">
+      <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-select
+                v-model="cultureForm.cultureType"
+                placeholder="璇烽�夋嫨鍩瑰吇绫诲瀷"
+                style="width: 100%"
+              >
                 <el-option
                   v-for="item in cultureTypeOptions"
                   :key="item.value"
                   :label="item.label"
-                  :value="item.value"
+                  :value="item.label"
                 />
               </el-select>
             </el-form-item>
@@ -302,54 +424,35 @@
         <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-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-col :span="12">
-            <el-form-item label="鑿岀" prop="bacteria">
-              <el-input v-model="cultureForm.bacteria" placeholder="璇疯緭鍏ユ娴嬪埌鐨勮弻绉�" />
-            </el-form-item>
-          </el-col>
         </el-row>
 
-        <el-form-item label="鑽晱缁撴灉" prop="drugSensitivity">
-          <el-input
-            type="textarea"
-            :rows="3"
-            v-model="cultureForm.drugSensitivity"
-            placeholder="璇疯緭鍏ヨ嵂鏁忚瘯楠岀粨鏋�"
-          />
-        </el-form-item>
-
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="妫�娴嬫満鏋�" prop="testingInstitution">
-              <el-input v-model="cultureForm.testingInstitution" placeholder="璇疯緭鍏ユ娴嬫満鏋�" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏍囨湰绫诲瀷" prop="specimenType">
-              <el-input v-model="cultureForm.specimenType" placeholder="璇疯緭鍏ユ爣鏈被鍨�" />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-form-item label="澶囨敞" prop="remarks">
-          <el-input
-            type="textarea"
-            :rows="2"
-            v-model="cultureForm.remarks"
-            placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+        <!-- 闄勪欢涓婁紶 -->
+        <el-form-item label="闄勪欢">
+          <upload-attachment
+            :file-list="cultureForm.attachments"
+            @change="handleCultureAttachmentChange"
           />
         </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>
+        <el-button
+          type="primary"
+          @click="handleSaveCulture"
+          :loading="cultureSaveLoading"
+          >淇濆瓨</el-button
+        >
       </span>
     </el-dialog>
 
@@ -357,10 +460,15 @@
     <el-dialog
       :title="recordDialogTitle"
       :visible.sync="recordDialogVisible"
-      width="800px"
+      width="700px"
       :close-on-click-modal="false"
     >
-      <el-form :model="recordForm" ref="recordForm" :rules="recordRules" label-width="120px">
+      <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">
@@ -375,203 +483,374 @@
           </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-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="浣撴俯(鈩�)" prop="temperature">
-              <el-input-number
-                v-model="recordForm.temperature"
-                :min="30" :max="45" :step="0.1"
-                controls-position="right"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="蹇冪巼(娆�/鍒�)" prop="heartRate">
-              <el-input-number
-                v-model="recordForm.heartRate"
-                :min="0" :max="200"
-                controls-position="right"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鍛煎惛(娆�/鍒�)" prop="respirationRate">
-              <el-input-number
-                v-model="recordForm.respirationRate"
-                :min="0" :max="60"
-                controls-position="right"
-                style="width: 100%"
+              <el-input
+                v-model="recordForm.recorder"
+                placeholder="璇疯緭鍏ユ牳鏌ヤ汉濮撳悕"
               />
             </el-form-item>
           </el-col>
         </el-row>
 
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="琛�鍘�(mmHg)" prop="bloodPressure">
-              <el-input v-model="recordForm.bloodPressure" placeholder="鏍煎紡锛氭敹缂╁帇/鑸掑紶鍘�" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="琛�姘чケ鍜屽害(%)" prop="oxygenSaturation">
-              <el-input-number
-                v-model="recordForm.oxygenSaturation"
-                :min="0" :max="100"
-                controls-position="right"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="灏块噺(ml/h)" prop="urineOutput">
-              <el-input-number
-                v-model="recordForm.urineOutput"
-                :min="0" :max="1000"
-                controls-position="right"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="涓績闈欒剦鍘�" prop="cvp">
-              <el-input-number
-                v-model="recordForm.cvp"
-                :min="0" :max="20" :step="0.1"
-                controls-position="right"
-                style="width: 100%"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-
-        <el-form-item label="澶囨敞" prop="remarks">
+        <el-form-item label="鏍告煡璁板綍" prop="checkRecord">
           <el-input
             type="textarea"
-            :rows="3"
-            v-model="recordForm.remarks"
-            placeholder="璇疯緭鍏ユ牳鏌ュ娉ㄤ俊鎭�"
+            :rows="4"
+            v-model="recordForm.checkRecord"
+            placeholder="璇疯緭鍏ユ牳鏌ヨ褰曞唴瀹�"
+          />
+        </el-form-item>
+
+        <!-- 闄勪欢涓婁紶 -->
+        <el-form-item label="闄勪欢">
+          <upload-attachment
+            :file-list="recordForm.attachments"
+            @change="handleRecordAttachmentChange"
           />
         </el-form-item>
       </el-form>
 
       <span slot="footer" class="dialog-footer">
         <el-button @click="recordDialogVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="handleSaveRecord" :loading="recordSaveLoading">淇濆瓨</el-button>
+        <el-button
+          type="primary"
+          @click="handleSaveRecord"
+          :loading="recordSaveLoading"
+          >淇濆瓨</el-button
+        >
       </span>
     </el-dialog>
+
+    <!-- 闄勪欢棰勮瀵硅瘽妗� -->
+    <attachment-preview
+      :visible="attachmentPreviewVisible"
+      :file-list="currentAttachmentList"
+      :title="attachmentPreviewTitle"
+      @close="attachmentPreviewVisible = false"
+    />
   </div>
 </template>
 
 <script>
 import { getMaintenanceDetail, updateMaintenance } from "./mockMaintenanceApi";
-import { listCultureResults, addCultureResult, updateCultureResult, deleteCultureResult } from "./mockMaintenanceApi";
-import { listNursingRecords, addNursingRecord, updateNursingRecord, deleteNursingRecord } from "./mockMaintenanceApi";
+import {
+  listCultureResults,
+  addCultureResult,
+  updateCultureResult,
+  deleteCultureResult
+} from "./mockMaintenanceApi";
+import {
+  listNursingRecords,
+  addNursingRecord,
+  updateNursingRecord,
+  deleteNursingRecord
+} from "./mockMaintenanceApi";
 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";
 
 export default {
- name: "MaintenanceDetail",
-  components: { Pagination },
+  name: "MaintenanceDetail",
+  components: {
+    Pagination,
+    UploadAttachment,
+    AttachmentPreview,
+    LiverKidneyPanel,
+    BloodRoutinePanel,
+    UrineRoutinePanel
+  },
   data() {
     return {
-      isEdit: false,
+      isEdit: true,
       form: {
         id: undefined,
-        caseNo: '',
-        donorName: '',
-        gender: '',
-        age: '',
-        diagnosis: '',
-        hospitalName: '',
-        patientStatus: '1',
-        admissionTime: '',
-        dischargeTime: '',
-        coordinator: '',
-        bloodType: '',
-        rhFactor: '',
-        specialMedicalHistory: '',
-        incompleteReason: ''
+        caseNo: "",
+        donorName: "",
+        gender: "",
+        age: "",
+        diagnosis: "",
+        hospitalName: "",
+        patientStatus: "1",
+        admissionTime: "",
+        dischargeTime: "",
+        coordinator: "",
+        bloodType: "",
+        rhFactor: "",
+        specialMedicalHistory: "",
+        incompleteReason: ""
       },
-
+      activeTab: "culture",
       // 鍩瑰吇缁撴灉鐩稿叧鏁版嵁
-      cultureList: [],
+      // 鍩瑰吇缁撴灉鐩稿叧鏁版嵁
+      cultureList: [
+        {
+          id: 1,
+          cultureType: "琛�鍩瑰吇",
+          sampleTime: "2024-12-19 10:30:00",
+          result: "闃存��",
+          bacteria: "",
+          drugSensitivity: "",
+          testingInstitution: "鍖椾含鍖诲妫�楠屼腑蹇�",
+          specimenType: "琛�娑�",
+          remarks: "甯歌妫�娴�",
+          attachments: [
+            {
+              id: 1,
+              fileName: "琛�鍩瑰吇鎶ュ憡.pdf",
+              fileUrl:
+                "http://localhost:8080/profile/upload/2025/12/27/1.COPO渚涗綋璇勪及琛�.pdf",
+              fileSize: 1024000,
+              uploadTime: "2024-12-19 11:00:00"
+            }
+          ]
+        },
+        {
+          id: 3,
+          cultureType: "琛�鍩瑰吇",
+          sampleTime: "2024-12-20 09:15:00",
+          result: "闃存��",
+          bacteria: "",
+          drugSensitivity: "",
+          testingInstitution: "骞垮窞妫�娴嬩腑蹇�",
+          specimenType: "灏挎恫",
+          remarks: "娓呮磥涓灏挎爣鏈�",
+          attachments: []
+        },
+        {
+          id: 2,
+          cultureType: "鐥板煿鍏荤粨鏋�",
+          sampleTime: "2024-12-19 14:20:00",
+          result: "闃虫��",
+          bacteria: "閲戦粍鑹茶憽钀勭悆鑿�",
+          drugSensitivity: "瀵归潚闇夌礌鏁忔劅锛屽澶村绫讳腑浠�",
+          testingInstitution: "涓婃捣鍖诲妫�楠屾墍",
+          specimenType: "鐥版恫",
+          remarks: "鑽晱璇曢獙瀹屾垚",
+          attachments: [
+            {
+              id: 2,
+              fileName: "鐥板煿鍏荤粨鏋�.jpg",
+              fileUrl:
+                "https://img95.699pic.com/photo/40142/8262.jpg_wh860.jpg",
+              fileSize: 512000,
+              uploadTime: "2024-12-19 15:30:00"
+            },
+            {
+              id: 3,
+              fileName: "鑽晱鎶ュ憡.pdf",
+              fileUrl:
+                "http://localhost:8080/profile/upload/2025/12/27/(鍚撮緳8.7)姣忔棩宸ヤ綔鎬荤粨.pdf",
+              fileSize: 768000,
+              uploadTime: "2024-12-19 16:00:00"
+            }
+          ]
+        },
+
+        {
+          id: 4,
+          cultureType: "鐪熻弻鍩瑰吇",
+          sampleTime: "2024-12-20 11:45:00",
+          result: "闃虫��",
+          bacteria: "澶ц偁鏉嗚弻",
+          drugSensitivity: "瀵瑰乏姘ф盁娌欐槦鏁忔劅",
+          testingInstitution: "娣卞湷浜烘皯鍖婚櫌",
+          specimenType: "浼ゅ彛鍒嗘硨鐗�",
+          remarks: "鏈悗浼ゅ彛鎰熸煋鐩戞祴",
+          attachments: [
+            {
+              id: 4,
+              fileName: "鐪熻弻鍩瑰吇.pdf",
+              fileUrl: "/reports/culture4.pdf",
+              fileSize: 890000,
+              uploadTime: "2024-12-20 13:20:00"
+            }
+          ]
+        }
+      ],
       cultureLoading: false,
-      cultureTotal: 0,
+      cultureTotal: 5,
       cultureQueryParams: {
         pageNum: 1,
         pageSize: 10
       },
       cultureDialogVisible: false,
-      cultureDialogTitle: '',
+      cultureDialogTitle: "",
       cultureSaveLoading: false,
       cultureForm: {
         id: undefined,
-        cultureType: '',
-        sampleTime: '',
-        result: '闃存��',
-        bacteria: '',
-        drugSensitivity: '',
-        testingInstitution: '',
-        specimenType: '',
-        remarks: ''
+        cultureType: "",
+        sampleTime: "",
+        result: "闃存��",
+        attachments: [] // 鏂板闄勪欢瀛楁
       },
       cultureRules: {
-        cultureType: [{ required: true, message: '璇烽�夋嫨鍩瑰吇绫诲瀷', trigger: 'change' }],
-        sampleTime: [{ required: true, message: '璇烽�夋嫨閲囨牱鏃堕棿', trigger: 'change' }],
-        result: [{ required: true, message: '璇烽�夋嫨鍩瑰吇缁撴灉', trigger: 'change' }]
+        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: '鍏朵粬' }
+        { value: "1", label: "琛�鍩瑰吇" },
+        { value: "2", label: "鐥板煿鍏�" },
+        { value: "3", label: "灏垮煿鍏�" },
+        { value: "4", label: "浼ゅ彛鍒嗘硨鐗�" },
+        { value: "5", label: "鑴戣剨娑插煿鍏�" },
+        { value: "6", label: "鍏朵粬" }
       ],
 
       // 鎶ょ悊鏍告煡璁板綍鐩稿叧鏁版嵁
-      recordList: [],
+      recordList: [
+        {
+          id: 1,
+          recordTime: "2024-12-19 08:30:00",
+          recorder: "寮犳姢澹�",
+          temperature: 36.8,
+          heartRate: 78,
+          bloodPressure: "120/80",
+          respirationRate: 18,
+          oxygenSaturation: 98,
+          urineOutput: 60,
+          cvp: 8,
+          checkRecord: "鎮h�呯敓鍛戒綋寰佸钩绋筹紝鎰忚瘑娓呮锛岄厤鍚堟不鐤�",
+          remarks: "澶滈棿鐫$湢鑹ソ",
+          attachments: [
+            {
+              id: 1,
+              fileName: "鏃╃彮鎶ょ悊璁板綍.jpg",
+              fileUrl: "/records/nursing1.jpg",
+              fileSize: 1024000,
+              uploadTime: "2024-12-19 09:00:00"
+            }
+          ]
+        },
+        {
+          id: 2,
+          recordTime: "2024-12-19 14:30:00",
+          recorder: "鏉庢姢澹�",
+          temperature: 37.2,
+          heartRate: 82,
+          bloodPressure: "118/76",
+          respirationRate: 16,
+          oxygenSaturation: 97,
+          urineOutput: 45,
+          cvp: 7.5,
+          checkRecord: "鎮h�呭崍鍚庝綋娓╃暐鏈夊崌楂橈紝瑙傚療涓�",
+          remarks: "寤鸿澧炲姞姘村垎鎽勫叆",
+          attachments: []
+        },
+        {
+          id: 3,
+          recordTime: "2024-12-19 20:30:00",
+          recorder: "鐜嬫姢澹�",
+          temperature: 36.9,
+          heartRate: 75,
+          bloodPressure: "122/78",
+          respirationRate: 17,
+          oxygenSaturation: 98,
+          urineOutput: 55,
+          cvp: 8.2,
+          checkRecord: "鏅氶棿鐢熷懡浣撳緛绋冲畾锛屾偅鑰呬紤鎭壇濂�",
+          remarks: "澶滈棿鐩戞祴鏃犲紓甯�",
+          attachments: [
+            {
+              id: 2,
+              fileName: "鏅氱彮鎶ょ悊璁板綍.pdf",
+              fileUrl: "/records/nursing3.pdf",
+              fileSize: 890000,
+              uploadTime: "2024-12-19 21:00:00"
+            },
+            {
+              id: 3,
+              fileName: "浣撳緛鐩戞祴琛�.xlsx",
+              fileUrl: "/records/monitoring3.xlsx",
+              fileSize: 256000,
+              uploadTime: "2024-12-19 21:15:00"
+            }
+          ]
+        },
+        {
+          id: 4,
+          recordTime: "2024-12-20 08:30:00",
+          recorder: "璧垫姢澹�",
+          temperature: 36.7,
+          heartRate: 80,
+          bloodPressure: "119/77",
+          respirationRate: 18,
+          oxygenSaturation: 99,
+          urineOutput: 65,
+          cvp: 7.8,
+          checkRecord: "鏅ㄩ棿鐢熷懡浣撳緛姝e父锛屾偅鑰呯簿绁炵姸鎬佽壇濂�",
+          remarks: "鍑嗗浠婃棩妫�鏌�",
+          attachments: []
+        },
+        {
+          id: 5,
+          recordTime: "2024-12-20 12:30:00",
+          recorder: "鍒樻姢澹�",
+          temperature: 37.1,
+          heartRate: 85,
+          bloodPressure: "121/79",
+          respirationRate: 19,
+          oxygenSaturation: 96,
+          urineOutput: 40,
+          cvp: 8.5,
+          checkRecord: "鍗堥棿浣撴俯鐣ユ湁娉㈠姩锛岀户缁瀵�",
+          remarks: "宸查�氱煡鍖荤敓",
+          attachments: [
+            {
+              id: 4,
+              fileName: "鍗堥棿鎶ょ悊璁板綍.jpg",
+              fileUrl: "/records/nursing5.jpg",
+              fileSize: 765000,
+              uploadTime: "2024-12-20 13:00:00"
+            }
+          ]
+        }
+      ],
       recordLoading: false,
-      recordTotal: 0,
+      recordTotal: 4,
       recordQueryParams: {
         pageNum: 1,
         pageSize: 10
       },
       recordDialogVisible: false,
-      recordDialogTitle: '',
+      recordDialogTitle: "",
       recordSaveLoading: false,
       recordForm: {
         id: undefined,
-        recordTime: '',
-        recorder: '',
-        temperature: 36.5,
-        heartRate: 80,
-        bloodPressure: '120/80',
-        respirationRate: 18,
-        oxygenSaturation: 98,
-        urineOutput: 50,
-        cvp: 8,
-        remarks: ''
+        recordTime: "",
+        recorder: "",
+        checkRecord: "", // 鏀逛负鍗曞瓧娈佃褰�
+        attachments: [] // 鏂板闄勪欢瀛楁
       },
       recordRules: {
-        recordTime: [{ required: true, message: '璇烽�夋嫨鏍告煡鏃堕棿', trigger: 'change' }],
-        recorder: [{ required: true, message: '璇疯緭鍏ユ牳鏌ヤ汉', trigger: 'blur' }],
-        temperature: [{ required: true, message: '璇疯緭鍏ヤ綋娓�', trigger: 'blur' }]
-      }
+        recordTime: [
+          { required: true, message: "璇烽�夋嫨鏍告煡鏃堕棿", trigger: "change" }
+        ],
+        recorder: [
+          { required: true, message: "璇疯緭鍏ユ牳鏌ヤ汉", trigger: "blur" }
+        ],
+        checkRecord: [
+          { required: true, message: "璇疯緭鍏ユ牳鏌ヨ褰�", trigger: "blur" }
+        ]
+      },
+
+      // 闄勪欢棰勮鐩稿叧
+      attachmentPreviewVisible: false,
+      currentAttachmentList: [],
+      attachmentPreviewTitle: ""
     };
   },
- created() {
+  created() {
     const id = this.$route.query.id;
-    this.isEdit = this.$route.query.edit === 'true';
+    // this.isEdit = this.$route.query.edit === "true";
     if (id) {
       this.getDetail(id);
       this.getCultureList();
@@ -579,7 +858,7 @@
     }
   },
   methods: {
-     // 鑾峰彇璇︽儏
+    // 鑾峰彇璇︽儏
     getDetail(id) {
       getMaintenanceDetail(id).then(response => {
         if (response.code === 200) {
@@ -587,33 +866,78 @@
         }
       });
     },
+    // 鍩瑰吇璁板綍闄勪欢鍙樻洿
+    handleCultureAttachmentChange(fileList) {
+      this.cultureForm.attachments = fileList;
+    },
 
+    // 鎶ょ悊璁板綍闄勪欢鍙樻洿
+    handleRecordAttachmentChange(fileList) {
+      this.recordForm.attachments = fileList;
+    },
+
+    // 鏌ョ湅鍩瑰吇璁板綍闄勪欢
+    handleViewCultureAttachments(row) {
+      console.log(22, row.attachments);
+
+      this.currentAttachmentList = row.attachments || [];
+      this.attachmentPreviewTitle = `鍩瑰吇璁板綍闄勪欢 - ${row.cultureType}`;
+      this.attachmentPreviewVisible = true;
+    },
+    handleTabClick(tab) {
+      this.$nextTick(() => {
+        console.log(tab.name, 88);
+        const tableRef=null;
+        if (tab.name == "liverKidney") {
+           tableRef = this.$refs.liverKidney; // 璇锋浛鎹负鎮ㄧ殑琛ㄦ牸 ref
+        } else if (tab.name == "bloodRoutine") {
+           tableRef = this.$refs.bloodRoutine; // 璇锋浛鎹负鎮ㄧ殑琛ㄦ牸 ref
+        } else if (tab.name == "bloodRoutine") {
+           tableRef = this.$refs.bloodRoutine; // 璇锋浛鎹负鎮ㄧ殑琛ㄦ牸 ref
+        }
+        // 濡傛灉鏄� el-table锛屽皾璇曡皟鐢ㄥ叾 doLayout 鏂规硶
+        if (tableRef && tableRef.doLayout) {
+          tableRef.doLayout();
+        }
+
+        // 鎴栬�咃紝鏇撮�氱敤鐨勫己鍒堕噸鏂版覆鏌撴柟寮�
+        this.$forceUpdate(); // 鎱庣敤锛屽彲鑳藉紩鍙戝叾浠栭棶棰榌1](@ref)
+      });
+    },
+    // 鏌ョ湅鎶ょ悊璁板綍闄勪欢
+    handleViewRecordAttachments(row) {
+      this.currentAttachmentList = row.attachments || [];
+      this.attachmentPreviewTitle = `鎶ょ悊鏍告煡璁板綍闄勪欢 - ${row.recorder}`;
+      this.attachmentPreviewVisible = true;
+    },
     // 鍩瑰吇璁板綍鐩稿叧鏂规硶
     getCultureList() {
       this.cultureLoading = true;
-      listCultureResults(this.form.id, this.cultureQueryParams).then(response => {
-        if (response.code === 200) {
-          this.cultureList = response.data.rows;
-          this.cultureTotal = response.data.total;
-        }
-        this.cultureLoading = false;
-      }).catch(() => {
-        this.cultureLoading = false;
-      });
+      listCultureResults(this.form.id, this.cultureQueryParams)
+        .then(response => {
+          if (response.code === 200) {
+            // this.cultureList = response.data.rows;
+            // this.cultureTotal = response.data.total;
+          }
+          this.cultureLoading = false;
+        })
+        .catch(() => {
+          this.cultureLoading = false;
+        });
     },
 
     handleAddCulture() {
-      this.cultureDialogTitle = '鏂板鍩瑰吇璁板綍';
+      this.cultureDialogTitle = "鏂板鍩瑰吇璁板綍";
       this.cultureForm = {
         id: undefined,
-        cultureType: '',
-        sampleTime: '',
-        result: '闃存��',
-        bacteria: '',
-        drugSensitivity: '',
-        testingInstitution: '',
-        specimenType: '',
-        remarks: ''
+        cultureType: "",
+        sampleTime: "",
+        result: "闃存��",
+        bacteria: "",
+        drugSensitivity: "",
+        testingInstitution: "",
+        specimenType: "",
+        remarks: ""
       };
       this.cultureDialogVisible = true;
       this.$nextTick(() => {
@@ -622,7 +946,7 @@
     },
 
     handleEditCulture(row) {
-      this.cultureDialogTitle = '缂栬緫鍩瑰吇璁板綍';
+      this.cultureDialogTitle = "缂栬緫鍩瑰吇璁板綍";
       this.cultureForm = { ...row };
       this.cultureDialogVisible = true;
       this.$nextTick(() => {
@@ -631,93 +955,128 @@
     },
 
     handleViewCulture(row) {
-      this.$alert(`
+      this.$alert(
+        `
         <div>
-          <p><strong>鍩瑰吇绫诲瀷锛�</strong>${this.getCultureTypeLabel(row.cultureType)}</p>
+          <p><strong>鍩瑰吇绫诲瀷锛�</strong>${this.getCultureTypeLabel(
+            row.cultureType
+          )}</p>
           <p><strong>閲囨牱鏃堕棿锛�</strong>${row.sampleTime}</p>
           <p><strong>鍩瑰吇缁撴灉锛�</strong>${row.result}</p>
-          <p><strong>鑿岀锛�</strong>${row.bacteria || '鏃�'}</p>
-          <p><strong>鑽晱缁撴灉锛�</strong>${row.drugSensitivity || '鏃�'}</p>
           <p><strong>妫�娴嬫満鏋勶細</strong>${row.testingInstitution}</p>
         </div>
-      `, '鍩瑰吇璁板綍璇︽儏', {
-        dangerouslyUseHTMLString: true,
-        customClass: 'detail-dialog'
-      });
+      `,
+        "鍩瑰吇璁板綍璇︽儏",
+        {
+          dangerouslyUseHTMLString: true,
+          customClass: "detail-dialog"
+        }
+      );
     },
-
+    toggleEditMode() {
+      this.isEdit = !this.isEdit;
+      // if (!this.isEdit) {
+      //   this.saveAllData();
+      // }
+    },
+    handleLiverKidneyDataChange(data) {
+      console.log("鑲濆姛鑳借偩鍔熻兘鏁版嵁鍙樻洿:", data);
+      // 澶勭悊鏁版嵁淇濆瓨鎴栦复鏃跺瓨鍌�
+    },
+    handleBloodRoutineDataChange(data) {
+      console.log("琛�甯歌鍔熻兘鏁版嵁鍙樻洿:", data);
+      // 澶勭悊鏁版嵁淇濆瓨鎴栦复鏃跺瓨鍌�
+    },
+    handleUrineRoutineDataChange(data) {
+      console.log("灏垮父瑙勫姛鑳芥暟鎹彉鏇�:", data);
+      // 澶勭悊鏁版嵁淇濆瓨鎴栦复鏃跺瓨鍌�
+    },
+    // 淇濆瓨鍩瑰吇璁板綍
     handleSaveCulture() {
       this.$refs.cultureForm.validate(valid => {
         if (valid) {
           this.cultureSaveLoading = true;
-          const api = this.cultureForm.id ? updateCultureResult : addCultureResult;
+          const api = this.cultureForm.id
+            ? updateCultureResult
+            : addCultureResult;
           const requestData = {
             ...this.cultureForm,
             maintenanceId: this.form.id
           };
 
-          api(requestData).then(response => {
-            if (response.code === 200) {
-              this.$message.success(this.cultureForm.id ? '淇敼鎴愬姛' : '鏂板鎴愬姛');
-              this.cultureDialogVisible = false;
-              this.getCultureList();
-            }
-            this.cultureSaveLoading = false;
-          }).catch(() => {
-            this.cultureSaveLoading = false;
-          });
+          api(requestData)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success(
+                  this.cultureForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛"
+                );
+                this.cultureDialogVisible = false;
+                this.getCultureList();
+              }
+              this.cultureSaveLoading = false;
+            })
+            .catch(() => {
+              this.cultureSaveLoading = false;
+            });
         }
       });
     },
 
     handleDeleteCulture(row) {
-      this.$confirm('纭畾瑕佸垹闄よ繖鏉″煿鍏昏褰曞悧锛�', '鎻愮ず', {
-        confirmButtonText: '纭畾',
-        cancelButtonText: '鍙栨秷',
-        type: 'warning'
-      }).then(() => {
-        deleteCultureResult(row.id).then(response => {
-          if (response.code === 200) {
-            this.$message.success('鍒犻櫎鎴愬姛');
-            this.getCultureList();
-          }
-        });
-      }).catch(() => {});
+      this.$confirm("纭畾瑕佸垹闄よ繖鏉″煿鍏昏褰曞悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          deleteCultureResult(row.id).then(response => {
+            if (response.code === 200) {
+              this.$message.success("鍒犻櫎鎴愬姛");
+              this.getCultureList();
+            }
+          });
+        })
+        .catch(() => {});
     },
 
     getCultureTypeLabel(value) {
       const type = this.cultureTypeOptions.find(item => item.value === value);
-      return type ? type.label : '鏈煡';
+      return type ? type.label : "鏈煡";
     },
 
     // 鎶ょ悊鏍告煡璁板綍鐩稿叧鏂规硶
     getRecordList() {
       this.recordLoading = true;
-      listNursingRecords(this.form.id, this.recordQueryParams).then(response => {
-        if (response.code === 200) {
-          this.recordList = response.data.rows;
-          this.recordTotal = response.data.total;
-        }
-        this.recordLoading = false;
-      }).catch(() => {
-        this.recordLoading = false;
-      });
+      listNursingRecords(this.form.id, this.recordQueryParams)
+        .then(response => {
+          if (response.code === 200) {
+            // this.recordList = response.data.rows;
+            // this.recordTotal = response.data.total;
+          }
+          this.recordLoading = false;
+        })
+        .catch(() => {
+          this.recordLoading = false;
+        });
     },
 
     handleAddRecord() {
-      this.recordDialogTitle = '鏂板鎶ょ悊鏍告煡璁板綍';
+      this.recordDialogTitle = "鏂板鎶ょ悊鏍告煡璁板綍";
       this.recordForm = {
         id: undefined,
-        recordTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
-        recorder: '褰撳墠鐢ㄦ埛', // 瀹為檯椤圭洰涓粠鐢ㄦ埛淇℃伅鑾峰彇
+        recordTime: new Date()
+          .toISOString()
+          .replace("T", " ")
+          .substring(0, 19),
+        recorder: "褰撳墠鐢ㄦ埛", // 瀹為檯椤圭洰涓粠鐢ㄦ埛淇℃伅鑾峰彇
         temperature: 36.5,
         heartRate: 80,
-        bloodPressure: '120/80',
+        bloodPressure: "120/80",
         respirationRate: 18,
         oxygenSaturation: 98,
         urineOutput: 50,
         cvp: 8,
-        remarks: ''
+        remarks: ""
       };
       this.recordDialogVisible = true;
       this.$nextTick(() => {
@@ -726,7 +1085,7 @@
     },
 
     handleEditRecord(row) {
-      this.recordDialogTitle = '缂栬緫鎶ょ悊鏍告煡璁板綍';
+      this.recordDialogTitle = "缂栬緫鎶ょ悊鏍告煡璁板綍";
       this.recordForm = { ...row };
       this.recordDialogVisible = true;
       this.$nextTick(() => {
@@ -735,7 +1094,8 @@
     },
 
     handleViewRecord(row) {
-      this.$alert(`
+      this.$alert(
+        `
         <div>
           <p><strong>鏍告煡鏃堕棿锛�</strong>${row.recordTime}</p>
           <p><strong>鏍告煡浜猴細</strong>${row.recorder}</p>
@@ -748,51 +1108,62 @@
             <li>琛�姘чケ鍜屽害锛�${row.oxygenSaturation}%</li>
             <li>灏块噺锛�${row.urineOutput}ml/h</li>
           </ul>
-          <p><strong>澶囨敞锛�</strong>${row.remarks || '鏃�'}</p>
+          <p><strong>澶囨敞锛�</strong>${row.remarks || "鏃�"}</p>
         </div>
-      `, '鎶ょ悊鏍告煡璁板綍璇︽儏', {
-        dangerouslyUseHTMLString: true,
-        customClass: 'detail-dialog'
-      });
+      `,
+        "鎶ょ悊鏍告煡璁板綍璇︽儏",
+        {
+          dangerouslyUseHTMLString: true,
+          customClass: "detail-dialog"
+        }
+      );
     },
 
     handleSaveRecord() {
       this.$refs.recordForm.validate(valid => {
         if (valid) {
           this.recordSaveLoading = true;
-          const api = this.recordForm.id ? updateNursingRecord : addNursingRecord;
+          const api = this.recordForm.id
+            ? updateNursingRecord
+            : addNursingRecord;
           const requestData = {
             ...this.recordForm,
             maintenanceId: this.form.id
           };
 
-          api(requestData).then(response => {
-            if (response.code === 200) {
-              this.$message.success(this.recordForm.id ? '淇敼鎴愬姛' : '鏂板鎴愬姛');
-              this.recordDialogVisible = false;
-              this.getRecordList();
-            }
-            this.recordSaveLoading = false;
-          }).catch(() => {
-            this.recordSaveLoading = false;
-          });
+          api(requestData)
+            .then(response => {
+              if (response.code === 200) {
+                this.$message.success(
+                  this.recordForm.id ? "淇敼鎴愬姛" : "鏂板鎴愬姛"
+                );
+                this.recordDialogVisible = false;
+                this.getRecordList();
+              }
+              this.recordSaveLoading = false;
+            })
+            .catch(() => {
+              this.recordSaveLoading = false;
+            });
         }
       });
     },
 
     handleDeleteRecord(row) {
-      this.$confirm('纭畾瑕佸垹闄よ繖鏉℃姢鐞嗘牳鏌ヨ褰曞悧锛�', '鎻愮ず', {
-        confirmButtonText: '纭畾',
-        cancelButtonText: '鍙栨秷',
-        type: 'warning'
-      }).then(() => {
-        deleteNursingRecord(row.id).then(response => {
-          if (response.code === 200) {
-            this.$message.success('鍒犻櫎鎴愬姛');
-            this.getRecordList();
-          }
-        });
-      }).catch(() => {});
+      this.$confirm("纭畾瑕佸垹闄よ繖鏉℃姢鐞嗘牳鏌ヨ褰曞悧锛�", "鎻愮ず", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          deleteNursingRecord(row.id).then(response => {
+            if (response.code === 200) {
+              this.$message.success("鍒犻櫎鎴愬姛");
+              this.getRecordList();
+            }
+          });
+        })
+        .catch(() => {});
     },
 
     // 淇濆瓨鍩烘湰淇℃伅
@@ -853,7 +1224,41 @@
   font-size: 16px;
   font-weight: bold;
 }
+.medical-panel {
+  padding: 20px;
+}
 
+.attachment-section {
+  margin-top: 20px;
+  padding: 15px;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+}
+
+.attachment-title {
+  font-weight: bold;
+  margin-bottom: 10px;
+  color: #409eff;
+}
+
+.required-item::before {
+  content: "*";
+  color: #f56c6c;
+  margin-right: 4px;
+}
+
+.assessment-card {
+  margin-bottom: 20px;
+}
+
+.medical-table {
+  width: 100%;
+  margin-bottom: 20px;
+}
+
+.dynamic-column {
+  min-width: 120px;
+}
 .fixed-width .el-button {
   margin: 0 2px;
 }
diff --git a/src/views/project/donatebaseinfo/index.vue b/src/views/project/donatebaseinfo/index.vue
index bd603bd..bb2da0d 100644
--- a/src/views/project/donatebaseinfo/index.vue
+++ b/src/views/project/donatebaseinfo/index.vue
@@ -1850,7 +1850,7 @@
 
     handleUpdate(row) {
       this.$router.push({
-        path: "/organ/donationdetails/",
+        path: "/case/course",
         query: {
           id: row.id,
           organType: "edit"

--
Gitblit v1.9.3