| .env.development | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| App.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| components/op-select/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| index.html | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| manifest.json | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| pages/case/CaseDetails.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| pages/case/CaseInfo.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| pages/case/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| pages/login/Login.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| static/avatar/logo.png | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| static/avatar/logo1.jpg | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| static/avatar/yisn.jpg | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| static/avatar/yisna.jpg | 补丁 | 查看 | 原始文档 | blame | 历史 | |
| uni_modules/uview-plus/libs/util/route.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
.env.development
@@ -1,4 +1,4 @@ # å¼åç¯å¢APIå°å VITE_APP_BASE_API = 'http://192.168.100.10:8080' # VITE_APP_BASE_API = 'http://192.168.100.125:8080' # VITE_APP_BASE_API = 'http://192.168.100.10:8080' VITE_APP_BASE_API = 'http://localhost:8080' VUE_APP_PLATFORM = 'h5' App.vue
@@ -1,35 +1,74 @@ <script setup> import { onLaunch, onShow, onHide } from '@dcloudio/uni-app' import { useI18n } from 'vue-i18n' import { onLaunch } from '@dcloudio/uni-app' import { getToken } from '@/utils/auth' import { useUserStore } from '@/stores/user' const { t } = useI18n() // å®ä¹é¡µé¢ç½åå - è¿äºé¡µé¢ä¸éè¦tokenæ ¡éª const pageWhiteList = [ 'pages/login/Login', 'pages/login/DingTalkLogin' ] onLaunch(() => { console.log('App Launch') try { const currentLang = uni.getStorageSync('language') console.log('å½åè¯è¨:', currentLang) } catch (error) { console.error('è¯è¨é ç½®é误:', error) } }) // æ¹è¿çç½ååæ£æ¥æ¹æ³ const isPageInWhiteList = (currentPage) => { return pageWhiteList.some(path => currentPage.includes(path)) } onShow(() => { console.log('App Show') }) onHide(() => { console.log('App Hide') onLaunch(async () => { console.log('App Launch') const userStore = useUserStore() try { const token = getToken() const launchOptions = uni.getLaunchOptionsSync() const currentPage = launchOptions.path || '' console.log(launchOptions); console.log(launchOptions.path); if (!token) { if (!isPageInWhiteList(currentPage)) { console.log('æªéè¿ç½åå跳转ç»å½é¡µ') return uni.redirectTo({ url: '/pages/login/Login' }) } return } // æ ¡éªtokenæææ§ï¼éè¿è°ç¨/current/user/current_rolesæ¥å£ const current = await uni.$uapi.get("/system/user/profile"); // 妿æ¥å£è¿åæåï¼è¯´ætokenææï¼ç»§ç»è·åç¨æ·ä¿¡æ¯ if (current ) { // const resuser = await uni.$uapi.get("/system/user/profile"); userStore.setUserInfo(current); // userStore.setroleKey(current[0].roleKey); // 妿å½åæ¯ç»å½é¡µï¼è·³è½¬é¦é¡µ if (isPageInWhiteList(currentPage)) { uni.switchTab({ url: '/pages/index/index' }) } } else { // æ¥å£è¿åä½è§è²ä¿¡æ¯ä¸ºç©ºï¼è§ä¸ºtokenæ æ console.error('è§è²ä¿¡æ¯è·å失败ï¼tokenå¯è½æ æ') userStore.clearUser() // æ¸ é¤æ¬å°ç¨æ·ä¿¡æ¯ uni.redirectTo({ url: '/pages/login/Login' }) } } catch (error) { console.error('åå§å失败:', error) // tokenæ ææå ¶ä»éè¯¯ï¼æ¸ 餿¬å°ç¨æ·ä¿¡æ¯å¹¶è·³è½¬ç»å½é¡µ userStore.clearUser() uni.redirectTo({ url: '/pages/login/Login' }) } }) </script> <style lang="scss"> @import "@/uni_modules/uview-plus/index.scss"; // 主é¢é¢è² $primary-color: #0f95b0; $primary-color: #67AFAB; $primary-light: rgba($primary-color, 0.1); $primary-gradient: linear-gradient(135deg, #0f95b0, #89C4C1); $primary-gradient: linear-gradient(135deg, #67AFAB, #89C4C1); // æåé¢è² $text-primary: #333333; components/op-select/index.vue
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,137 @@ <!-- components/fs-select/fs-select.vue --> <template> <view style="width: 100%"> <u-input :input-align="inputaling" :placeholder="placeholderText" v-model="valueLable" type="select" :select-open="show" @click="show = true" :border="border" readonly /> <u-select v-model="show" :mode="mode" :list="list" @confirm="confirm" :value-name="valuename" :label-name="labelname" :safe-area-inset-bottom="true" ></u-select> </view> </template> <script> export default { name: "fs-select", props: { placeholder: { type: String, default: '' }, // æ¾ç¤ºææ¬çåæ®µå labelname: { type: String, default: 'label' }, // å¼çåæ®µå valuename: { type: String, default: 'value' }, // 鿩卿¨¡å¼ mode: { type: String, default: 'single-column' }, // æ°æ®å表 list: { type: Array, default() { return [] } }, // éä¸çå¼ value: { type: [String, Number], required: true }, // æ¯å¦æ¾ç¤ºè¾¹æ¡ border: { type: Boolean, default: false }, // ææ¬å¯¹é½æ¹å¼ inputaling: { type: String, default: 'right' } }, data() { return { show: false, valueLable: '' }; }, computed: { placeholderText() { return this.placeholder || `è¯·éæ©`; } }, watch: { // çå¬valueå¼ååï¼æ´æ°æ¾ç¤ºææ¬ value: { handler(newValue) { this.updateDisplayLabel(newValue); }, immediate: true }, // çå¬listæ°æ®ååï¼æ´æ°æ¾ç¤ºææ¬ list: { handler(newList) { this.updateDisplayLabel(this.value); }, deep: true } }, methods: { // æ´æ°æ¾ç¤ºææ¬ updateDisplayLabel(currentValue) { if (!currentValue && currentValue !== 0) { this.valueLable = ''; return; } const foundItem = this.list.find(item => String(item[this.valuename]) === String(currentValue) ); if (foundItem) { this.valueLable = foundItem[this.labelname]; } else { this.valueLable = ''; } }, // ç¡®è®¤éæ© confirm(e) { if (e.length > 0) { this.valueLable = e[0].label; // æåºéä¸çvalueå¼ this.$emit('input', e[0].value); // 妿éè¦æ´è¯¦ç»çæ°æ®ï¼å¯ä»¥é¢å¤æåºäºä»¶ this.$emit('change', { value: e[0].value, label: e[0].label, item: e[0] }); } } } } </script> <style lang="scss" scoped> // å¯ä»¥å¨è¿éæ·»å èªå®ä¹æ ·å¼ </style> index.html
@@ -10,7 +10,7 @@ (coverSupport ? ', viewport-fit=cover' : '') + '" />') </script> <title>éå²OPO管çç³»ç»</title> <link rel="icon" href="/static/avatar/logo.jpg"> <!-- å¼ç¨æ ¹ç®å½ç徿 --> <link rel="icon" href="/static/avatar/logo.png"> <!-- å¼ç¨æ ¹ç®å½ç徿 --> <!--preload-links--> <!--app-context--> </head> manifest.json
@@ -73,7 +73,7 @@ "disableHostCheck" : true, "proxy" : { "/api" : { "target" : "http://192.168.100.10:8080", "target" : "http://localhost:8080", "changeOrigin" : true } } 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"> @@ -12,53 +17,56 @@ <view class="form-grid"> <view class="form-item"> <text class="item-label">æç®ç¼å·</text> <text class="item-label">æ¡ä¾ç¼å·</text> <u-input v-model="form.donorno" placeholder="ç³»ç»èªå¨çæ" v-model="form.caseNo" placeholder="䏿¥åèªå¨çæ" disabled :disabledColor="disabledColor" border="none" /> </view> <!-- æ¹é åçå»çæºæéæ© --> <view class="form-item"> <text class="item-label">å»çæºæ</text> <u-input v-model="form.treatmenthospitalno" placeholder="è¯·éæ©å»çæºæ" readonly border="none" @click="showHospitalPicker = true" <picker mode="selector" :range="hospitalLabels" :value="hospitalIndex" @change="onHospitalChange" > <template #suffix> <u-icon name="arrow-down" color="#86868b"></u-icon> </template> </u-input> <view class="picker"> <text>{{ currentHospital }}</text> <text class="icon-arrow">âº</text> </view> </picker> </view> <!-- æ¹é åçç§å®¤éæ© --> <view class="form-item"> <text class="item-label">ç§å®¤</text> <u-input v-model="form.treatmentdeptname" placeholder="è¯·éæ©ç§å®¤" readonly border="none" @click="selectShow = true" <picker mode="selector" :range="deptLabels" :value="deptIndex" @change="onDeptChange" > <template #suffix> <u-icon name="arrow-down" color="#86868b"></u-icon> </template> </u-input> <view class="picker"> <text>{{ currentDept }}</text> <text class="icon-arrow">âº</text> </view> </picker> </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 +80,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" @@ -181,6 +195,14 @@ <u-input v-model="form.inpatientno" placeholder="请è¾å ¥ä½é¢å·" border="none" /> </view> <view class="form-item"> <text class="item-label">GCSè¯å</text> <u-input v-model="form.gscScore" placeholder="请è¾å ¥GCSè¯å" border="none" /> </view> @@ -212,6 +234,31 @@ <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.bloodtype === 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"> @@ -261,7 +308,7 @@ /> </view> <view class="form-item"> <!-- <view class="form-item"> <text class="item-label">æ¥å人</text> <u-input v-model="form.reporterno" @@ -274,7 +321,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 +337,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 +391,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 +430,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 +449,52 @@ sex: "", birthday: "", age: "", ageunit: "", // æ°å¢ï¼å¹´é¾åä½ inpatientno: "", diagnosisname: "", 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 isReadonly = ref(false); const id = ref(null); const selectShow = ref(false); const showHospitalPicker = ref(false); const showNationPicker = ref(false); @@ -481,7 +568,114 @@ const isFormValid = computed(() => { return form.value.name && form.value.idcardno && form.value.diagnosisname; }); // éæ©å¨ç´¢å¼ 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(() => nationOptions.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 onHospitalChange = (e) => { const index = parseInt(e.detail.value); hospitalIndex.value = index; form.value.treatmenthospitalname = hospitalOptions.value[index].label; }; const onDeptChange = (e) => { const index = parseInt(e.detail.value); deptIndex.value = index; form.value.treatmentdeptname = pickerColumns.value[0][index].label; }; const onNationChange = (e) => { const index = parseInt(e.detail.value); nationIndex.value = index; 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 +691,130 @@ // çå½å¨æ 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_BloodType", "sys_Infectious", "sys_AgeUnit", // æ°å¢å¹´é¾åä½ "sys_education", // æ°å¢å¦å "sys_nation", // æ°å¢æ°æ "sys_occupation" // æ°å¢èä¸ ); initOptions(); updateCurrentTime(); }); // åå§åéé¡¹æ°æ®çæ¹æ³ const initOptions = () => { infectiousDiseaselist.value = dict.value.sys_Infectious || []; idCardTypeOptions.value = dict.value.sys_IDType || []; }; // æ¹æ³å®ä¹ 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); @@ -615,7 +877,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 +891,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 +923,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 +958,162 @@ return; } loading.value = true; try { await new Promise((resolve) => setTimeout(resolve, 1500)); uni.showLoading({ title: isEditMode.value ? "ä¿®æ¹ä¸..." : "æäº¤ä¸..." }); uni.showToast({ title: "䏿¥æå", icon: "success", }); // åå¤æäº¤æ°æ® 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( "/system/donatebaseinforeport/edit", submitData ); } else { // æ°å¢æ¥å£ res = await uni.$uapi.post( "/system/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( `/system/donatebaseinforeport/getInfo/${id}` ); if (res.code === 200 && res.data) { // å¡«å è¡¨åæ°æ® Object.keys(form.value).forEach((key) => { if (res.data[key] !== undefined && res.data[key] !== null) { form.value[key] = res.data[key]; } }); // å¤çéæ©å¨ç´¢å¼ updatePickerIndexes(); // å¤çéä»¶ if (res.data.annexfilesList) { attachments.value = res.data.annexfilesList; } 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 +1273,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> pages/case/CaseInfo.vue
@@ -123,7 +123,7 @@ <text class="step-person" v-if="step.person">ç»å人ï¼{{ step.person }}</text> </view> </view> </view> </view> + </view> </view> pages/case/index.vue
@@ -124,8 +124,8 @@ <text class="value">{{ caseItem.reviewerName }}</text> </view> </view> <!-- æ¾ç¤ºè½¬è¿è¯¦æ --> <!-- å¨ .detail-info é¨åä¹åï¼.footer é¨åä¹åæ·»å 转è¿ä¿¡æ¯åºå --> <!-- 转è¿ä¿¡æ¯åºå --> <view class="transport-section"> <view class="transport-info"> <text class="label">转è¿ç¶æ</text> @@ -137,31 +137,80 @@ </text> </view> <!-- æ¾ç¤ºè½¬è¿è¯¦æ --> <!-- æ¾ç¤ºè½¬è¿è¯¦æ ï¼åªè¦æè½¬è¿åå·å°±æ¾ç¤º --> <view class="transport-details" v-if="caseItem.transportStatus !== 'not_transported'" v-if="caseItem.transportOrderNo && caseItem.transportOrderNo !== ''" > <view class="detail-item"> <text class="detail-label">转è¿åå·</text> <text class="detail-value">{{ caseItem.transportOrderNo }}</text> </view> <view class="detail-item" v-if="caseItem.transportDetails"> <view class="detail-item" v-if="caseItem.transportTime"> <text class="detail-label">计åè½¬è¿æ¶é´</text> <text class="detail-value">{{ caseItem.transportTime }}</text> </view> <view class="detail-item" v-if="caseItem.transportDetails?.vehicle"> <text class="detail-label">转è¿è½¦è¾</text> <text class="detail-value">{{ caseItem.transportDetails.vehicle }}</text> </view> <view class="detail-item" v-if="caseItem.transportDetails?.driver"> <text class="detail-label">驾驶å</text> <text class="detail-value">{{ caseItem.transportDetails.driver }}</text> </view> <view class="detail-item" v-if="caseItem.transportDetails?.phone"> <text class="detail-label">èç³»çµè¯</text> <text class="detail-value">{{ caseItem.transportDetails.phone }}</text> </view> <!-- 转è¿ä¸ææ¾ç¤ºçå¨æä¿¡æ¯ --> <view class="detail-item" v-if=" caseItem.transportDetails && caseItem.transportStatus === 'transporting' caseItem.transportStatus === 'transporting' && caseItem.transportDetails?.currentLocation " > <text class="detail-label">å½åä½ç½®</text> <text class="detail-value">{{ caseItem.transportDetails.currentLocation }}</text> </view> <view class="detail-item" v-if=" caseItem.transportStatus === 'transporting' && caseItem.transportDetails?.estimatedTime " > <text class="detail-label">é¢è®¡å°è¾¾</text> <text class="detail-value">{{ caseItem.transportDetails.estimatedTime }}</text> </view> <!-- å®æåæ¾ç¤ºçä¿¡æ¯ --> <view class="detail-item" v-if=" caseItem.transportStatus === 'completed' && caseItem.transportDetails?.completedTime " > <text class="detail-label">宿æ¶é´</text> <text class="detail-value">{{ caseItem.transportDetails.completedTime }}</text> </view> </view> @@ -170,7 +219,7 @@ <view class="transport-actions"> <button v-if=" caseItem.transportStatus === 'not_transported' && !caseItem.transportOrderNo && caseItem.status === 'agreed' " class="transport-btn primary" @@ -190,8 +239,11 @@ éå åææ¡ä¾ </button> <!-- åªè¦æè½¬è¿åå·å°±å¯ä»¥æ¥ç详æ --> <button v-if="caseItem.transportStatus !== 'not_transported'" v-if=" caseItem.transportOrderNo && caseItem.transportOrderNo !== '' " class="transport-btn secondary" @tap.stop="viewTransportDetail(caseItem)" > @@ -207,6 +259,7 @@ </button> </view> </view> <view class="footer"> <view class="action-info"> <text class="label">æ¡ä¾ç¶æ</text> @@ -248,9 +301,14 @@ </view> <!-- ç©ºç¶æ --> <view class="empty-state" v-if="filteredCases.length === 0"> <view class="empty-state" v-if="!loading && filteredCases.length === 0"> <image src="/static/empty/no-case.png" mode="aspectFit" /> <text>ææ å¨å®æç®æ¡ä¾è®°å½</text> </view> <!-- å è½½ç¶æ --> <view class="empty-state" v-if="loading"> <text>æ°æ®å è½½ä¸...</text> </view> </scroll-view> @@ -275,70 +333,31 @@ </template> <script setup> import { ref, computed } from "vue"; import { ref, computed, onMounted } from "vue"; import { onLoad, onShow } from "@dcloudio/uni-app"; import { useDict } from "@/utils/dict"; // ååºå¼æ°æ® const dict = ref({}); const genderOptions = ref([]); const educationOptions = ref([]); const loading = ref(false); const cases = ref([]); const total = ref(0); const pageNum = ref(1); const pageSize = ref(10); const hasMore = ref(true); const refreshing = ref(false); // ç»è®¡æ°æ® const stats = ref({ totalCases: 8, readCases: 4, agreedCases: 2, totalCases: 0, readCases: 0, agreedCases: 0, }); // æ¤å确认弹çªç¸å ³ const showWithdrawModal = ref(false); const currentCase = ref({}); onLoad(async (options) => { // è·ååå ¸æ°æ® dict.value = await useDict( "sys_IDType", "sys_user_sex", "sys_BloodType", "sys_DiseaseType" ); // åå§åéé¡¹æ°æ® initOptions(); donatebaseinforeportList(); donateTotal(); }); onShow(() => { // è¿éå¯ä»¥æ·»å ä»è½¬è¿é¡µé¢è¿åæ¶çæ°æ®å·æ°é»è¾ // ä¾å¦æ£æ¥æ¬å°åå¨ä¸æ¯å¦æéè¦æ´æ°ç转è¿ç¶æ const transportUpdate = uni.getStorageSync("transportStatusUpdate"); if (transportUpdate) { updateTransportStatus(transportUpdate.orderNo, transportUpdate.status); uni.removeStorageSync("transportStatusUpdate"); } }); // åå§åéé¡¹æ°æ®çæ¹æ³ const initOptions = () => { genderOptions.value = dict.value.sys_IDType || []; educationOptions.value = dict.value.sys_user_sex || []; }; const donatebaseinforeportList = async () => { const params = { pageNum: pageNum.value, pageSize: pageSize.value, }; const res = await uni.$uapi.post("/system/donatebaseinforeport/list", params); total.value = res.total; console.log(res.records, "11"); }; const donateTotal = async () => { const res = await uni.$uapi.post("/system/donatebaseinforeport/getTotal"); console.log(res); }; // çéç¸å ³ const caseTypes = [ { label: "å ¨é¨", value: "all" }, @@ -350,186 +369,7 @@ const currentType = ref("all"); const startDate = ref(""); const endDate = ref(""); // æ¡ä¾è®°å½æ°æ® - å¢å æ´å¤æ°æ®[1,4](@ref) const cases = ref([ { id: 1, donorNo: "DON20240325001", hospitalName: "éå²éæ¹å»é¢", hospitalLogo: "/static/hospital/kiang-wu.jpg", caseType: "å¨å®æç®æ¡ä¾", donorName: "å¼ ä¸", idCardNo: "370203198510123456", gender: "ç·", age: 38, bloodType: "Aå", diagnosis: "èå¤ä¼¤å¯¼è´èæ»äº¡", reportTime: "2024-03-25 09:30", reporterName: "æå»ç", status: "agreed", statusText: "å·²åæ", departmentName: "ç¥ç»å¤ç§", contactPerson: "çæ¤å£«", contactPhone: "13800138000", redCrossOrg: "éå²å¸çº¢ååä¼", acquisitionOrg: "éå²å¸å¨å®è·åç»ç»", transportStatus: "not_transported", // 转è¿ç¶æï¼not_transported-æªè½¬è¿, transporting-转è¿ä¸, completed-已宿 transportOrderNo: "", // 转è¿åå· transportTime: "", // è½¬è¿æ¶é´ transportDetails: null, // 转è¿è¯¦æ }, { id: 2, donorNo: "DON20240320002", hospitalName: "éå²ç§å¤§å»é¢", hospitalLogo: "/static/hospital/must.jpg", caseType: "å¨å®æç®æ¡ä¾", donorName: "æå", idCardNo: "370205197805207890", gender: "女", age: 45, bloodType: "Oå", diagnosis: "æ¥æ§å¿èæ¢æ»", reportTime: "2024-03-20 15:00", reporterName: "å¼ å»ç", status: "read", statusText: "å·²é 读", reviewTime: "2024-03-21 10:15", reviewerName: "å®¡æ ¸ä¸åA", departmentName: "å¿å ç§", contactPerson: "èµµæ¤å£«", contactPhone: "13900139000", redCrossOrg: "éå²å¸çº¢ååä¼", acquisitionOrg: "éå²å¸å¨å®è·åç»ç»", transportStatus: "transporting", // 转è¿ä¸ transportOrderNo: "TR20240321001", transportTime: "2024-03-21 14:30", transportDetails: { driver: "å¼ å¸å ", vehicle: "é²B12345", phone: "13800138000", estimatedTime: "2å°æ¶", currentLocation: "éå²å¸ååº", }, }, { id: 3, donorNo: "DON20240318003", hospitalName: "éå²å¤§å¦éå±å»é¢", hospitalLogo: "/static/hospital/qingda.jpg", caseType: "å¨å®æç®æ¡ä¾", donorName: "çäº", idCardNo: "370211197212153214", gender: "ç·", age: 51, bloodType: "Bå", diagnosis: "é¢ å åºè¡", reportTime: "2024-03-18 14:20", reporterName: "åå»ç", status: "agreed", statusText: "å·²åæ", reviewTime: "2024-03-19 09:45", reviewerName: "å®¡æ ¸ä¸åB", departmentName: "ç¥ç»å ç§", contactPerson: "鱿¤å£«", contactPhone: "13600136000", redCrossOrg: "éå²å¸çº¢ååä¼", acquisitionOrg: "éå²å¸å¨å®è·åç»ç»", transportStatus: "completed", // 已宿 transportOrderNo: "TR20240319001", transportTime: "2024-03-19 11:20", transportDetails: { driver: "æå¸å ", vehicle: "é²B67890", phone: "13900139000", completedTime: "2024-03-19 13:45", distance: "156å ¬é", }, }, { id: 4, donorNo: "DON20240315004", hospitalName: "éå²å¸ç«å»é¢", hospitalLogo: "/static/hospital/shili.jpg", caseType: "å¨å®æç®æ¡ä¾", donorName: "èµµå ", idCardNo: "370205198803274561", gender: "女", age: 36, bloodType: "ABå", diagnosis: "å¤å¨å®åè½è¡°ç«", reportTime: "2024-03-15 16:40", reporterName: "éå»ç", status: "rejected", statusText: "已驳å", reviewTime: "2024-03-16 11:20", reviewerName: "å®¡æ ¸ä¸åC", rejectReason: "èµæä¸å®æ´ï¼éè¡¥å å®¶å±åæä¹¦", departmentName: "ICU", contactPerson: "忤士", contactPhone: "13700137000", redCrossOrg: "éå²å¸çº¢ååä¼", acquisitionOrg: "éå²å¸å¨å®è·åç»ç»", transportStatus: "not_transported", // 转è¿ç¶æï¼not_transported-æªè½¬è¿, transporting-转è¿ä¸, completed-已宿 transportOrderNo: "", // 转è¿åå· transportTime: "", // è½¬è¿æ¶é´ transportDetails: null, // 转è¿è¯¦æ }, { id: 5, donorNo: "DON20240310005", hospitalName: "éå²ç¼ç§å»é¢", hospitalLogo: "/static/hospital/yanke.jpg", caseType: "è§èæç®æ¡ä¾", donorName: "åä¸", idCardNo: "370203199205187896", gender: "ç·", age: 32, bloodType: "Oå", diagnosis: "è§ç½èæ¯ç»èç¤", reportTime: "2024-03-10 08:15", reporterName: "ç¼ç§å¼ å»ç", status: "read", statusText: "å·²é 读", reviewTime: "2024-03-11 14:30", reviewerName: "å®¡æ ¸ä¸åA", departmentName: "ç¼ç§", contactPerson: "卿¤å£«", contactPhone: "13500135000", redCrossOrg: "éå²å¸çº¢ååä¼", acquisitionOrg: "éå²å¸ç¼åº", transportStatus: "not_transported", // 转è¿ç¶æï¼not_transported-æªè½¬è¿, transporting-转è¿ä¸, completed-已宿 transportOrderNo: "", // 转è¿åå· transportTime: "", // è½¬è¿æ¶é´ transportDetails: null, // 转è¿è¯¦æ }, { id: 6, donorNo: "DON20240305006", hospitalName: "éå²å¿ç«¥å»é¢", hospitalLogo: "/static/hospital/children.jpg", caseType: "å¨å®æç®æ¡ä¾", donorName: "å¨å «", idCardNo: "370211201802153248", gender: "女", age: 6, bloodType: "Aå", diagnosis: "å 天æ§å¿èç ", reportTime: "2024-03-05 11:25", reporterName: "å¿ç§æå»ç", status: "reported", statusText: "已䏿¥", departmentName: "å¿ç§ICU", contactPerson: "å´æ¤å£«", contactPhone: "13400134000", redCrossOrg: "éå²å¸çº¢ååä¼", acquisitionOrg: "éå²å¸å¨å®è·åç»ç»", transportStatus: "not_transported", // 转è¿ç¶æï¼not_transported-æªè½¬è¿, transporting-转è¿ä¸, completed-已宿 transportOrderNo: "", // 转è¿åå· transportTime: "", // è½¬è¿æ¶é´ transportDetails: null, // 转è¿è¯¦æ }, ]); // 转è¿ç¶ææ å° const transportStatusMap = { not_transported: { @@ -541,16 +381,186 @@ completed: { text: "已宿", color: "success", class: "completed" }, }; // çéè®°å½[3](@ref) // æ°æ®æ å°å½æ° // æ°æ®æ å°å½æ° const mapApiDataToCaseItem = (apiData) => { const statusMap = { 1: { status: "reported", statusText: "已䏿¥" }, 2: { status: "read", statusText: "å·²é 读" }, 3: { status: "agreed", statusText: "å·²åæ" }, 4: { status: "rejected", statusText: "已驳å" }, }; const transportStatusMap = { 1: "not_transported", 2: "transporting", 3: "completed", 4: "not_transported", 5: "not_transported", }; const statusInfo = statusMap[apiData.reportStatus] || statusMap["1"]; // å¤ç转è¿ä¿¡æ¯ - æ´å å¥å£®çå¤ç let transportDetails = null; let transportStatus = "not_transported"; let transportOrderNo = ""; let transportTime = ""; // ä¼å ä» serviceTransport è·å转è¿ä¿¡æ¯ if ( apiData.serviceTransport && Array.isArray(apiData.serviceTransport) && apiData.serviceTransport.length > 0 ) { const transport = apiData.serviceTransport[0]; transportDetails = { driver: transport.driver || "", vehicle: transport.vehicle || "", phone: transport.driverPhone || "", currentLocation: transport.transportStartPlace || "", estimatedTime: transport.estimatedTime || "", completedTime: transport.completedTime || "", }; transportStatus = transportStatusMap[transport.transitStatus] || "not_transported"; transportOrderNo = transport.id || ""; transportTime = transport.transportStartTime || ""; } // å¦æç´æ¥æè½¬è¿ä¿¡æ¯ï¼ä¹è¿è¡å¤ç if (apiData.transportOrderNo) { transportOrderNo = apiData.transportOrderNo; } if (apiData.transportStartTime) { transportTime = apiData.transportStartTime; } if (apiData.transitStatus) { transportStatus = transportStatusMap[apiData.transitStatus] || "not_transported"; } return { id: apiData.id || apiData.donatebaseinfoReportId, donorNo: apiData.caseNo, hospitalName: apiData.treatmenthospitalname, hospitalLogo: "/static/hospital/default.jpg", caseType: "å¨å®æç®æ¡ä¾", donorName: apiData.name, idCardNo: apiData.idcardno, gender: dict.value.sys_user_sex?.find((item) => item.dictValue === apiData.sex) ?.dictLabel || apiData.sex, age: apiData.age, bloodType: dict.value.sys_BloodType?.find( (item) => item.dictValue === apiData.bloodType )?.dictLabel || apiData.bloodType, diagnosis: apiData.diagnosisname, reportTime: apiData.reporttime, reporterName: apiData.reportername, reviewTime: apiData.reviewTime, reviewerName: apiData.reviewerName, departmentName: apiData.treatmentdeptname, contactPerson: apiData.userName || apiData.contactPerson, contactPhone: apiData.phone, ...statusInfo, transportStatus: transportStatus, transportOrderNo: transportOrderNo, transportTime: transportTime, transportDetails: transportDetails, }; }; // çå½å¨æ onLoad(async (options) => { // è·ååå ¸æ°æ® dict.value = await useDict( "sys_IDType", "sys_user_sex", "sys_BloodType", "sys_DiseaseType" ); // å è½½æ°æ® await loadInitialData(); }); onShow(() => { const transportUpdate = uni.getStorageSync("transportStatusUpdate"); if (transportUpdate) { updateTransportStatus(transportUpdate.orderNo, transportUpdate.status); uni.removeStorageSync("transportStatusUpdate"); } }); // æ°æ®å è½½å½æ° const loadInitialData = async () => { loading.value = true; try { await Promise.all([donatebaseinforeportList(), donateTotal()]); } catch (error) { console.error("åå§åæ°æ®å¤±è´¥:", error); } finally { loading.value = false; } }; // è·åæ¡ä¾å表 const donatebaseinforeportList = async () => { try { const params = { pageNum: pageNum.value, pageSize: pageSize.value, }; const res = await uni.$uapi.post( "/system/donatebaseinforeport/list", params ); console.log(res, "res"); const mappedData = res.map((item) => mapApiDataToCaseItem(item)); if (pageNum.value === 1) { cases.value = mappedData; } else { cases.value = [...cases.value, ...mappedData]; } hasMore.value = pageNum.value * pageSize.value < res.total; total.value = res.total; } catch (error) { console.error("è·åæ¡ä¾å表失败:", error); uni.showToast({ title: "ç½ç»è¯·æ±å¤±è´¥", icon: "none", }); } }; // è·åç»è®¡æ°æ® const donateTotal = async () => { try { const res = await uni.$uapi.post("/system/donatebaseinforeport/getTotal"); stats.value = { totalCases: res["1"] || 0, readCases: res["2"] || 0, agreedCases: res["3"] || 0, }; } catch (error) { console.error("è·åç»è®¡æ°æ®å¤±è´¥:", error); } }; // 计ç®å±æ§ï¼çéè®°å½ const filteredCases = computed(() => { let result = cases.value; // ç¶æçé if (currentType.value !== "all") { result = result.filter((caseItem) => caseItem.status === currentType.value); } // æ¥æçé if (startDate.value && endDate.value) { result = result.filter((caseItem) => { const caseDate = caseItem.reportTime.split(" ")[0]; @@ -561,47 +571,11 @@ return result; }); // å页ç¸å ³ const hasMore = ref(true); const refreshing = ref(false); // å建转è¿å const createTransportOrder = (caseItem) => { console.log(caseItem); uni.navigateTo({ url: `/pages/case/transferinfo?caseId=${caseItem.id}&donorNo=${caseItem.donorNo}`, }); }; // æ¥ç转è¿è¯¦æ const viewTransportDetail = (caseItem) => { uni.navigateTo({ url: `/pages/transport/detail?orderNo=${caseItem.transportOrderNo}`, }); }; // 宿¶è·è¸ª const trackTransport = (caseItem) => { uni.navigateTo({ url: `/pages/transport/track?orderNo=${caseItem.transportOrderNo}`, }); }; // æ´æ°è½¬è¿ç¶æï¼ç¨äºä»è½¬è¿é¡µé¢è¿åæ¶å·æ°æ°æ®ï¼ const updateTransportStatus = (orderNo, newStatus) => { const caseItem = cases.value.find( (item) => item.transportOrderNo === orderNo ); if (caseItem) { caseItem.transportStatus = newStatus; } }; // éæ©ç±»å // äºä»¶å¤ç彿° const selectType = (type) => { currentType.value = type; }; // æ¥æéæ© const onStartDateChange = (e) => { startDate.value = e.detail.value; }; @@ -610,28 +584,67 @@ endDate.value = e.detail.value; }; // æ¥ç详æ // å·æ°åå è½½æ´å¤ const onRefresh = async () => { refreshing.value = true; pageNum.value = 1; await donatebaseinforeportList(); setTimeout(() => { refreshing.value = false; }, 1000); }; const onLoadMore = async () => { if (!hasMore.value || loading.value) return; pageNum.value += 1; await donatebaseinforeportList(); }; // å ¶ä»åè½å½æ°ï¼ä¿æåæé»è¾ï¼ const createTransportOrder = (caseItem) => { uni.navigateTo({ url: `/pages/case/transferinfo?caseId=${caseItem.id}&donorNo=${caseItem.donorNo}`, }); }; const viewTransportDetail = (caseItem) => { uni.navigateTo({ url: `/pages/transport/detail?orderNo=${caseItem.transportOrderNo}`, }); }; const trackTransport = (caseItem) => { uni.navigateTo({ url: `/pages/transport/track?orderNo=${caseItem.transportOrderNo}`, }); }; const updateTransportStatus = (orderNo, newStatus) => { const caseItem = cases.value.find( (item) => item.transportOrderNo === orderNo ); if (caseItem) { caseItem.transportStatus = newStatus; } }; const viewDetail = (caseItem) => { uni.navigateTo({ url: `/pages/case/detail?id=${caseItem.id}`, }); }; // æ¤åæ¡ä¾[7](@ref) const withdrawCase = (caseItem) => { currentCase.value = caseItem; showWithdrawModal.value = true; }; // 确认æ¤å const confirmWithdraw = () => { const index = cases.value.findIndex( (item) => item.id === currentCase.value.id ); if (index !== -1) { // ä»å表ä¸ç§»é¤å·²æ¤åçæ¡ä¾[4](@ref) cases.value.splice(index, 1); // æ´æ°ç»è®¡æ°æ® stats.value.totalCases -= 1; uni.showToast({ title: "æ¤åæå", @@ -641,46 +654,20 @@ showWithdrawModal.value = false; }; // åæ¶æ¤å const cancelWithdraw = () => { showWithdrawModal.value = false; }; // æ¥ç详æ const viewDetails = (caseItem) => { uni.navigateTo({ url: `/pages/case/detail?id=${caseItem.id}`, }); }; // ç¼è¾æ¡ä¾ const editCase = (caseItem) => { uni.navigateTo({ url: `/pages/case/edit?id=${caseItem.id}`, }); }; // 䏿巿° const onRefresh = () => { refreshing.value = true; loadCases(); setTimeout(() => { refreshing.value = false; }, 1000); }; // å è½½æ´å¤ const onLoadMore = () => { if (!hasMore.value) return; loadCases(); }; // å è½½è®°å½ const loadCases = () => { // è¿éè°ç¨APIå è½½æ°æ® setTimeout(() => { hasMore.value = false; }, 1000); }; </script> pages/login/Login.vue
@@ -1,7 +1,7 @@ <template> <view class="login-container"> <view class="header"> <image src="/static/avatar/logo.jpg" class="logo" /> <image src="/static/avatar/logo.png" class="logo" /> <text class="hospital-name">éå²OPO</text> </view> @@ -110,8 +110,10 @@ // 夿æ¯å¦ä¸ºtabBaré¡µé¢ const tabBarPages = ["/pages/index/index", "/pages/appointment/index", "/pages/consultation/index", "/pages/my/index"]; if (tabBarPages.includes(redirects)) { console.log(redirects,'é¢è·¯ç±1'); uni.switchTab({ url: redirects }); } else { console.log(redirects,'é¢è·¯ç±2'); uni.redirectTo({ url: redirects }); } } catch (err) { static/avatar/logo.png
static/avatar/logo1.jpgstatic/avatar/yisn.jpg
static/avatar/yisna.jpg
uni_modules/uview-plus/libs/util/route.js
@@ -99,11 +99,15 @@ }) } if (config.type == 'redirectTo' || config.type == 'redirect') { console.log(url,'è¿å ¥è·¯ç±'); uni.redirectTo({ url }) } if (config.type == 'switchTab' || config.type == 'tab') { console.log(url,'è¿å ¥è·¯ç±'); uni.switchTab({ url })