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/CaseDetails.vue |  969 ++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 794 insertions(+), 175 deletions(-)

diff --git a/pages/case/CaseDetails.vue b/pages/case/CaseDetails.vue
index cac11a6..acb1963 100644
--- a/pages/case/CaseDetails.vue
+++ b/pages/case/CaseDetails.vue
@@ -3,6 +3,11 @@
     <!-- 琛ㄥ崟鍐呭 -->
     <scroll-view scroll-y class="form-scroll" :show-scrollbar="false">
       <view class="form-content">
+        <view class="page-header">
+          <text class="page-title">{{
+            isEditMode ? "淇敼妗堜緥" : "涓婃姤妗堜緥"
+          }}</text>
+        </view>
         <!-- 鍩烘湰淇℃伅鍗$墖 -->
         <view class="form-section">
           <view class="section-header">
@@ -11,54 +16,47 @@
           </view>
 
           <view class="form-grid">
+            <!-- 淇敼鍚庯細娌荤枟鍖婚櫌杈撳叆妗� -->
             <view class="form-item">
-              <text class="item-label">鎹愮尞缂栧彿</text>
+              <text class="item-label required">娌荤枟鍖婚櫌</text>
               <u-input
-                v-model="form.donorno"
-                placeholder="绯荤粺鑷姩鐢熸垚"
-                disabled
-                :disabledColor="disabledColor"
-                border="none"
+                v-model="form.treatmenthospitalname"
+                placeholder="璇疯緭鍏ユ不鐤楀尰闄㈠悕绉�"
+                maxlength="100"
+                class="custom-input"
+              />
+            </view>
+
+            <!-- 鏂板锛氫笂鎶ュ尰闄� -->
+            <view class="form-item">
+              <text class="item-label">涓婃姤鍖婚櫌</text>
+              <u-input
+                v-model="form.toHospital"
+                placeholder="璇疯緭鍏ヤ笂鎶ュ尰闄�"
+                maxlength="100"
+                class="custom-input"
+              />
+            </view>
+
+            <!-- 鏂板锛氶儴闂ㄥ悕绉� -->
+            <view class="form-item">
+              <text class="item-label">閮ㄩ棬鍚嶇О</text>
+              <u-input
+                v-model="form.deptName"
+                placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�"
+                maxlength="50"
+                class="custom-input"
               />
             </view>
 
             <view class="form-item">
-              <text class="item-label">鍖荤枟鏈烘瀯</text>
+              <text class="item-label required">鎮h�呭鍚�</text>
               <u-input
-                v-model="form.treatmenthospitalno"
-                placeholder="璇烽�夋嫨鍖荤枟鏈烘瀯"
-                readonly
-                border="none"
-                @click="showHospitalPicker = true"
-              >
-                <template #suffix>
-                  <u-icon name="arrow-down" color="#86868b"></u-icon>
-                </template>
-              </u-input>
-            </view>
-
-            <view class="form-item">
-              <text class="item-label">绉戝</text>
-              <u-input
-                v-model="form.treatmentdeptname"
-                placeholder="璇烽�夋嫨绉戝"
-                readonly
-                border="none"
-                @click="selectShow = true"
-              >
-                <template #suffix>
-                  <u-icon name="arrow-down" color="#86868b"></u-icon>
-                </template>
-              </u-input>
-            </view>
-
-            <view class="form-item">
-              <text class="item-label required">濮撳悕</text>
-              <u-input
+                type="text"
                 v-model="form.name"
                 placeholder="璇疯緭鍏ュ鍚�"
-                border="none"
-                :customStyle="inputStyle(!form.name)"
+                maxlength="20"
+                class="custom-input"
               />
             </view>
           </view>
@@ -72,93 +70,99 @@
           </view>
 
           <view class="form-grid">
+            <!-- 鏀归�犲悗鐨勬皯鏃忛�夋嫨 -->
             <view class="form-item">
               <text class="item-label">姘戞棌</text>
-              <u-input
-                v-model="form.nation"
-                placeholder="璇烽�夋嫨姘戞棌"
-                readonly
-                border="none"
-                @click="showNationPicker = true"
+              <picker
+                mode="selector"
+                :range="nationLabels"
+                :value="nationIndex"
+                @change="onNationChange"
               >
-                <template #suffix>
-                  <u-icon name="arrow-down" color="#86868b"></u-icon>
-                </template>
-              </u-input>
+                <view class="picker">
+                  <text>{{ currentNation }}</text>
+                  <text class="icon-arrow">鈥�</text>
+                </view>
+              </picker>
             </view>
 
             <view class="form-item">
               <text class="item-label">鍥界睄</text>
               <u-input
+                type="text"
                 v-model="form.nationality"
                 placeholder="璇疯緭鍏ュ浗绫�"
-                border="none"
+                class="custom-input"
               />
             </view>
 
+            <!-- 鏀归�犲悗鐨勮瘉浠剁被鍨嬮�夋嫨 -->
             <view class="form-item">
               <text class="item-label">璇佷欢绫诲瀷</text>
-              <u-input
-                v-model="form.idcardtype"
-                placeholder="璇烽�夋嫨璇佷欢绫诲瀷"
-                readonly
-                border="none"
-                @click="showIdCardTypePicker = true"
+              <picker
+                mode="selector"
+                :range="idCardTypeLabels"
+                :value="idCardTypeIndex"
+                @change="onIdCardTypeChange"
               >
