From 9bce51f651aad297ef9eb6df832bfdaf1de05d84 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期三, 22 四月 2026 14:27:54 +0800
Subject: [PATCH] 青岛推送

---
 pages/case/transfer.vue |  402 ++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 268 insertions(+), 134 deletions(-)

diff --git a/pages/case/transfer.vue b/pages/case/transfer.vue
index fba65b6..3b931f7 100644
--- a/pages/case/transfer.vue
+++ b/pages/case/transfer.vue
@@ -70,61 +70,68 @@
         <view class="header">
           <view class="case-info">
             <view class="info">
-              <text class="case-no">{{ item.caseNo }}</text>
+              <text class="case-no">{{ item.caseNo || item.reportId }}</text>
               <text class="patient"
-                >{{ item.donorName }} | {{ item.gender }} |
+                >{{ item.patName }} | {{ getGenderText(item.sex) }} |
                 {{ item.age }}宀�</text
               >
             </view>
           </view>
-          <text class="status" :class="item.status">{{ item.statusText }}</text>
+          <text class="status" :class="getStatusClass(item.transitStatus)">{{
+            getStatusText(item.transitStatus)
+          }}</text>
         </view>
 
         <view class="detail-info">
           <view class="info-item">
             <text class="label">鐤剧梾璇婃柇</text>
-            <text class="value">{{ item.diagnosis }}</text>
+            <text class="value">{{ item.diagnosisname || "鏈~鍐�" }}</text>
           </view>
           <view class="info-item">
             <text class="label">鎵�鍦ㄥ尰鐤楁満鏋�</text>
-            <text class="value">{{ item.hospitalName }}</text>
+            <text class="value">{{
+              item.treatmentHospitalName || "鏈~鍐�"
+            }}</text>
           </view>
           <view class="info-item">
             <text class="label">璁″垝杞繍鏃堕棿</text>
-            <text class="value">{{ item.transportTime }}</text>
+            <text class="value">{{ formatTime(item.transportStartTime) }}</text>
           </view>
           <view class="info-item">
             <text class="label">璐熻矗鍗忚皟鍛�</text>
-            <text class="value">{{ item.coordinator }}</text>
+            <text class="value">{{ item.contactPerson || "鏈寚瀹�" }}</text>
           </view>
           <view class="info-item">
             <text class="label">鍒涘缓鏃堕棿</text>
-            <text class="value">{{ item.createTime }}</text>
+            <text class="value">{{ formatTime(item.createTime) }}</text>
           </view>
         </view>
 
         <view class="footer">
           <view class="action-info">
             <text class="label">杞繍鐘舵��</text>
-            <text class="transport-status">{{ item.statusText }}</text>
+            <text class="transport-status">{{
+              getStatusText(item.transitStatus)
+            }}</text>
           </view>
           <view class="actions">
             <button
               class="action-btn"
-              v-if="item.status === 'pending'"
+              v-if="item.transitStatus === 1"
               @tap.stop="startTransport(item)"
             >
               寮�濮嬭浆杩�
             </button>
             <button
               class="action-btn"
-              v-if="item.status === 'transporting'"
+              v-if="item.transitStatus === 2"
               @tap.stop="completeTransport(item)"
             >
               瀹屾垚杞繍
             </button>
             <button
               class="action-btn secondary"
+              v-if="item.transitStatus === 1 || item.transitStatus === 5"
               @tap.stop="editTransport(item)"
             >
               缂栬緫
@@ -137,12 +144,15 @@
       </view>
 
       <!-- 鍔犺浇鏇村 -->
-      <view class="load-more" v-if="hasMore">
-        <text>鍔犺浇涓�...</text>
+      <view class="load-more" v-if="loading">
+        <u-loading-icon text="鍔犺浇涓�..."></u-loading-icon>
       </view>
 
       <!-- 绌虹姸鎬� -->
