From 1a1df739a5f866de1014762167ac9ecb8e06595f Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期一, 22 十二月 2025 13:33:03 +0800
Subject: [PATCH] 评估相关

---
 src/views/business/assess/components/AttachmentPreview.vue   |   46 ++
 src/views/business/assess/index.vue                          |  501 +++++++++++++++++++++
 src/views/business/assess/components/OrganAssessmentForm.vue |   56 ++
 src/views/business/assess/assessmentData.js                  |  156 ++++++
 src/views/business/assess/assessInfo.vue                     |  455 +++++++++++++++++++
 src/views/business/assess/mockAssessmentApi.js               |  121 +++++
 6 files changed, 1,335 insertions(+), 0 deletions(-)

diff --git a/src/views/business/assess/assessInfo.vue b/src/views/business/assess/assessInfo.vue
new file mode 100644
index 0000000..33cf2ac
--- /dev/null
+++ b/src/views/business/assess/assessInfo.vue
@@ -0,0 +1,455 @@
+<template>
+  <div class="assessment-detail">
+    <el-card class="basic-info-card">
+      <div slot="header" class="clearfix">
+        <span>妗堜緥鍩烘湰淇℃伅</span>
+        <el-button
+          style="float: right; padding: 3px 0"
+          type="text"
+          @click="handleAttachmentPreview"
+        >
+          <i class="el-icon-folder-opened"></i> 鏌ョ湅闄勪欢
+        </el-button>
+      </div>
+
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="妗堜緥缂栧彿">{{
+          assessmentData.caseNo
+        }}</el-descriptions-item>
+        <el-descriptions-item label="娼滃湪鎹愮尞鑰呭鍚�">{{
+          assessmentData.donorName
+        }}</el-descriptions-item>
+        <el-descriptions-item label="鎬у埆">
+          <dict-tag :options="genderOptions" :value="assessmentData.gender" />
+        </el-descriptions-item>
+        <el-descriptions-item label="骞撮緞"
+          >{{ assessmentData.age }}宀�</el-descriptions-item
+        >
+        <el-descriptions-item label="琛�鍨�">
+          <dict-tag
+            :options="bloodTypeOptions"
+            :value="assessmentData.bloodType"
+          />
+        </el-descriptions-item>
+        <el-descriptions-item label="璇佷欢鍙风爜">{{
+          assessmentData.idCardNo
+        }}</el-descriptions-item>
+        <el-descriptions-item label="鐤剧梾璇婃柇">{{
+          assessmentData.diagnosis
+        }}</el-descriptions-item>
+        <el-descriptions-item label="鎵�鍦ㄥ尰鐤楁満鏋�">{{
+          assessmentData.hospitalName
+        }}</el-descriptions-item>
+        <el-descriptions-item label="涓绘不鍖荤敓">{{
+          assessmentData.doctorName
+        }}</el-descriptions-item>
+        <el-descriptions-item label="鐢宠璇勪及鏃堕棿">{{
+          assessmentData.applyTime
+        }}</el-descriptions-item>
+        <el-descriptions-item label="璇勪及绫诲瀷">
+          <dict-tag
+            :options="assessmentTypeOptions"
+            :value="assessmentData.assessmentType"
+          />
+        </el-descriptions-item>
+        <el-descriptions-item label="璇勪及鐘舵��">
+          <el-tag :type="statusFilter(assessmentData.assessmentStatus)">
+            {{ statusTextFilter(assessmentData.assessmentStatus) }}
+          </el-tag>
+        </el-descriptions-item>
+      </el-descriptions>
+    </el-card>
+
+    <el-card class="organ-assessment-card">
+      <div slot="header" class="clearfix">
+        <span>鍣ㄥ畼璇勪及琛�</span>
+        <el-button
+          v-if="isCoordinator && allOrgansAssessed"
+          style="float: right; margin-left: 10px"
+          type="primary"
+          size="mini"
+          @click="handleCompleteAssessment"
+        >
+          纭瀹屾垚璇勪及
+        </el-button>
+        <span v-if="!isCoordinator" class="jstitle">
+          褰撳墠瑙掕壊锛歿{ currentDepartment }}璇勪及浜哄憳
+        </span>
+      </div>
+
+      <el-table
+        :data="organAssessmentList"
+        v-loading="assessmentLoading"
+        style="width: 100%"
+        :row-class-name="getRowClassName"
+      >
+        <el-table-column
+          label="鍣ㄥ畼绫诲瀷"
+          align="center"
+          prop="organType"
+          width="120"
+        >
+          <template slot-scope="scope">
+            <dict-tag
+              :options="organTypeOptions"
+              :value="scope.row.organType"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="璇勪及绉戝"
+          align="center"
+          prop="department"
+          width="120"
+        />
+        <el-table-column
+          label="璇勪及浜哄憳"
+          align="center"
+          prop="assessor"
+          width="100"
+        />
+        <el-table-column label="璇勪及鐘舵��" align="center" width="100">
+          <template slot-scope="scope">
+            <el-tag
+              :type="scope.row.assessmentStatus === '1' ? 'success' : 'warning'"
+              size="small"
+            >
+              {{ scope.row.assessmentStatus === "1" ? "宸茶瘎浼�" : "寰呰瘎浼�" }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="鍔熻兘鐘舵��" align="center" width="100">
+          <template slot-scope="scope">
+            <el-tag
+              :type="getFunctionStatusType(scope.row.functionStatus)"
+              size="small"
+            >
+              {{ getFunctionStatusText(scope.row.functionStatus) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="璇勪及鎰忚"
+          align="center"
+          prop="assessmentOpinion"
+          min-width="150"
+          show-overflow-tooltip
+        />
+        <el-table-column label="璇勪及鏃堕棿" align="center" width="120">
+          <template slot-scope="scope">
+            <span>{{ scope.row.assessmentTime || "-" }}</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
+              v-if="canAssessOrgan(scope.row)"
+              size="mini"
+              type="text"
+              @click="handleOrganAssess(scope.row)"
+              >{{
+                scope.row.assessmentStatus === "1" ? "鏌ョ湅/淇敼" : "璇勪及"
+              }}</el-button
+            >
+            <el-button v-else size="mini" type="text" disabled
+              >鏃犳潈闄�</el-button
+            >
+            <el-button
+              v-if="isCoordinator"
+              size="mini"
+              type="text"
+              @click="handleViewOrganDetail(scope.row)"
+              >璇︽儏</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <!-- 鍣ㄥ畼璇勪及璇︽儏 -->
+      <el-collapse
+        v-model="activeOrgans"
+        accordion
+        class="organ-detail-collapse"
+      >
+        <el-collapse-item
+          v-for="organ in organAssessmentList"
+          :key="organ.organType"
+          :name="organ.organType"
+          :title="getOrganTitle(organ)"
+        >
+          <organ-assessment-form
+            :organ-data="organ"
+            :readonly="!canAssessOrgan(organ)"
+            @save="handleSaveOrganAssessment"
+          />
+        </el-collapse-item>
+      </el-collapse>
+    </el-card>
+
+    <!-- 闄勪欢棰勮寮圭獥 -->
+    <attachment-preview
+      :visible="attachmentVisible"
+      :attachment-list="attachmentList"
+      @close="attachmentVisible = false"
+    />
+  </div>
+</template>
+
+<script>
+// import { getAssessment, updateOrganAssessment, completeAssessment } from "@/api/case/assessment";
+import {
+  getAssessment,
+  updateOrganAssessment,
+  completeAssessment
+} from "./mockAssessmentApi";
+
+import OrganAssessmentForm from "./components/OrganAssessmentForm.vue";
+import AttachmentPreview from "./components/AttachmentPreview.vue";
+
+export default {
+  name: "AssessmentDetail",
+  components: { OrganAssessmentForm, AttachmentPreview },
+  data() {
+    return {
+      // 璇勪及ID
+      assessmentId: undefined,
+      // 璇勪及鏁版嵁
+      assessmentData: {},
+      // 鍣ㄥ畼璇勪及鍒楄〃
+      organAssessmentList: [],
+      // 闄勪欢鍒楄〃
+      attachmentList: [],
+      // 鍔犺浇鐘舵��
+      assessmentLoading: false,
+      // 褰撳墠鐢ㄦ埛淇℃伅
+      currentUser: {
+        id: "001",
+        name: "寮犲尰鐢�",
+        department: "蹇冭剰澶栫",
+        role: "department" // coordinator: 鍗忚皟鍛�, department: 绉戝浜哄憳
+      },
+      // 灞曞紑鐨勫櫒瀹�
+      activeOrgans: [],
+      // 闄勪欢棰勮鍙鎬�
+      attachmentVisible: false,
+      // 瀛楀吀閫夐」
+      genderOptions: [
+        { value: "0", label: "鐢�" },
+        { value: "1", label: "濂�" }
+      ],
+      bloodTypeOptions: [
+        { value: "A", label: "A鍨�" },
+        { value: "B", label: "B鍨�" },
+        { value: "O", label: "O鍨�" },
+        { value: "AB", label: "AB鍨�" }
+      ],
+      assessmentTypeOptions: [
+        { value: "1", label: "鍒濇璇勪及" },
+        { value: "2", label: "鏈�缁堣瘎浼�" }
+      ],
+      organTypeOptions: [
+        { value: "heart", label: "蹇冭剰" },
+        { value: "liver", label: "鑲濊剰" },
+        { value: "kidney", label: "鑲捐剰" },
+        { value: "lung", label: "鑲鸿剰" },
+        { value: "pancreas", label: "鑳拌吅" },
+        { value: "intestine", label: "鑲犻亾" },
+        { value: "cornea", label: "瑙掕啘" },
+        { value: "skin", label: "鐨偆" }
+      ]
+    };
+  },
+  computed: {
+    // 鏄惁鏄崗璋冨憳
+    isCoordinator() {
+      return this.currentUser.role === "coordinator";
+    },
+    // 褰撳墠绉戝
+    currentDepartment() {
+      return this.currentUser.department;
+    },
+    // 鎵�鏈夊櫒瀹樻槸鍚﹂兘宸茶瘎浼�
+    allOrgansAssessed() {
+      return this.organAssessmentList.every(
+        organ => organ.assessmentStatus === "1"
+      );
+    }
+  },
+  created() {
+    this.assessmentId = this.$route.query.id;
+    this.getAssessmentDetail();
+  },
+  methods: {
+    // 鑾峰彇璇勪及璇︽儏 - 浣跨敤Mock鏁版嵁
+    getAssessmentDetail() {
+      this.assessmentLoading = true;
+      getAssessment(this.assessmentId)
+        .then(response => {
+          if (response.code === 200) {
+            this.assessmentData = response.data.caseInfo;
+            this.organAssessmentList = response.data.organAssessments || [];
+            this.attachmentList = response.data.attachments || [];
+          } else {
+            this.$message.error("鑾峰彇璇勪及璇︽儏澶辫触");
+          }
+          this.assessmentLoading = false;
+        })
+        .catch(error => {
+          console.error("鑾峰彇璇勪及璇︽儏澶辫触:", error);
+          this.assessmentLoading = false;
+          this.$message.error("鑾峰彇璇勪及璇︽儏澶辫触");
+        });
+    },
+    // 鐘舵�佽繃婊ゅ櫒
+    statusFilter(status) {
+      const statusMap = {
+        "0": "warning",
+        "1": "primary",
+        "2": "success",
+        "3": "danger"
+      };
+      return statusMap[status] || "info";
+    },
+    statusTextFilter(status) {
+      const statusMap = {
+        "0": "寰呰瘎浼�",
+        "1": "璇勪及涓�",
+        "2": "宸插畬鎴�",
+        "3": "宸插叧闂�"
+      };
+      return statusMap[status] || "鏈煡";
+    },
+    // 鑾峰彇鍔熻兘鐘舵�佺被鍨�
+    getFunctionStatusType(status) {
+      const typeMap = {
+        "1": "success", // 姝e父
+        "2": "warning", // 杞诲害寮傚父
+        "3": "danger", // 閲嶅害寮傚父
+        "4": "info" // 鏃犳硶璇勪及
+      };
+      return typeMap[status] || "info";
+    },
+    // 鑾峰彇鍔熻兘鐘舵�佹枃鏈�
+    getFunctionStatusText(status) {
+      const textMap = {
+        "1": "姝e父",
+        "2": "杞诲害寮傚父",
+        "3": "閲嶅害寮傚父",
+        "4": "鏃犳硶璇勪及"
+      };
+      return textMap[status] || "鏈煡";
+    },
+    // 妫�鏌ユ槸鍚︽湁鏉冮檺璇勪及璇ュ櫒瀹�
+    canAssessOrgan(organ) {
+      if (this.isCoordinator) return true;
+      return organ.department === this.currentDepartment;
+    },
+    // 鑾峰彇琛岀被鍚�
+    getRowClassName({ row }) {
+      return this.canAssessOrgan(row) ? "assessable-row" : "non-assessable-row";
+    },
+    // 鑾峰彇鍣ㄥ畼鏍囬
+    getOrganTitle(organ) {
+      const organName =
+        this.organTypeOptions.find(opt => opt.value === organ.organType)
+          ?.label || organ.organType;
+      return `${organName}璇勪及璇︽儏锛�${organ.department}锛塦;
+    },
+    // 鍣ㄥ畼璇勪及
+    handleOrganAssess(organ) {
+      this.activeOrgans = [organ.organType];
+    },
+    // 鏌ョ湅鍣ㄥ畼璇︽儏
+    handleViewOrganDetail(organ) {
+      this.activeOrgans = [organ.organType];
+    },
+    // 淇濆瓨鍣ㄥ畼璇勪及 - 浣跨敤Mock API
+    handleSaveOrganAssessment(organData) {
+      updateOrganAssessment(organData)
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("璇勪及淇濆瓨鎴愬姛");
+            // 鍒锋柊鏁版嵁
+            this.getAssessmentDetail();
+          }
+        })
+        .catch(error => {
+          console.error("淇濆瓨璇勪及澶辫触:", error);
+          this.$message.error("淇濆瓨澶辫触");
+        });
+    },
+    // 鏌ョ湅闄勪欢棰勮
+    handleAttachmentPreview() {
+      this.attachmentVisible = true;
+    },
+    // 瀹屾垚璇勪及 - 浣跨敤Mock API
+    handleCompleteAssessment() {
+      this.$confirm("纭瀹屾垚鎵�鏈夊櫒瀹樿瘎浼板悧锛熷畬鎴愬悗灏嗘棤娉曚慨鏀�", "纭鎿嶄綔", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      }).then(() => {
+        completeAssessment(this.assessmentId)
+          .then(response => {
+            if (response.code === 200) {
+              this.$message.success("璇勪及瀹屾垚纭鎴愬姛");
+              this.getAssessmentDetail();
+            }
+          })
+          .catch(error => {
+            console.error("瀹屾垚璇勪及澶辫触:", error);
+            this.$message.error("鎿嶄綔澶辫触");
+          });
+      });
+    }
+  }
+};
+</script>
+
+<style scoped>
+.assessment-detail {
+  padding: 20px;
+}
+
+.basic-info-card {
+  margin-bottom: 20px;
+}
+
+.organ-assessment-card {
+  margin-bottom: 20px;
+}
+
+.organ-detail-collapse {
+  margin-top: 20px;
+}
+
+::v-deep .assessable-row {
+  background-color: #f0f9ff;
+}
+
+::v-deep .non-assessable-row {
+  background-color: #fafafa;
+}
+
+::v-deep .el-descriptions__label {
+  width: 120px;
+  background-color: #f5f7fa;
+  font-weight: bold;
+}
+
+.fixed-width .el-button {
+  margin: 0 2px;
+}
+.jstitle {
+  float: right;
+  font-size: 18px !important;
+  font-weight: 600;
+  color: #2645f7;
+  font-size: 12px;
+}
+</style>
diff --git a/src/views/business/assess/assessmentData.js b/src/views/business/assess/assessmentData.js
new file mode 100644
index 0000000..08325e7
--- /dev/null
+++ b/src/views/business/assess/assessmentData.js
@@ -0,0 +1,156 @@
+// src/mock/assessmentData.js
+
+// 妯℃嫙璇勪及鍒楄〃鏁版嵁
+export const assessmentListData = {
+  code: 200,
+  message: 'success',
+  data: {
+    total: 15,
+    rows: [
+      {
+        id: '20241220001',
+        caseNo: 'CASE20241220001',
+        donorName: '寮犱笁',
+        gender: '0',
+        age: 45,
+        diagnosis: '鑴戝浼ゅ鑷磋剳姝讳骸',
+        hospitalName: '鍖椾含鍗忓拰鍖婚櫌',
+        applyTime: '2024-12-20 10:00:00',
+        assessmentTime: '',
+        assessmentStatus: '0',
+        assignee: '鏉庡崗璋冨憳',
+        assessmentType: '1'
+      },
+      {
+        id: '20241220002',
+        caseNo: 'CASE20241220002',
+        donorName: '鏉庡洓',
+        gender: '1',
+        age: 32,
+        diagnosis: '鎬ユ�у績鑲屾姝�',
+        hospitalName: '涓婃捣鐟為噾鍖婚櫌',
+        applyTime: '2024-12-19 14:30:00',
+        assessmentTime: '2024-12-20 09:00:00',
+        assessmentStatus: '1',
+        assignee: '鐜嬪尰鐢�',
+        assessmentType: '2'
+      },
+      {
+        id: '20241220003',
+        caseNo: 'CASE20241220003',
+        donorName: '鐜嬩簲',
+        gender: '0',
+        age: 58,
+        diagnosis: '鑴戝嚭琛�',
+        hospitalName: '骞垮窞涓北鍖婚櫌',
+        applyTime: '2024-12-18 09:15:00',
+        assessmentTime: '2024-12-20 14:20:00',
+        assessmentStatus: '2',
+        assignee: '璧靛崗璋冨憳',
+        assessmentType: '1'
+      }
+    ]
+  }
+}
+
+// 妯℃嫙璇勪及璇︽儏鏁版嵁
+export const assessmentDetailData = {
+  code: 200,
+  message: 'success',
+  data: {
+    caseInfo: {
+      id: '20241220001',
+      caseNo: 'CASE20241220001',
+      donorName: '寮犱笁',
+      gender: '0',
+      age: 45,
+      bloodType: 'A',
+      idCardNo: '110101198001010011',
+      diagnosis: '鑴戝浼ゅ鑷磋剳姝讳骸',
+      hospitalName: '鍖椾含鍗忓拰鍖婚櫌',
+      doctorName: '鍒樹富浠�',
+      applyTime: '2024-12-20 10:00:00',
+      assessmentType: '1',
+      assessmentStatus: '0'
+    },
+    organAssessments: [
+      {
+        id: 1,
+        organType: 'heart',
+        department: '蹇冭剰澶栫',
+        assessor: '鐜嬪尰鐢�',
+        assessmentStatus: '1',
+        functionStatus: '1',
+        assessmentOpinion: '蹇冭剰鍔熻兘姝e父锛屽皠琛�鍒嗘暟65%锛岀鍚堟崘鐚潯浠�',
+        assessmentTime: '2024-12-20 10:30:00',
+        details: {
+          ejectionFraction: '65%',
+          valveFunction: '姝e父',
+          wallMotion: '姝e父',
+          ecgResult: '绐︽�у績寰�',
+          specialNotes: '鏃犵壒娈婃敞鎰忎簨椤�'
+        }
+      },
+      {
+        id: 2,
+        organType: 'liver',
+        department: '鑲濊儐澶栫',
+        assessor: '',
+        assessmentStatus: '0',
+        functionStatus: '',
+        assessmentOpinion: '',
+        assessmentTime: '',
+        details: null
+      },
+      {
+        id: 3,
+        organType: 'kidney',
+        department: '娉屽翱澶栫',
+        assessor: '鏉庡尰鐢�',
+        assessmentStatus: '1',
+        functionStatus: '2',
+        assessmentOpinion: '宸﹁偩鍔熻兘姝e父锛屽彸鑲捐交搴︾Н姘达紝闇�杩涗竴姝ヨ瘎浼�',
+        assessmentTime: '2024-12-20 11:15:00',
+        details: {
+          leftKidneyFunction: '姝e父',
+          rightKidneyFunction: '杞诲害寮傚父',
+          creatinineLevel: '1.2mg/dL',
+          urineOutput: '姝e父',
+          specialNotes: '寤鸿杩涜CT澧炲己鎵弿'
+        }
+      },
+      {
+        id: 4,
+        organType: 'lung',
+        department: '鑳稿绉�',
+        assessor: '',
+        assessmentStatus: '0',
+        functionStatus: '',
+        assessmentOpinion: '',
+        assessmentTime: '',
+        details: null
+      }
+    ],
+    attachments: [
+      {
+        id: 1,
+        fileName: '鎹愮尞鑰呰韩浠借瘉.jpg',
+        fileType: 'jpg',
+        fileSize: 1024000,
+        uploadTime: '2024-12-19 10:30:00',
+        fileUrl: '/mock/files/id_card.jpg'
+      },
+      {
+        id: 2,
+        fileName: '鍖荤枟璇婃柇璇佹槑.pdf',
+        fileType: 'pdf',
+        fileSize: 2048000,
+        uploadTime: '2024-12-19 11:20:00',
+        fileUrl: '/mock/files/diagnosis.pdf'
+      }
+    ]
+  }
+}
+
+// 妯℃嫙API鍝嶅簲寤惰繜
+export const mockDelay = (ms = 500) => new Promise(resolve => setTimeout(resolve, ms))
diff --git a/src/views/business/assess/components/AttachmentPreview.vue b/src/views/business/assess/components/AttachmentPreview.vue
new file mode 100644
index 0000000..3c5defe
--- /dev/null
+++ b/src/views/business/assess/components/AttachmentPreview.vue
@@ -0,0 +1,46 @@
+<!-- src/views/case/assessment/components/AttachmentPreview.vue -->
+<template>
+  <el-dialog
+    title="闄勪欢棰勮"
+    :visible="visible"
+    width="70%"
+    @close="$emit('close')"
+  >
+    <el-table :data="attachmentList">
+      <el-table-column label="鏂囦欢鍚�" prop="fileName" />
+      <el-table-column label="绫诲瀷" prop="fileType" width="100" />
+      <el-table-column label="澶у皬" width="100">
+        <template slot-scope="scope">
+          {{ (scope.row.fileSize / 1024 / 1024).toFixed(2) }} MB
+        </template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" width="150">
+        <template slot-scope="scope">
+          <el-button type="text" @click="handlePreview(scope.row)">棰勮</el-button>
+          <el-button type="text" @click="handleDownload(scope.row)">涓嬭浇</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  name: "AttachmentPreview",
+  props: {
+    visible: Boolean,
+    attachmentList: {
+      type: Array,
+      default: () => []
+    }
+  },
+  methods: {
+    handlePreview(file) {
+      this.$message.info(`棰勮鏂囦欢: ${file.fileName}`);
+    },
+    handleDownload(file) {
+      this.$message.success(`寮�濮嬩笅杞�: ${file.fileName}`);
+    }
+  }
+}
+</script>
diff --git a/src/views/business/assess/components/OrganAssessmentForm.vue b/src/views/business/assess/components/OrganAssessmentForm.vue
new file mode 100644
index 0000000..29e03e9
--- /dev/null
+++ b/src/views/business/assess/components/OrganAssessmentForm.vue
@@ -0,0 +1,56 @@
+<!-- src/views/case/assessment/components/OrganAssessmentForm.vue -->
+<template>
+  <div class="organ-assessment-form">
+    <el-form :model="organData" label-width="120px">
+      <el-form-item label="鍔熻兘鐘舵��">
+        <el-select v-model="organData.functionStatus" :disabled="readonly">
+          <el-option label="姝e父" value="1" />
+          <el-option label="杞诲害寮傚父" value="2" />
+          <el-option label="閲嶅害寮傚父" value="3" />
+          <el-option label="鏃犳硶璇勪及" value="4" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="璇勪及鎰忚">
+        <el-input
+          type="textarea"
+          v-model="organData.assessmentOpinion"
+          :rows="4"
+          :disabled="readonly"
+          placeholder="璇疯緭鍏ヨ瘎浼版剰瑙�"
+        />
+      </el-form-item>
+      <el-form-item v-if="!readonly">
+        <el-button type="primary" @click="handleSave">淇濆瓨璇勪及</el-button>
+        <el-button @click="handleCancel">鍙栨秷</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "OrganAssessmentForm",
+  props: {
+    organData: {
+      type: Object,
+      default: () => ({})
+    },
+    readonly: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    handleSave() {
+      this.$emit('save', {
+        ...this.organData,
+        assessmentTime: new Date().toISOString(),
+        assessor: '褰撳墠鐢ㄦ埛'
+      });
+    },
+    handleCancel() {
+      this.$emit('cancel');
+    }
+  }
+}
+</script>
diff --git a/src/views/business/assess/index.vue b/src/views/business/assess/index.vue
new file mode 100644
index 0000000..1ca3ea8
--- /dev/null
+++ b/src/views/business/assess/index.vue
@@ -0,0 +1,501 @@
+<template>
+  <div class="assessment-list">
+    <!-- 鏌ヨ鏉′欢 -->
+    <el-card class="search-card">
+      <el-form
+        :model="queryParams"
+        ref="queryForm"
+        :inline="true"
+        label-width="100px"
+      >
+        <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="hospitalName">
+          <el-input
+            v-model="queryParams.hospitalName"
+            placeholder="璇疯緭鍏ュ尰鐤楁満鏋�"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="涓氬姟浜哄憳" prop="assignee">
+          <el-input
+            v-model="queryParams.assignee"
+            placeholder="璇疯緭鍏ヤ笟鍔′汉鍛�"
+            clearable
+            style="width: 200px"
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="璇勪及鐘舵��" prop="assessmentStatus">
+          <el-select
+            v-model="queryParams.assessmentStatus"
+            placeholder="璇烽�夋嫨璇勪及鐘舵��"
+            clearable
+            style="width: 200px"
+          >
+            <el-option label="寰呰瘎浼�" value="0" />
+            <el-option label="璇勪及涓�" value="1" />
+            <el-option label="宸插畬鎴�" value="2" />
+            <el-option label="宸插叧闂�" value="3" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鐢宠鏃堕棿" prop="applyTimeRange">
+          <el-date-picker
+            v-model="queryParams.applyTimeRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            value-format="yyyy-MM-dd"
+            style="width: 240px"
+          />
+        </el-form-item>
+        <el-form-item label="璇勪及鏃堕棿" prop="assessmentTimeRange">
+          <el-date-picker
+            v-model="queryParams.assessmentTimeRange"
+            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="assessmentList"
+        @selection-change="handleSelectionChange"
+        @row-click="handleRowClick"
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column
+          label="妗堜緥缂栧彿"
+          align="center"
+          prop="caseNo"
+          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="genderOptions" :value="scope.row.gender" /> -->
+            <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="hospitalName"
+          width="150"
+          show-overflow-tooltip
+        />
+        <el-table-column
+          label="鐢宠璇勪及鏃堕棿"
+          align="center"
+          prop="applyTime"
+          width="120"
+        >
+          <template slot-scope="scope">
+            <span>{{ parseTime(scope.row.applyTime, "{y}-{m}-{d}") }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="璇勪及鏃堕棿"
+          align="center"
+          prop="assessmentTime"
+          width="120"
+        >
+          <template slot-scope="scope">
+            <span>{{
+              scope.row.assessmentTime
+                ? parseTime(scope.row.assessmentTime, "{y}-{m}-{d}")
+                : "-"
+            }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="璇勪及鐘舵��"
+          align="center"
+          prop="assessmentStatus"
+          width="100"
+        >
+          <template slot-scope="scope">
+            <el-tag :type="statusFilter(scope.row.assessmentStatus)">
+              {{ statusTextFilter(scope.row.assessmentStatus) }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column
+          label="涓氬姟浜哄憳"
+          align="center"
+          prop="assignee"
+          width="100"
+        />
+        <el-table-column
+          label="璇勪及绫诲瀷"
+          align="center"
+          prop="assessmentType"
+          width="100"
+        >
+          <template slot-scope="scope">
+            <dict-tag
+              :options="dict.type.assessment_Type"
+              :value="parseInt(scope.row.assessmentType)"
+            />
+          </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-view"
+              @click.stop="handleView(scope.row)"
+              >璇︽儏</el-button
+            >
+            <el-button
+              v-if="
+                scope.row.assessmentStatus === '0' ||
+                  scope.row.assessmentStatus === '1'
+              "
+              size="mini"
+              type="text"
+              icon="el-icon-edit"
+              @click.stop="handleAssess(scope.row)"
+              >璇勪及</el-button
+            >
+            <el-button
+              v-if="scope.row.assessmentStatus === '2'"
+              size="mini"
+              type="text"
+              icon="el-icon-check"
+              @click.stop="handleConfirm(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 { listAssessment, delAssessment, exportAssessment } from "@/api/case/assessment";
+import {
+  listAssessment,
+  delAssessment,
+  exportAssessment
+} from "./mockAssessmentApi";
+
+import Pagination from "@/components/Pagination";
+
+export default {
+  name: "AssessmentList",
+  components: { Pagination },
+  dicts: ["sys_user_sex", "assessment_Type"],
+  data() {
+    return {
+      // 閬僵灞�
+      loading: true,
+      // 閫変腑鏁扮粍
+      ids: [],
+      // 闈炲崟涓鐢�
+      single: true,
+      // 闈炲涓鐢�
+      multiple: true,
+      // 鎬绘潯鏁�
+      total: 0,
+      // 璇勪及琛ㄦ牸鏁版嵁
+      assessmentList: [],
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        donorName: undefined,
+        hospitalName: undefined,
+        assignee: undefined,
+        assessmentStatus: undefined,
+        applyTimeRange: [],
+        assessmentTimeRange: []
+      },
+      // 鎬у埆閫夐」
+      genderOptions: [
+        { value: "0", label: "鐢�" },
+        { value: "1", label: "濂�" }
+      ],
+      // 璇勪及绫诲瀷閫夐」
+      assessmentTypeOptions: [
+        { value: "1", label: "鍒濇璇勪及" },
+        { value: "2", label: "鏈�缁堣瘎浼�" }
+      ]
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    // 鐘舵�佽繃婊ゅ櫒
+    statusFilter(status) {
+      const statusMap = {
+        "0": "warning", // 寰呰瘎浼�
+        "1": "primary", // 璇勪及涓�
+        "2": "success", // 宸插畬鎴�
+        "3": "danger" // 宸插叧闂�
+      };
+      return statusMap[status] || "info";
+    },
+    statusTextFilter(status) {
+      const statusMap = {
+        "0": "寰呰瘎浼�",
+        "1": "璇勪及涓�",
+        "2": "宸插畬鎴�",
+        "3": "宸插叧闂�"
+      };
+      return statusMap[status] || "鏈煡";
+    },
+    // 鏌ヨ璇勪及鍒楄〃
+    getList() {
+      this.loading = true;
+      listAssessment(this.queryParams)
+        .then(response => {
+          if (response.code === 200) {
+            this.assessmentList = 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;
+    },
+    // 琛岀偣鍑讳簨浠�
+    handleRowClick(row) {
+      this.$router.push({
+        path: "/case/assessment/detail",
+        query: { id: row.id }
+      });
+    },
+    // 鏌ョ湅璇︽儏
+    handleView(row) {
+      this.$router.push({ path: "/organ/assessInfo", query: { id: row.id } });
+    },
+    // 杩涜璇勪及
+    handleAssess(row) {
+      this.$router.push({
+        path: "/case/assessment/detail",
+        query: { id: row.id, assess: true }
+      });
+    },
+    // 纭璇勪及
+    handleConfirm(row) {
+      this.$confirm("纭瀹屾垚璇ユ渚嬬殑璇勪及鍚楋紵", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          // 璋冪敤Mock纭API
+          this.$message.success("纭鎴愬姛");
+          // 鍒锋柊鍒楄〃
+          this.getList();
+        })
+        .catch(() => {});
+    },
+    // 鏂板鎸夐挳鎿嶄綔
+    handleCreate() {
+      this.$router.push("/case/assessment/add");
+    },
+    // 淇敼鎸夐挳鎿嶄綔
+    handleUpdate() {
+      const id = this.ids[0];
+      this.$router.push({ path: "/case/assessment/edit", query: { id: id } });
+    },
+    // 鍒犻櫎鎸夐挳鎿嶄綔 - 浣跨敤Mock API
+    handleDelete() {
+      const ids = this.ids;
+      this.$confirm("鏄惁纭鍒犻櫎閫変腑鐨勬暟鎹」锛�", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          return delAssessment(ids);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("鍒犻櫎鎴愬姛");
+            this.getList();
+          }
+        })
+        .catch(() => {});
+    },
+    // 瀵煎嚭鎸夐挳鎿嶄綔 - 浣跨敤Mock API
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm("鏄惁纭瀵煎嚭鎵�鏈夎瘎浼版暟鎹紵", "璀﹀憡", {
+        confirmButtonText: "纭畾",
+        cancelButtonText: "鍙栨秷",
+        type: "warning"
+      })
+        .then(() => {
+          this.loading = true;
+          return exportAssessment(queryParams);
+        })
+        .then(response => {
+          if (response.code === 200) {
+            this.$message.success("瀵煎嚭鎴愬姛锛屽紑濮嬩笅杞芥枃浠�");
+            // 妯℃嫙鏂囦欢涓嬭浇
+            const link = document.createElement("a");
+            link.href = response.data.downloadUrl;
+            link.download = "妗堜緥璇勪及鏁版嵁.xlsx";
+            link.click();
+          }
+          this.loading = false;
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+    },
+    // 鏃堕棿鏍煎紡鍖�
+    parseTime(time, pattern) {
+      if (!time) return "";
+      // 浣跨敤moment.js鎴栫畝鍗曟牸寮忓寲
+      if (this.$moment) {
+        return this.$moment(time).format(pattern || "{y}-{m}-{d} {h}:{i}:{s}");
+      } else {
+        // 绠�鍗曟牸寮忓寲
+        const date = new Date(time);
+        return `${date.getFullYear()}-${(date.getMonth() + 1)
+          .toString()
+          .padStart(2, "0")}-${date
+          .getDate()
+          .toString()
+          .padStart(2, "0")}`;
+      }
+    }
+  }
+};
+</script>
+
+<style scoped>
+.assessment-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/assess/mockAssessmentApi.js b/src/views/business/assess/mockAssessmentApi.js
new file mode 100644
index 0000000..bd0437d
--- /dev/null
+++ b/src/views/business/assess/mockAssessmentApi.js
@@ -0,0 +1,121 @@
+// src/api/mockAssessmentApi.js
+import { assessmentListData, assessmentDetailData, mockDelay } from './assessmentData.js'
+
+// 妯℃嫙璇勪及鍒楄〃API
+export const listAssessment = async (queryParams) => {
+  await mockDelay(800)
+
+  console.log('Mock API: 鑾峰彇璇勪及鍒楄〃', queryParams)
+
+  // 妯℃嫙绛涢�夐�昏緫
+  let data = assessmentListData.data.rows
+
+  if (queryParams.donorName) {
+    data = data.filter(item => item.donorName.includes(queryParams.donorName))
+  }
+
+  if (queryParams.hospitalName) {
+    data = data.filter(item => item.hospitalName.includes(queryParams.hospitalName))
+  }
+
+  if (queryParams.assessmentStatus) {
+    data = data.filter(item => item.assessmentStatus === queryParams.assessmentStatus)
+  }
+
+  // 妯℃嫙鍒嗛〉
+  const pageNum = queryParams.pageNum || 1
+  const pageSize = queryParams.pageSize || 10
+  const startIndex = (pageNum - 1) * pageSize
+  const endIndex = startIndex + pageSize
+  const pagedData = data.slice(startIndex, endIndex)
+
+  return {
+    code: 200,
+    message: 'success',
+    data: {
+      total: data.length,
+      rows: pagedData
+    }
+  }
+}
+
+// 妯℃嫙璇勪及璇︽儏API
+export const getAssessment = async (id) => {
+  await mockDelay(500)
+
+  console.log('Mock API: 鑾峰彇璇勪及璇︽儏', id)
+
+  // 鏍规嵁ID杩斿洖涓嶅悓鐨勬ā鎷熸暟鎹�
+  const detailData = JSON.parse(JSON.stringify(assessmentDetailData))
+
+  if (id === '20241220002') {
+    detailData.data.caseInfo.donorName = '鏉庡洓'
+    detailData.data.caseInfo.caseNo = 'CASE20241220002'
+    detailData.data.organAssessments[0].assessor = '寮犲尰鐢�'
+  } else if (id === '20241220003') {
+    detailData.data.caseInfo.donorName = '鐜嬩簲'
+    detailData.data.caseInfo.caseNo = 'CASE20241220003'
+    detailData.data.organAssessments[0].assessor = '闄堝尰鐢�'
+  }
+
+  return detailData
+}
+
+// 妯℃嫙鍣ㄥ畼璇勪及鏇存柊API
+export const updateOrganAssessment = async (organData) => {
+  await mockDelay(300)
+
+  console.log('Mock API: 鏇存柊鍣ㄥ畼璇勪及', organData)
+
+  return {
+    code: 200,
+    message: '鍣ㄥ畼璇勪及鏇存柊鎴愬姛',
+    data: organData
+  }
+}
+
+// 妯℃嫙瀹屾垚璇勪及API
+export const completeAssessment = async (id) => {
+  await mockDelay(500)
+
+  console.log('Mock API: 瀹屾垚璇勪及', id)
+
+  return {
+    code: 200,
+    message: '璇勪及瀹屾垚纭鎴愬姛',
+    data: {
+      assessmentId: id,
+      completeTime: new Date().toISOString()
+    }
+  }
+}
+
+// 妯℃嫙鍒犻櫎璇勪及API
+export const delAssessment = async (ids) => {
+  await mockDelay(400)
+
+  console.log('Mock API: 鍒犻櫎璇勪及', ids)
+
+  return {
+    code: 200,
+    message: '鍒犻櫎鎴愬姛',
+    data: ids
+  }
+}
+
+// 妯℃嫙瀵煎嚭璇勪及API
+export const exportAssessment = async (queryParams) => {
+  await mockDelay(1000)
+
+  console.log('Mock API: 瀵煎嚭璇勪及', queryParams)
+
+  // 妯℃嫙鏂囦欢涓嬭浇
+  return {
+    code: 200,
+    message: '瀵煎嚭鎴愬姛',
+    data: {
+      downloadUrl: '/mock/export/assessment.xlsx',
+      fileSize: '2.5MB'
+    }
+  }
+}

--
Gitblit v1.9.3