-                <template #suffix>
-                  <u-icon name="arrow-down" color="#86868b"></u-icon>
-                </template>
-              </u-input>
+                <view class="picker">
+                  <text>{{ currentIdCardType }}</text>
+                  <text class="icon-arrow">鈥�</text>
+                </view>
+              </picker>
             </view>
 
             <view class="form-item">
               <text class="item-label required">璇佷欢鍙风爜</text>
               <u-input
+                type="idcard"
                 v-model="form.idcardno"
                 placeholder="璇疯緭鍏ヨ瘉浠跺彿鐮�"
-                border="none"
-                :customStyle="inputStyle(!form.idcardno)"
+                maxlength="18"
+                class="custom-input"
                 @blur="validateIdCard"
               />
+              <text class="error-text" v-if="idCardError">{{
+                idCardError
+              }}</text>
             </view>
 
+            <!-- 鏀归�犲悗鐨勬�у埆閫夋嫨 -->
             <view class="form-item">
               <text class="item-label">鎬у埆</text>
-              <view class="radio-group">
+              <view class="radio-options">
                 <view
                   v-for="gender in genderOptions"
                   :key="gender.value"
-                  class="radio-item"
+                  class="option-item"
+                  :class="{ active: form.sex === gender.value }"
                   @click="form.sex = gender.value"
                 >
-                  <view
-                    class="radio-dot"
-                    :class="{ active: form.sex === gender.value }"
-                  ></view>
-                  <text class="radio-label">{{ gender.label }}</text>
+                  <text class="radio-dot"></text>
+                  <text class="option-label">{{ gender.label }}</text>
                 </view>
               </view>
             </view>
 
+            <!-- 鏀归�犲悗鐨勫嚭鐢熸棩鏈熼�夋嫨 -->
             <view class="form-item">
               <text class="item-label">鍑虹敓鏃ユ湡</text>
-              <u-input
-                v-model="form.birthday"
-                placeholder="閫夋嫨鍑虹敓鏃ユ湡"
-                readonly
-                border="none"
-                @click="showDatePicker = true"
+              <picker
+                mode="date"
+                :value="form.birthday"
+                @change="onBirthdayChange"
               >
-                <template #suffix>
-                  <u-icon name="arrow-down" color="#86868b"></u-icon>
-                </template>
-              </u-input>
+                <view class="picker">
+                  <text>{{ form.birthday || "閫夋嫨鍑虹敓鏃ユ湡" }}</text>
+                  <text class="icon-arrow">鈥�</text>
+                </view>
+              </picker>
             </view>
 
             <view class="form-item">
               <text class="item-label">骞撮緞</text>
               <u-input
-                v-model="form.age"
+                v-model="ageDisplay"
                 placeholder="鑷姩璁$畻"
                 disabled
                 :disabledColor="disabledColor"
@@ -184,6 +188,14 @@
                 border="none"
               />
             </view>
+            <view class="form-item">
+              <text class="item-label">GCS璇勫垎</text>
+              <u-input
+                v-model="form.gcsScore"
+                placeholder="璇疯緭鍏CS璇勫垎"
+                border="none"
+              />
+            </view>
 
             <view class="form-item full-width">
               <text class="item-label required">鐤剧梾璇婃柇</text>
@@ -195,7 +207,23 @@
                 :customStyle="textareaStyle(!form.diagnosisname)"
               />
             </view>
-
+            <view class="form-item">
+              <text class="item-label">鏄惁闇�瑕佽浆杩�</text>
+              <view class="radio-group horizontal">
+                <view
+                  v-for="bloodType in isTransportOptions"
+                  :key="bloodType.value"
+                  class="radio-item"
+                  @click="form.isTransport = bloodType.value"
+                >
+                  <view
+                    class="radio-dot"
+                    :class="{ active: form.isTransport === bloodType.value }"
+                  ></view>
+                  <text class="radio-label">{{ bloodType.label }}</text>
+                </view>
+              </view>
+            </view>
             <view class="form-item">
               <text class="item-label">琛�鍨�</text>
               <view class="radio-group horizontal">
@@ -203,15 +231,40 @@
                   v-for="bloodType in bloodTypeOptions"
                   :key="bloodType.value"
                   class="radio-item"
-                  @click="form.bloodtype = bloodType.value"
+                  @click="form.bloodType = bloodType.value"
                 >
                   <view
                     class="radio-dot"
-                    :class="{ active: form.bloodtype === bloodType.value }"
+                    :class="{ active: form.bloodType === bloodType.value }"
                   ></view>
                   <text class="radio-label">{{ bloodType.label }}</text>
                 </view>
               </view>
+            </view>
+            <view class="form-item">
+              <text class="item-label">浼犳煋鐥�</text>
+              <view class="radio-group horizontal">
+                <view
+                  v-for="bloodType in infectiousDiseaselist"
+                  :key="bloodType.value"
+                  class="radio-item"
+                  @click="form.infectious = bloodType.value"
+                >
+                  <view
+                    class="radio-dot"
+                    :class="{ active: form.infectious == bloodType.value }"
+                  ></view>
+                  <text class="radio-label">{{ bloodType.label }}</text>
+                </view>
+              </view>
+            </view>
+            <view class="form-item">
+              <text class="item-label">鍏朵粬</text>
+              <u-input
+                v-model="form.infectiousOther"
+                placeholder="璇疯緭鍏ヤ綇闄㈠彿"
+                border="none"
+              />
             </view>
 
             <view class="form-item">