-      <view class="empty-state" v-if="filteredTransports.length === 0">
+      <view
+        class="empty-state"
+        v-if="!loading && filteredTransports.length === 0"
+      >
         <image src="/static/empty/no-transport.png" mode="aspectFit" />
         <text>鏆傛棤杞繍鍗曡褰�</text>
       </view>
@@ -170,121 +180,105 @@
 </template>
 
 <script setup>
-import { ref, computed } from "vue";
-import { onLoad } from "@dcloudio/uni-app";
+import { ref, computed, onMounted } from "vue";
+import { onLoad, onShow } from "@dcloudio/uni-app";
+import { useDict } from "@/utils/dict";
+
+// 瀛楀吀鏁版嵁
+const dict = ref({});
 
 // 缁熻鏁版嵁
 const stats = ref({
-  totalTransports: 12,
-  pendingTransports: 4,
-  completedTransports: 6,
+  totalTransports: 0,
+  pendingTransports: 0,
+  completedTransports: 0,
 });
+
+// 杞繍鍗曟暟鎹�
+const transports = ref([]);
+const loading = ref(false);
+const refreshing = ref(false);
+const hasMore = ref(true);
 const pageNum = ref(1);
 const pageSize = ref(10);
+
 // 鎿嶄綔纭寮圭獥鐩稿叧
 const showActionModal = ref(false);
 const currentTransport = ref({});
 const modalTitle = ref("");
 const modalAction = ref("");
 
-onLoad(async (options) => {
-  // 鍒濆鍖栨暟鎹�
-  loadTransports();
-});
-
 // 绛涢�夌浉鍏�
 const transportTypes = [
-  { label: "鍏ㄩ儴", value: "all" },
-  { label: "寰呭嚭鍙�", value: "pending" },
-  { label: "杞繍涓�", value: "transporting" },
-  { label: "宸插畬鎴�", value: "completed" },
-  { label: "宸插彇娑�", value: "cancelled" },
+  { label: "鍏ㄩ儴", value: "" },
+  { label: "寰呰浆杩�", value: 1 },
+  { label: "杞繍涓�", value: 2 },
+  { label: "宸插畬鎴�", value: 3 },
+  { label: "宸插彇娑�", value: 4 },
+  { label: "鏆傚瓨", value: 5 },
 ];
-const currentType = ref("all");
+const currentType = ref("");
 const startDate = ref("");
 const endDate = ref("");
 
