| | |
| | | <!-- 表单内容 --> |
| | | <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"> |
| | |
| | | </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">患者姓名</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> |
| | |
| | | </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" |
| | |
| | | border="none" |
| | | /> |
| | | </view> |
| | | <view class="form-item"> |
| | | <text class="item-label">GCS评分</text> |
| | | <u-input |
| | | v-model="form.gcsScore" |
| | | placeholder="请输入GCS评分" |
| | | border="none" |
| | | /> |
| | | </view> |
| | | |
| | | <view class="form-item full-width"> |
| | | <text class="item-label required">疾病诊断</text> |
| | |
| | | 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"> |
| | |
| | | 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> |
| | |
| | | /> |
| | | </view> |
| | | |
| | | <view class="form-item"> |
| | | <!-- <view class="form-item"> |
| | | <text class="item-label">报告人</text> |
| | | <u-input |
| | | v-model="form.reporterno" |
| | |
| | | <u-icon name="arrow-down" color="#86868b"></u-icon> |
| | | </template> |
| | | </u-input> |
| | | </view> |
| | | </view> --> |
| | | |
| | | <view class="form-item"> |
| | | <text class="item-label">报告时间</text> |
| | |
| | | |
| | | <!-- 操作按钮 --> |
| | | <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" |
| | |
| | | ></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 |
| | |
| | | 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: "", |
| | |
| | | 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); |
| | |
| | | |
| | | // 计算属性 |
| | | 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 |
| | |
| | | |
| | | // 生命周期 |
| | | 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); |
| | |
| | | .map((f) => |
| | | f.url.startsWith("http") |
| | | ? f.url |
| | | : baseUrlHt + (f.url.startsWith("/") ? "" : "/") + f.url |
| | | : baseUrlHt + (f.url.startsWith("/") ? "" : "/") + f.url, |
| | | ), |
| | | current: fullUrl, |
| | | }); |
| | |
| | | |
| | | 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; |
| | | }; |
| | |
| | | |
| | | 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]) { |
| | |
| | | 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: "请填写姓名、证件号码和疾病诊断", |
| | |
| | | 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( |
| | | "/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> |
| | |
| | | } |
| | | } |
| | | } |
| | | .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> |