Sfoglia il codice sorgente

fix : 流程优化

master
leiyun 2 settimane fa
parent
commit
48d44bf882
2 ha cambiato i file con 97 aggiunte e 56 eliminazioni
  1. +70
    -44
      pages/myinfo/myinfo.vue
  2. +27
    -12
      pages/sample-info/sample-info.vue

+ 70
- 44
pages/myinfo/myinfo.vue Vedi File

@@ -1,5 +1,6 @@
<template>
<view class="page">
<u-loading-page :loading="pageLoading" loading-text="加载中..." />
<!-- 驳回原因提示 -->
<view v-if="info.status === 2 && info.reject_reason" class="reject-tip">
<u-icon name="warning-fill" size="20" color="#fa8c16" />
@@ -25,33 +26,33 @@
<view class="form-group" v-if="!info.gender">
<text class="form-label">性别</text>
<view class="gender-row">
<view class="gender-item" :class="{ active: form.gender === '男' }" @tap="form.gender = '男'">男</view>
<view class="gender-item" :class="{ active: form.gender === '女' }" @tap="form.gender = '女'">女</view>
<view class="gender-item" :class="{ active: form.gender === '男', disabled: isInfoApproved }" @tap="setGender('男')">男</view>
<view class="gender-item" :class="{ active: form.gender === '女', disabled: isInfoApproved }" @tap="setGender('女')">女</view>
</view>
</view>
<view class="form-group">
<text class="form-label">联系地址</text>
<view class="region-row" @tap="showRegionPicker = true">
<view :class="['region-row', isInfoApproved ? 'disabled' : '']" @tap="openRegionPicker">
<text :class="['region-text', regionText ? '' : 'placeholder']">{{ regionText || '请选择省/市/区' }}</text>
<text class="arrow">›</text>
</view>
<u-input v-model="form.address" placeholder="详细街道地址" border="surround"
<u-input v-model="form.address" :disabled="isInfoApproved" placeholder="详细街道地址" border="surround"
:customStyle="{ marginTop: '16rpx' }" />
</view>
<view class="form-group">
<text class="form-label">紧急联系人</text>
<view class="contact-row">
<view class="contact-input">
<u-input v-model="form.emergency_contact" placeholder="联系人姓名" border="surround" />
<u-input v-model="form.emergency_contact" :disabled="isInfoApproved" placeholder="联系人姓名" border="surround" />
</view>
<view class="contact-input">
<u-input v-model="form.emergency_phone" type="number" placeholder="联系人电话" border="surround" maxlength="11" />
<u-input v-model="form.emergency_phone" :disabled="isInfoApproved" type="number" placeholder="联系人电话" border="surround" maxlength="11" />
</view>
</view>
</view>
<view class="form-group">
<text class="form-label">医院名称</text>
<view class="region-row" @tap="openHospitalPicker">
<view :class="['region-row', isInfoApproved ? 'disabled' : '']" @tap="openHospitalPicker">
<text :class="['region-text', form.hospital ? '' : 'placeholder']">{{ form.hospital || '请选择就诊医院' }}</text>
<text class="arrow">›</text>
</view>
@@ -60,7 +61,7 @@
<text class="form-label">癌种</text>
<u-radio-group v-model="form.tag" placement="row" :wrap="true">
<u-radio v-for="t in tagOptions" :key="t" :label="t" :name="t"
activeColor="#0E63E3" :customStyle="{ marginRight: '24rpx', marginBottom: '16rpx' }" />
:disabled="isInfoApproved" activeColor="#0E63E3" :customStyle="{ marginRight: '24rpx', marginBottom: '16rpx' }" />
</u-radio-group>
</view>
</view>
@@ -75,9 +76,9 @@
<view class="upload-row">
<view class="upload-item" v-for="(doc, idx) in form.documents" :key="idx">
<image class="upload-img" :src="doc" mode="aspectFill" @tap="previewImage(idx)" />
<view class="upload-del" @tap="form.documents.splice(idx, 1)">×</view>
<view v-if="!isInfoApproved" class="upload-del" @tap="form.documents.splice(idx, 1)">×</view>
</view>
<view class="upload-box" @tap="chooseDocument">
<view v-if="!isInfoApproved" class="upload-box" @tap="chooseDocument">
<text class="upload-icon">+</text>
<text class="upload-text">上传图片</text>
</view>
@@ -97,9 +98,9 @@
</view>
<view class="sign-btns" v-if="signedIncome">
<view class="sign-btn view" @tap="previewSign('income')">查看</view>
<view class="sign-btn resign" @tap="goSign('income')">重签</view>
<view v-if="!isInfoApproved" class="sign-btn resign" @tap="goSign('income')">重签</view>
</view>
<view class="sign-btn primary" v-else @tap="goSign('income')">去签署</view>
<view class="sign-btn primary" v-else-if="!isInfoApproved" @tap="goSign('income')">去签署</view>
</view>
<view class="sign-item">
<view class="sign-left">
@@ -108,9 +109,9 @@
</view>
<view class="sign-btns" v-if="signedPrivacy">
<view class="sign-btn view" @tap="previewSign('privacy')">查看</view>
<view class="sign-btn resign" @tap="goSign('privacy')">重签</view>
<view v-if="!isInfoApproved" class="sign-btn resign" @tap="goSign('privacy')">重签</view>
</view>
<view class="sign-btn primary" v-else @tap="goSign('privacy')">去签署</view>
<view class="sign-btn primary" v-else-if="!isInfoApproved" @tap="goSign('privacy')">去签署</view>
</view>
<view class="sign-item" v-if="isMinor">
<view class="sign-left">
@@ -119,9 +120,9 @@
</view>
<view class="sign-btns" v-if="signedPrivacyJhr">
<view class="sign-btn view" @tap="previewSign('privacy_jhr')">查看</view>
<view class="sign-btn resign" @tap="goSign('privacy_jhr')">重签</view>
<view v-if="!isInfoApproved" class="sign-btn resign" @tap="goSign('privacy_jhr')">重签</view>
</view>
<view class="sign-btn primary" v-else @tap="goSign('privacy_jhr')">去签署</view>
<view class="sign-btn primary" v-else-if="!isInfoApproved" @tap="goSign('privacy_jhr')">去签署</view>
</view>
<view class="sign-item">
<view class="sign-left">
@@ -130,22 +131,22 @@
</view>
<view class="sign-btns" v-if="signedPromise">
<view class="sign-btn view" @tap="previewSign('promise')">查看</view>
<view class="sign-btn resign" @tap="goSign('promise')">重签</view>
<view v-if="!isInfoApproved" class="sign-btn resign" @tap="goSign('promise')">重签</view>
</view>
<view class="sign-btn primary" v-else @tap="goSign('promise')">去签署</view>
<view class="sign-btn primary" v-else-if="!isInfoApproved" @tap="goSign('promise')">去签署</view>
</view>
</view>

