| @@ -67,7 +67,7 @@ const countdownText = computed(() => { | |||||
| onShow(() => { | onShow(() => { | ||||
| const info = getUserInfo() | const info = getUserInfo() | ||||
| currentPhone.value = info?.patient?.phone || '' | |||||
| currentPhone.value = (info && info.patient && info.patient.phone) || '' | |||||
| }) | }) | ||||
| const handleSendCode = async () => { | const handleSendCode = async () => { | ||||
| @@ -19,7 +19,7 @@ const content = ref('') | |||||
| const loaded = ref(false) | const loaded = ref(false) | ||||
| onLoad((options) => { | onLoad((options) => { | ||||
| const key = options?.key || '' | |||||
| const key = (options && options.key) || '' | |||||
| if (key) { | if (key) { | ||||
| loadContent(key) | loadContent(key) | ||||
| } | } | ||||
| @@ -32,9 +32,12 @@ const userInfo = ref(null) | |||||
| const isLoggedIn = ref(false) | const isLoggedIn = ref(false) | ||||
| // 患者状态 | // 患者状态 | ||||
| const patient = computed(() => userInfo.value?.patient || null) | |||||
| const isAuthed = computed(() => patient.value?.auth_status === 1) | |||||
| const patientStatus = computed(() => patient.value?.status ?? null) | |||||
| const patient = computed(() => (userInfo.value && userInfo.value.patient) || null) | |||||
| const isAuthed = computed(() => patient.value && patient.value.auth_status === 1) | |||||
| const patientStatus = computed(() => { | |||||
| if (!patient.value || patient.value.status === undefined || patient.value.status === null) return null | |||||
| return patient.value.status | |||||
| }) | |||||
| // 按钮文案和样式 | // 按钮文案和样式 | ||||
| const btnText = computed(() => { | const btnText = computed(() => { | ||||
| @@ -130,6 +130,13 @@ | |||||
| <!-- 提交按钮 --> | <!-- 提交按钮 --> | ||||
| <view class="btn-wrap"> | <view class="btn-wrap"> | ||||
| <view class="agree-row" @tap="agreed = !agreed"> | |||||
| <u-checkbox-group> | |||||
| <u-checkbox :checked="agreed" shape="circle" activeColor="#0E63E3" size="18" @change="agreed = !agreed" /> | |||||
| </u-checkbox-group> | |||||
| <text class="agree-text">请阅读并同意</text> | |||||
| <text class="agree-link" @tap.stop="openNotice">《患者告知书》</text> | |||||
| </view> | |||||
| <u-button text="提交审核" :loading="submitting" @click="handleSubmit" color="#0E63E3" size="large" /> | <u-button text="提交审核" :loading="submitting" @click="handleSubmit" color="#0E63E3" size="large" /> | ||||
| </view> | </view> | ||||
| @@ -176,6 +183,7 @@ const submitting = ref(false) | |||||
| const showRegionPicker = ref(false) | const showRegionPicker = ref(false) | ||||
| const showConfirmPopup = ref(false) | const showConfirmPopup = ref(false) | ||||
| const subscribeTmplId = ref('') | const subscribeTmplId = ref('') | ||||
| const agreed = ref(false) | |||||
| // 签署时的额外信息(用于重签回显) | // 签署时的额外信息(用于重签回显) | ||||
| const signExtra = reactive({ | const signExtra = reactive({ | ||||
| @@ -437,7 +445,14 @@ const previewImage = (idx) => { | |||||
| uni.previewImage({ urls: form.documents, current: idx }) | uni.previewImage({ urls: form.documents, current: idx }) | ||||
| } | } | ||||
| const openNotice = () => { | |||||
| uni.navigateTo({ url: '/pages/content/content?key=patient_information_sheet' }) | |||||
| } | |||||
| const handleSubmit = async () => { | const handleSubmit = async () => { | ||||
| if (!agreed.value) { | |||||
| return uni.showToast({ title: '请阅读并同意《患者告知书》', icon: 'none' }) | |||||
| } | |||||
| if (!info.value.gender && !form.gender) { | if (!info.value.gender && !form.gender) { | ||||
| return uni.showToast({ title: '请选择性别', icon: 'none' }) | return uni.showToast({ title: '请选择性别', icon: 'none' }) | ||||
| } | } | ||||
| @@ -775,6 +790,24 @@ const doSubmit = async () => { | |||||
| z-index: 100; | z-index: 100; | ||||
| } | } | ||||
| .agree-row { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| margin-bottom: 16rpx; | |||||
| padding-left: 4rpx; | |||||
| } | |||||
| .agree-text { | |||||
| font-size: 24rpx; | |||||
| color: #666; | |||||
| margin-left: 8rpx; | |||||
| } | |||||
| .agree-link { | |||||
| font-size: 24rpx; | |||||
| color: #0e63e3; | |||||
| } | |||||
| .confirm-popup { | .confirm-popup { | ||||
| padding: 48rpx 40rpx 40rpx; | padding: 48rpx 40rpx 40rpx; | ||||
| width: 560rpx; | width: 560rpx; | ||||
| @@ -5,7 +5,7 @@ | |||||
| <image class="header-bg" src="https://cdn.csybhelp.com/images/cytx/profile-bg.jpg" mode="aspectFill" /> | <image class="header-bg" src="https://cdn.csybhelp.com/images/cytx/profile-bg.jpg" mode="aspectFill" /> | ||||
| <view class="user-row"> | <view class="user-row"> | ||||
| <view class="avatar-wrap" @tap="isLoggedIn && changeAvatar()"> | <view class="avatar-wrap" @tap="isLoggedIn && changeAvatar()"> | ||||
| <image class="avatar" :src="userInfo?.avatar || 'https://cdn.csybhelp.com/images/cytx/default-avatar.jpg'" | |||||
| <image class="avatar" :src="(userInfo && userInfo.avatar) || 'https://cdn.csybhelp.com/images/cytx/default-avatar.jpg'" | |||||
| mode="aspectFill" /> | mode="aspectFill" /> | ||||
| <view v-if="isLoggedIn" class="camera-icon"> | <view v-if="isLoggedIn" class="camera-icon"> | ||||
| <u-icon name="camera-fill" size="20" color="#666" /> | <u-icon name="camera-fill" size="20" color="#666" /> | ||||
| @@ -13,7 +13,7 @@ | |||||
| </view> | </view> | ||||
| <view class="info" @tap="!isLoggedIn && goLogin()"> | <view class="info" @tap="!isLoggedIn && goLogin()"> | ||||
| <view class="name">{{ displayName }}</view> | <view class="name">{{ displayName }}</view> | ||||
| <view v-if="isLoggedIn && userInfo?.patient?.patient_no" class="patient-no">{{ userInfo.patient.patient_no }}</view> | |||||
| <view v-if="isLoggedIn && userInfo && userInfo.patient && userInfo.patient.patient_no" class="patient-no">{{ userInfo.patient.patient_no }}</view> | |||||
| </view> | </view> | ||||
| </view> | </view> | ||||
| </view> | </view> | ||||
| @@ -96,9 +96,9 @@ const userInfo = ref(getUserInfo()) | |||||
| const isLoggedIn = ref(!!getToken()) | const isLoggedIn = ref(!!getToken()) | ||||
| const unreadCount = ref(0) | const unreadCount = ref(0) | ||||
| const isAuthed = computed(() => userInfo.value?.patient?.auth_status === 1) | |||||
| const isAuthed = computed(() => userInfo.value && userInfo.value.patient && userInfo.value.patient.auth_status === 1) | |||||
| const patientStatus = computed(() => { | const patientStatus = computed(() => { | ||||
| const p = userInfo.value?.patient | |||||
| const p = userInfo.value && userInfo.value.patient | |||||
| if (!p) return null | if (!p) return null | ||||
| return p.status | return p.status | ||||
| }) | }) | ||||
| @@ -106,8 +106,8 @@ const isRejected = computed(() => patientStatus.value === 2) | |||||
| const displayName = computed(() => { | const displayName = computed(() => { | ||||
| if (!isLoggedIn.value) return '点击登录' | if (!isLoggedIn.value) return '点击登录' | ||||
| if (isAuthed.value && userInfo.value?.patient?.name) return userInfo.value.patient.name | |||||
| return userInfo.value?.nickname || '微信用户' | |||||
| if (isAuthed.value && userInfo.value && userInfo.value.patient && userInfo.value.patient.name) return userInfo.value.patient.name | |||||
| return (userInfo.value && userInfo.value.nickname) || '微信用户' | |||||
| }) | }) | ||||
| onShow(() => { | onShow(() => { | ||||
| @@ -127,7 +127,7 @@ const fetchUserInfo = async () => { | |||||
| userInfo.value = res.data | userInfo.value = res.data | ||||
| setUserInfo(res.data) | setUserInfo(res.data) | ||||
| } catch (e) { | } catch (e) { | ||||
| if (e?.code === 1009) { | |||||
| if (e && e.code === 1009) { | |||||
| clearAll() | clearAll() | ||||
| userInfo.value = null | userInfo.value = null | ||||
| } | } | ||||
| @@ -137,7 +137,7 @@ const fetchUserInfo = async () => { | |||||
| const fetchUnreadCount = async () => { | const fetchUnreadCount = async () => { | ||||
| try { | try { | ||||
| const res = await get('/api/mp/unreadCount') | const res = await get('/api/mp/unreadCount') | ||||
| unreadCount.value = res.data?.count || 0 | |||||
| unreadCount.value = (res.data && res.data.count) || 0 | |||||
| } catch (e) {} | } catch (e) {} | ||||
| } | } | ||||
| @@ -222,7 +222,7 @@ const changeAvatar = () => { | |||||
| try { | try { | ||||
| uni.showLoading({ title: '上传中...' }) | uni.showLoading({ title: '上传中...' }) | ||||
| const uploadRes = await upload('/api/mp/upload', { filePath, name: 'file' }) | const uploadRes = await upload('/api/mp/upload', { filePath, name: 'file' }) | ||||
| if (!uploadRes.data?.url) throw { msg: '上传失败' } | |||||
| if (!(uploadRes.data && uploadRes.data.url)) throw { msg: '上传失败' } | |||||
| const avatarUrl = uploadRes.data.url | const avatarUrl = uploadRes.data.url | ||||
| await post('/api/mp/updateAvatar', { avatar: avatarUrl }) | await post('/api/mp/updateAvatar', { avatar: avatarUrl }) | ||||
| if (userInfo.value) { | if (userInfo.value) { | ||||
| @@ -231,7 +231,7 @@ const changeAvatar = () => { | |||||
| } | } | ||||
| uni.showToast({ title: '头像已更新', icon: 'success' }) | uni.showToast({ title: '头像已更新', icon: 'success' }) | ||||
| } catch (e) { | } catch (e) { | ||||
| if (e?.msg) uni.showToast({ title: e.msg, icon: 'none' }) | |||||
| if (e && e.msg) uni.showToast({ title: e.msg, icon: 'none' }) | |||||
| } finally { | } finally { | ||||
| uni.hideLoading() | uni.hideLoading() | ||||
| } | } | ||||
| @@ -278,7 +278,7 @@ const sendSms = async () => { | |||||
| try { | try { | ||||
| const res = await post('/api/mp/sendSmsCode', { mobile: form.phone, bizType: 'real_name_auth' }) | const res = await post('/api/mp/sendSmsCode', { mobile: form.phone, bizType: 'real_name_auth' }) | ||||
| // 开发环境可能返回验证码 | // 开发环境可能返回验证码 | ||||
| if (res.data?.code) { | |||||
| if (res.data && res.data.code) { | |||||
| uni.showToast({ title: `验证码: ${res.data.code}`, icon: 'none', duration: 3000 }) | uni.showToast({ title: `验证码: ${res.data.code}`, icon: 'none', duration: 3000 }) | ||||
| } else { | } else { | ||||
| uni.showToast({ title: '验证码已发送', icon: 'none' }) | uni.showToast({ title: '验证码已发送', icon: 'none' }) | ||||
| @@ -354,8 +354,8 @@ const doSubmit = async (confirmBind) => { | |||||
| if (e && e.code === 1010) { | if (e && e.code === 1010) { | ||||
| // 患者已存在,弹出确认绑定弹窗 | // 患者已存在,弹出确认绑定弹窗 | ||||
| bindPatientInfo.value = { | bindPatientInfo.value = { | ||||
| name: e.data?.patientName || '', | |||||
| phone: e.data?.patientPhone || '' | |||||
| name: (e.data && e.data.patientName) || '', | |||||
| phone: (e.data && e.data.patientPhone) || '' | |||||
| } | } | ||||
| showBindPopup.value = true | showBindPopup.value = true | ||||
| } else if (e && e.msg) { | } else if (e && e.msg) { | ||||
| @@ -0,0 +1,27 @@ | |||||
| -----BEGIN RSA PRIVATE KEY----- | |||||
| MIIEowIBAAKCAQEAwtVO/Qlh6bgOVAdSUFk4fgqucdl8xog1lALeRrcDBrFk5Mh6 | |||||
| 5TqB7Y1ws+Nl4n3X59Om2hM0J/0C7pOuG/oLNiR+FFxySESwxIs7okvWa7LpPxTt | |||||
| Elocy0zELu9lifZGYxCfCXRalCCoq6SiPdQJXZ145cRvdWbonxdd3bYhGW66lCn4 | |||||
| VS5tLOtBhr3FEqMMUY2wTppU1P1C8SZ7zh4IU2YSVC2TdAwV+1d2OBBJ/u51+LFB | |||||
| 1losqPEp4yaBm5Kmhar16yL9xxVLMSy83H2MoxU162Mz1fHR5jaQIRRxqhdjdiAB | |||||
| gpJpZToCWkvE5GQqGA4MnEy6F2nBlYSZep9wfwIDAQABAoIBAH0avyeXuLl8qCao | |||||
| tOBHChFVBoKwZoCMweqSlOvPZDAOBH0rhk5e7UL+SVoZMDjpGZQQwdjR7/GlcxaC | |||||
| 2Y+5VS2k7Rhh7Dgfc2ohBV/HVp29Oix5YWkhV8/rMSX6LrcR3kyKRbSqc+cduXDN | |||||
| vCf7WTA1h4XyRqeaNtDBDlLpOgO7hvtxfhi3dwXxJVcjePb4LMWzZdTQul8RvJj+ | |||||
| RuShXm9I25tw1DEL0QUYVasaYT+/bdUm/IKahO7qB40HaV7/OFwE449Np1FIBFUX | |||||
| Crztg4X9Gl0xfSld463TNKPegH9wX2DVvAk4fQev6vv22ldJ7Bw/u8tmSuldKnT2 | |||||
| n6pshQECgYEA/hKknNbuCO3/q1ykjoEiVbsilraMcxMd3wO8az8j71glaWEsNlJ5 | |||||
| T6OAvKFQwTUO5OGWS1mrrfFyvEJ+J0IaJh9Sig0xRlWJ2XsQaiI6Wff9oCSUhzUD | |||||
| 3EUn0vovoPqiFAdpUUL1IiPhxXd83DgMOerMaHB1wGRqUjO++W4SksECgYEAxE+i | |||||
| bS6r8m4BI2HBnLSPct5MXqOJRQCj3FALa6IQn7Y18qQpjX6f12hRAg6pwPYn8vrs | |||||
| FiW4RIbbjKuswT2ww6+3HhV9dbN30lUuopcTJhdJd2s3lfgPqsf8Vwe0HAviL3BW | |||||
| Up6oWTl0cskHJ14SyUQ9hDoJrBb7wwcAbFJpEz8CgYEA/Ucwenl4ScaYPQfZs4Xf | |||||
| 6H7o+D16vays9okO6ArFk+/XO7n3DSAidtWTnHdjvXdbJagM34jAsGIl8q6GfDRV | |||||
| RPOsoJqOKINVLEyWDHeam92wJFjTCAY9lvQJwzRNDrlLoZPR1YReQm5qvyNigVYO | |||||
| Oh5rLyINAIIZy2ByXMzyDwECgYBMRDfxPQGWVMBic5cZf1h/ovd+iQBKa349mGdn | |||||
| cHYO5mY9FyQBkaEduaxHJVUz3y4UCwHvdMYK8W2YUBX0mTf0Pm7g5C5yrL+vWmKc | |||||
| zh6lXMSw/VmCDPZhPgK9+QMzJjbAgV84B+WVjGm+MnVyCO05fiZ8GWQqlF9JHI5A | |||||
| hx/FVwKBgDR5Hyxng8qyAMD6cG3u7Fs+coIdjGWZr6k1+FxlPWF/E9R4KDoa3ylL | |||||
| OMTXiyFxbtroNCB5cHsdQLPOJbEg2aU8ldFm/KCOE0JB59Y9WgyZ7XTHKA6DwGw4 | |||||
| 6yOxyWd4+3RtcCrEfJ8OFuUGrLRJHpI3IBhsZIlvTlkcV5RKtegB | |||||
| -----END RSA PRIVATE KEY----- | |||||