From c80bc467a41daa6cbae4e5515a300a8ca98cfeaa Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期二, 21 七月 2026 15:44:01 +0800
Subject: [PATCH] 维护

---
 pagesSub/case/CaseInfo.vue | 1695 ++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 1,103 insertions(+), 592 deletions(-)

diff --git a/pagesSub/case/CaseInfo.vue b/pagesSub/case/CaseInfo.vue
index 6ab3ebc..98de021 100644
--- a/pagesSub/case/CaseInfo.vue
+++ b/pagesSub/case/CaseInfo.vue
@@ -5,7 +5,7 @@
       <view class="case-header">
         <view class="hospital-info">
           <image
-            :src="caseDetail.hospitalLogo"
+            :src="caseDetail.hospitalLogo || '/static/hospital-default.png'"
             mode="aspectFit"
             class="hospital-logo"
           />
@@ -47,7 +47,7 @@
       <text
         v-for="tab in tabs"
         :key="tab.id"
-        :class="{ active: activeTab === tab.id }"
+        :class="{ active: activeTab == tab.id }"
         @tap="switchTab(tab.id)"
         class="tab-item"
       >
@@ -55,41 +55,50 @@
       </text>
     </view>
 
-    <!-- 鎹愮尞鑰呭熀鏈俊鎭� -->
-    <view v-if="activeTab === 'basic'" class="info-section fade-in-up">
+    <!-- ==================== 鍩烘湰淇℃伅 ==================== -->
+    <view v-if="activeTab == 'basic'" class="info-section fade-in-up">
       <view class="section-card">
         <view class="section-header">
-          <text class="section-title">鎹愮尞鑰呭熀鏈俊鎭�</text>
+          <text class="section-title">馃搵 鎹愮尞鑰呭熀鏈俊鎭�</text>
         </view>
         <view class="info-grid">
+          <!-- 绗竴琛岋細濮撳悕銆佹�у埆銆佸勾榫� -->
           <view class="info-item">
             <text class="label">濮撳悕</text>
             <text class="value">{{ caseDetail.name || "鏈~鍐�" }}</text>
           </view>
           <view class="info-item">
             <text class="label">鎬у埆</text>
-            <text class="value">{{ getGenderText(caseDetail.sex) }}</text>
+            <text class="value">{{
+              getDictLabel("sys_user_sex", caseDetail.sex)
+            }}</text>
           </view>
           <view class="info-item">
             <text class="label">骞撮緞</text>
             <text class="value"
               >{{ caseDetail.age || "0" }}
-              {{ getAgeUnitText(caseDetail.ageunit) }}</text
+              {{ getDictLabel("sys_AgeUnit", caseDetail.ageunit) }}</text
             >
           </view>
+
+          <!-- 绗簩琛岋細璇佷欢绫诲瀷銆佽瘉浠跺彿鐮� -->
           <view class="info-item">
+            <text class="label">璇佷欢绫诲瀷</text>
+            <text class="value">{{
+              getDictLabel("sys_IDType", caseDetail.idcardtype)
+            }}</text>
+          </view>
+          <view class="info-item full-width">
             <text class="label">璇佷欢鍙风爜</text>
             <text class="value">{{ caseDetail.idcardno || "鏈~鍐�" }}</text>
           </view>
-          <view class="info-item">
-            <text class="label">琛�鍨�</text>
-            <text class="value">{{
-              getBloodTypeText(caseDetail.bloodType)
-            }}</text>
-          </view>
+
+          <!-- 绗笁琛岋細姘戞棌銆佸浗绫嶃�佺睄璐� -->
           <view class="info-item">
             <text class="label">姘戞棌</text>
-            <text class="value">{{ caseDetail.nation || "鏈~鍐�" }}</text>
+            <text class="value">{{
+              getDictLabel("sys_Nation", caseDetail.nation)
+            }}</text>
           </view>
           <view class="info-item">
             <text class="label">鍥界睄</text>
@@ -99,21 +108,35 @@
             <text class="label">绫嶈疮</text>
             <text class="value">{{ caseDetail.nativeplace || "鏈~鍐�" }}</text>
           </view>
+
+          <!-- 绗洓琛岋細瀛﹀巻銆佽亴涓� -->
           <view class="info-item">
             <text class="label">瀛﹀巻</text>
-            <text class="value">{{ caseDetail.education || "鏈~鍐�" }}</text>
+            <text class="value">{{
+              getDictLabel("sys_education", caseDetail.education)
+            }}</text>
           </view>
           <view class="info-item">
             <text class="label">鑱屼笟</text>
-            <text class="value">{{ caseDetail.occupation || "鏈~鍐�" }}</text>
+            <text class="value">{{
+              getDictLabel("sys_occupation", caseDetail.occupation)
+            }}</text>
           </view>
-          <view class="info-item full-width">
+
+          <!-- 绗簲琛岋細鑱旂郴鐢佃瘽 -->
+          <view class="info-item">
+            <text class="label">鑱旂郴鐢佃瘽</text>
+            <text class="value">{{ caseDetail.phone || "鏈~鍐�" }}</text>
+          </view>
+
+          <!-- 鍦板潃淇℃伅锛氬崟鐙竴琛岋紝鍗犳嵁鏁磋 -->
+          <view class="info-item full-width address-item">
             <text class="label">鎴风睄鍦板潃</text>
             <text class="value">{{
               getFullRegisterAddress() || "鏈~鍐�"
             }}</text>
           </view>