<!-- 提交按钮 -->
<view class="btn-wrap">
<view class="agree-row" @tap="agreed = !agreed">
<view v-if="!isInfoApproved" 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="submitButtonText" :disabled="isInfoApproved" :loading="submitting" @click="handleSubmit" color="#0E63E3" size="large" />
</view>

<!-- 地区选择器 -->
@@ -154,18 +155,6 @@

<!-- 医院选择器组件 -->
<hospital-picker ref="hospitalPickerRef" :hospital-data="hospitalTree" @confirm="onHospitalConfirm" />

<!-- 已通过重新提交确认弹窗 -->
<u-popup :show="showConfirmPopup" mode="center" round="12" :safeAreaInsetBottom="false" @close="showConfirmPopup = false">
<view class="confirm-popup">
<view class="confirm-title">提示</view>
<view class="confirm-content">您的资料审核已通过,如果重新提交审核会变为待审核,需要平台重新审核,是否确认提交?</view>
<view class="confirm-btns">
<u-button text="取消" size="normal" :plain="true" shape="circle" @click="showConfirmPopup = false" />
<u-button text="确认提交" size="normal" color="#0E63E3" shape="circle" @click="doSubmit" />
</view>
</view>
</u-popup>
</view>
</template>

@@ -196,8 +185,8 @@ const form = reactive({
income_amount: ''
})
const submitting = ref(false)
const pageLoading = ref(true)
const showRegionPicker = ref(false)
const showConfirmPopup = ref(false)
const subscribeTmplId = ref('')
const agreed = ref(false)

@@ -208,7 +197,25 @@ const tagOptions = ref([])
const hospitalTree = ref([])
const hospitalPickerRef = ref(null)

