|
- <template>
- <view class="page">
- <u-loading-page :loading="pageLoading" loading-text="加载中..." />
- <!-- 患者基本信息(只读) -->
- <view class="section">
- <view class="section-title">
- <u-icon name="account-fill" size="18" color="#0e63e3" />
- <text>基本信息</text>
- </view>
- <view class="info-compact">
- <view class="info-compact-row">
- <text class="info-compact-item">姓名:{{ patient.name }}</text>
- <text class="info-compact-item">性别:{{ patient.gender }}</text>
- </view>
- <view class="info-compact-row">
- <text class="info-compact-item">身份证:{{ maskedIdCard }}</text>
- <text class="info-compact-item">手机号:{{ maskedPhone }}</text>
- </view>
- <view class="info-compact-row">
- <text class="info-compact-item">联系地址:{{ patient.region_text }} {{ patient.address }}</text>
- </view>
- <view class="info-compact-row">
- <text class="info-compact-item">医院:{{ patient.hospital || '—' }}</text>
- <text class="info-compact-item">癌种:{{ patient.tag || '—' }}</text>
- </view>
- </view>
- </view>
-
- <!-- 平台收件信息 -->
- <view class="section">
- <view class="section-title">
- <u-icon name="order" size="18" color="#0e63e3" />
- <text>平台收件信息</text>
- </view>
- <view class="receiver-info">
- <view class="receiver-row">
- <text class="receiver-label">收件地址</text>
- <text class="receiver-value">{{ sampleReceiverInfo.address || '—' }}</text>
- </view>
- <view class="receiver-row">
- <text class="receiver-label">收件人</text>
- <text class="receiver-value">{{ sampleReceiverInfo.receiver || '—' }}</text>
- </view>
- <view class="receiver-row">
- <text class="receiver-label">电话</text>
- <text class="receiver-value">{{ sampleReceiverInfo.phone || '—' }}</text>
- </view>
- </view>
- <view class="copy-receiver" @tap="copySampleReceiverInfo">复制送检信息</view>
- </view>
-
- <!-- 送检信息 -->
- <view class="section">
- <view class="section-title">
- <u-icon name="file-text" size="18" color="#fa541c" />
- <text>送检信息</text>
- <text v-if="sampleInfoStatusText" class="status-pill" :class="sampleInfoStatusClass">{{ sampleInfoStatusText }}</text>
- </view>
- <view v-if="isSampleReturned" class="return-info">
- <text class="return-title">样品已经寄回</text>
- <text class="return-text">回寄物流单号:{{ returnTrackingNo || '—' }}</text>
- <text v-if="returnTime" class="return-time">回寄时间:{{ returnTime }}</text>
- <text class="copy-return-no" @tap="copyReturnTrackingNo">复制单号</text>
- </view>
- <view v-if="sampleEditRejectReason" class="reject-info">
- <text class="reject-title">修改申请未通过</text>
- <text class="reject-text">原因:{{ sampleEditRejectReason }}</text>
- </view>
- <view class="form-group">
- <text class="form-label">送检样本类型{{ sampleRequired ? '' : '(选填)' }}</text>
- <u-checkbox-group v-model="form.sample_types" placement="row" :wrap="true" @change="onSampleTypesChange">
- <u-checkbox v-for="st in sampleTypeList" :key="st.id" :label="st.name" :name="st.name"
- :disabled="isSampleInfoLocked" activeColor="#0E63E3" :customStyle="{ marginRight: '24rpx', marginBottom: '16rpx' }" />
- </u-checkbox-group>
- </view>
- <view class="form-group" v-if="showWaxReturn">
- <text class="form-label">{{ needReturnNames }}是否需寄回</text>
- <u-radio-group v-model="form.wax_return" placement="row">
- <u-radio label="是" :name="1" :disabled="isSampleInfoLocked" activeColor="#0E63E3" :customStyle="{ marginRight: '40rpx' }" />
- <u-radio label="否" :name="0" :disabled="isSampleInfoLocked" activeColor="#0E63E3" />
- </u-radio-group>
- </view>
- <template v-if="form.wax_return === 1 && showWaxReturn">
- <view class="form-group">
- <view style="display:flex;align-items:center;justify-content:space-between;">
- <text class="form-label" style="margin-bottom:0;">收件人姓名</text>
- <text :class="['fill-self-btn', isSampleInfoLocked ? 'disabled' : '']" @tap="fillSelfReturn">本人接收</text>
- </view>
- <u-input v-model="form.return_name" :disabled="isSampleInfoLocked" placeholder="请输入收件人姓名" border="surround" :customStyle="{ marginTop: '16rpx' }" />
- </view>
- <view class="form-group">
- <text class="form-label">收件人电话</text>
- <u-input v-model="form.return_phone" :disabled="isSampleInfoLocked" type="number" placeholder="请输入收件人电话" border="surround" maxlength="11" />
- </view>
- <view class="form-group">
- <text class="form-label">收件地址</text>
- <view :class="['region-row', isSampleInfoLocked ? 'disabled' : '']" @tap="openRegionPicker">
- <text :class="['region-text', returnRegionText ? '' : 'placeholder']">{{ returnRegionText || '请选择省/市/区' }}</text>
- <text class="arrow">›</text>
- </view>
- <u-input v-model="form.return_address" :disabled="isSampleInfoLocked" placeholder="详细门牌号" border="surround"
- :customStyle="{ marginTop: '16rpx' }" />
- </view>
- </template>
- <template v-if="(form.sample_types && form.sample_types.length) || sampleRequired">
- <view class="form-group">
- <text class="form-label">报告接收邮箱</text>
- <u-input v-model="form.report_email" :disabled="isSampleInfoLocked" placeholder="请输入邮箱地址" border="surround" />
- </view>
- <view class="form-group">
- <text class="form-label">送检样本物流单号</text>
- <u-input v-model="form.sample_tracking_no" :disabled="isSampleInfoLocked" placeholder="请输入物流单号" border="surround" />
- </view>
- <view class="form-group">
- <text class="form-label">送检单照片(可上传多张)</text>
- <view class="upload-row">
- <view class="upload-item" v-for="(photo, idx) in form.sample_photos" :key="'sp'+idx">
- <image class="upload-img" :src="photo" mode="aspectFill" @tap="previewSamplePhoto(idx)" />
- <view v-if="!isSampleInfoLocked" class="upload-del" @tap="form.sample_photos.splice(idx, 1)">×</view>
- </view>
- <view v-if="!isSampleInfoLocked" class="upload-box" @tap="chooseSamplePhoto">
- <text class="upload-icon">+</text>
- <text class="upload-text">上传图片</text>
- </view>
- </view>
- </view>
- </template>
- </view>
-
- <!-- 提交按钮 -->
- <view class="btn-wrap">
- <view class="agree-row" @tap="toggleAgree">
- <view :class="['agree-checkbox', agreed ? 'checked' : '', isSampleInfoLocked ? 'disabled' : '']">
- <text v-if="agreed" class="agree-check-icon">✓</text>
- </view>
- <text class="agree-text">请阅读并同意</text>
- <text class="agree-link" @tap.stop="openNotice">《患者告知书》</text>
- </view>
- <u-button v-if="canApplySampleEdit" text="申请修改送检信息" :loading="applyEditSubmitting" @click="showApplyEditDialog"
- color="#0E63E3" plain size="large" />
- <u-button v-if="!canApplySampleEdit" :text="submitButtonText" :loading="submitting" @click="handleSubmit" color="#0E63E3" size="large" />
- </view>
-
- <!-- 修改申请弹窗 -->
- <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="请输入申请原因"
- :adjust-position="true" :cursor-spacing="40" />
- <view class="apply-actions">
- <u-button text="取消" @click="closeApplyEditDialog" plain color="#909399" />
- <u-button text="提交申请" :loading="applyEditSubmitting" @click="submitApplyEdit" color="#0E63E3" />
- </view>
- </view>
- </u-popup>
-
- <!-- 地区选择器 -->
- <u-picker v-if="regionColumns[0].length" :show="showRegionPicker" :columns="regionColumns" @confirm="onRegionConfirm"
- @cancel="showRegionPicker = false" @change="onRegionChange" :defaultIndex="regionDefaultIndex" />
- </view>
- </template>
-
- <script setup>
- import { ref, reactive, computed } from 'vue'
- import { onLoad } from '@dcloudio/uni-app'
- import { get, post, upload } from '@/utils/request.js'
-
- const patient = ref({})
- const form = reactive({
- 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: []
- })
- const submitting = ref(false)
- const pageLoading = ref(true)
- const agreed = ref(false)
- const sampleTypeList = ref([])
- const sampleRequired = ref(false)
- const sampleReceiverInfo = ref({ address: '', receiver: '', phone: '', contact_phone: '' })
- const sampleInfoStatus = ref(0)
- const returnTrackingNo = ref('')
- 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)
- const sampleEditAuditTmplId = ref('')
- const isSampleReturned = computed(() => sampleInfoStatus.value === 2)
- const isSampleEditApplying = computed(() => sampleInfoStatus.value === 3)
- const isSampleInfoLocked = computed(() => sampleInfoStatus.value === 1 || sampleInfoStatus.value === 2 || sampleInfoStatus.value === 3)
- const canApplySampleEdit = computed(() => sampleInfoStatus.value === 1)
- const sampleInfoStatusText = computed(() => {
- if (sampleInfoStatus.value === 3) return '申请审核中'
- if (sampleInfoStatus.value === 2) return '已寄回'
- if (sampleInfoStatus.value === 1) return '已生效'
- return ''
- })
- const sampleInfoStatusClass = computed(() => {
- if (sampleInfoStatus.value === 3) return 'applying'
- return sampleInfoStatus.value === 2 ? 'returned' : 'effective'
- })
- const submitButtonText = computed(() => {
- if (sampleInfoStatus.value === 3) return '修改申请审核中'
- if (sampleInfoStatus.value === 2) return '样品已寄回'
- if (sampleInfoStatus.value === 1) return '送检信息已生效'
- return '提交送检信息'
- })
-
- // 地区数据
- const allRegions = ref([])
- const regionColumns = ref([[], [], []])
- const regionDefaultIndex = ref([0, 0, 0])
- const showRegionPicker = ref(false)
-
- const maskedIdCard = computed(() => {
- const v = patient.value.id_card || ''
- if (v.length === 18) return v.slice(0, 3) + '****' + v.slice(-4)
- return v
- })
-
- const maskedPhone = computed(() => {
- const v = patient.value.phone || ''
- if (v.length === 11) return v.slice(0, 3) + '****' + v.slice(-4)
- return v
- })
-
- 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 = () => {
- if (isSampleInfoLocked.value) return
- if (!showWaxReturn.value) {
- form.wax_return = 0
- }
- if (!form.sample_types || form.sample_types.length === 0) {
- form.report_email = ''
- form.sample_tracking_no = ''
- form.sample_photos = []
- form.wax_return = 0
- form.return_name = ''
- form.return_phone = ''
- form.return_province_code = ''
- form.return_city_code = ''
- form.return_district_code = ''
- form.return_address = ''
- }
- }
-
- const fillSelfReturn = () => {
- if (isSampleInfoLocked.value) return showLockedTip()
- form.return_name = patient.value.name || ''
- form.return_phone = patient.value.phone || ''
- form.return_province_code = patient.value.province_code || ''
- form.return_city_code = patient.value.city_code || ''
- form.return_district_code = patient.value.district_code || ''
- form.return_address = patient.value.address || ''
- }
-
- const openRegionPicker = () => {
- if (isSampleInfoLocked.value) return showLockedTip()
- showRegionPicker.value = true
- }
-
- onLoad(async () => {
- 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 () => {
- try {
- const res = await get('/api/mp/subscribeConfig')
- if (res.data && res.data.sample_edit_audit) {
- sampleEditAuditTmplId.value = res.data.sample_edit_audit
- }
- } catch (e) {}
- }
-
- const requestSampleEditSubscribe = () => {
- return new Promise((resolve) => {
- if (!sampleEditAuditTmplId.value) return resolve(false)
- // #ifdef MP-WEIXIN
- wx.requestSubscribeMessage({
- tmplIds: [sampleEditAuditTmplId.value],
- success: () => resolve(true),
- fail: () => resolve(false)
- })
- // #endif
- // #ifndef MP-WEIXIN
- resolve(false)
- // #endif
- })
- }
-
- const loadPatientInfo = async () => {
- try {
- const res = await get('/api/mp/sampleInfo')
- if (res.data) {
- patient.value = res.data.patient || {}
- // 回显送检信息
- 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 || []
- sampleInfoStatus.value = Number(res.data.sample_info_status) || 0
- returnTrackingNo.value = res.data.return_tracking_no || ''
- returnTime.value = res.data.return_time || ''
- sampleEditReason.value = res.data.sample_edit_reason || ''
- 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: '' }
- pendingLockedTip.value = (sampleInfoStatus.value === 1 && !sampleEditRejectReason.value) || sampleInfoStatus.value === 3
- }
- } 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 loadRegions = async () => {
- try {
- const res = await get('/common/regions')
- allRegions.value = res.data || []
- buildRegionColumns()
- } catch (e) {}
- }
-
- const buildRegionColumns = (pIdx = 0, cIdx = 0) => {
- const provinces = allRegions.value
- const col0 = provinces.map(p => p.name)
- const cities = (provinces[pIdx] && provinces[pIdx].children) || []
- const col1 = cities.map(c => c.name)
- const districts = (cities[cIdx] && cities[cIdx].children) || []
- const col2 = districts.map(d => d.name)
- regionColumns.value = [col0, col1, col2]
- }
-
- const onRegionChange = (e) => {
- const { columnIndex, index } = e
- if (columnIndex === 0) {
- buildRegionColumns(index, 0)
- regionDefaultIndex.value = [index, 0, 0]
- } else if (columnIndex === 1) {
- const pIdx = regionDefaultIndex.value[0]
- buildRegionColumns(pIdx, index)
- regionDefaultIndex.value = [pIdx, index, 0]
- }
- }
-
- const onRegionConfirm = (e) => {
- if (isSampleInfoLocked.value) return
- 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 : ''
- showRegionPicker.value = false
- }
-
- const chooseSamplePhoto = () => {
- if (isSampleInfoLocked.value) return showLockedTip()
- 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 openNotice = () => {
- uni.navigateTo({ url: '/pages/content/content?key=patient_information_sheet' })
- }
-
- const getContactPhone = () => sampleReceiverInfo.value.contact_phone || ''
- const getCleanPhone = () => getContactPhone().replace(/[^\d+]/g, '')
-
- const contactPlatform = () => {
- const phone = getContactPhone()
- if (!phone) return uni.showToast({ title: '暂无联系电话', icon: 'none' })
- // #ifdef H5
- uni.setClipboardData({
- data: phone,
- success: () => uni.showToast({ title: '电话已复制', icon: 'success' })
- })
- // #endif
- // #ifndef H5
- uni.makePhoneCall({ phoneNumber: getCleanPhone() })
- // #endif
- }
-
- const showLockedTip = () => {
- if (isSampleEditApplying.value) {
- uni.showModal({
- title: '温馨提示',
- content: '送检信息修改申请正在审核中,请等待平台处理。',
- showCancel: false,
- confirmText: '知道了'
- })
- return
- }
- if (isSampleReturned.value) {
- uni.showModal({
- title: '温馨提示',
- content: `样品已经寄回,回寄物流单号:${returnTrackingNo.value || '—'}。`,
- cancelText: '知道了',
- confirmText: '复制单号',
- success: (res) => {
- if (res.confirm) copyReturnTrackingNo()
- }
- })
- return
- }
- const phone = getContactPhone()
- let content = '送检信息已生效,如需修改请点击页面的【申请修改送检信息】按钮申请,通过后可重新提交送检信息。'
- if (phone) content += `详情咨询${phone}。`
- uni.showModal({
- title: '温馨提示',
- content,
- showCancel: false,
- confirmText: '知道了'
- })
- }
-
- const showApplyEditDialog = () => {
- if (!canApplySampleEdit.value) return showLockedTip()
- applyEditReason.value = ''
- applyEditVisible.value = true
- }
-
- const closeApplyEditDialog = () => {
- applyEditVisible.value = false
- }
-
- const submitApplyEdit = async () => {
- if (!applyEditReason.value.trim()) {
- return uni.showToast({ title: '请填写申请原因', icon: 'none' })
- }
- applyEditSubmitting.value = true
- try {
- await requestSampleEditSubscribe()
- const params = { reason: applyEditReason.value.trim() }
- // #ifdef MP-WEIXIN
- params.mp_env_version = uni.getAccountInfoSync().miniProgram.envVersion || 'release'
- // #endif
- await post('/api/mp/applySampleInfoEdit', params)
- sampleInfoStatus.value = 3
- sampleEditReason.value = applyEditReason.value.trim()
- sampleEditApplyTime.value = ''
- applyEditVisible.value = false
- uni.showToast({ title: '申请已提交', icon: 'success' })
- } catch (e) {
- if (e && e.msg) uni.showToast({ title: e.msg, icon: 'none' })
- } finally {
- applyEditSubmitting.value = false
- }
- }
-
- const copyReturnTrackingNo = () => {
- if (!returnTrackingNo.value) return uni.showToast({ title: '暂无单号', icon: 'none' })
- uni.setClipboardData({
- data: returnTrackingNo.value,
- success: () => uni.showToast({ title: '单号已复制', icon: 'success' })
- })
- }
-
- const copySampleReceiverInfo = () => {
- const info = sampleReceiverInfo.value
- const text = [
- `收件地址:${info.address || ''}`,
- `收件人:${info.receiver || ''}`,
- `电话:${info.phone || ''}`
- ].join('\n')
- uni.setClipboardData({
- data: text,
- success: () => uni.showToast({ title: '已复制', icon: 'success' })
- })
- }
-
- const toggleAgree = () => {
- if (isSampleInfoLocked.value) return showLockedTip()
- agreed.value = !agreed.value
- }
-
- const handleSubmit = async () => {
- if (isSampleInfoLocked.value) {
- return showLockedTip()
- }
- if (!agreed.value) {
- 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 (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(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' })
- }
- submitting.value = true
- try {
- await post('/api/mp/saveSampleInfo', { ...form })
- sampleInfoStatus.value = 1
- uni.showToast({ title: '提交成功', icon: 'success' })
- setTimeout(() => uni.navigateBack(), 1500)
- } catch (e) {
- if (e && e.data && [1, 2, 3].includes(Number(e.data.sample_info_status))) {
- sampleInfoStatus.value = Number(e.data.sample_info_status)
- returnTrackingNo.value = e.data.return_tracking_no || returnTrackingNo.value
- returnTime.value = e.data.return_time || returnTime.value
- sampleEditReason.value = e.data.sample_edit_reason || sampleEditReason.value
- sampleEditApplyTime.value = e.data.sample_edit_apply_time || sampleEditApplyTime.value
- if (e.data.sample_receiver_info) sampleReceiverInfo.value = e.data.sample_receiver_info
- return showLockedTip()
- }
- if (e && e.msg) uni.showToast({ title: e.msg, icon: 'none' })
- } finally {
- submitting.value = false
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .page { min-height: 100vh; background: #f4f4f5; padding: 24rpx; padding-bottom: 260rpx; }
- .section { background: #fff; border-radius: 10rpx; padding: 32rpx; margin-bottom: 24rpx; border: 1rpx solid #ebeef5; }
- .section-title { display: flex; align-items: center; gap: 12rpx; font-size: 32rpx; font-weight: 600; color: #333; margin-bottom: 28rpx; }
- .status-pill { margin-left: auto; font-size: 22rpx; font-weight: 500; padding: 4rpx 14rpx; border-radius: 6rpx; &.effective { color: #52c41a; background: #f6ffed; border: 1rpx solid #b7eb8f; } &.returned { color: #0e63e3; background: #f0f5ff; border: 1rpx solid #adc6ff; } &.applying { color: #d46b08; background: #fff7e6; border: 1rpx solid #ffd591; } }
- .info-compact { padding-bottom: 8rpx; }
- .info-compact-row { display: flex; gap: 32rpx; margin-bottom: 12rpx; &:last-child { margin-bottom: 0; } }
- .info-compact-item { font-size: 26rpx; color: #666; }
- .return-info { background: #f0f5ff; border-left: 6rpx solid #0e63e3; border-radius: 8rpx; padding: 24rpx; margin-bottom: 20rpx; }
- .return-title { display: block; font-size: 30rpx; font-weight: 600; color: #303133; margin-bottom: 12rpx; }
- .return-text { display: block; font-size: 28rpx; color: #0e63e3; font-weight: 600; line-height: 1.5; }
- .return-time { display: block; font-size: 24rpx; color: #909399; margin-top: 8rpx; }
- .copy-return-no { display: block; text-align: right; font-size: 26rpx; color: #0e63e3; margin-top: 12rpx; }
- .reject-info { background: #fff2f0; border-left: 6rpx solid #ff4d4f; border-radius: 8rpx; padding: 24rpx; margin-bottom: 20rpx; }
- .reject-title { display: block; font-size: 28rpx; font-weight: 600; color: #a8071a; margin-bottom: 10rpx; }
- .reject-text { display: block; font-size: 26rpx; color: #606266; line-height: 1.6; }
- .receiver-info { padding-bottom: 8rpx; }
- .receiver-row { display: flex; gap: 20rpx; margin-bottom: 14rpx; &:last-child { margin-bottom: 0; } }
- .receiver-label { width: 120rpx; flex-shrink: 0; font-size: 26rpx; color: #909399; }
- .receiver-value { flex: 1; font-size: 26rpx; color: #303133; line-height: 1.6; }
- .copy-receiver { margin-top: 20rpx; color: #0e63e3; font-size: 26rpx; text-align: right; }
- .form-group { padding: 20rpx 0; border-bottom: 1rpx solid #f0f0f0; &:last-child { border-bottom: none; } }
- .form-label { font-size: 28rpx; color: #555; margin-bottom: 16rpx; display: block; }
- .region-row { display: flex; align-items: center; justify-content: space-between; padding: 20rpx 24rpx; border: 1rpx solid #ddd; border-radius: 8rpx; &.disabled { background: #f7f8fa; } }
- .region-text { font-size: 28rpx; color: #333; &.placeholder { color: #c0c4cc; } }
- .arrow { font-size: 28rpx; color: #c0c4cc; }
- .fill-self-btn { font-size: 24rpx; color: #0e63e3; padding: 6rpx 16rpx; border: 1rpx solid #d0e0ff; border-radius: 20rpx; background: #f0f5ff; &.disabled { color: #c0c4cc; border-color: #e4e7ed; background: #f7f8fa; } }
- .upload-row { display: flex; gap: 16rpx; flex-wrap: wrap; }
- .upload-item { position: relative; width: 180rpx; height: 180rpx; }
- .upload-img { width: 180rpx; height: 180rpx; border-radius: 8rpx; border: 1rpx solid #eee; }
- .upload-del { position: absolute; top: -10rpx; right: -10rpx; width: 40rpx; height: 40rpx; background: rgba(0,0,0,0.5); color: #fff; border-radius: 50%; font-size: 24rpx; display: flex; align-items: center; justify-content: center; }
- .upload-box { width: 180rpx; height: 180rpx; border: 2rpx dashed #ccc; border-radius: 8rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; background: #fafafa; }
- .upload-icon { font-size: 56rpx; color: #ccc; }
- .upload-text { font-size: 22rpx; color: #999; margin-top: 4rpx; }
- .btn-wrap { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; padding: 20rpx 32rpx; padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); box-shadow: 0 -4rpx 16rpx rgba(0,0,0,0.06); z-index: 100; }
- .agree-row { display: flex; align-items: center; margin-bottom: 16rpx; padding-left: 4rpx; }
- .agree-checkbox { width: 36rpx; height: 36rpx; border: 2rpx solid #dcdfe6; border-radius: 50%; box-sizing: border-box; display: flex; align-items: center; justify-content: center; flex-shrink: 0; background: #fff; }
- .agree-checkbox.checked { border-color: #0e63e3; background: #0e63e3; }
- .agree-checkbox.disabled { border-color: #dcdfe6; background: #f5f7fa; }
- .agree-checkbox.checked.disabled { border-color: #c0c4cc; background: #c0c4cc; }
- .agree-check-icon { font-size: 24rpx; line-height: 1; color: #fff; font-weight: 600; }
- .agree-text { font-size: 24rpx; color: #666; margin-left: 8rpx; }
- .agree-link { font-size: 24rpx; color: #0e63e3; }
- .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: 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>
|