diff --git a/pages/myinfo/myinfo.vue b/pages/myinfo/myinfo.vue index c1658d4..845bc2f 100644 --- a/pages/myinfo/myinfo.vue +++ b/pages/myinfo/myinfo.vue @@ -12,23 +12,17 @@ 基本信息 - - 姓名 - {{ info.name }} - - - 身份证号 - {{ maskedIdCard }} - - - 手机号 - {{ maskedPhone }} - - - 性别 - {{ info.gender }} + + + 姓名:{{ info.name }} + 性别:{{ info.gender }} + + + 身份证:{{ maskedIdCard }} + 手机号:{{ maskedPhone }} + - + 性别 @@ -45,7 +39,7 @@ :customStyle="{ marginTop: '16rpx' }" /> - 紧急联系人(选填) + 紧急联系人 @@ -57,6 +51,85 @@ + + + + + 情况描述 + + + 医院名称 + + + + 癌种 + + + + + + 送检样本类型{{ sampleRequired ? '' : '(选填)' }} + + + + + + {{ needReturnNames }}是否需寄回 + + + + + + + + + + @@ -144,6 +217,10 @@ + + + @@ -170,9 +247,22 @@ const form = reactive({ city_code: '', district_code: '', address: '', + hospital: '', emergency_contact: '', emergency_phone: '', + tag: '', documents: [], + sample_types: [], + wax_return: 0, + return_name: '', + return_phone: '', + return_province_code: '', + return_city_code: '', + return_district_code: '', + return_address: '', + report_email: '', + sample_tracking_no: '', + sample_photos: [], sign_income: '', sign_privacy: '', sign_privacy_jhr: '', @@ -185,6 +275,75 @@ const showConfirmPopup = ref(false) const subscribeTmplId = ref('') const agreed = ref(false) +// 瘤种选项和送检样本类型 +const tagOptions = ref([]) +const sampleTypeList = ref([]) +const sampleRequired = ref(false) +const showReturnRegionPicker = ref(false) +const returnRegionDefaultIndex = ref([0, 0, 0]) + +// 是否显示"是否需寄回" +const showWaxReturn = computed(() => { + if (!form.sample_types || !form.sample_types.length) return false + return form.sample_types.some(name => { + const st = sampleTypeList.value.find(s => s.name === name) + return st && st.need_return + }) +}) + +// 需要寄回的样本类型名称(用"、"分隔) +const needReturnNames = computed(() => { + if (!form.sample_types || !form.sample_types.length) return '' + const names = form.sample_types.filter(name => { + const st = sampleTypeList.value.find(s => s.name === name) + return st && st.need_return + }) + return names.join('、') +}) + +// 寄回地址文本 +const returnRegionText = computed(() => { + const parts = [] + if (form.return_province_code) { + const p = allRegions.value.find(r => r.code === form.return_province_code) + if (p) parts.push(p.name) + } + if (form.return_city_code) { + const prov = allRegions.value.find(r => r.code === form.return_province_code) + if (prov && prov.children) { + const c = prov.children.find(r => r.code === form.return_city_code) + if (c) parts.push(c.name) + } + } + if (form.return_district_code) { + const prov = allRegions.value.find(r => r.code === form.return_province_code) + if (prov && prov.children) { + const city = prov.children.find(r => r.code === form.return_city_code) + if (city && city.children) { + const d = city.children.find(r => r.code === form.return_district_code) + if (d) parts.push(d.name) + } + } + } + return parts.join(' ') +}) + +const onSampleTypesChange = () => { + // 如果取消了所有 need_return 的样本类型,重置寄回选项 + if (!showWaxReturn.value) { + form.wax_return = 0 + } +} + +const fillSelfReturn = () => { + form.return_name = info.value.name || '' + form.return_phone = info.value.phone || '' + form.return_province_code = form.province_code + form.return_city_code = form.city_code + form.return_district_code = form.district_code + form.return_address = form.address +} + // 签署时的额外信息(用于重签回显) const signExtra = reactive({ income_amount: '', @@ -227,7 +386,7 @@ const regionDefaultIndex = ref([0, 0, 0]) const maskedIdCard = computed(() => { const v = info.value.id_card || '' - if (v.length === 18) return v.slice(0, 3) + '***********' + v.slice(-4) + if (v.length === 18) return v.slice(0, 3) + '****' + v.slice(-4) return v }) @@ -308,6 +467,8 @@ onLoad(async () => { await loadRegions() await loadInfo() loadSubscribeConfig() + loadTagOptions() + loadSampleTypes() }) onBeforeUnmount(() => { @@ -395,9 +556,22 @@ const loadInfo = async () => { form.city_code = res.data.city_code || '' form.district_code = res.data.district_code || '' form.address = res.data.address || '' + form.hospital = res.data.hospital || '' form.emergency_contact = res.data.emergency_contact || '' form.emergency_phone = res.data.emergency_phone || '' + form.tag = res.data.tag || '' form.documents = res.data.documents || [] + form.sample_types = res.data.sample_types || [] + form.wax_return = res.data.wax_return || 0 + form.return_name = res.data.return_name || '' + form.return_phone = res.data.return_phone || '' + form.return_province_code = res.data.return_province_code || '' + form.return_city_code = res.data.return_city_code || '' + form.return_district_code = res.data.return_district_code || '' + form.return_address = res.data.return_address || '' + form.report_email = res.data.report_email || '' + form.sample_tracking_no = res.data.sample_tracking_no || '' + form.sample_photos = res.data.sample_photos || [] form.sign_income = res.data.sign_income || '' form.sign_privacy = res.data.sign_privacy || '' form.sign_privacy_jhr = res.data.sign_privacy_jhr || '' @@ -423,6 +597,55 @@ const loadInfo = async () => { } catch (e) {} } +const loadTagOptions = async () => { + try { + const res = await get('/common/tagOptions') + tagOptions.value = res.data || [] + } catch (e) {} +} + +const loadSampleTypes = async () => { + try { + const res = await get('/common/sampleTypes') + sampleTypeList.value = (res.data && res.data.list) || [] + sampleRequired.value = (res.data && res.data.required) || false + } catch (e) {} +} + +const chooseSamplePhoto = () => { + uni.chooseImage({ + count: 9 - form.sample_photos.length, + sizeType: ['compressed'], + sourceType: ['album', 'camera'], + success: async (res) => { + for (const filePath of res.tempFilePaths) { + try { + const uploadRes = await upload('/api/mp/upload', { filePath, name: 'file' }) + if (uploadRes.data && uploadRes.data.url) { + form.sample_photos.push(uploadRes.data.url) + } + } catch (e) {} + } + } + }) +} + +const previewSamplePhoto = (idx) => { + uni.previewImage({ urls: form.sample_photos, current: idx }) +} + +const onReturnRegionConfirm = (e) => { + const idxs = e.indexs || e.index || [0, 0, 0] + const provinces = allRegions.value + const prov = provinces[idxs[0]] + const city = prov && prov.children ? prov.children[idxs[1]] : null + const dist = city && city.children ? city.children[idxs[2]] : null + form.return_province_code = prov ? prov.code : '' + form.return_city_code = city ? city.code : '' + form.return_district_code = dist ? dist.code : '' + showReturnRegionPicker.value = false +} + const chooseDocument = () => { uni.chooseImage({ count: 9 - form.documents.length, @@ -462,6 +685,35 @@ const handleSubmit = async () => { if (!form.address.trim()) { return uni.showToast({ title: '请填写详细地址', icon: 'none' }) } + if (!form.emergency_contact || !form.emergency_phone) { + return uni.showToast({ title: '请填写紧急联系人信息', icon: 'none' }) + } + if (form.emergency_phone === info.value.phone) { + return uni.showToast({ title: '紧急联系人电话不能与本人手机号一致', icon: 'none' }) + } + if (!form.hospital || !form.hospital.trim()) { + return uni.showToast({ title: '请填写医院名称', icon: 'none' }) + } + if (!form.tag) { + return uni.showToast({ title: '请选择癌种', icon: 'none' }) + } + // 送检样本校验 + if (sampleRequired.value && (!form.sample_types || form.sample_types.length === 0)) { + return uni.showToast({ title: '请选择送检样本类型', icon: 'none' }) + } + // 寄回信息校验 + if (form.wax_return === 1 && showWaxReturn.value) { + if (!form.return_name) return uni.showToast({ title: '请输入收件人姓名', icon: 'none' }) + if (!form.return_phone) return uni.showToast({ title: '请输入收件人电话', icon: 'none' }) + if (!form.return_province_code) return uni.showToast({ title: '请选择收件地址', icon: 'none' }) + if (!form.return_address) return uni.showToast({ title: '请输入收件详细地址', icon: 'none' }) + } + // 选了送检样本后,邮箱/物流单号/送检照片必填 + if (form.sample_types && form.sample_types.length > 0) { + if (!form.report_email) return uni.showToast({ title: '请输入报告接收邮箱', icon: 'none' }) + if (!form.sample_tracking_no) return uni.showToast({ title: '请输入送检样本物流单号', icon: 'none' }) + if (!form.sample_photos || form.sample_photos.length === 0) return uni.showToast({ title: '请上传送检单照片', icon: 'none' }) + } // 资料上传校验:至少上传一个 if (!form.documents || form.documents.length === 0) { return uni.showToast({ title: '请至少上传一份检查报告或诊断证明', icon: 'none' }) @@ -499,9 +751,22 @@ const doSubmit = async () => { city_code: form.city_code, district_code: form.district_code, address: form.address.trim(), + hospital: form.hospital, emergency_contact: form.emergency_contact, emergency_phone: form.emergency_phone, + tag: form.tag, documents: form.documents, + sample_types: form.sample_types, + wax_return: form.wax_return, + return_name: form.return_name, + return_phone: form.return_phone, + return_province_code: form.return_province_code, + return_city_code: form.return_city_code, + return_district_code: form.return_district_code, + return_address: form.return_address, + report_email: form.report_email, + sample_tracking_no: form.sample_tracking_no, + sample_photos: form.sample_photos, sign_income: form.sign_income, sign_privacy: form.sign_privacy, sign_privacy_jhr: form.sign_privacy_jhr, @@ -578,6 +843,35 @@ const doSubmit = async () => { } } +.info-compact { + padding-bottom: 20rpx; + border-bottom: 1rpx solid #f0f0f0; +} + +.info-compact-row { + display: flex; + gap: 32rpx; + margin-bottom: 12rpx; + + &:last-child { + margin-bottom: 0; + } +} + +.info-compact-item { + font-size: 26rpx; + color: #666; +} + +.fill-self-btn { + font-size: 24rpx; + color: #0e63e3; + padding: 6rpx 16rpx; + border: 1rpx solid #d0e0ff; + border-radius: 20rpx; + background: #f0f5ff; +} + .form-label { font-size: 28rpx; color: #555;