const isInfoApproved = computed(() => Number(info.value.status) === 1)
const submitButtonText = computed(() => isInfoApproved.value ? '已通过审核' : '提交审核')

const showApprovedTip = () => {
uni.showToast({ title: '资料已审核通过,不能修改', icon: 'none' })
}

const setGender = (gender) => {
if (isInfoApproved.value) return showApprovedTip()
form.gender = gender
}

const openRegionPicker = () => {
if (isInfoApproved.value) return showApprovedTip()
showRegionPicker.value = true
}

const openHospitalPicker = () => {
if (isInfoApproved.value) return showApprovedTip()
if (!hospitalTree.value.length) {
uni.showToast({ title: '医院列表加载中,请稍候', icon: 'none' })
loadHospitalTree()
@@ -223,6 +230,7 @@ const openHospitalPicker = () => {
}

const onHospitalConfirm = (data) => {
if (isInfoApproved.value) return
form.hospital = data.hospitalName || ''
form.hospital_province_code = data.province_code || ''
form.hospital_city_code = data.city_code || ''
@@ -349,11 +357,18 @@ const onSignResult = (data) => {

onLoad(async () => {
uni.$on('signResult', onSignResult)
await loadRegions()
await loadInfo()
loadSubscribeConfig()
loadTagOptions()
loadHospitalTree()
pageLoading.value = true
try {
await loadRegions()
await Promise.all([
loadInfo(),
loadSubscribeConfig(),
loadTagOptions(),
loadHospitalTree()
])
} finally {
pageLoading.value = false
}
})

onBeforeUnmount(() => {
@@ -361,6 +376,7 @@ onBeforeUnmount(() => {
})

const goSign = (type) => {
if (isInfoApproved.value) return showApprovedTip()
let url = `/pages/sign/sign?type=${type}`
if (type === 'income') {
const amt = form.income_amount || signExtra.income_amount || ''
@@ -419,6 +435,10 @@ const onRegionChange = (e) => {
}

const onRegionConfirm = (e) => {
if (isInfoApproved.value) {
showRegionPicker.value = false
return
}
const idxs = e.indexs || e.index || [0, 0, 0]
const provinces = allRegions.value
const prov = provinces[idxs[0]]
@@ -489,6 +509,7 @@ const loadHospitalTree = async () => {
}

const chooseDocument = () => {
if (isInfoApproved.value) return showApprovedTip()
uni.chooseImage({
count: 9 - form.documents.length,
sizeType: ['compressed'],
@@ -515,6 +536,7 @@ const openNotice = () => {
}

const handleSubmit = async () => {
if (isInfoApproved.value) return showApprovedTip()
if (!agreed.value) {
return uni.showToast({ title: '请阅读并同意《患者告知书》', icon: 'none' })
}
@@ -556,16 +578,11 @@ const handleSubmit = async () => {
if (!signedPromise.value) {
return uni.showToast({ title: '请签署声明与承诺', icon: 'none' })
}
// 已通过状态需要二次确认
if (info.value.status === 1) {
showConfirmPopup.value = true
return
}
await doSubmit()
}

const doSubmit = async () => {
showConfirmPopup.value = false
if (isInfoApproved.value) return showApprovedTip()
// 先请求订阅消息授权(用户拒绝也继续提交)
await requestSubscribe()
submitting.value = true
@@ -715,6 +732,11 @@ const doSubmit = async () => {
color: #0e63e3;
background: rgba(14, 99, 227, 0.05);
}

&.disabled {
color: #909399;
background: #f5f7fa;
}
}

.region-row {
@@ -724,6 +746,10 @@ const doSubmit = async () => {
padding: 20rpx 24rpx;
border: 1rpx solid #ddd;
border-radius: 8rpx;

&.disabled {
background: #f5f7fa;
}
}

.region-text {


+ 27
- 12
pages/sample-info/sample-info.vue Vedi File

@@ -1,5 +1,6 @@
<template>
<view class="page">
<u-loading-page :loading="pageLoading" loading-text="加载中..." />
<!-- 患者基本信息(只读) -->
<view class="section">
<view class="section-title">
@@ -141,13 +142,14 @@
</view>

<!-- 修改申请弹窗 -->
<u-popup :show="applyEditVisible" mode="center" round="12" :safeAreaInsetBottom="false" @close="applyEditVisible = false">
<u-popup :show="applyEditVisible" mode="bottom" round="12" :safeAreaInsetBottom="true" @close="closeApplyEditDialog">
<view class="apply-popup">
<view class="apply-title">申请修改送检信息</view>
<view class="apply-desc">请填写需要修改送检信息的原因,平台审核通过后即可重新编辑。</view>
<textarea v-model="applyEditReason" class="apply-textarea" maxlength="500" placeholder="请输入申请原因" />
<textarea v-model="applyEditReason" class="apply-textarea" maxlength="500" placeholder="请输入申请原因"
:adjust-position="true" :cursor-spacing="40" />
<view class="apply-actions">
<u-button text="取消" @click="applyEditVisible = false" plain color="#909399" />
<u-button text="取消" @click="closeApplyEditDialog" plain color="#909399" />
<u-button text="提交申请" :loading="applyEditSubmitting" @click="submitApplyEdit" color="#0E63E3" />
</view>
</view>
@@ -179,6 +181,7 @@ const form = reactive({
sample_photos: []
})
const submitting = ref(false)
const pageLoading = ref(true)
const agreed = ref(false)
const sampleTypeList = ref([])
const sampleRequired = ref(false)
@@ -189,6 +192,7 @@ const returnTime = ref('')
const sampleEditReason = ref('')
const sampleEditRejectReason = ref('')
const sampleEditApplyTime = ref('')
const pendingLockedTip = ref(false)
const applyEditVisible = ref(false)
const applyEditReason = ref('')
const applyEditSubmitting = ref(false)
@@ -310,10 +314,19 @@ const openRegionPicker = () => {
}

onLoad(async () => {
await loadRegions()
await loadPatientInfo()
await loadSampleTypes()
await loadSubscribeConfig()
pageLoading.value = true
try {
await loadRegions()
await loadPatientInfo()
await loadSampleTypes()
await loadSubscribeConfig()
} finally {
pageLoading.value = false
if (pendingLockedTip.value) {
pendingLockedTip.value = false
setTimeout(() => showLockedTip(), 100)
}
}
})

const loadSubscribeConfig = async () => {
@@ -365,9 +378,7 @@ const loadPatientInfo = async () => {
sampleEditRejectReason.value = res.data.sample_edit_reject_reason || ''
sampleEditApplyTime.value = res.data.sample_edit_apply_time || ''
sampleReceiverInfo.value = res.data.sample_receiver_info || { address: '', receiver: '', phone: '', contact_phone: '' }
if ((sampleInfoStatus.value === 1 && !sampleEditRejectReason.value) || sampleInfoStatus.value === 3) {
setTimeout(() => showLockedTip(), 300)
}
pendingLockedTip.value = (sampleInfoStatus.value === 1 && !sampleEditRejectReason.value) || sampleInfoStatus.value === 3
}
} catch (e) {}
}
@@ -506,6 +517,10 @@ const showApplyEditDialog = () => {
applyEditVisible.value = true
}

const closeApplyEditDialog = () => {
applyEditVisible.value = false
}

const submitApplyEdit = async () => {
if (!applyEditReason.value.trim()) {
return uni.showToast({ title: '请填写申请原因', icon: 'none' })
@@ -639,9 +654,9 @@ const handleSubmit = async () => {
.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; }
.apply-popup { width: 620rpx; background: #fff; border-radius: 16rpx; padding: 32rpx; }
.apply-popup { width: 100%; box-sizing: border-box; background: #fff; border-radius: 24rpx 24rpx 0 0; padding: 36rpx 32rpx 24rpx; }
.apply-title { font-size: 32rpx; font-weight: 600; color: #303133; margin-bottom: 12rpx; }
.apply-desc { font-size: 26rpx; color: #606266; line-height: 1.6; margin-bottom: 20rpx; }
.apply-textarea { width: 100%; height: 180rpx; box-sizing: border-box; border: 1rpx solid #dcdfe6; border-radius: 8rpx; padding: 20rpx; font-size: 28rpx; color: #303133; background: #fff; }
.apply-textarea { width: 100%; height: 150rpx; box-sizing: border-box; border: 1rpx solid #dcdfe6; border-radius: 8rpx; padding: 20rpx; font-size: 28rpx; color: #303133; background: #fff; }
.apply-actions { display: flex; gap: 20rpx; margin-top: 24rpx; }
</style>

Caricamento…
Annulla
Salva