@@ -221,11 +274,11 @@
                   v-for="rh in rhOptions"
                   :key="rh.value"
                   class="radio-item"
-                  @click="form.rhyin = rh.value"
+                  @click="form.rhYin = rh.value"
                 >
                   <view
                     class="radio-dot"
-                    :class="{ active: form.rhyin === rh.value }"
+                    :class="{ active: form.rhYin === rh.value }"
                   ></view>
                   <text class="radio-label">{{ rh.label }}</text>
                 </view>
@@ -261,7 +314,7 @@
               />
             </view>
 
-            <view class="form-item">
+            <!-- <view class="form-item">
               <text class="item-label">鎶ュ憡浜�</text>
               <u-input
                 v-model="form.reporterno"
@@ -274,7 +327,7 @@
                   <u-icon name="arrow-down" color="#86868b"></u-icon>
                 </template>
               </u-input>
-            </view>
+            </view> -->
 
             <view class="form-item">
               <text class="item-label">鎶ュ憡鏃堕棿</text>
@@ -290,13 +343,15 @@
 
         <!-- 鎿嶄綔鎸夐挳 -->
         <view class="action-buttons">
+          <u-button class="btn secondary" @click="handleCancel">鍙栨秷</u-button>
           <u-button class="btn secondary" @click="resetForm">閲嶇疆琛ㄥ崟</u-button>
           <u-button
             class="btn primary"
-            :disabled="!isFormValid"
-            @click="submitForm"
-            >鎻愪氦涓婃姤</u-button
+            :disabled="!isFormValid || loading"
+            @click="handleSubmit"
           >
+            {{ loading ? "鎻愪氦涓�..." : isEditMode ? "淇濆瓨淇敼" : "鎻愪氦涓婃姤" }}
+          </u-button>
         </view>
         <attachment-upload
           ref="attachment"
@@ -342,14 +397,14 @@
     ></u-picker>
 
     <!-- 璇佷欢绫诲瀷閫夋嫨鍣� -->
-    <u-picker
+    <!-- <u-picker
       :show="showIdCardTypePicker"
       :columns="[idCardTypeOptions]"
       keyName="label"
       @confirm="onIdCardTypeConfirm"
       @cancel="showIdCardTypePicker = false"
       title="璇烽�夋嫨璇佷欢绫诲瀷"
-    ></u-picker>
+    ></u-picker> -->
 
     <!-- 鏃ユ湡閫夋嫨鍣� -->
     <u-datetime-picker
@@ -381,11 +436,16 @@
 import { onLoad } from "@dcloudio/uni-app";
 import attachmentUpload from "@/components/attachment";
 import { useUserStore } from "@/stores/user";
+import { useDict } from "@/utils/dict";
 
+const dict = ref({});
+const userStore = useUserStore();
+const isEditMode = ref(false);
+const currentId = ref(null);
 // 琛ㄥ崟鏁版嵁
 const form = ref({
-  donorno: "",
-  treatmenthospitalno: "",
+  caseNo: "",
+  treatmenthospitalname: "",
   treatmentdeptname: "",
   name: "",
   nation: "",
@@ -395,19 +455,54 @@
   sex: "",
   birthday: "",
   age: "",
+  ageunit: "", // 鏂板锛氬勾榫勫崟浣�
   inpatientno: "",
   diagnosisname: "",
-  bloodtype: "",
-  rhyin: "",
+  bloodType: "",
+  rhYin: "",
   infoname: "",
   infophone: "",
-  reporterno: "",
+  reportername: userStore.name || "",
+  reporterno: userStore.userId || "",
+  reporterphone: "", // 鎶ュ憡鑰呰仈绯荤數璇�
   reporttime: "",
+  contactperson: "", // 鏂板锛氳仈绯讳汉锛堝崗璋冨憳锛�
+  education: "", // 鏂板锛氬鍘�
+  illnessoverview: "", // 鏂板锛氱梾鎯呮鍐�
+  infectious: "", // 浼犳煋鐥呮儏鍐�
+  infectiousOther: "", // 浼犳煋鐥呭叾浠�
+  isTransport: "1", // 鏂板锛氭槸鍚﹂渶瑕佽浆杩愶紝榛樿1涓嶉渶瑕�
+  nativeplace: "", // 鏂板锛氱睄璐�
+  occupation: "", // 鏂板锛氳亴涓�
+  patientstate: "", // 鏂板锛氱梾浜虹姸鍐�
+  phone: "", // 鏂板锛氳仈绯荤數璇�
+  registeraddress: "", // 鏂板锛氭埛绫嶅湴鍧�
+  registerprovince: "", // 鏂板锛氭埛绫嶅湴鍧�鐪佺紪鍙�
+  registerprovincename: "", // 鏂板锛氭埛绫嶅湴鍧�鐪佸悕绉�
+  registercityname: "", // 鏂板锛氬競鍚嶇О
+  registertownname: "", // 鏂板锛氭墍灞炶閬擄紙闀囷級鍚嶇О
+  registercommunityname: "", // 鏂板锛氱ぞ鍖猴紙鏉戯級鍚嶇О
+  residenceaddress: "", // 鏂板锛氱幇浣忓湴鍧�
+  residenceprovince: "", // 鏂板锛氱幇浣忓湴鍧�鐪佷唬鐮�
+  residenceprovincename: "", // 鏂板锛氱幇浣忓湴鍧�鐪佸悕绉�
+  residencecountycode: "", // 鏂板锛氭墍灞炲尯鍩熺紪鍙�
+  residencecountyname: "", // 鏂板锛氭墍灞炲尯鍩熷悕绉�
+  residencetownname: "", // 鏂板锛氭墍灞炶閬擄紙闀囷級鍚嶇О
+  residencecommunity: "", // 鏂板锛氱ぞ鍖猴紙鏉戯級缂栧彿
+  residencecommunityname: "", // 鏂板锛氱ぞ鍖猴紙鏉戯級鍚嶇О
+  remark: "", // 鏂板锛氬娉�
+  reportStatus: "1", // 鏂板锛氫笂鎶ョ姸鎬侊紝榛樿1宸蹭笂鎶�
+  terminationCase: 0, // 鏂板锛氭槸鍚︾粓姝㈡渚嬶紝榛樿0寮�鍚�
+  annexfilesList: [], // 闄勪欢鏂囦欢鍦板潃闆嗗悎
 });
 
 // 閫夋嫨鍣ㄧ姸鎬�
 const attachments = ref([]);