-// 杞繍鍗曟暟鎹�
-const transports = ref([
-  {
-    id: "T20241217001",
-    caseNo: "DON20241216001",
-    donorName: "寮犱笁",
-    gender: "鐢�",
-    age: 38,
-    diagnosis: "鑴戝浼ゅ鑷磋剳姝讳骸",
-    hospitalName: "闈掑矝闀滄箹鍖婚櫌",
-    transportTime: "2024-12-17 14:30",
-    coordinator: "寮犲尰鐢�",
-    createTime: "2024-12-16 09:30",
-    status: "pending",
-    statusText: "寰呭嚭鍙�",
-    departureLocation: "闈掑矝甯傜珛鍖婚櫌鎬ヨ瘖绉�",
-    destinationHospital: "闈掑矝闀滄箹鍖婚櫌",
-  },
-  {
-    id: "T20241217002",
-    caseNo: "DON20241216002",
-    donorName: "鏉庡洓",
-    gender: "濂�",
-    age: 45,
-    diagnosis: "鑴戞姝�",
-    hospitalName: "闈掑矝澶у闄勫睘鍖婚櫌",
-    transportTime: "2024-12-17 16:00",
-    coordinator: "鏉庡尰鐢�",
-    createTime: "2024-12-16 11:20",
-    status: "transporting",
-    statusText: "杞繍涓�",
-    departureLocation: "闈掑矝澶у闄勫睘鍖婚櫌ICU",
-    destinationHospital: "闈掑矝鍣ㄥ畼绉绘涓績",
-  },
-  {
-    id: "T20241216003",
-    caseNo: "DON20241215001",
-    donorName: "鐜嬩簲",
-    gender: "鐢�",
-    age: 52,
-    diagnosis: "蹇冭剰楠ゅ仠",
-    hospitalName: "闈掑矝甯傜珛鍖婚櫌",
-    transportTime: "2024-12-16 10:15",
-    coordinator: "鐜嬪尰鐢�",
-    createTime: "2024-12-15 14:45",
-    status: "completed",
-    statusText: "宸插畬鎴�",
-    departureLocation: "闈掑矝甯傜珛鍖婚櫌蹇冨唴绉�",
-    destinationHospital: "闈掑矝鍣ㄥ畼绉绘涓績",
-  },
-  {
-    id: "T20241216004",
-    caseNo: "DON20241214001",
-    donorName: "璧靛叚",
-    gender: "濂�",
-    age: 29,
-    diagnosis: "鎬ユ�ц倽琛扮",
-    hospitalName: "闈掑矝绉戝ぇ鍖婚櫌",
-    transportTime: "2024-12-16 08:30",
-    coordinator: "璧靛尰鐢�",
-    createTime: "2024-12-14 16:20",
-    status: "cancelled",
-    statusText: "宸插彇娑�",
-    departureLocation: "闈掑矝绉戝ぇ鍖婚櫌娑堝寲绉�",
-    destinationHospital: "闈掑矝鍣ㄥ畼绉绘涓績",
-  },
-]);
+onLoad(async (options) => {
+  // 鑾峰彇瀛楀吀鏁版嵁
+  dict.value = await useDict("sys_user_sex");
+  // 鍒濆鍖栨暟鎹�
+  loadTransports();
+  // 鍔犺浇缁熻鏁版嵁
+  loadStats();
+});
+
+onShow(() => {
+  // 妫�鏌ユ槸鍚︽湁杞繍鐘舵�佹洿鏂�
+  const update = uni.getStorageSync("transportStatusUpdate");
+  if (update) {
+    handleStatusUpdate(update);
+    uni.removeStorageSync("transportStatusUpdate");
+  }
+});
+
+// 鏁版嵁鏄犲皠鍑芥暟
+const mapApiDataToTransportItem = (apiData) => {
+  return {
+    id: apiData.id,
+    reportId: apiData.reportId,
+    caseNo: apiData.caseNo,
+    patName: apiData.patName,
+    sex: apiData.sex,
+    age: apiData.age,
+    diagnosisname: apiData.diagnosisname,
+    treatmentHospitalName: apiData.treatmentHospitalName,
+    transportStartTime: apiData.transportStartTime,
+    contactPerson: apiData.contactPerson,
+    createTime: apiData.createTime,
+    transitStatus: apiData.transitStatus,
+    // 鍖绘姢浜哄憳淇℃伅
+    doctor: apiData.doctor,
+    nurse: apiData.nurse,
+    driver: apiData.driver,
+    // 鍏朵粬瀛楁
+    transportStartPlace: apiData.transportStartPlace,
+    remark: apiData.remark,
+  };
+};
 
 // 绛涢�夎褰�
 const filteredTransports = computed(() => {
   let result = transports.value;
 
   // 鐘舵�佺瓫閫�
-  if (currentType.value !== "all") {
-    result = result.filter((item) => item.status === currentType.value);
+  if (currentType.value !== "") {
+    result = result.filter((item) => item.transitStatus === currentType.value);
   }
 
   // 鏃ユ湡绛涢��
   if (startDate.value && endDate.value) {
     result = result.filter((item) => {
-      const transportDate = item.createTime.split(" ")[0];
+      const transportDate = item.createTime
+        ? item.createTime.split(" ")[0]
+        : "";
       return transportDate >= startDate.value && transportDate <= endDate.value;
     });
   }
@@ -292,9 +286,45 @@
   return result;
 });
 
-// 鍒嗛〉鐩稿叧
-const hasMore = ref(true);
-const refreshing = ref(false);
+// 鑾峰彇鐘舵�佹牱寮�
+const getStatusClass = (status) => {
+  const map = {
+    1: "pending", // 寰呰浆杩�
+    2: "transporting", // 杞繍涓�
+    3: "completed", // 宸插畬鎴�
+    4: "cancelled", // 宸插彇娑�
+    5: "cancelled", // 鏆傚瓨
+  };
+  return map[status] || "pending";
+};
+
+// 鑾峰彇鐘舵�佹枃鏈�
+const getStatusText = (status) => {
+  const map = {
+    1: "寰呭嚭鍙�",
+    2: "杞繍涓�",
+    3: "宸插畬鎴�",
+    4: "宸插彇娑�",
+    5: "鏆傚瓨",
+  };
+  return map[status] || "鏈煡";
+};
+
+// 鑾峰彇鎬у埆鏂囨湰
+const getGenderText = (gender) => {
+  if (!gender) return "鏈煡";
+  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 formatTime = (timeStr) => {
+  if (!timeStr) return "鏈缃�";
+  return timeStr.replace("T", " ").substring(0, 16);
+};
 
 // 閫夋嫨绫诲瀷
 const selectType = (type) => {
@@ -312,8 +342,20 @@
 
 // 鏌ョ湅璇︽儏
 const viewDetail = (item) => {
+  viewDetails(item);
+};
+
+// 鏌ョ湅璇︽儏
+const viewDetails = (item) => {
   uni.navigateTo({
     url: `/pages/transport/detail?id=${item.id}`,
+  });
+};
+
+// 缂栬緫杞繍鍗�
+const editTransport = (item) => {
+  uni.navigateTo({
+    url: `/pages/transport/detail?id=${item.id}&edit=true`,
   });
 };
 
@@ -334,27 +376,27 @@
 };
 
 // 纭鎿嶄綔
-const confirmAction = () => {
-  const index = transports.value.findIndex(
-    (item) => item.id === currentTransport.value.id
-  );
-  if (index !== -1) {
+const confirmAction = async () => {
+  try {
     if (modalAction.value === "寮�濮�") {
-      transports.value[index].status = "transporting";
-      transports.value[index].statusText = "杞繍涓�";
-      stats.value.pendingTransports -= 1;
+      await updateTransportStatus(2, "寮�濮嬭浆杩�");
     } else if (modalAction.value === "瀹屾垚") {
-      transports.value[index].status = "completed";
-      transports.value[index].statusText = "宸插畬鎴�";
-      stats.value.completedTransports += 1;
+      await updateTransportStatus(3, "瀹屾垚杞繍");
     }
 
     uni.showToast({
       title: `${modalAction.value}鎴愬姛`,
       icon: "success",
     });
+  } catch (error) {
+    console.error(`${modalAction.value}澶辫触:`, error);
+    uni.showToast({
+      title: `${modalAction.value}澶辫触锛岃閲嶈瘯`,
+      icon: "none",
+    });
+  } finally {
+    showActionModal.value = false;
   }
-  showActionModal.value = false;
 };
 
 // 鍙栨秷鎿嶄綔
@@ -362,24 +404,12 @@
   showActionModal.value = false;
 };
 
-// 鏌ョ湅璇︽儏
-const viewDetails = (item) => {
-  uni.navigateTo({
-    url: `/pages/case/transferinfo?id=${item.id}`,
-  });
-};
-
-// 缂栬緫杞繍鍗�
-const editTransport = (item) => {
-  uni.navigateTo({
-    url: `/pages/case/transferinfo?id=${item.id}`,
-  });
-};
-
 // 涓嬫媺鍒锋柊
 const onRefresh = () => {
   refreshing.value = true;
+  pageNum.value = 1;
   loadTransports();
+  loadStats();
   setTimeout(() => {
     refreshing.value = false;
   }, 1000);
@@ -387,21 +417,125 @@
 
 // 鍔犺浇鏇村
 const onLoadMore = () => {
-  if (!hasMore.value) return;
+  if (!hasMore.value || loading.value) return;
+  pageNum.value++;
   loadTransports();
 };
 
 // 鍔犺浇璁板綍
 const loadTransports = async () => {
+  if (loading.value) return;
 
-  // 杩欓噷璋冪敤API鍔犺浇鏁版嵁
-  setTimeout(() => {
-    hasMore.value = false;
-  }, 1000);
+  loading.value = true;
+  try {
+    const params = {
+      pageNum: pageNum.value,
+      pageSize: pageSize.value,
+    };
+
+    if (currentType.value) {
+      params.transitStatus = currentType.value;
+    }
+
+    if (startDate.value && endDate.value) {
+      params.startDate = startDate.value;
+      params.endDate = endDate.value;
+    }
+
+    const res = await uni.$uapi.post("/project/transport/list", params);
+
+    if (res) {
+      const data = res || [];
+      const mappedData = data.map((item) => mapApiDataToTransportItem(item));
+
+      if (pageNum.value === 1) {
+        transports.value = mappedData;
+      } else {
+        transports.value = [...transports.value, ...mappedData];
+      }
+
+      hasMore.value = (res.rows || []).length >= pageSize.value;
+    } else {
+      throw new Error(res.msg || "鍔犺浇澶辫触");
+    }
+  } catch (error) {
+    console.error("鍔犺浇杞繍鍗曞垪琛ㄥけ璐�:", error);
+    uni.showToast({
+      title: "缃戠粶璇锋眰澶辫触",
+      icon: "none",
+    });
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 鍔犺浇缁熻鏁版嵁
+const loadStats = async () => {
+  try {
+    const res = await uni.$uapi.post("/api/totalServiceTransportState");
+    if (res) {
+      stats.value = {
+        totalTransports: res.reduce((sum, item) => sum + item.count, 0) || 0,
+        pendingTransports: res[0].count || 0,
+        completedTransports: res[3].count || 0,
+      };
+    }
+  } catch (error) {
+    console.error("鍔犺浇缁熻澶辫触:", error);
+  }
+};
+
+// 鏇存柊杞繍鐘舵��
+const updateTransportStatus = async (newStatus, actionName) => {
+  try {
+    const updateData = {
+      id: currentTransport.value.id,
+      transitStatus: newStatus,
+    };
+
+    const res = await uni.$uapi.post("/project/transport/edit", updateData);
+
+    if (res.code === 200) {
+      // 鏇存柊鏈湴鏁版嵁
+      const index = transports.value.findIndex(
+        (item) => item.id === currentTransport.value.id,
+      );
+      if (index !== -1) {
+        transports.value[index].transitStatus = newStatus;
+      }
+
+      // 鏇存柊缁熻鏁版嵁
+      await loadStats();
+
+      // 瀛樺偍鐘舵�佹洿鏂�
+      uni.setStorageSync("transportStatusUpdate", {
+        orderId: currentTransport.value.id,
+        status: newStatus,
+      });
+
+      return true;
+    } else {
+      throw new Error(res.msg || `${actionName}澶辫触`);
+    }
+  } catch (error) {
+    console.error(`${actionName}澶辫触:`, error);
+    throw error;
+  }
+};
+
+// 澶勭悊鐘舵�佹洿鏂�
+const handleStatusUpdate = (update) => {
+  const index = transports.value.findIndex(
+    (item) => item.id === update.orderId,
+  );
+  if (index !== -1) {
+    transports.value[index].transitStatus = update.status;
+  }
 };
 </script>
 
 <style lang="scss" scoped>
+/* 淇濇寔鍘熸湁鏍峰紡瀹屽叏涓嶅彉 */
 .transport-record {
   min-height: 100vh;
   background: linear-gradient(135deg, #fafdff 0%, #e3f0ff 100%);

--
Gitblit v1.9.3