-          <view class="info-item full-width">
+          <view class="info-item full-width address-item">
             <text class="label">鐜颁綇鍦板潃</text>
             <text class="value">{{
               getFullResidenceAddress() || "鏈~鍐�"
@@ -123,71 +146,76 @@
       </view>
     </view>
 
-    <!-- 鍖荤枟淇℃伅 -->
-    <view v-if="activeTab === 'medical'" class="info-section fade-in-up">
+    <!-- ==================== 鍖荤枟淇℃伅 ==================== -->
+    <view v-if="activeTab == 'medical'" class="info-section fade-in-up">
       <view class="section-card">
         <view class="section-header">
-          <text class="section-title">鍖荤枟淇℃伅</text>
+          <text class="section-title">馃彞 鍖荤枟淇℃伅</text>
         </view>
-        <view class="info-content">
-          <view class="info-group">
-            <text class="group-title">鐤剧梾璇婃柇</text>
-            <text class="group-content">{{
+        <view class="info-grid">
+          <!-- 浣忛櫌鍙枫�丟CS璇勫垎 -->
+          <view class="info-item">
+            <text class="label">浣忛櫌鍙�</text>
+            <text class="value">{{ caseDetail.inpatientno || "鏈~鍐�" }}</text>
+          </view>
+          <view class="info-item">
+            <text class="label">GCS璇勫垎</text>
+            <text class="value">{{ caseDetail.gcsScore || "鏈瘎浼�" }}</text>
+          </view>
+
+          <!-- 琛�鍨嬨�丷h闃存�� -->
+          <view class="info-item">
+            <text class="label">琛�鍨�</text>
+            <text class="value">{{
+              getDictLabel("sys_BloodType", caseDetail.bloodType)
+            }}</text>
+          </view>
+          <view class="info-item">
+            <text class="label">Rh(D)闃存��</text>
+            <text class="value">{{
+              caseDetail.rhYin == "1" ? "鏄�" : "鍚�"
+            }}</text>
+          </view>
+
+          <!-- 浼犳煋鐥咃細鍗犳嵁鏁磋 -->
+          <view class="info-item full-width">
+            <text class="label">浼犳煋鐥�</text>
+            <text class="value">{{ getInfectiousText() || "鏃�" }}</text>
+          </view>
+
+          <!-- 鐤剧梾璇婃柇锛氬崰鎹暣琛� -->
+          <view class="info-item full-width">
+            <text class="label">鐤剧梾璇婃柇</text>
+            <text class="value diagnosis-text">{{
               caseDetail.diagnosisname || "鏈~鍐�"
             }}</text>
           </view>
-          <view class="info-group">
-            <text class="group-title">鐥呮儏姒傚喌</text>
-            <text class="group-content">{{
+
+          <!-- 鐥呮儏姒傚喌锛氬崰鎹暣琛� -->
+          <view class="info-item full-width">
+            <text class="label">鐥呮儏姒傚喌</text>
+            <text class="value">{{
               caseDetail.illnessoverview || "鏈~鍐�"
             }}</text>
           </view>
-          <view class="info-group">
-            <text class="group-title">鐥呬汉鐘跺喌</text>
-            <text class="group-content">{{
-              caseDetail.patientstate || "鏈~鍐�"
-            }}</text>
-          </view>
-          <view class="info-group">
-            <text class="group-title">浣忛櫌鍙�</text>
-            <text class="group-content">{{
-              caseDetail.inpatientno || "鏈~鍐�"
-            }}</text>
-          </view>
-          <view class="info-group">
-            <text class="group-title">GCS璇勫垎</text>
-            <text class="group-content">{{
-              caseDetail.gcsScore || "鏈瘎浼�"
-            }}</text>
-          </view>
-          <view class="info-group">
-            <text class="group-title">浼犳煋鐥呮儏鍐�</text>
-            <text class="group-content"
-              >{{ caseDetail.infectious || "鏃�"
-              }}{{
-                caseDetail.infectiousOther
-                  ? `(${caseDetail.infectiousOther})`
-                  : ""
-              }}</text
-            >
-          </view>
-          <view class="info-group">
-            <text class="group-title">Rh闃存��</text>
-            <text class="group-content">{{
-              caseDetail.rhYin === "1" ? "鏄�" : "鍚�"
-            }}</text>
+
+          <!-- 鐥呬汉鐘跺喌锛氬崰鎹暣琛� -->
+          <view class="info-item full-width">
+            <text class="label">鐥呬汉鐘跺喌</text>
+            <text class="value">{{ caseDetail.patientstate || "鏈~鍐�" }}</text>
           </view>
         </view>
       </view>
     </view>
 
-    <!-- 鍖婚櫌涓庤仈绯讳俊鎭� -->
-    <view v-if="activeTab === 'contact'" class="info-section fade-in-up">
+    <!-- ==================== 鑱旂郴淇℃伅 ==================== -->
+    <view v-if="activeTab == 'contact'" class="info-section fade-in-up">
       <view class="section-card">
         <view class="section-header">
-          <text class="section-title">鍖婚櫌涓庤仈绯讳俊鎭�</text>
+          <text class="section-title">馃摓 鍖婚櫌涓庤仈绯讳俊鎭�</text>
         </view>
         <view class="info-grid">
+          <!-- 鍖婚櫌淇℃伅 -->
           <view class="info-item full-width">
             <text class="label">娌荤枟鍖婚櫌</text>
             <text class="value">{{
@@ -204,19 +232,18 @@
             <text class="label">涓婃姤鍖婚櫌</text>
             <text class="value">{{ caseDetail.toHospital || "鏈~鍐�" }}</text>
           </view>
-          <view class="info-item full-width">
-            <text class="label">鑱旂郴鐢佃瘽</text>
-            <text class="value">{{ caseDetail.phone || "鏈~鍐�" }}</text>
-          </view>
+
+          <!-- 鑱旂郴浜轰俊鎭� -->
           <view class="info-item">
-            <text class="label">淇℃伅鍛�</text>
+            <text class="label">涓婃姤淇℃伅鍛�</text>
             <text class="value">{{ caseDetail.infoName || "鏈~鍐�" }}</text>
           </view>
           <view class="info-item">
             <text class="label">淇℃伅鍛樼紪鍙�</text>
             <text class="value">{{ caseDetail.infoNo || "鏈~鍐�" }}</text>
           </view>
-          <view class="info-item">
+
+          <!-- <view class="info-item">
             <text class="label">ICU璇勪及鍖荤敓</text>
             <text class="value">{{ caseDetail.icuDoctor || "鏈~鍐�" }}</text>
           </view>
@@ -225,7 +252,8 @@
             <text class="value">{{
               caseDetail.icuDoctorPhone || "鏈~鍐�"
             }}</text>
-          </view>
+          </view> -->
+
           <view class="info-item">
             <text class="label">鍗忚皟鍛�</text>
             <text class="value">{{
@@ -242,8 +270,8 @@
       </view>
     </view>
 
-    <!-- 杞繍淇℃伅 -->
-    <view v-if="activeTab === 'transport'" class="info-section fade-in-up">
+    <!-- ==================== 杞繍淇℃伅 ==================== -->
+    <view v-if="activeTab == 'transport'" class="info-section fade-in-up">
       <view class="section-card">
         <view class="section-header">
           <view
@@ -251,16 +279,16 @@
               display: flex;
               justify-content: space-between;
               align-items: center;
+              width: 100%;
             "
           >
-            <text class="section-title">杞繍淇℃伅</text>
-            <!-- 杞繍鎿嶄綔鎸夐挳 -->
+            <text class="section-title">馃殤 杞繍淇℃伅</text>
             <view
-              v-if="caseDetail.reportStatus === '3'"
-              style="display: flex; gap: 20rpx"
+              v-if="caseDetail.reportStatus == '3'"
+              style="display: flex; gap: 16rpx"
             >
               <button
-                v-if="caseDetail.isTransport === '2' && !hasTransport"
+                v-if="caseDetail.isTransport == '2' && !hasTransport"
                 class="small-btn primary"
                 @tap.stop="createTransport"
               >
@@ -277,121 +305,93 @@
           </view>
         </view>
 
-        <view class="info-content">
-          <view class="info-group">
-            <text class="group-title">鏄惁闇�瑕佽浆杩�</text>
-            <text class="group-content">{{
-              caseDetail.isTransport === "2" ? "闇�瑕�" : "涓嶉渶瑕�"
+        <view class="info-grid">
+          <view class="info-item">
+            <text class="label">鏄惁闇�瑕佽浆杩�</text>
+            <text class="value">{{
+              caseDetail.isTransport == "2" ? "闇�瑕�" : "涓嶉渶瑕�"
             }}</text>
           </view>
+        </view>
 
-          <!-- 鏈夎浆杩愪俊鎭椂鏄剧ず -->
+        <!-- 鏈夎浆杩愪俊鎭椂鏄剧ず -->
+        <view
+          v-if="hasTransport && caseDetail.serviceTransport"
+          class="transport-list"
+        >
           <view
-            v-if="hasTransport && caseDetail.serviceTransport"
-            class="transport-info"
+            class="transport-item"
+            v-for="transport in caseDetail.serviceTransport"
+            :key="transport.id"
           >
-            <view
-              class="info-group"
-              v-for="transport in caseDetail.serviceTransport"
-              :key="transport.id"
-            >
-              <view class="sub-group">
-                <text class="sub-label">杞繍鍗曞彿:</text>
-                <text class="sub-value">{{
-                  transport.reportId || transport.id
+            <view class="transport-header">
+              <text class="transport-no"
+                >杞繍鍗曞彿锛歿{ transport.reportId || transport.id }}</text
+              >
+              <text
+                class="transport-status"
+                :class="getTransportStatusClass(transport.transitStatus)"
+              >
+                {{ getTransportStatusText(transport.transitStatus) }}
+              </text>
+            </view>
+            <view class="transport-body">
+              <view class="transport-row">
+                <text class="t-label">鍑哄彂鍦扮偣</text>
+                <text class="t-value">{{
+                  transport.transportStartPlace || "鏈~鍐�"
                 }}</text>
               </view>
-              <view class="sub-group">
-                <text class="sub-label">鍑哄彂鍦扮偣:</text>
-                <text class="sub-value">{{
-                  transport.transportStartPlace
-                }}</text>
-              </view>
-              <view class="sub-group">
-                <text class="sub-label">鍑哄彂鏃堕棿:</text>
-                <text class="sub-value">{{
+              <view class="transport-row">
+                <text class="t-label">鍑哄彂鏃堕棿</text>
+                <text class="t-value">{{
                   formatDateTime(transport.transportStartTime)
                 }}</text>
               </view>
-              <view class="sub-group">
-                <text class="sub-label">璐熻矗鍗忚皟鍛�:</text>
-                <text class="sub-value">{{ transport.contactPerson }}</text>
+              <view class="transport-row">
+                <text class="t-label">璐熻矗鍗忚皟鍛�</text>
+                <text class="t-value">{{
+                  transport.contactPerson || "鏈~鍐�"
+                }}</text>
               </view>
-              <view class="sub-group">
-                <text class="sub-label">杞繍鐘舵��:</text>
-                <text
-                  class="sub-value status"
-                  :class="getTransportStatusClass(transport.transitStatus)"
-                >
-                  {{ getTransportStatusText(transport.transitStatus) }}
-                </text>
+              <view v-if="transport.doctor" class="transport-row">
+                <text class="t-label">鍑鸿瘖鍖荤敓</text>
+                <text class="t-value">{{ transport.doctor }}</text>
               </view>
-              <view class="sub-group" v-if="transport.doctor">
-                <text class="sub-label">鎬ヨ瘖绉戝尰鐢�:</text>
-                <text class="sub-value">{{ transport.doctor }}</text>
+              <view v-if="transport.nurse" class="transport-row">
+                <text class="t-label">鍑鸿瘖鎶ゅ+</text>
+                <text class="t-value">{{ transport.nurse }}</text>
               </view>
-              <view class="sub-group" v-if="transport.nurse">
-                <text class="sub-label">鎶ゅ+:</text>
-                <text class="sub-value">{{ transport.nurse }}</text>
+              <view v-if="transport.driver" class="transport-row">
+                <text class="t-label">椹鹃┒鍛�</text>
+                <text class="t-value">{{ transport.driver }}</text>
               </view>
-              <view class="sub-group" v-if="transport.driver">
-                <text class="sub-label">椹鹃┒鍛�:</text>
-                <text class="sub-value">{{ transport.driver }}</text>
-              </view>
-              <view class="sub-group" v-if="transport.icuDoctor">
-                <text class="sub-label">ICU璇勪及鍖荤敓:</text>
-                <text class="sub-value">{{ transport.icuDoctor }}</text>
+              <view v-if="transport.icuDoctor" class="transport-row">
+                <text class="t-label">ICU璇勪及鍖荤敓</text>
+                <text class="t-value">{{ transport.icuDoctor }}</text>
               </view>
             </view>
           </view>
+        </view>
 
-          <!-- 鏃犺浆杩愪俊鎭絾闇�瑕佽浆杩� -->
-          <view
-            v-else-if="caseDetail.isTransport === '2'"
-            class="transport-info"
+        <!-- 鏃犺浆杩愪俊鎭絾闇�瑕佽浆杩� -->
+        <view v-else-if="caseDetail.isTransport == '2'" class="empty-transport">
+          <text>璇ユ渚嬮渶瑕佽浆杩愶紝浣嗗皻鏈垱寤鸿浆杩愬崟</text>
+          <text
+            v-if="caseDetail.reportStatus !== '3'"
+            style="color: #f0ad4e; font-size: 24rpx; margin-top: 10rpx"
           >
-            <view class="empty-transport">
-              <text>璇ユ渚嬮渶瑕佽浆杩愶紝浣嗗皻鏈垱寤鸿浆杩愬崟</text>
-              <text
-                v-if="caseDetail.reportStatus !== '3'"
-                style="color: #f0ad4e; font-size: 24rpx; margin-top: 10rpx"
-              >
-                闇�鍏堝鎵瑰悓鎰忔墠鑳藉垱寤鸿浆杩愬崟
-              </text>
-            </view>
-          </view>
+            闇�鍏堝鎵瑰悓鎰忔墠鑳藉垱寤鸿浆杩愬崟
+          </text>
+        </view>
 
-          <!-- 鏃犻渶杞繍 -->
-          <view v-else class="transport-info">
-            <view class="empty-transport">
-              <text>璇ユ渚嬫棤闇�杞繍</text>
-            </view>
-          </view>
+        <!-- 鏃犻渶杞繍 -->
+        <view v-else class="empty-transport">
+          <text>璇ユ渚嬫棤闇�杞繍</text>
         </view>
       </view>
     </view>
 
-    <!-- 鎿嶄綔鎸夐挳 -->
-    <view class="action-bar">
-      <button class="action-btn secondary" @tap="goBack">杩斿洖</button>
-
-      <!-- 鏍规嵁鐘舵�佹樉绀轰笉鍚屾搷浣� -->
-      <button
-        v-if="
-          caseDetail.reportStatus === '1' || caseDetail.reportStatus === '2'
-        "
-        class="action-btn primary"
-        @tap="handleEdit"
-      >
-        缂栬緫妗堜緥
-      </button>
-
-      <!-- <button v-if="canDelete" 
-              class="action-btn error" 
-              @tap="handleDelete">
-        鍒犻櫎妗堜緥
-      </button> -->
-    </view>
     <!-- 闄勪欢 -->
     <attachment-upload
       ref="attachment"
@@ -400,7 +400,194 @@
       :maxCount="5"
       @preview="handlePreview"
     />
-    <!-- <view v-if="showHomeButton" class="home-btn" @click="goHome">棣栭〉</view> -->
+
+    <!-- 鎿嶄綔鎸夐挳 -->
+    <view class="action-bar">
+      <button class="action-btn secondary" @tap="goBack">杩斿洖</button>
+
+      <!-- 纭鎸夐挳锛氫粎admin瑙掕壊鍙锛屼笖鐘舵�佷负"宸查槄璇�"(2)鏃舵樉绀� -->
+      <button
+        v-if="canApprove && caseDetail.delFlag == 0"
+        class="action-btn approve"
+        @tap="openApprovePanel"
+      >
+        纭妗堜緥
+      </button>
+
+      <button
+        v-if="caseDetail.reportStatus == '1' || caseDetail.reportStatus == '2'"
+        class="action-btn primary"
+        @tap="handleEdit"
+      >
+        缂栬緫妗堜緥
+      </button>
+    </view>
+
+    <!-- ==================== 纭搴曢儴寮瑰嚭闈㈡澘 ==================== -->
+    <view
+      class="approve-mask"
+      v-if="showApprovePanel"
+      @tap="closeApprovePanel"
+    ></view>
+    <view class="approve-panel" :class="{ 'panel-show': showApprovePanel }">
+      <view class="panel-header">
+        <text class="panel-title">妗堜緥纭</text>
+        <text class="panel-close" @tap="closeApprovePanel">鉁�</text>
+      </view>
+
+      <scroll-view scroll-y class="panel-body">
+        <!-- 妗堜緥鎽樿 -->
+        <view class="summary-card">
+          <view class="summary-row">
+            <text class="s-label">妗堜緥缂栧彿</text>
+            <text class="s-value">{{ caseDetail.caseNo }}</text>
+          </view>
+          <view class="summary-row">
+            <text class="s-label">鎮h�呭鍚�</text>
+            <text class="s-value">{{ caseDetail.name }}</text>
+          </view>
+          <view class="summary-row">
+            <text class="s-label">鐤剧梾璇婃柇</text>
+            <text class="s-value">{{ caseDetail.diagnosisname }}</text>
+          </view>
+          <view class="summary-row">
+            <text class="s-label">涓婃姤鍖婚櫌</text>
+            <text class="s-value">{{ caseDetail.treatmenthospitalname }}</text>
+          </view>
+        </view>
+
+        <!-- 纭缁撴灉 -->
+        <view class="form-group">
+          <text class="form-label"
+            >纭缁撴灉 <text class="required">*</text></text
+          >
+          <view class="radio-group">
+            <view
+              class="radio-item"
+              :class="{ active: approveForm.approveResult == '3' }"
+              @tap="
+                approveForm.approveResult = '3';
+                handleApproveResultChange('3');
+              "
+            >
+              <text
+                class="radio-icon"
+                :class="{ checked: approveForm.approveResult == '3' }"
+                >鉁�</text
+              >
+              <text class="radio-text">鍚屾剰</text>
+            </view>
+            <view
+              class="radio-item"
+              :class="{ active: approveForm.approveResult == '4' }"
+              @tap="
+                approveForm.approveResult = '4';
+                handleApproveResultChange('4');
+              "
+            >
+              <text
+                class="radio-icon"
+                :class="{ checked: approveForm.approveResult == '4' }"
+                >鉁�</text
+              >
+              <text class="radio-text">椹冲洖</text>
+            </view>
+          </view>
+        </view>
+
+        <!-- 鍚屾剰鏃剁殑杞繍閫夐」 -->
+        <view class="form-group" v-if="approveForm.approveResult == '3'">
+          <text class="form-label"
+            >鏄惁闇�瑕佽浆杩� <text class="required">*</text></text
+          >
+          <view class="radio-group">
+            <view
+              class="radio-item"
+              :class="{ active: approveForm.isTransport == '1' }"
+              @tap="approveForm.isTransport = '1'"
+            >
+              <text
+                class="radio-icon"
+                :class="{ checked: approveForm.isTransport == '1' }"
+                >鉁�</text
+              >
+              <text class="radio-text">涓嶉渶瑕�</text>
+            </view>
+            <view
+              class="radio-item"
+              :class="{ active: approveForm.isTransport == '2' }"
+              @tap="approveForm.isTransport = '2'"
+            >
+              <text
+                class="radio-icon"
+                :class="{ checked: approveForm.isTransport == '2' }"
+                >鉁�</text
+              >
+              <text class="radio-text">闇�瑕�</text>
+            </view>
+          </view>
+        </view>
+
+        <!-- 椹冲洖鍘熷洜 -->
+        <view class="form-group" v-if="approveForm.approveResult == '4'">
+          <text class="form-label"
+            >椹冲洖鍘熷洜 <text class="required">*</text></text
+          >
+          <view class="radio-group vertical">
+            <view
+              v-for="reason in rejectReasons"
+              :key="reason.value"
+              class="radio-item"
+              :class="{ active: approveForm.rejectType == reason.value }"
+              @tap="approveForm.rejectType = reason.value"
+            >
+              <text
+                class="radio-icon"
+                :class="{ checked: approveForm.rejectType == reason.value }"
+                >鉁�</text
+              >
+              <text class="radio-text">{{ reason.label }}</text>
+            </view>
+          </view>
+        </view>
+
+        <!-- 纭/椹冲洖鎰忚 -->
+        <view class="form-group">
+          <text class="form-label">
+            {{ approveForm.approveResult == "4" ? "椹冲洖鎰忚" : "纭鎰忚" }}
+            <text class="required" v-if="approveForm.approveResult == '4'"
+              >*</text
+            >
+          </text>
+          <textarea
+            v-model="approveForm.confirmResult"
+            class="form-textarea"
+            :placeholder="
+              approveForm.approveResult == '4'
+                ? '璇疯緭鍏ヨ缁嗙殑椹冲洖鎰忚'
+                : '璇疯緭鍏ョ‘璁ゆ剰瑙�'
+            "
+            maxlength="500"
+          />
+          <text class="word-count"
+            >{{ approveForm.confirmResult.length }}/500</text
+          >
+        </view>
+      </scroll-view>
+
+      <!-- 搴曢儴鎸夐挳 -->
+      <view class="panel-footer">
+        <button class="panel-btn cancel" @tap="closeApprovePanel">鍙栨秷</button>
+        <button
+          class="panel-btn submit"
+          @tap="submitApprove"
+          :loading="approveLoading"
+        >
+          纭畾
+        </button>
+      </view>
+    </view>
+
     <!-- 鍔犺浇鐘舵�� -->
     <u-loading-icon v-if="loading" :show="loading" text="鍔犺浇涓�..." />
   </view>
@@ -408,19 +595,89 @@
 
 <script setup>
 import { ref, computed, onMounted } from "vue";
-import { onLoad } from "@dcloudio/uni-app";
-import { useDict } from "@/utils/dict";
+import { onLoad, onShow } from "@dcloudio/uni-app";
 import { useHomeButton } from "@/stores/useHomeButton";
 import attachmentUpload from "@/components/attachment";
-const { showHomeButton, checkAutoLogin, goHome } = useHomeButton();
-// 瀛楀吀鏁版嵁
-const dict = ref({});
+import { useUserStore } from "@/stores/user";
+import { useDictMapper } from "@/utils/useDictMapper";
+import dayjs from "dayjs";
 
-// 鏁版嵁
+const { showHomeButton, checkAutoLogin, goHome } = useHomeButton();
+
+// ==================== 瀛楀吀鏄犲皠 ====================
+const requiredDictTypes = [
+  "sys_user_sex",
+  "sys_BloodType",
+  "sys_AgeUnit",
+  "sys_IDType",
+  "sys_Nation",
+  "sys_education",
+  "sys_occupation",
+  "sys_Infectious",
+];
+
+const { dictData, loading: dictLoading } = useDictMapper(requiredDictTypes);
+
+// 閫氱敤瀛楀吀鏌ヨ鏂规硶
+const getDictList = (dictType) => {
+  return dictData.value[dictType] || [];
+};
+
+const getDictLabel = (dictType, value) => {
+  if (!value) return "鏈~鍐�";
+  const dictList = getDictList(dictType);
+  const found = dictList.find(
+    (item) => item.value == value || item.value === value,
+  );
+  return found ? found.label : value;
+};
+
+// 浼犳煋鐥呯壒娈婂鐞嗭紙澶氫釜鍊肩敤閫楀彿鍒嗛殧锛�
+const getInfectiousText = () => {
+  const infectious = caseDetail.value.infectious;
+  if (!infectious) return "鏃�";
+  const values = infectious.split(",").filter((v) => v.trim());
+  if (values.length === 0) return "鏃�";
+  const labels = values.map((v) => getDictLabel("sys_Infectious", v.trim()));
+  const other = caseDetail.value.infectiousOther;
+  return labels.join("銆�") + (other ? `锛�${other}锛塦 : "");
+};
+
+// ==================== 鏁版嵁 ====================
 const caseDetail = ref({});
+const userStore = useUserStore();
 const loading = ref(false);
+const approveLoading = ref(false);
 const activeTab = ref("basic");
 const caseId = ref(null);
+const attachments = ref([]);
+const showApprovePanel = ref(false);
+
+const canApprove = computed(() => {
+  console.log(userStore.userInfo.roles);
+
+  const roles = userStore.userInfo?.roles || [];
+  return roles.some((role) => role.roleKey === "admin" || "opoadmin"|| "leader"|| "business");
+});
+
+// 椹冲洖鍘熷洜閫夐」
+const rejectReasons = [
+  { label: "濂借浆", value: "1" },
+  { label: "姝讳骸", value: "2" },
+  { label: "涓嶇鍚堟崘鐚爣鍑�", value: "3" },
+  { label: "瀹跺睘鏀惧純鎹愮尞", value: "4" },
+  { label: "鍏朵粬", value: "5" },
+];
+
+// 纭琛ㄥ崟
+const approveForm = ref({
+  id: null,
+  approveResult: "3",
+  confirmResult: "",
+  rejectType: "",
+  isTransport: "2",
+  isDonate: "0",
+});
 
 // 閫夐」鍗�
 const tabs = ref([
@@ -429,223 +686,101 @@
   { id: "contact", label: "鑱旂郴淇℃伅" },
   { id: "transport", label: "杞繍淇℃伅" },
 ]);
-const attachments = ref([]);
 
 // 璁$畻灞炴��
-const hasTransport = computed(() => {
-  return caseDetail.value.serviceTransport;
-});
+const hasTransport = computed(
+  () =>
+    caseDetail.value.serviceTransport &&
+    caseDetail.value.serviceTransport.length > 0,
+);
 
-const canDelete = computed(() => {
-  // 鍏佽鍒犻櫎鏈鎵规垨宸查┏鍥炵殑妗堜緥
-  return (
-    caseDetail.value.reportStatus === "1" ||
-    caseDetail.value.reportStatus === "2" ||
-    caseDetail.value.reportStatus === "4"
-  );
+// ==================== 鐢熷懡鍛ㄦ湡 ====================
+onShow(() => {
+  if (caseId.value) {
+    loadCaseDetail(caseId.value);
+  }
 });
 
 onLoad(async (options) => {
   checkAutoLogin(options);
   if (options.id) {
     caseId.value = options.id;
-    // 鑾峰彇瀛楀吀鏁版嵁
-    dict.value = await useDict(
-      "sys_user_sex",
-      "sys_BloodType",
-      "sys_IDType",
-      "sys_AgeUnit",
-    );
-    // 鍔犺浇妗堜緥璇︽儏
     await loadCaseDetail(options.id);
   }
 });
 
-// 鍔犺浇妗堜緥璇︽儏
+// ==================== 鍔犺浇鏁版嵁 ====================
 const loadCaseDetail = async (id) => {
   loading.value = true;
   try {
     const res = await uni.$uapi.get(
       `/project/donatebaseinforeport/getInfo/${id}`,
     );
-
     if (res.data) {
       caseDetail.value = res.data;
       if (res.data.annexfilesList) {
-        attachments.value = res.data.annexfilesList;
-        attachments.value.forEach((item) => {
-          item.url = item.path;
-          item.name = item.fileName;
-        });
+        attachments.value = res.data.annexfilesList.map((item) => ({
+          ...item,
+          url: item.path,
+          name: item.fileName,
+        }));
       }
-      // 濡傛灉鐘舵�佹槸"宸蹭笂鎶�"(1)锛岃嚜鍔ㄦ洿鏂颁负"宸查槄璇�"(2)
-      // if (caseDetail.value.reportStatus === '1') {
-      //   await updateCaseStatus('2')
-      // }
     } else {
       throw new Error(res.msg || "鏁版嵁鍔犺浇澶辫触");
     }
   } catch (error) {
     console.error("鍔犺浇妗堜緥璇︽儏澶辫触:", error);
-    uni.showToast({
-      title: "鏁版嵁鍔犺浇澶辫触锛岃閲嶈瘯",
-      icon: "none",
-    });
+    uni.showToast({ title: "鏁版嵁鍔犺浇澶辫触锛岃閲嶈瘯", icon: "none" });
   } finally {
     loading.value = false;
   }
 };
-// 棰勮鏂囦欢 - 淇敼涓轰娇鐢ㄥ畬鏁碪RL
-const handlePreview = (file) => {
-  const fullUrl = file.url.startsWith("http")
-    ? file.url
-    : baseUrlHt + (file.url.startsWith("/") ? "" : "/") + file.url;
 
-  if (file.type.includes("image")) {
-    uni.previewImage({
-      urls: attachments.value
-        .filter((f) => f.type.includes("image"))
-        .map((f) =>
-          f.url.startsWith("http")
-            ? f.url
-            : baseUrlHt + (f.url.startsWith("/") ? "" : "/") + f.url,
-        ),
-      current: fullUrl,
-    });
-  } else if (file.type.includes("pdf")) {
-    uni.downloadFile({
-      url: fullUrl,
-      success: (res) => {
-        uni.openDocument({
-          filePath: res.tempFilePath,
-          fileType: "pdf",
-          showMenu: true,
-        });
-      },
-      fail: (err) => {
-        console.error("鎵撳紑鏂囨。澶辫触:", err);
-        uni.showToast({ title: "鎵撳紑鏂囦欢澶辫触", icon: "none" });
-      },
-    });
-  } else {
-    uni.showToast({ title: "鏆備笉鏀寔姝ゆ枃浠剁被鍨嬮瑙�", icon: "none" });
-  }
-};
-// 鏇存柊妗堜緥鐘舵��
-const updateCaseStatus = async (newStatus) => {
-  try {
-    const updateData = {
-      ...caseDetail.value,
-      reportStatus: newStatus,
-      updateTime: new Date().toISOString().replace("T", " ").substring(0, 19),
-      updateBy: "绉诲姩绔敤鎴�",
-    };
-
-    const res = await uni.$uapi.post(
-      "/project/donatebaseinforeport/edit",
-      updateData,
-    );
-
-    if (res.code === 200) {
-      caseDetail.value.reportStatus = newStatus;
-    }
-  } catch (error) {
-    console.error("鏇存柊鐘舵�佸け璐�:", error);
-  }
-};
-
-// 鑾峰彇鐘舵�佹牱寮�
-const getStatusClass = (status) => {
-  const map = {
-    1: "reported",
-    2: "read",
-    3: "agreed",
-    4: "rejected",
-  };
-  return map[status] || "reported";
-};
-
-// 鑾峰彇鐘舵�佹枃鏈�
-const getStatusText = (status) => {
-  const map = {
-    1: "宸蹭笂鎶�",
-    2: "宸查槄璇�",
-    3: "宸插悓鎰�",
-    4: "宸查┏鍥�",
-  };
-  return map[status] || "宸蹭笂鎶�";
-};
-
-// 鑾峰彇鎬у埆鏂囨湰
-const getGenderText = (gender) => {
-  if (!dict.value.sys_user_sex) return gender;
-  const genderItem = dict.value.sys_user_sex.find(
-    (item) => item.dictValue === gender,
-  );
-  return genderItem ? genderItem.dictLabel : gender;
-};
-
-// 鑾峰彇琛�鍨嬫枃鏈�
-const getBloodTypeText = (bloodType) => {
-  if (!dict.value.sys_BloodType) return bloodType;
-  const bloodTypeItem = dict.value.sys_BloodType.find(
-    (item) => item.dictValue === bloodType,
-  );
-  return bloodTypeItem ? bloodTypeItem.dictLabel : bloodType;
-};
-
-// 鑾峰彇骞撮緞鍗曚綅鏂囨湰
-const getAgeUnitText = (ageunit) => {
-  if (!ageunit) return "";
-  const unitMap = {
-    year: "宀�",
-    month: "涓湀",
-    day: "澶�",
-  };
-  return unitMap[ageunit] || ageunit;
-};
-
-// 鑾峰彇瀹屾暣鎴风睄鍦板潃
+// ==================== 鍦板潃鎷兼帴 ====================
 const getFullRegisterAddress = () => {
   const {
     registerprovincename,
     registercityname,
     registertownname,
-    registercommunityname,
     registeraddress,
   } = caseDetail.value;
-
   const parts = [
     registerprovincename,
     registercityname,
     registertownname,
-    registercommunityname,
     registeraddress,
   ];
-  return parts.filter((part) => part).join("");
+  return parts.filter((p) => p && p.trim()).join("");
 };
 
-// 鑾峰彇瀹屾暣鐜颁綇鍦板潃
 const getFullResidenceAddress = () => {
   const {
     residenceprovincename,
-    residencecountyname,
+    residencecityname,
     residencetownname,
-    residencecommunityname,
     residenceaddress,
   } = caseDetail.value;
-
   const parts = [
     residenceprovincename,
-    residencecountyname,
+    residencecityname,
     residencetownname,
-    residencecommunityname,
     residenceaddress,
   ];
-  return parts.filter((part) => part).join("");
+  return parts.filter((p) => p && p.trim()).join("");
 };
 
-// 鑾峰彇杞繍鐘舵�佹枃鏈�
+// ==================== 鐘舵�佺浉鍏� ====================
+const getStatusClass = (status) => {
+  const map = { 1: "reported", 2: "read", 3: "agreed", 4: "rejected" };
+  return map[status] || "reported";
+};
+
+const getStatusText = (status) => {
+  const map = { 1: "宸蹭笂鎶�", 2: "宸查槄璇�", 3: "宸插悓鎰�", 4: "宸查┏鍥�" };
+  return map[status] || "宸蹭笂鎶�";
+};
+
+// ==================== 杞繍鐩稿叧 ====================
 const getTransportStatusText = (status) => {
   const map = {
     1: "寰呰浆杩�",
@@ -657,7 +792,6 @@
   return map[status] || "鏈煡";
 };
 
-// 鑾峰彇杞繍鐘舵�佹牱寮�
 const getTransportStatusClass = (status) => {
   const map = {
     1: "pending",
@@ -669,18 +803,146 @@
   return map[status] || "pending";
 };
 
-// 鏍煎紡鍖栨棩鏈熸椂闂�
+// ==================== 宸ュ叿鏂规硶 ====================
 const formatDateTime = (dateTime) => {
   if (!dateTime) return "";
   return dateTime.replace("T", " ").substring(0, 16);
 };
 
-// 閫夐」鍗″垏鎹�
+// ==================== 纭鍔熻兘 ====================
+/** 鎵撳紑纭闈㈡澘 */
+const openApprovePanel = () => {
+  // 鍒濆鍖栬〃鍗�
+  approveForm.value = {
+    id: caseDetail.value.id,
+    approveResult: "3",
+    confirmResult: "",
+    rejectType: "",
+    isTransport: caseDetail.value.isTransport || "2",
+    isDonate: "0",
+  };
+  showApprovePanel.value = true;
+};
+
+/** 鍏抽棴纭闈㈡澘 */
+const closeApprovePanel = () => {
+  showApprovePanel.value = false;
+};
+
+/** 纭缁撴灉鍙樺寲澶勭悊 */
+const handleApproveResultChange = (value) => {
+  if (value == "3") {
+    // 閫夋嫨鍚屾剰鏃讹紝閲嶇疆椹冲洖鍘熷洜
+    approveForm.value.rejectType = "";
+    approveForm.value.isDonate = "0";
+  } else if (value == "4") {
+    // 閫夋嫨椹冲洖鏃讹紝閲嶇疆杞繍閫夐」
+    approveForm.value.isTransport = "1";
+  }
+};
+
+/** 琛ㄥ崟鏍¢獙 */
+const validateApproveForm = () => {
+  if (!approveForm.value.approveResult) {
+    uni.showToast({ title: "璇烽�夋嫨纭缁撴灉", icon: "none" });
+    return false;
+  }
+  if (
+    approveForm.value.approveResult == "3" &&
+    !approveForm.value.isTransport
+  ) {
+    uni.showToast({ title: "璇烽�夋嫨鏄惁闇�瑕佽浆杩�", icon: "none" });
+    return false;
+  }
+  if (approveForm.value.approveResult == "4") {
+    if (!approveForm.value.rejectType) {
+      uni.showToast({ title: "璇烽�夋嫨椹冲洖鍘熷洜", icon: "none" });
+      return false;
+    }
+    if (!approveForm.value.confirmResult) {
+      uni.showToast({ title: "椹冲洖鏃跺繀椤诲~鍐欓┏鍥炴剰瑙�", icon: "none" });
+      return false;
+    }
+  }
+  return true;
+};
+
+/** 鎻愪氦纭 */
+const submitApprove = async () => {
+  if (!validateApproveForm()) return;
+
+  approveLoading.value = true;
+  try {
+    // 鍑嗗纭鏁版嵁
+    const approveData = {
+      ...caseDetail.value,
+      reportStatus: approveForm.value.approveResult,
+      confirmResult: approveForm.value.confirmResult,
+      approvername: userStore.user?.name || "褰撳墠鐢ㄦ埛",
+      approvetime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
+      updateTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
+      updateBy: userStore.user?.name || "褰撳墠鐢ㄦ埛",
+    };
+
+    // 澶勭悊纭缁撴灉
+    if (approveForm.value.approveResult == "3") {
+      // 鍚屾剰
+      approveData.isTransport = approveForm.value.isTransport;
+      // 濡傛灉涓嶉渶瑕佽浆杩愶紝璁剧疆isDonate涓�1
+      if (approveForm.value.isTransport == "1") {
+        approveData.isDonate = "1";
+      } else {
+        approveData.isDonate = "0";
+      }
+    } else if (approveForm.value.approveResult == "4") {
+      // 椹冲洖
+      approveData.rejectType = approveForm.value.rejectType;
+      approveData.isTransport = "1"; // 椹冲洖鐨勬渚嬩笉闇�瑕佽浆杩�
+      approveData.isDonate = "0"; // 椹冲洖鐨勬渚嬫爣璁颁负宸叉崘鐚�
+    }
+
+    // 璋冪敤缂栬緫鎺ュ彛鏇存柊鐘舵��
+    const res = await uni.$uapi.post(
+      "/project/donatebaseinforeport/edit",
+      approveData,
+    );
+
+    if (res.code == 200) {
+      uni.showToast({ title: "纭鎴愬姛", icon: "success" });
+      showApprovePanel.value = false;
+
+      // 閲嶆柊鍔犺浇璇︽儏
+      await loadCaseDetail(caseId.value);
+
+      // 濡傛灉鍚屾剰涓旈渶瑕佽浆杩愶紝璺宠浆鍒拌浆杩愬崟鍒涘缓椤甸潰
+      if (
+        approveForm.value.approveResult == "3" &&
+        approveForm.value.isTransport == "2"
+      ) {
+        console.log(caseId.value);
+
+        setTimeout(() => {
+          uni.navigateTo({
+            url: `/pagesSub/case/transferinfo?caseId=${caseId.value}&caseNo=${caseDetail.value.caseNo}&autoCreate=true`,
+          });
+        }, 800);
+      }
+    } else {
+      uni.showToast({ title: res.msg || "纭澶辫触", icon: "none" });
+    }
+  } catch (error) {
+    console.error("纭澶辫触:", error);
+    uni.showToast({ title: "纭澶辫触锛岃閲嶈瘯", icon: "none" });
+  } finally {
+    approveLoading.value = false;
+  }
+};
+
+// ==================== 浜嬩欢澶勭悊 ====================
 const switchTab = (tabId) => {
   activeTab.value = tabId;
 };
 
-// 杩斿洖
 const goBack = () => {
   if (showHomeButton) {
     uni.switchTab({ url: "/pages/index/index" });
@@ -689,60 +951,59 @@
   }
 };
 
-// 缂栬緫妗堜緥
 const handleEdit = () => {
   uni.navigateTo({
     url: `/pagesSub/case/CaseDetails?id=${caseId.value}&edit=true`,
   });
 };
 
-// 鍒犻櫎妗堜緥
-const handleDelete = () => {
-  uni.showModal({
-    title: "纭鍒犻櫎",
-    content: `纭畾瑕佸垹闄ゆ渚� ${caseDetail.value.caseNo} 鍚楋紵`,
-    success: async (res) => {
-      if (res.confirm) {
-        try {
-          const result = await uni.$uapi.delete(
-            `/project/donatebaseinforeport/${caseId.value}`,
-          );
-          if (result.code === 200) {
-            uni.showToast({ title: "鍒犻櫎鎴愬姛", icon: "success" });
-            setTimeout(() => {
-              uni.navigateBack();
-            }, 1500);
-          } else {
-            uni.showToast({ title: result.msg || "鍒犻櫎澶辫触", icon: "none" });
-          }
-        } catch (error) {
-          console.error("鍒犻櫎澶辫触:", error);
-          uni.showToast({ title: "鍒犻櫎澶辫触", icon: "none" });
-        }
-      }
-    },
-  });
-};
-
-// 鍒涘缓杞繍鍗�
 const createTransport = () => {
   if (caseDetail.value.reportStatus !== "3") {
     uni.showToast({ title: "妗堜緥闇�鍏堝鎵瑰悓鎰�", icon: "none" });
     return;
   }
-
   uni.navigateTo({
     url: `/pages/transport/create?caseId=${caseId.value}&caseNo=${caseDetail.value.caseNo}`,
   });
 };
 
-// 鏌ョ湅杞繍鍗曡鎯�
 const viewTransportDetail = () => {
-  if (hasTransport.value && caseDetail.value.serviceTransport[0]) {
+  if (hasTransport.value) {
     const transport = caseDetail.value.serviceTransport[0];
-    uni.navigateTo({
-      url: `/pages/transport/detail?id=${transport.id}`,
+    uni.navigateTo({ url: `/pages/transport/detail?id=${transport.id}` });
+  }
+};
+
+// 闄勪欢棰勮
+const handlePreview = (file) => {
+  const fullUrl = file.url.startsWith("http")
+    ? file.url
+    : (file.url.startsWith("/") ? "" : "/") + file.url;
+  if (file.type && file.type.includes("image")) {
+    uni.previewImage({
+      urls: attachments.value
+        .filter((f) => f.type && f.type.includes("image"))
+        .map((f) =>
+          f.url.startsWith("http")
+            ? f.url
+            : (f.url.startsWith("/") ? "" : "/") + f.url,
+        ),
+      current: fullUrl,
     });
+  } else if (file.type && file.type.includes("pdf")) {
+    uni.downloadFile({
+      url: fullUrl,
+      success: (res) => {
+        uni.openDocument({
+          filePath: res.tempFilePath,
+          fileType: "pdf",
+          showMenu: true,
+        });
+      },
+      fail: () => uni.showToast({ title: "鎵撳紑鏂囦欢澶辫触", icon: "none" }),
+    });
+  } else {
+    uni.showToast({ title: "鏆備笉鏀寔姝ゆ枃浠剁被鍨嬮瑙�", icon: "none" });
   }
 };
 </script>
@@ -750,84 +1011,84 @@
 <style lang="scss" scoped>
 .case-detail {
   min-height: 100vh;
-  background: linear-gradient(135deg, #fafdff 0%, #e3f0ff 100%);
+  background: #f5f7fa;
   padding: 20rpx;
-  padding-bottom: 120rpx; /* 涓烘搷浣滄爮鐣欏嚭绌洪棿 */
+  padding-bottom: 180rpx; /* 澧炲姞搴曢儴闂磋窛缁欐搷浣滄爮 */
 }
 
+/* ========== 澶撮儴鍗$墖 ========== */
 .header-card {
-  background: linear-gradient(135deg, #fff 60%, #f5f6fa 100%);
-  border-radius: 32rpx;
-  padding: 40rpx 30rpx;
-  margin-bottom: 30rpx;
-  box-shadow: 0 12px 48px 0 rgba(0, 113, 227, 0.1);
-  border: 1.5px solid #e5eaf0;
+  background: #fff;
+  border-radius: 24rpx;
+  padding: 30rpx 28rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
 }
 
 .case-header {
   display: flex;
   justify-content: space-between;
   align-items: flex-start;
-  margin-bottom: 30rpx;
+  margin-bottom: 24rpx;
 }
 
 .hospital-info {
   display: flex;
   align-items: center;
+  flex: 1;
+  min-width: 0;
 }
 
 .hospital-logo {
-  width: 80rpx;
-  height: 80rpx;
+  width: 72rpx;
+  height: 72rpx;
   border-radius: 16rpx;
-  margin-right: 20rpx;
-  background: #f5f5f7;
+  margin-right: 16rpx;
+  background: #f0f2f5;
+  flex-shrink: 0;
 }
 
 .hospital-details {
   display: flex;
   flex-direction: column;
+  min-width: 0;
 }
 
 .hospital-name {
-  font-size: 32rpx;
+  font-size: 30rpx;
   font-weight: 600;
   color: #1d1d1f;
-  margin-bottom: 8rpx;
-  max-width: 400rpx;
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
 }
 
 .case-type {
-  font-size: 24rpx;
-  color: #86868b;
+  font-size: 22rpx;
+  color: #8e8e93;
+  margin-top: 4rpx;
 }
 
 .case-status {
-  padding: 8rpx 20rpx;
+  padding: 6rpx 18rpx;
   border-radius: 20rpx;
-  font-size: 24rpx;
+  font-size: 22rpx;
   font-weight: 500;
-
+  flex-shrink: 0;
   &.reported {
-    background: rgba(255, 149, 0, 0.1);
+    background: rgba(255, 149, 0, 0.12);
     color: #ff9500;
   }
-
   &.read {
-    background: rgba(0, 122, 255, 0.1);
+    background: rgba(0, 122, 255, 0.12);
     color: #007aff;
   }
-
   &.agreed {
-    background: rgba(52, 199, 89, 0.1);
+    background: rgba(52, 199, 89, 0.12);
     color: #34c759;
   }
-
   &.rejected {
-    background: rgba(255, 59, 48, 0.1);
+    background: rgba(255, 59, 48, 0.12);
     color: #ff3b30;
   }
 }
@@ -836,36 +1097,34 @@
   .info-row {
     display: flex;
     justify-content: space-between;
+    gap: 20rpx;
   }
-
   .info-item {
     display: flex;
     flex-direction: column;
+    flex: 1;
   }
-
   .label {
-    font-size: 24rpx;
-    color: #86868b;
-    margin-bottom: 8rpx;
+    font-size: 22rpx;
+    color: #8e8e93;
+    margin-bottom: 4rpx;
   }
-
   .value {
-    font-size: 28rpx;
+    font-size: 26rpx;
     color: #1d1d1f;
     font-weight: 500;
   }
 }
 
+/* ========== 閫夐」鍗� ========== */
 .tab-navigation {
   display: flex;
   background: #fff;
   border-radius: 16rpx;
-  padding: 8rpx;
-  margin-bottom: 30rpx;
-  box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.05);
+  padding: 6rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
   overflow-x: auto;
-  white-space: nowrap;
-
   &::-webkit-scrollbar {
     display: none;
   }
@@ -873,264 +1132,507 @@
 
 .tab-item {
   flex: 1;
-  min-width: 140rpx;
+  min-width: 120rpx;
   text-align: center;
-  padding: 20rpx;
-  font-size: 28rpx;
-  color: #86868b;
+  padding: 16rpx 10rpx;
+  font-size: 26rpx;
+  color: #8e8e93;
+  border-radius: 12rpx;
   transition: all 0.3s ease;
-
   &.active {
     color: #007aff;
     background: #f0f7ff;
-    border-radius: 12rpx;
     font-weight: 600;
   }
 }
 
+/* ========== 鍐呭鍗$墖 ========== */
 .section-card {
-  background: linear-gradient(135deg, #fff 60%, #f5f6fa 100%);
-  border-radius: 32rpx;
-  padding: 40rpx 30rpx;
-  margin-bottom: 30rpx;
-  box-shadow: 0 12px 48px 0 rgba(0, 113, 227, 0.1);
-  border: 1.5px solid #e5eaf0;
+  background: #fff;
+  border-radius: 24rpx;
+  padding: 28rpx 24rpx;
+  margin-bottom: 24rpx;
+  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.04);
 }
 
 .section-header {
-  margin-bottom: 30rpx;
+  margin-bottom: 24rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
 }
 
 .section-title {
-  font-size: 32rpx;
+  font-size: 30rpx;
   font-weight: 600;
-  background: linear-gradient(90deg, #0071e3 0%, #2997ff 100%);
-  -webkit-background-clip: text;
-  -webkit-text-fill-color: transparent;
-  color: #0071e3;
+  color: #1d1d1f;
 }
 
+/* ========== 淇℃伅缃戞牸 ========== */
 .info-grid {
   display: grid;
   grid-template-columns: 1fr 1fr;
-  gap: 24rpx;
+  gap: 16rpx 24rpx;
 }
 
 .info-item {
   display: flex;
   flex-direction: column;
+  padding: 12rpx 0;
+  border-bottom: 1rpx solid #f5f5f7;
 
   &.full-width {
     grid-column: 1 / -1;
   }
 
+  &.address-item {
+    padding-bottom: 8rpx;
+  }
+
   .label {
-    font-size: 24rpx;
-    color: #86868b;
-    margin-bottom: 8rpx;
+    font-size: 22rpx;
+    color: #8e8e93;
+    margin-bottom: 4rpx;
+    font-weight: 400;
   }
 
   .value {
-    font-size: 28rpx;
+    font-size: 27rpx;
+    color: #1d1d1f;
+    font-weight: 500;
+    word-break: break-all;
+    line-height: 1.5;
+  }
+
+  .diagnosis-text {
+    color: #007aff;
+    font-weight: 600;
+  }
+}
+
+/* 鍦板潃椤圭壒娈婂鐞嗭細鍘绘帀杈规鏇存竻鐖� */
+.address-item {
+  border-bottom: none !important;
+  padding-bottom: 4rpx !important;
+}
+
+/* ========== 杞繍淇℃伅 ========== */
+.transport-list {
+  margin-top: 16rpx;
+}
+
+.transport-item {
+  background: #f8f9fc;
+  border-radius: 16rpx;
+  padding: 20rpx;
+  margin-bottom: 16rpx;
+  border: 1rpx solid #e8ecf0;
+  &:last-child {
+    margin-bottom: 0;
+  }
+}
+
+.transport-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-bottom: 14rpx;
+  border-bottom: 1rpx solid #e8ecf0;
+  margin-bottom: 14rpx;
+}
+
+.transport-no {
+  font-size: 26rpx;
+  font-weight: 600;
+  color: #1d1d1f;
+}
+
+.transport-status {
+  font-size: 22rpx;
+  padding: 4rpx 16rpx;
+  border-radius: 12rpx;
+  font-weight: 500;
+  &.pending {
+    background: rgba(240, 173, 78, 0.15);
+    color: #f0ad4e;
+  }
+  &.transporting {
+    background: rgba(0, 122, 255, 0.12);
+    color: #007aff;
+  }
+  &.completed {
+    background: rgba(52, 199, 89, 0.12);
+    color: #34c759;
+  }
+  &.cancelled {
+    background: rgba(142, 142, 147, 0.12);
+    color: #8e8e93;
+  }
+  &.draft {
+    background: rgba(142, 142, 147, 0.08);
+    color: #8e8e93;
+  }
+}
+
+.transport-body {
+  display: flex;
+  flex-direction: column;
+  gap: 8rpx;
+}
+
+.transport-row {
+  display: flex;
+  align-items: baseline;
+  .t-label {
+    font-size: 24rpx;
+    color: #8e8e93;
+    width: 140rpx;
+    flex-shrink: 0;
+  }
+  .t-value {
+    font-size: 26rpx;
+    color: #1d1d1f;
+    word-break: break-all;
+  }
+}
+
+.empty-transport {
+  text-align: center;
+  padding: 40rpx 0;
+  color: #8e8e93;
+  font-size: 26rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+
+/* ========== 灏忓瀷鎸夐挳 ========== */
+.small-btn {
+  padding: 8rpx 20rpx;
+  font-size: 22rpx;
+  border-radius: 8rpx;
+  border: none;
+  &.primary {
+    background: #007aff;
+    color: #fff;
+  }
+  &.secondary {
+    background: #ecf5ff;
+    color: #007aff;
+    border: 1rpx solid #007aff;
+  }
+  &:active {
+    opacity: 0.8;
+  }
+}
+
+/* ========== 搴曢儴鎿嶄綔鏍� ========== */
+.action-bar {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background: #fff;
+  padding: 18rpx 30rpx calc(18rpx + env(safe-area-inset-bottom));
+  box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
+  z-index: 2;
+  display: flex;
+  gap: 16rpx;
+}
+
+.action-btn {
+  flex: 1;
+  height: 88rpx;
+  border-radius: 44rpx;
+  font-size: 32rpx;
+  font-weight: 700;
+  border: none;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  letter-spacing: 1rpx;
+
+  &.secondary {
+    background: #f5f5f7;
+    color: #1d1d1f;
+    &:active {
+      background: #e5e5e7;
+    }
+  }
+  &.primary {
+    background: linear-gradient(90deg, #0071e3, #2997ff);
+    color: #fff;
+    &:active {
+      transform: scale(0.96);
+    }
+  }
+  &.approve {
+    background: linear-gradient(135deg, #34c759, #30b350);
+    color: #fff;
+    box-shadow: 0 4rpx 16rpx rgba(52, 199, 89, 0.35);
+    &:active {
+      transform: scale(0.96);
+      box-shadow: 0 2rpx 8rpx rgba(52, 199, 89, 0.25);
+    }
+  }
+}
+
+/* ========== 纭搴曢儴寮瑰嚭闈㈡澘 ========== */
+.approve-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.45);
+  z-index: 999;
+  animation: fadeIn 0.25s ease;
+}
+
+.approve-panel {
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: #ffffff;
+  border-radius: 32rpx 32rpx 0 0;
+  z-index: 1000;
+  max-height: 82vh;
+  display: flex;
+  flex-direction: column;
+  transform: translateY(100%);
+  transition: transform 0.35s cubic-bezier(0.32, 0.94, 0.6, 1);
+  box-shadow: 0 -8rpx 40rpx rgba(0, 0, 0, 0.12);
+
+  &.panel-show {
+    transform: translateY(0);
+  }
+}
+
+.panel-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 36rpx 32rpx 20rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+  flex-shrink: 0;
+}
+
+.panel-title {
+  font-size: 34rpx;
+  font-weight: 700;
+  color: #1d1d1f;
+}
+
+.panel-close {
+  width: 50rpx;
+  height: 50rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 32rpx;
+  color: #8e8e93;
+  background: #f5f5f7;
+  border-radius: 50%;
+  &:active {
+    background: #e5e5e7;
+  }
+}
+
+.panel-body {
+  flex: 1;
+  padding: 24rpx 32rpx 20rpx;
+  overflow-y: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+/* 妗堜緥鎽樿鍗$墖 */
+.summary-card {
+  background: #f8f9fc;
+  border-radius: 16rpx;
+  padding: 20rpx 24rpx;
+  margin-bottom: 28rpx;
+  border: 1rpx solid #e8ecf0;
+}
+
+.summary-row {
+  display: flex;
+  align-items: baseline;
+  padding: 8rpx 0;
+
+  .s-label {
+    font-size: 24rpx;
+    color: #8e8e93;
+    width: 130rpx;
+    flex-shrink: 0;
+  }
+  .s-value {
+    font-size: 26rpx;
     color: #1d1d1f;
     font-weight: 500;
     word-break: break-all;
   }
 }
 
-.info-content {
-  .info-group {
-    margin-bottom: 32rpx;
-    padding-bottom: 20rpx;
-    border-bottom: 1rpx solid #f0f0f0;
+/* 琛ㄥ崟缁� */
+.form-group {
+  margin-bottom: 28rpx;
+}
 
-    &:last-child {
-      margin-bottom: 0;
-      padding-bottom: 0;
-      border-bottom: none;
-    }
-  }
+.form-label {
+  display: block;
+  font-size: 28rpx;
+  font-weight: 600;
+  color: #1d1d1f;
+  margin-bottom: 16rpx;
 
-  .group-title {
-    font-size: 26rpx;
-    color: #86868b;
-    margin-bottom: 12rpx;
-    display: block;
-    font-weight: 500;
-  }
-
-  .group-content {
-    font-size: 28rpx;
-    color: #1d1d1f;
-    line-height: 1.6;
+  .required {
+    color: #ff3b30;
+    margin-left: 4rpx;
   }
 }
 
-/* 杞繍淇℃伅鏍峰紡 */
-.transport-info {
-  .info-group {
-    border: 2rpx solid #f0f0f0;
-    border-radius: 12rpx;
-    padding: 20rpx;
-    margin-bottom: 20rpx;
-    background: #fafafa;
+/* 鍗曢�夌粍 - 姘村钩鎺掑垪 */
+.radio-group {
+  display: flex;
+  gap: 16rpx;
+  flex-wrap: wrap;
 
-    &:last-child {
-      margin-bottom: 0;
-    }
-  }
-
-  .sub-group {
-    display: flex;
-    margin-bottom: 12rpx;
-    align-items: center;
-
-    &:last-child {
-      margin-bottom: 0;
-    }
-  }
-
-  .sub-label {
-    font-size: 26rpx;
-    color: #606266;
-    min-width: 160rpx;
-    margin-right: 10rpx;
-  }
-
-  .sub-value {
-    font-size: 26rpx;
-    color: #303133;
-    flex: 1;
-
-    &.status {
-      padding: 4rpx 12rpx;
-      border-radius: 6rpx;
-      font-size: 24rpx;
-
-      &.pending {
-        background: rgba(240, 173, 78, 0.1);
-        color: #f0ad4e;
-      }
-
-      &.transporting {
-        background: rgba(0, 122, 255, 0.1);
-        color: #007aff;
-      }
-
-      &.completed {
-        background: rgba(76, 217, 100, 0.1);
-        color: #4cd964;
-      }
-
-      &.cancelled {
-        background: rgba(220, 223, 230, 0.1);
-        color: #dcdfe6;
-      }
-
-      &.draft {
-        background: rgba(144, 147, 153, 0.1);
-        color: #909399;
-      }
-    }
-  }
-
-  .empty-transport {
-    text-align: center;
-    padding: 40rpx 0;
-    color: #909399;
-    font-size: 28rpx;
+  &.vertical {
+    flex-direction: column;
+    gap: 12rpx;
   }
 }
 
-/* 灏忓瀷鎸夐挳 */
-.small-btn {
-  padding: 8rpx 20rpx;
-  font-size: 24rpx;
-  border-radius: 6rpx;
-  border: none;
+.radio-item {
+  display: flex;
+  align-items: center;
+  padding: 16rpx 24rpx;
+  border-radius: 12rpx;
+  border: 2rpx solid #e0e0e0;
+  background: #fafafa;
+  transition: all 0.2s ease;
 
-  &.primary {
-    background: #007aff;
-    color: #fff;
-  }
+  &.active {
+    border-color: #007aff;
+    background: #f0f7ff;
 
-  &.secondary {
-    background: #ecf5ff;
-    color: #007aff;
-    border: 1rpx solid #007aff;
+    .radio-text {
+      color: #007aff;
+      font-weight: 600;
+    }
   }
 
   &:active {
-    opacity: 0.8;
+    transform: scale(0.97);
   }
 }
 
-.action-bar {
+.radio-icon {
+  width: 38rpx;
+  height: 38rpx;
+  border-radius: 19rpx;
+  border: 2rpx solid #c8c8cc;
   display: flex;
-  gap: 20rpx;
-  padding: 20rpx 0;
-  margin-top: 40rpx;
-  background: #fff;
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  padding: 20rpx 30rpx;
-  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
-  box-shadow: 0 -2rpx 20rpx rgba(0, 0, 0, 0.08);
-  z-index: 9;
+  align-items: center;
+  justify-content: center;
+  font-size: 22rpx;
+  color: transparent;
+  margin-right: 12rpx;
+  flex-shrink: 0;
+  transition: all 0.2s ease;
+
+  &.checked {
+    background: #007aff;
+    border-color: #007aff;
+    color: #ffffff;
+  }
 }
 
-.action-btn {
-  flex: 1;
-  height: 80rpx;
-  border-radius: 20rpx;
-  font-size: 28rpx;
-  font-weight: 600;
-  border: none;
-  transition: all 0.3s ease;
+.radio-text {
+  font-size: 26rpx;
+  color: #3a3a3c;
+  white-space: nowrap;
+}
 
-  &.secondary {
+/* 鏂囨湰鍩� */
+.form-textarea {
+  width: 92%;
+  min-height: 170rpx;
+  padding: 20rpx 24rpx;
+  border-radius: 14rpx;
+  border: 2rpx solid #e0e0e0;
+  background: #fafafa;
+  font-size: 26rpx;
+  color: #1d1d1f;
+  line-height: 1.6;
+  resize: none;
+
+  &:focus {
+    border-color: #007aff;
+    background: #ffffff;
+    outline: none;
+  }
+
+  &::placeholder {
+    color: #aeaeb2;
+  }
+}
+
+.word-count {
+  display: block;
+  text-align: right;
+  font-size: 22rpx;
+  color: #aeaeb2;
+  margin-top: 8rpx;
+  padding-right: 8rpx;
+}
+
+/* 搴曢儴鎸夐挳 */
+.panel-footer {
+  display: flex;
+  gap: 20rpx;
+  padding: 20rpx 32rpx calc(20rpx + env(safe-area-inset-bottom));
+  border-top: 1rpx solid #f0f0f0;
+  flex-shrink: 0;
+}
+
+.panel-btn {
+  flex: 1;
+  height: 84rpx;
+  border-radius: 42rpx;
+  font-size: 30rpx;
+  font-weight: 700;
+  border: none;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  letter-spacing: 1rpx;
+
+  &.cancel {
     background: #f5f5f7;
     color: #1d1d1f;
-
     &:active {
       background: #e5e5e7;
     }
   }
 
-  &.primary {
-    background: linear-gradient(90deg, #0071e3 0%, #2997ff 100%);
+  &.submit {
+    background: linear-gradient(90deg, #0071e3, #2997ff);
     color: #fff;
-
+    box-shadow: 0 4rpx 16rpx rgba(0, 113, 227, 0.3);
     &:active {
-      transform: scale(0.98);
-    }
-  }
-
-  &.success {
-    background: linear-gradient(90deg, #34c759 0%, #4cd964 100%);
-    color: #fff;
-
-    &:active {
-      transform: scale(0.98);
-    }
-  }
-
-  &.error {
-    background: linear-gradient(90deg, #ff3b30 0%, #ff5a5a 100%);
-    color: #fff;
-
-    &:active {
-      transform: scale(0.98);
+      transform: scale(0.97);
+      box-shadow: 0 2rpx 8rpx rgba(0, 113, 227, 0.2);
     }
   }
 }
 
+/* ========== 鍔ㄧ敾 ========== */
 .fade-in-up {
   opacity: 0;
-  transform: translateY(40rpx);
-  animation: fadeInUp 0.6s ease forwards;
+  transform: translateY(30rpx);
+  animation: fadeInUp 0.4s ease forwards;
 }
 
 @keyframes fadeInUp {
@@ -1139,4 +1641,13 @@
     transform: translateY(0);
   }
 }
+
+@keyframes fadeIn {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
 </style>

--
Gitblit v1.9.3