+const infectiousDiseaselist = ref([]);
+const nationLabel = ref([]);
+
 const isReadonly = ref(false);
+const id = ref(null);
 const selectShow = ref(false);
 const showHospitalPicker = ref(false);
 const showNationPicker = ref(false);
@@ -461,7 +556,10 @@
   { label: "O鍨�", value: "O" },
   { label: "AB鍨�", value: "AB" },
 ]);
-
+const isTransportOptions = ref([
+  { label: "闇�瑕�", value: "2" },
+  { label: "涓嶉渶瑕�", value: "1" },
+]);
 const rhOptions = ref([
   { label: "闃虫��", value: "positive" },
   { label: "闃存��", value: "negative" },
@@ -479,9 +577,108 @@
 
 // 璁$畻灞炴��
 const isFormValid = computed(() => {
-  return form.value.name && form.value.idcardno && form.value.diagnosisname;
+  return (
+    form.value.name &&
+    form.value.idcardno &&
+    form.value.diagnosisname &&
+    form.value.toHospital
+  );
+});
+// 閫夋嫨鍣ㄧ储寮�
+const hospitalIndex = ref(-1);
+const deptIndex = ref(-1);
+const nationIndex = ref(-1);
+const idCardTypeIndex = ref(-1);
+
+// 璁$畻灞炴�� - 鏍囩鏁扮粍
+const hospitalLabels = computed(() =>
+  hospitalOptions.value.map((item) => item.label),
+);
+const ageDisplay = computed(() => {
+  if (!form.value.age || !form.value.ageunit) {
+    return "鑷姩璁$畻";
+  }
+  return `${form.value.age}${form.value.ageunit}`;
+});
+const deptLabels = computed(() => {
+  return pickerColumns.value[0].map((item) => item.label);
+});
+const nationLabels = computed(() =>
+  nationLabel.value.map((item) => item.label),
+);
+const idCardTypeLabels = computed(() =>
+  idCardTypeOptions.value.map((item) => item.label),
+);
+
+// 璁$畻灞炴�� - 褰撳墠閫変腑鏄剧ず鏂囨湰
+const currentHospital = computed(() => {
+  return hospitalIndex.value >= 0
+    ? hospitalLabels.value[hospitalIndex.value]
+    : "璇烽�夋嫨鍖荤枟鏈烘瀯";
 });
 
+const currentDept = computed(() => {
+  return deptIndex.value >= 0
+    ? deptLabels.value[deptIndex.value]
+    : "璇烽�夋嫨绉戝";
+});
+
+const currentNation = computed(() => {
+  return nationIndex.value >= 0
+    ? nationLabels.value[nationIndex.value]
+    : "璇烽�夋嫨姘戞棌";
+});
+
+const currentIdCardType = computed(() => {
+  return idCardTypeIndex.value >= 0
+    ? idCardTypeLabels.value[idCardTypeIndex.value]
+    : "璇烽�夋嫨璇佷欢绫诲瀷";
+});
+
+const onNationChange = (e) => {
+  const index = parseInt(e.detail.value);
+  nationIndex.value = nationOptions.value[index].label;
+  form.value.nation = nationOptions.value[index].label;
+};
+
+const onIdCardTypeChange = (e) => {
+  const index = parseInt(e.detail.value);
+  idCardTypeIndex.value = index;
+  form.value.idcardtype = idCardTypeOptions.value[index].value;
+};
+
+const onBirthdayChange = (e) => {
+  form.value.birthday = e.detail.value;
+  calculateAge();
+};
+const onDateConfirm = (e) => {
+  const date = new Date(e.value);
+
+  // 鏍煎紡鍖栨棩鏈熶负 YYYY-MM-DD
+  form.value.birthday = `${date.getFullYear()}-${(date.getMonth() + 1)
+    .toString()
+    .padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
+
+  calculateAge();
+  showDatePicker.value = false;
+};
+
+// 韬唤璇侀獙璇�
+const idCardError = ref("");
+const validateIdCard = () => {
+  if (!form.value.idcardno) {
+    idCardError.value = "璇疯緭鍏ヨ瘉浠跺彿鐮�";
+    return false;
+  }
+
+  if (form.value.idcardno.length !== 18) {
+    idCardError.value = "璇疯緭鍏�18浣嶈韩浠借瘉鍙风爜";
+    return false;
+  }
+
+  idCardError.value = "";
+  return true;
+};
 // 鏍峰紡鏂规硶
 const inputStyle = (isError) => {
   return isError
@@ -497,62 +694,131 @@
 
 // 鐢熷懡鍛ㄦ湡
 onMounted(() => {
-  updateCurrentTime();
-  generateDonorNo();
+  // updateCurrentTime();
+  // generateDonorNo();
   setInterval(updateCurrentTime, 1000);
 });
 
-onLoad((options) => {
-  if (options.edit && options.id) {
-    loadCaseData(options.id);
+onLoad(async (options) => {
+  id.value = options.id;
+  if (options.id) {
+    currentId.value = options.id;
+    isEditMode.value = true;
+    await loadCaseData(options.id);
+  } else {
+    isEditMode.value = false;
+    generateDonorNo();
   }
+  // 鑾峰彇瀛楀吀鏁版嵁
+  dict.value = await useDict(
+    "sys_IDType",
+    "sys_user_sex",
+    "sys_Nation",
+    "sys_BloodType",
+    "sys_Infectious",
+    "sys_AgeUnit", // 鏂板骞撮緞鍗曚綅
+    "sys_education", // 鏂板瀛﹀巻
+    "sys_occupation", // 鏂板鑱屼笟
+  );
+  initOptions();
+  updateCurrentTime();
 });
-
+// 鍒濆鍖栭�夐」鏁版嵁鐨勬柟娉�
+const initOptions = () => {
+  infectiousDiseaselist.value = dict.value.sys_Infectious || [];
+  idCardTypeOptions.value = dict.value.sys_IDType || [];
+  nationLabel.value = dict.value.sys_Nation || [];
+};
 // 鏂规硶瀹氫箟
 const updateCurrentTime = () => {
   const now = new Date();
-  currentTime.value = now.toLocaleString("zh-CN", {
+  // 鍏堣幏鍙栨牸寮忓寲鐨勫瓧绗︿覆锛岀劧鍚庢浛鎹㈠垎闅旂鍜岃皟鏁撮『搴�
+  const localString = now.toLocaleString("zh-CN", {
     year: "numeric",
     month: "2-digit",
     day: "2-digit",
     hour: "2-digit",
     minute: "2-digit",
+    second: "2-digit",
+    hour12: false,
   });
+  // 灏� "yyyy/mm/dd hh:mm:ss" 杞崲涓� "yyyy-mm-dd hh:mm:ss"
+  currentTime.value = localString.replace(/\//g, "-");
   form.value.reporttime = currentTime.value;
 };
 
 const generateDonorNo = () => {
   const date = new Date();
   const timestamp = date.getTime().toString().slice(-6);
-  form.value.donorno = `DON${date.getFullYear()}${(date.getMonth() + 1)
-    .toString()
-    .padStart(2, "0")}${timestamp}`;
+  // form.value.caseNo = `DON${date.getFullYear()}${(date.getMonth() + 1)
+  //   .toString()
+  //   .padStart(2, "0")}${timestamp}`;
 };
 
 const calculateAge = () => {
-  if (!form.value.birthday) return;
+  if (!form.value.birthday) {
+    form.value.age = "";
+    form.value.ageunit = "";
+    return;
+  }
+
   const birthDate = new Date(form.value.birthday);
   const today = new Date();
-  let age = today.getFullYear() - birthDate.getFullYear();
-  const monthDiff = today.getMonth() - birthDate.getMonth();
 
-  if (
-    monthDiff < 0 ||
-    (monthDiff === 0 && today.getDate() < birthDate.getDate())
-  ) {
-    age--;
+  // 妫�鏌ユ棩鏈熸湁鏁堟��
+  if (isNaN(birthDate.getTime())) {
+    form.value.age = "";
+    form.value.ageunit = "";
+    return;
   }
-  form.value.age = age.toString();
+
+  // 璁$畻鎬诲ぉ鏁板樊
+  const timeDiff = today.getTime() - birthDate.getTime();
+  const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
+
+  if (daysDiff < 0) {
+    // 鏈潵鏃ユ湡澶勭悊
+    form.value.age = "";
+    form.value.ageunit = "";
+    return;
+  }
+
+  // 璁$畻骞淬�佹湀銆佹棩
+  const years = today.getFullYear() - birthDate.getFullYear();
+  const months = today.getMonth() - birthDate.getMonth();
+  const days = today.getDate() - birthDate.getDate();
+
+  let ageValue, ageUnit;
+
+  if (years >= 1) {
+    // 澶т簬绛変簬1骞达細鏄剧ず骞�
+    let actualYears = years;
+
+    // 澶勭悊鏈堜唤鍜屾棩鏈熺殑杈圭晫鎯呭喌
+    if (months < 0 || (months === 0 && days < 0)) {
+      actualYears = years - 1;
+    }
+
+    ageValue = actualYears.toString();
+    ageUnit = "宀�";
+  } else if (daysDiff >= 30) {
+    // 澶т簬绛変簬30澶╋細鏄剧ず鏈�
+    let totalMonths = years * 12 + months;
+    if (days < 0) {
+      totalMonths--;
+    }
+    ageValue = Math.max(1, totalMonths).toString(); // 纭繚鑷冲皯1涓湀
+    ageUnit = "涓湀";
+  } else {
+    // 灏忎簬30澶╋細鏄剧ず澶�
+    ageValue = Math.max(1, daysDiff).toString(); // 纭繚鑷冲皯1澶�
+    ageUnit = "澶�";
+  }
+
+  form.value.age = ageValue;
+  form.value.ageunit = ageUnit;
 };
 
-const validateIdCard = () => {
-  if (form.value.idcardno && form.value.idcardno.length !== 18) {
-    uni.showToast({
-      title: "璇疯緭鍏�18浣嶈韩浠借瘉鍙风爜",
-      icon: "none",
-    });
-  }
-};
 // 澶勭悊鍩虹闄勪欢涓婁紶
 const handleBaseUpload = (file) => {
   console.log("鍩虹闄勪欢涓婁紶鎴愬姛:", file);
@@ -560,7 +826,7 @@
 
 // 澶勭悊鍏朵粬闄勪欢涓婁紶
 const handleFilesUpdate = (files) => {
-  formData.attachments = files.map((file) => ({
+  attachments.value = files.map((file) => ({
     ...file,
     // 纭繚鍙瓨鍌ㄥ崐璺緞
     url: file.url.startsWith("http")
@@ -577,12 +843,12 @@
 
   if (file.type.includes("image")) {
     uni.previewImage({
-      urls: formData.attachments
+      urls: attachments.value
         .filter((f) => f.type.includes("image"))
         .map((f) =>
           f.url.startsWith("http")
             ? f.url
-            : baseUrlHt + (f.url.startsWith("/") ? "" : "/") + f.url
+            : baseUrlHt + (f.url.startsWith("/") ? "" : "/") + f.url,
         ),
       current: fullUrl,
     });
@@ -615,7 +881,7 @@
 
 const onHospitalConfirm = (e) => {
   if (e.value && e.value[0]) {
-    form.value.treatmenthospitalno = e.value[0].label;
+    form.value.treatmenthospitalname = e.value[0].label;
   }
   showHospitalPicker.value = false;
 };
@@ -629,19 +895,19 @@
 
 const onIdCardTypeConfirm = (e) => {
   if (e.value && e.value[0]) {
-    form.value.idcardtype = e.value[0].label;
+    form.value.idcardtype = e.value[0].value;
   }
   showIdCardTypePicker.value = false;
 };
 
-const onDateConfirm = (e) => {
-  const date = new Date(e.value);
-  form.value.birthday = `${date.getFullYear()}-${(date.getMonth() + 1)
-    .toString()
-    .padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
-  calculateAge();
-  showDatePicker.value = false;
-};
+// const onDateConfirm = (e) => {
+//   const date = new Date(e.value);
+//   form.value.birthday = `${date.getFullYear()}-${(date.getMonth() + 1)
+//     .toString()
+//     .padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
+//   calculateAge();
+//   showDatePicker.value = false;
+// };
 
 const onReporterConfirm = (e) => {
   if (e.value && e.value[0]) {
@@ -661,19 +927,33 @@
     success: (res) => {
       if (res.confirm) {
         Object.keys(form.value).forEach((key) => {
-          if (key !== "donorno") {
+          if (!["id", "caseNo"].includes(key)) {
             form.value[key] = "";
           }
         });
+
+        // 閲嶇疆閫夋嫨鍣ㄧ储寮�
+        hospitalIndex.value = -1;
+        deptIndex.value = -1;
+        nationIndex.value = -1;
+        idCardTypeIndex.value = -1;
+        attachments.value = [];
         form.value.nationality = "涓浗";
-        generateDonorNo();
+        form.value.isTransport = "1";
+        form.value.terminationCase = 0;
+        form.value.reportStatus = "1";
+
+        if (!isEditMode.value) {
+          generateDonorNo();
+        }
+
         uni.showToast({ title: "琛ㄥ崟宸查噸缃�", icon: "success" });
       }
     },
   });
 };
 
-const submitForm = async () => {
+const handleSubmit = async () => {
   if (!isFormValid.value) {
     uni.showToast({
       title: "璇峰~鍐欏鍚嶃�佽瘉浠跺彿鐮佸拰鐤剧梾璇婃柇",
@@ -682,52 +962,162 @@
     return;
   }
 
-  loading.value = true;
-
   try {
-    await new Promise((resolve) => setTimeout(resolve, 1500));
+    console.log(attachments.value);
 
-    uni.showToast({
-      title: "涓婃姤鎴愬姛",
-      icon: "success",
-    });
+    uni.showLoading({ title: isEditMode.value ? "淇敼涓�..." : "鎻愪氦涓�..." });
+    // 鍑嗗鎻愪氦鏁版嵁
+    const submitData = {
+      ...form.value,
+      age: parseInt(form.value.age) || 0,
+      annexfilesList: attachments.value.map((file) => ({
+        url: file.url,
+        name: file.name,
+        type: file.type,
+      })),
+      phone: form.value.infophone,
+      isTransport: form.value.isTransport || "1",
+      terminationCase: form.value.terminationCase || 0,
+      reportStatus: form.value.reportStatus || "1",
+    };
 
-    setTimeout(() => {
-      uni.navigateBack();
-    }, 1500);
+    let res;
+    if (isEditMode.value) {
+      // 淇敼鎺ュ彛
+      res = await uni.$uapi.post(
+        "/project/donatebaseinforeport/edit",
+        submitData,
+      );
+    } else {
+      // 鏂板鎺ュ彛
+      res = await uni.$uapi.post(
+        "/project/donatebaseinforeport/add",
+        submitData,
+      );
+    }
+
+    uni.hideLoading();
+
+    if (res.code === 200) {
+      uni.showToast({
+        title: isEditMode.value ? "淇敼鎴愬姛" : "涓婃姤鎴愬姛",
+        icon: "success",
+      });
+
+      // 娓呯┖鏈湴瀛樺偍鐨勮崏绋�
+      removeDraft();
+
+      setTimeout(() => {
+        uni.navigateBack();
+      }, 1500);
+    } else {
+      throw new Error(res.msg || "鎿嶄綔澶辫触");
+    }
   } catch (error) {
+    console.error("鎿嶄綔澶辫触:", error);
     uni.showToast({
-      title: "涓婃姤澶辫触锛岃閲嶈瘯",
+      title: error.message || (isEditMode.value ? "淇敼澶辫触" : "涓婃姤澶辫触"),
       icon: "none",
     });
   } finally {
     loading.value = false;
   }
 };
+const removeDraft = () => {
+  localStorage.removeItem("caseReportDraft");
+};
+// 鍙栨秷澶勭悊
+const handleCancel = () => {
+  uni.navigateBack();
+};
 
-const loadCaseData = (id) => {
+const loadCaseData = async (id) => {
   // 妯℃嫙鍔犺浇缂栬緫鏁版嵁
-  form.value = {
-    donorno: "DON20241216001",
-    treatmenthospitalno: "闈掑矝闀滄箹鍖婚櫌",
-    treatmentdeptname: "绁炵粡澶栫",
-    name: "寮犱笁",
-    nation: "姹夋棌",
-    nationality: "涓浗",
-    idcardtype: "灞呮皯韬唤璇�",
-    idcardno: "370203198510123456",
-    sex: "1",
-    birthday: "1985-10-12",
-    age: "38",
-    inpatientno: "ZY20241216001",
-    diagnosisname: "鑴戝浼ゅ鑷磋剳姝讳骸",
-    bloodtype: "A",
-    rhyin: "positive",
-    infoname: "鏉庡尰鐢�",
-    infophone: "13800138000",
-    reporterno: "寮犲尰鐢�",
-    reporttime: currentTime.value,
-  };
+  // form.value = {
+  //   caseNo: "DON20241216001",
+  //   treatmenthospitalname: "闈掑矝闀滄箹鍖婚櫌",
+  //   treatmentdeptname: "绁炵粡澶栫",
+  //   name: "寮犱笁",
+  //   nation: "姹夋棌",
+  //   nationality: "涓浗",
+  //   idcardtype: "灞呮皯韬唤璇�",
+  //   idcardno: "370203198510123456",
+  //   sex: "1",
+  //   birthday: "1985-10-12",
+  //   age: "38",
+  //   inpatientno: "ZY20241216001",
+  //   diagnosisname: "鑴戝浼ゅ鑷磋剳姝讳骸",
+  //   bloodType: "A",
+  //   rhYin: "positive",
+  //   infoname: "鏉庡尰鐢�",
+  //   infophone: "13800138000",
+  //   reporterno: "寮犲尰鐢�",
+  //   reporttime: currentTime.value,
+  // };
+  try {
+    loading.value = true;
+    const res = await uni.$uapi.get(
+      `/project/donatebaseinforeport/getInfo/${id}`,
+    );
+
+    if (res) {
+      console.log(res, "res");
+
+      form.value = res;
+      console.log(1, "res");
+
+      // 澶勭悊閫夋嫨鍣ㄧ储寮�
+      // updatePickerIndexes();
+
+      console.log(2, "res");
+      // 澶勭悊闄勪欢
+      if (res.annexfilesList) {
+        attachments.value = res.annexfilesList;
+      }
+      console.log(3, "res");
+
+      uni.showToast({
+        title: "鏁版嵁鍔犺浇鎴愬姛",
+        icon: "success",
+      });
+    } else {
+      throw new Error(res.msg || "鏁版嵁鍔犺浇澶辫触");
+    }
+  } catch (error) {
+    console.error("鍔犺浇妗堜緥鏁版嵁澶辫触:", error);
+    uni.showToast({
+      title: "鏁版嵁鍔犺浇澶辫触锛岃閲嶈瘯",
+      icon: "none",
+    });
+  } finally {
+    loading.value = false;
+  }
+};
+// 鏇存柊閫夋嫨鍣ㄧ储寮�
+const updatePickerIndexes = () => {
+  // 鍖荤枟鏈烘瀯绱㈠紩
+  const hospitalIndex = hospitalOptions.value.findIndex(
+    (item) => item.label === form.value.treatmenthospitalname,
+  );
+  if (hospitalIndex !== -1) hospitalIndex.value = hospitalIndex;
+
+  // 绉戝绱㈠紩
+  const deptIndex = pickerColumns.value[0].findIndex(
+    (item) => item.label === form.value.treatmentdeptname,
+  );
+  if (deptIndex !== -1) deptIndex.value = deptIndex;
+
+  // 姘戞棌绱㈠紩
+  const nationIndex = nationOptions.value.findIndex(
+    (item) => item.label === form.value.nation,
+  );
+  if (nationIndex !== -1) nationIndex.value = nationIndex;
+
+  // 璇佷欢绫诲瀷绱㈠紩
+  const idCardTypeIndex = idCardTypeOptions.value.findIndex(
+    (item) => item.value === form.value.idcardtype,
+  );
+  if (idCardTypeIndex !== -1) idCardTypeIndex.value = idCardTypeIndex;
 };
 </script>
 <style lang="scss" scoped>
@@ -887,4 +1277,233 @@
     }
   }
 }
+.case-report-container {
+  min-height: 100vh;
+  background: linear-gradient(135deg, #f8fdff 0%, #e8f7f6 100%);
+}
+
+.form-scroll {
+  height: 100vh;
+}
+
+.form-content {
+  padding: 30rpx;
+}
+
+.form-section {
+  background: #fff;
+  border-radius: 20rpx;
+  padding: 30rpx;
+  margin-bottom: 30rpx;
+  box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
+}
+
+.section-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 30rpx;
+  padding-bottom: 20rpx;
+  border-bottom: 2rpx solid #f0f0f0;
+}
+
+.section-icon {
+  font-size: 32rpx;
+  margin-right: 16rpx;
+}
+
+.section-title {
+  font-size: 32rpx;
+  font-weight: 600;
+  color: #1d1d1f;
+}
+
+.form-grid {
+  display: flex;
+  flex-direction: column;
+  gap: 24rpx;
+}
+
+.form-item {
+  display: flex;
+  flex-direction: column;
+}
+
+.item-label {
+  font-size: 28rpx;
+  color: #1d1d1f;
+  font-weight: 500;
+  margin-bottom: 12rpx;
+
+  &.required::after {
+    content: "*";
+    color: #ff4757;
+    margin-left: 4rpx;
+  }
+}
+
+/* 鏀归�犲悗鐨勯�夋嫨鍣ㄦ牱寮� */
+.picker {
+  height: 88rpx;
+  background: #f5f5f7;
+  border-radius: 12rpx;
+  padding: 0 24rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  border: 2rpx solid #e5e5e7;
+
+  text {
+    font-size: 28rpx;
+    color: #1d1d1f;
+
+    &.icon-arrow {
+      font-size: 32rpx;
+      color: #86868b;
+      transform: rotate(90deg);
+    }
+  }
+}
+
+.page-header {
+  padding: 30rpx 0;
+  text-align: center;
+  margin-bottom: 20rpx;
+}
+
+.page-title {
+  font-size: 36rpx;
+  font-weight: 600;
+  color: #1d1d1f;
+}
+
+/* 鍦ㄥ師鏈夋牱寮忓熀纭�涓婃坊鍔� */
+.form-section {
+  position: relative;
+}
+
+.edit-badge {
+  position: absolute;
+  top: 30rpx;
+  right: 30rpx;
+  background: #ff6b35;
+  color: white;
+  padding: 8rpx 16rpx;
+  border-radius: 20rpx;
+  font-size: 24rpx;
+}
+
+/* 鍔犺浇鐘舵�佹牱寮� */
+.loading-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 9999;
+}
+
+/* 鍝嶅簲寮忚皟鏁� */
+@media (max-width: 768px) {
+  .form-content {
+    padding: 20rpx;
+  }
+
+  .form-section {
+    padding: 20rpx;
+  }
+}
+
+/* 鏀归�犲悗鐨勫崟閫夋寜閽牱寮� */
+.radio-options {
+  display: flex;
+  gap: 40rpx;
+}
+
+.option-item {
+  display: flex;
+  align-items: center;
+  gap: 16rpx;
+
+  .radio-dot {
+    width: 32rpx;
+    height: 32rpx;
+    border: 2rpx solid #e5e5e7;
+    border-radius: 50%;
+    position: relative;
+  }
+
+  .option-label {
+    font-size: 28rpx;
+    color: #1d1d1f;
+  }
+
+  &.active {
+    .radio-dot {
+      border-color: #0f95b0;
+
+      &::after {
+        content: "";
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        width: 16rpx;
+        height: 16rpx;
+        background: #0f95b0;
+        border-radius: 50%;
+      }
+    }
+
+    .option-label {
+      color: #0f95b0;
+    }
+  }
+}
+
+.error-text {
+  font-size: 24rpx;
+  color: #ff4757;
+  margin-top: 8rpx;
+}
+
+/* 鍘熸湁鏍峰紡璋冩暣 */
+:deep(.u-input) {
+  border: 2rpx solid #e5e5e7 !important;
+  border-radius: 12rpx !important;
+  padding: 20rpx 24rpx !important;
+  background: #fff !important;
+}
+
+.action-buttons {
+  display: flex;
+  gap: 20rpx;
+  margin-top: 40rpx;
+}
+
+.btn {
+  flex: 1;
+  height: 80rpx;
+  border-radius: 16rpx;
+  font-size: 32rpx;
+  font-weight: 500;
+
+  &.secondary {
+    background: #f5f5f7 !important;
+    color: #1d1d1f !important;
+  }
+
+  &.primary {
+    background: linear-gradient(135deg, #0f95b0, #89c4c1) !important;
+    color: #fff !important;
+
+    &:disabled {
+      background: #c0c0c0 !important;
+      opacity: 0.6;
+    }
+  }
+}
 </style>

--
Gitblit v1.9.3