feat: 地址选择改走地区选择器接口
编辑地址用 page-container 抽屉 + regionPicker children/search,提交仍传省市区中文名。
This commit is contained in:
25
App.vue
25
App.vue
@@ -168,6 +168,8 @@
|
||||
this.parseClaimPatientScene(rawScene)
|
||||
// 医生代支付:ppay={order_id}
|
||||
this.parseProxyPayScene(rawScene)
|
||||
// 挂号凭证:rid={register_id}(打印小程序码扫码进凭证页)
|
||||
this.parseRegisterVoucherScene(rawScene)
|
||||
|
||||
// 判断scene中是否包含sal_id
|
||||
let isSalespersonId = rawScene.includes('sal_id');
|
||||
@@ -236,7 +238,18 @@
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 登录后:弹出认领模态 / 代付确认模态(不再直接跳转代付页)
|
||||
* 解析挂号凭证 scene:rid=挂号单ID
|
||||
* 写入待跳转 ID,登录后由 tryHandlePendingSceneActions 进入凭证页
|
||||
*/
|
||||
parseRegisterVoucherScene(rawScene) {
|
||||
const match = String(rawScene).match(/(?:^|&)rid=(\d+)/)
|
||||
const registerId = Number((match && match[1]) || 0)
|
||||
if (registerId > 0) {
|
||||
uni.setStorageSync('pending_register_voucher_id', registerId)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 登录后:弹出认领模态 / 代付确认模态 / 跳转挂号凭证页
|
||||
*/
|
||||
tryHandlePendingSceneActions() {
|
||||
const token = uni.getStorageSync('token')
|
||||
@@ -256,6 +269,16 @@
|
||||
uni.$emit('open-proxy-pay-confirm-modal')
|
||||
}, 500)
|
||||
}
|
||||
// 挂号凭证扫码:登录后跳转一次并清掉 pending,避免反复 navigate
|
||||
const voucherId = Number(uni.getStorageSync('pending_register_voucher_id') || 0)
|
||||
if (voucherId > 0) {
|
||||
uni.removeStorageSync('pending_register_voucher_id')
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({
|
||||
url: '/subPackages/register/register-voucher?id=' + voucherId,
|
||||
})
|
||||
}, 600)
|
||||
}
|
||||
},
|
||||
initWebSocket() {
|
||||
webSocketManager.connect();
|
||||
|
||||
@@ -409,6 +409,13 @@
|
||||
"navigationBarTitleText": "挂号详情",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "register/register-voucher",
|
||||
"style": {
|
||||
"navigationBarTitleText": "挂号凭证",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
:key="item.key"
|
||||
class="order-remind-card"
|
||||
:class="{
|
||||
'order-remind-card--register': item.key === 'unpaid_register',
|
||||
'order-remind-card--register': item.key === 'unpaid_register' || item.key === 'queue_register',
|
||||
'order-remind-card--product': item.key === 'unpaid_product',
|
||||
'order-remind-card--shipped': item.key === 'shipped',
|
||||
'order-remind-card--arrived': item.key === 'arrived'
|
||||
@@ -155,7 +155,7 @@
|
||||
<view
|
||||
class="zone-icon-box order-remind-zone-icon"
|
||||
:class="{
|
||||
'order-remind-zone-icon--register': item.key === 'unpaid_register',
|
||||
'order-remind-zone-icon--register': item.key === 'unpaid_register' || item.key === 'queue_register',
|
||||
'order-remind-zone-icon--product': item.key === 'unpaid_product',
|
||||
'order-remind-zone-icon--shipped': item.key === 'shipped',
|
||||
'order-remind-zone-icon--arrived': item.key === 'arrived'
|
||||
@@ -397,6 +397,8 @@ import {silentLogin} from "@/utils/login";
|
||||
/** 待办入口默认图:后台未上传时用本地精致矢量透明 PNG */
|
||||
const REMIND_FALLBACK_ICON = {
|
||||
unpaid_register: '/static/home/remind/unpaid_register.png',
|
||||
// 排队中挂号未单独配图时复用待支付挂号图
|
||||
queue_register: '/static/home/remind/unpaid_register.png',
|
||||
unpaid_product: '/static/home/remind/unpaid_product.png',
|
||||
shipped: '/static/home/remind/shipped.png',
|
||||
arrived: '/static/home/remind/arrived.png',
|
||||
@@ -473,9 +475,14 @@ export default {
|
||||
isGuestMode() {
|
||||
return isGuestMode;
|
||||
},
|
||||
// 只展示有数量的订单提醒,避免空宫格占位
|
||||
// 只展示有数量的订单提醒;排队中挂号仅诊所态(storeType=0)展示
|
||||
visibleOrderReminds() {
|
||||
return (this.orderRemindItems || []).filter((item) => item && item.count > 0);
|
||||
const isClinic = this.storeType === '0' || this.storeType === 0;
|
||||
return (this.orderRemindItems || []).filter((item) => {
|
||||
if (!item || !(item.count > 0)) return false;
|
||||
if (item.key === 'queue_register' && !isClinic) return false;
|
||||
return true;
|
||||
});
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
@@ -609,6 +616,19 @@ export default {
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 排队中挂号:单条进凭证页,多条进预约列表
|
||||
if (item.key === 'queue_register') {
|
||||
if (count === 1 && firstId > 0) {
|
||||
uni.navigateTo({
|
||||
url: '/subPackages/register/register-voucher?id=' + firstId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: '/subPackages/my/myappiont',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (count === 1 && firstId > 0) {
|
||||
uni.navigateTo({
|
||||
url: `/subPackages/my/my-drug/drug-info?id=${firstId}`,
|
||||
|
||||
@@ -122,3 +122,12 @@ export async function registerReschedule(params = {}) {
|
||||
export async function registerRescheduleLogs(params = {}) {
|
||||
return await post('/register/reschedule-logs', params, 3)
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂号凭证详情(排队人数 + 预估等待)xk-api POST /register/voucher-detail
|
||||
* 取值:unwrapXkApi → code / result / message
|
||||
* @param {{ register_id: number }} params
|
||||
*/
|
||||
export async function getRegisterVoucherDetailApi(params = {}) {
|
||||
return await post('/register/voucher-detail', params, 3)
|
||||
}
|
||||
|
||||
@@ -174,6 +174,10 @@
|
||||
<view class="isbtn" @click="openReschedule" v-if="canReschedule">
|
||||
修改时间
|
||||
</view>
|
||||
<!-- 已支付未取消:进入挂号凭证(排队人数/预估等待,与扫码页同一路由) -->
|
||||
<view class="isbtn" @click="goVoucher" v-if="canViewVoucher">
|
||||
查看挂号凭证
|
||||
</view>
|
||||
<view class="btn" @click="goHome" v-if="registList.status>=1">返回首页</view>
|
||||
</view>
|
||||
|
||||
@@ -296,6 +300,16 @@
|
||||
if (r.is_cancel != 0 || r.status != 1 || r.is_pay != 1) return false;
|
||||
return appt.visit_date > this.todayStr;
|
||||
},
|
||||
/**
|
||||
* 是否展示「查看挂号凭证」:已支付且未取消(与纸质凭证扫码同一页)
|
||||
*/
|
||||
canViewVoucher() {
|
||||
const r = this.registList || {};
|
||||
if (!r || !r.id) return false;
|
||||
if (r.is_pay != 1) return false;
|
||||
if (r.is_cancel == 1 || r.status == 4 || r.status == 7) return false;
|
||||
return true;
|
||||
},
|
||||
/** 当前选中的日期对象 */
|
||||
selectedDay() {
|
||||
return this.calendarDays[this.selectedDayIndex] || null;
|
||||
@@ -488,6 +502,19 @@
|
||||
url: '/pages/home/home'
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 跳转挂号凭证页(与打印小程序码扫码落地同一页)
|
||||
*/
|
||||
goVoucher() {
|
||||
const id = this.register_id || (this.registList && this.registList.id)
|
||||
if (!id) {
|
||||
uni.showToast({ title: '缺少挂号单', icon: 'none' })
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: '/subPackages/register/register-voucher?id=' + id,
|
||||
})
|
||||
},
|
||||
|
||||
// 挂号信息(已迁 xk-api POST /register/detail:result 为单对象,老 Yii 是 data.list[0])
|
||||
getInfo() {
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
挂号成功
|
||||
</view>
|
||||
|
||||
<!-- 确认 -->
|
||||
<!-- 确认进详情;查看凭证进排队凭证页 -->
|
||||
<view class="btn">
|
||||
<view class="ghost" @click="goVoucher">
|
||||
查看挂号凭证
|
||||
</view>
|
||||
<view class="back" @click="goOrder">
|
||||
确认
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -48,12 +50,24 @@
|
||||
async bindSpecialPrescriptionRecord() {
|
||||
await tryCreateSpecialPrescriptionPatientRecord(this.register_id)
|
||||
},
|
||||
// 确认
|
||||
// 确认 → 挂号详情
|
||||
goOrder() {
|
||||
uni.navigateTo({
|
||||
url: '/subPackages/register/register-info?id=' + this.register_id,
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 查看挂号凭证(排队人数/预估,与扫码落地同一页)
|
||||
*/
|
||||
goVoucher() {
|
||||
if (!this.register_id) {
|
||||
uni.showToast({ title: '缺少挂号单', icon: 'none' })
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: '/subPackages/register/register-voucher?id=' + this.register_id,
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -90,15 +104,31 @@
|
||||
|
||||
.btn {
|
||||
width: 750rpx;
|
||||
height: 110rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12rpx 32rpx;
|
||||
margin-top: 44rpx;
|
||||
box-sizing: border-box;
|
||||
gap: 24rpx;
|
||||
|
||||
.ghost {
|
||||
flex: 1;
|
||||
height: 86rpx;
|
||||
text-align: center;
|
||||
line-height: 86rpx;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid rgba(65, 117, 238, 0.35);
|
||||
border-radius: 198rpx;
|
||||
font-size: 30rpx;
|
||||
font-family: PingFang SC-Medium, PingFang SC;
|
||||
font-weight: 500;
|
||||
color: #4175EE;
|
||||
box-shadow: 0 0 8rpx rgba(65, 117, 238, 0.12);
|
||||
}
|
||||
|
||||
.back {
|
||||
width: 686rpx;
|
||||
flex: 1;
|
||||
height: 86rpx;
|
||||
text-align: center;
|
||||
line-height: 86rpx;
|
||||
|
||||
546
subPackages/register/register-voucher.vue
Normal file
546
subPackages/register/register-voucher.vue
Normal file
@@ -0,0 +1,546 @@
|
||||
<template>
|
||||
<!-- 挂号凭证页:扫码/详情入口;风格由系统配置 ui_style 控制 -->
|
||||
<view
|
||||
class="voucher-page"
|
||||
:class="{
|
||||
'voucher-page--glass': isGlass,
|
||||
'voucher-page--receipt': !isGlass
|
||||
}"
|
||||
>
|
||||
<ListSkeleton v-if="loading" type="detail" :rows="3" />
|
||||
<block v-else-if="loadError">
|
||||
<view class="voucher-empty">
|
||||
<text class="voucher-empty__text">{{ loadError }}</text>
|
||||
<view class="voucher-empty__btn" @click="onTapRefresh">重新加载</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 模拟小票:版式对齐管理端打印凭证 -->
|
||||
<block v-else-if="!isGlass">
|
||||
<view class="voucher-toolbar">
|
||||
<text class="voucher-toolbar__hint" v-if="showQueue">每 30 秒自动更新排队</text>
|
||||
<text class="voucher-toolbar__hint" v-else> </text>
|
||||
<view
|
||||
class="voucher-toolbar__btn"
|
||||
:class="{ 'voucher-toolbar__btn--busy': refreshing }"
|
||||
@click="onTapRefresh"
|
||||
>
|
||||
{{ refreshing ? '刷新中' : '刷新' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="slip">
|
||||
<view class="slip__clinic">{{ detail.store || '—' }}</view>
|
||||
<view class="slip__title">挂号凭证</view>
|
||||
<view class="slip__orderno">{{ detail.order_no || '—' }}</view>
|
||||
<view class="slip__queue" v-if="showQueue">
|
||||
<text class="slip__queue-label">前面等待 {{ queueAheadText }} 人</text>
|
||||
<text class="slip__queue-eta">{{ detail.eta_display || '—' }}</text>
|
||||
</view>
|
||||
<view class="slip__line">病历号:{{ detail.order_no || '—' }}</view>
|
||||
<view class="slip__line">姓名:{{ patientText }}</view>
|
||||
<view class="slip__line">门诊号:{{ outpatientText }}</view>
|
||||
<view class="slip__line">挂号类型:自费</view>
|
||||
<view class="slip__line">挂号日期:{{ registerDateText }}</view>
|
||||
<view class="slip__line">挂号费:{{ feeText }}</view>
|
||||
<view class="slip__line">科室:{{ detail.depart || '—' }}</view>
|
||||
<view class="slip__line">医生:{{ detail.doctor || '—' }}</view>
|
||||
<view class="slip__line">状态:{{ detail.status_txt || '—' }}</view>
|
||||
<view class="slip__line" v-if="appointmentText">预约:{{ appointmentText }}</view>
|
||||
<view class="slip__dash">--------------------</view>
|
||||
<view class="slip__tip" v-if="showQueue">排队人数为当天同医生、同门店待接诊估算,仅供参考,请以现场叫号为准。</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 液态玻璃:卡片信息布局 -->
|
||||
<block v-else>
|
||||
<view class="voucher-toolbar">
|
||||
<text class="voucher-toolbar__hint" v-if="showQueue">每 30 秒自动更新排队</text>
|
||||
<text class="voucher-toolbar__hint" v-else> </text>
|
||||
<view
|
||||
class="voucher-toolbar__btn voucher-toolbar__btn--glass"
|
||||
:class="{ 'voucher-toolbar__btn--busy': refreshing }"
|
||||
@click="onTapRefresh"
|
||||
>
|
||||
{{ refreshing ? '刷新中' : '刷新' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="voucher-card voucher-card--queue" v-if="showQueue">
|
||||
<view class="voucher-queue__label">前面等待</view>
|
||||
<view class="voucher-queue__num">
|
||||
<text class="voucher-queue__count">{{ queueAheadText }}</text>
|
||||
<text class="voucher-queue__unit">人</text>
|
||||
</view>
|
||||
<view class="voucher-queue__eta">{{ detail.eta_display || '—' }}</view>
|
||||
</view>
|
||||
<view class="voucher-card">
|
||||
<view class="voucher-row">
|
||||
<text class="voucher-row__label">诊所</text>
|
||||
<text class="voucher-row__value">{{ detail.store || '—' }}</text>
|
||||
</view>
|
||||
<view class="voucher-row">
|
||||
<text class="voucher-row__label">医生</text>
|
||||
<text class="voucher-row__value">{{ detail.doctor || '—' }}</text>
|
||||
</view>
|
||||
<view class="voucher-row">
|
||||
<text class="voucher-row__label">科室</text>
|
||||
<text class="voucher-row__value">{{ detail.depart || '—' }}</text>
|
||||
</view>
|
||||
<view class="voucher-row">
|
||||
<text class="voucher-row__label">门诊号</text>
|
||||
<text class="voucher-row__value">{{ outpatientText }}</text>
|
||||
</view>
|
||||
<view class="voucher-row">
|
||||
<text class="voucher-row__label">就诊人</text>
|
||||
<text class="voucher-row__value">{{ patientText }}</text>
|
||||
</view>
|
||||
<view class="voucher-row">
|
||||
<text class="voucher-row__label">状态</text>
|
||||
<text class="voucher-row__value">{{ detail.status_txt || '—' }}</text>
|
||||
</view>
|
||||
<view class="voucher-row" v-if="appointmentText">
|
||||
<text class="voucher-row__label">预约</text>
|
||||
<text class="voucher-row__value">{{ appointmentText }}</text>
|
||||
</view>
|
||||
<view class="voucher-row voucher-row--last">
|
||||
<text class="voucher-row__label">病历号</text>
|
||||
<text class="voucher-row__value">{{ detail.order_no || '—' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="voucher-tip" v-if="showQueue">排队人数为当天同医生、同门店待接诊估算,仅供参考,请以现场叫号为准。</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 挂号凭证(扫码 rid= / register-info 入口)
|
||||
* - 数据:xk-api POST /register/voucher-detail(含排队/预估/ui_style)
|
||||
* - 仅待接诊 show_queue=true 展示预测;接诊/结束/取消不展示
|
||||
* - 刷新:按钮 + 下拉 + 待接诊时 30 秒自动
|
||||
*/
|
||||
import ListSkeleton from '@/subPackages/common/components/ListSkeleton.vue'
|
||||
import { getRegisterVoucherDetailApi } from '@/request/api/register.js'
|
||||
import { unwrapXkApi } from '@/utils/api-response.js'
|
||||
|
||||
const AUTO_REFRESH_MS = 30000
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ListSkeleton,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
registerId: 0,
|
||||
loading: true,
|
||||
refreshing: false,
|
||||
loadError: '',
|
||||
detail: {},
|
||||
autoTimer: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isGlass() {
|
||||
return this.detail && this.detail.ui_style === 'glass'
|
||||
},
|
||||
/** 后端仅待接诊为 true;兼容缺字段时用 status===1 */
|
||||
showQueue() {
|
||||
if (this.detail && this.detail.show_queue === true) return true
|
||||
if (this.detail && this.detail.show_queue === false) return false
|
||||
return Number(this.detail && this.detail.status) === 1
|
||||
},
|
||||
queueAheadText() {
|
||||
const n = Number(this.detail.queue_ahead)
|
||||
if (!Number.isFinite(n) || n < 0) return '—'
|
||||
return String(n)
|
||||
},
|
||||
outpatientText() {
|
||||
const n = this.detail.order_number
|
||||
if (n === undefined || n === null || n === '') return '—'
|
||||
return n + '号'
|
||||
},
|
||||
patientText() {
|
||||
const name = this.detail.patient || ''
|
||||
const mobile = this.detail.mobile_tm || ''
|
||||
if (name && mobile) return name + ' ' + mobile
|
||||
return name || mobile || '—'
|
||||
},
|
||||
feeText() {
|
||||
const n = Number(this.detail.price)
|
||||
return Number.isFinite(n) ? String(n) : '0'
|
||||
},
|
||||
registerDateText() {
|
||||
const raw = this.detail.created_at
|
||||
if (!raw) return '—'
|
||||
const s = String(raw)
|
||||
// 已是 Y-m-d 或带时间的字符串
|
||||
if (s.indexOf('-') >= 0) {
|
||||
return s.replace(/-/g, '/').slice(0, 10)
|
||||
}
|
||||
const ts = Number(raw)
|
||||
if (!Number.isFinite(ts) || ts <= 0) return s
|
||||
const d = new Date(ts * 1000)
|
||||
const m = d.getMonth() + 1
|
||||
const day = d.getDate()
|
||||
return d.getFullYear() + '/' + (m < 10 ? '0' + m : m) + '/' + (day < 10 ? '0' + day : day)
|
||||
},
|
||||
appointmentText() {
|
||||
const appt = this.detail.appointment
|
||||
if (!appt || !appt.visit_date) return ''
|
||||
let text = appt.visit_date + ' ' + (appt.slot_name || '')
|
||||
if (appt.start_time && appt.end_time && !(appt.start_time === '00:00' && appt.end_time === '23:59')) {
|
||||
text += ' ' + appt.start_time + '-' + appt.end_time
|
||||
}
|
||||
return text
|
||||
},
|
||||
},
|
||||
onLoad(e) {
|
||||
this.registerId = Number((e && e.id) || 0)
|
||||
this.loadDetail({ silent: false })
|
||||
},
|
||||
onShow() {
|
||||
this.syncAutoRefresh()
|
||||
},
|
||||
onHide() {
|
||||
this.stopAutoRefresh()
|
||||
},
|
||||
onUnload() {
|
||||
this.stopAutoRefresh()
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
// 下拉自带刷新动画,不再叠 showLoading
|
||||
this.loadDetail({ silent: true }).finally(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
onTapRefresh() {
|
||||
if (this.refreshing || this.loading) return
|
||||
this.loadDetail({ silent: true, toastLoading: true })
|
||||
},
|
||||
/**
|
||||
* 拉取凭证详情
|
||||
* @param {{ silent?: boolean, toastLoading?: boolean }} opts
|
||||
* silent=true 不整页骨架;toastLoading=true 时用 uni.showLoading(定时/按钮刷新)
|
||||
*/
|
||||
async loadDetail(opts) {
|
||||
const silent = !!(opts && opts.silent)
|
||||
const toastLoading = !!(opts && opts.toastLoading)
|
||||
if (!this.registerId) {
|
||||
this.loading = false
|
||||
this.loadError = '缺少挂号单参数'
|
||||
return
|
||||
}
|
||||
if (silent) {
|
||||
if (this.refreshing) return
|
||||
this.refreshing = true
|
||||
if (toastLoading) {
|
||||
uni.showLoading({ title: '更新中', mask: true })
|
||||
}
|
||||
} else {
|
||||
this.loading = true
|
||||
}
|
||||
this.loadError = ''
|
||||
try {
|
||||
const res = await getRegisterVoucherDetailApi({
|
||||
register_id: this.registerId,
|
||||
})
|
||||
const { ok, payload, message } = unwrapXkApi(res)
|
||||
if (!ok) {
|
||||
if (silent) {
|
||||
if (toastLoading) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
uni.showToast({ title: message || '刷新失败', icon: 'none' })
|
||||
} else {
|
||||
this.detail = {}
|
||||
this.loadError = message || '加载失败'
|
||||
}
|
||||
return
|
||||
}
|
||||
this.detail = payload || {}
|
||||
this.loadError = ''
|
||||
this.syncAutoRefresh()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
if (silent) {
|
||||
if (toastLoading) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
uni.showToast({ title: '网络异常', icon: 'none' })
|
||||
} else {
|
||||
this.detail = {}
|
||||
this.loadError = '网络异常,请稍后重试'
|
||||
}
|
||||
} finally {
|
||||
this.loading = false
|
||||
this.refreshing = false
|
||||
if (toastLoading) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
},
|
||||
/** 仅待接诊开启 30s 轮询;其它状态关掉定时器;到期刷新带 loading */
|
||||
syncAutoRefresh() {
|
||||
this.stopAutoRefresh()
|
||||
if (!this.showQueue) return
|
||||
this.autoTimer = setInterval(() => {
|
||||
if (this.loading || this.refreshing) return
|
||||
this.loadDetail({ silent: true, toastLoading: true })
|
||||
}, AUTO_REFRESH_MS)
|
||||
},
|
||||
stopAutoRefresh() {
|
||||
if (this.autoTimer) {
|
||||
clearInterval(this.autoTimer)
|
||||
this.autoTimer = null
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.voucher-page {
|
||||
min-height: 100vh;
|
||||
padding: 24rpx 20rpx 48rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.voucher-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 0 8rpx;
|
||||
}
|
||||
|
||||
.voucher-toolbar__hint {
|
||||
font-size: 22rpx;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.voucher-toolbar__btn {
|
||||
padding: 10rpx 28rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.voucher-toolbar__btn--glass {
|
||||
color: #1c1c1e;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
.voucher-toolbar__btn--busy {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* —— 模拟小票:对齐管理端打印版式 —— */
|
||||
.voucher-page--receipt {
|
||||
background: #e8e4dc;
|
||||
}
|
||||
|
||||
.slip {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 36rpx 40rpx 40rpx;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
border-radius: 4rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||||
font-size: 28rpx;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.slip__clinic {
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.slip__title {
|
||||
margin-top: 8rpx;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.2em;
|
||||
}
|
||||
|
||||
.slip__orderno {
|
||||
margin: 20rpx 0 12rpx;
|
||||
padding: 16rpx 8rpx;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
letter-spacing: 1rpx;
|
||||
word-break: break-all;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.slip__queue {
|
||||
margin-bottom: 16rpx;
|
||||
padding: 16rpx 0;
|
||||
text-align: center;
|
||||
border-bottom: 1px dashed #ccc;
|
||||
}
|
||||
|
||||
.slip__queue-label {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.slip__queue-eta {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.slip__line {
|
||||
text-align: left;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.slip__dash {
|
||||
margin: 20rpx 0 12rpx;
|
||||
text-align: center;
|
||||
letter-spacing: 2rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.slip__tip {
|
||||
font-size: 22rpx;
|
||||
line-height: 1.5;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* —— 液态玻璃:克制版(系统灰底 + 半透明白卡,无彩虹渐变) —— */
|
||||
.voucher-page--glass {
|
||||
background: #f2f2f7;
|
||||
}
|
||||
|
||||
.voucher-page--glass .voucher-card {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 28rpx 32rpx;
|
||||
background: rgba(255, 255, 255, 0.78);
|
||||
border-radius: 24rpx;
|
||||
border: 1px solid rgba(255, 255, 255, 0.9);
|
||||
box-shadow: 0 8rpx 28rpx rgba(0, 0, 0, 0.04);
|
||||
backdrop-filter: blur(24px);
|
||||
}
|
||||
|
||||
.voucher-page--glass .voucher-row {
|
||||
border-bottom: 1px solid rgba(60, 60, 67, 0.08);
|
||||
}
|
||||
|
||||
.voucher-page--glass .voucher-queue__count,
|
||||
.voucher-page--glass .voucher-queue__unit {
|
||||
color: #1c1c1e;
|
||||
}
|
||||
|
||||
.voucher-page--glass .voucher-queue__label,
|
||||
.voucher-page--glass .voucher-row__label,
|
||||
.voucher-page--glass .voucher-tip,
|
||||
.voucher-page--glass .voucher-toolbar__hint {
|
||||
color: #8e8e93;
|
||||
}
|
||||
|
||||
.voucher-page--glass .voucher-queue__eta,
|
||||
.voucher-page--glass .voucher-row__value {
|
||||
color: #1c1c1e;
|
||||
}
|
||||
|
||||
.voucher-card--queue {
|
||||
text-align: center;
|
||||
padding: 40rpx 32rpx;
|
||||
}
|
||||
|
||||
.voucher-queue__label {
|
||||
font-size: 28rpx;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.voucher-queue__num {
|
||||
margin-top: 12rpx;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.voucher-queue__count {
|
||||
font-size: 64rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.voucher-queue__unit {
|
||||
margin-left: 8rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.voucher-queue__eta {
|
||||
margin-top: 16rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.voucher-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 18rpx 0;
|
||||
}
|
||||
|
||||
.voucher-row--last {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.voucher-row__label {
|
||||
width: 140rpx;
|
||||
flex-shrink: 0;
|
||||
font-size: 28rpx;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.voucher-row__value {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #1e293b;
|
||||
word-break: break-all;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.voucher-tip {
|
||||
padding: 0 12rpx;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.6;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.voucher-empty {
|
||||
margin-top: 160rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0 48rpx;
|
||||
}
|
||||
|
||||
.voucher-empty__text {
|
||||
font-size: 30rpx;
|
||||
color: #64748b;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.voucher-empty__btn {
|
||||
margin-top: 32rpx;
|
||||
padding: 16rpx 48rpx;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
background: #4175ee;
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user