diff --git a/app/composables/useHjcPayStatus.ts b/app/composables/useHjcPayStatus.ts index 6a0a5dc..bef2efb 100644 --- a/app/composables/useHjcPayStatus.ts +++ b/app/composables/useHjcPayStatus.ts @@ -1,25 +1,33 @@ /** - * 支付状态机(hjc-web 购标支付步骤用)。 + * 支付状态机(hjc-web 购标支付步骤与收银台共用)。 * - * 唯一事实来源是**微信侧**:轮询 `GET /api/tender/pay-status`,由后端向微信查单后给出结论。 - * 不要退回 `mark-paid`——那个接口不查单,用户点一下就能把订单置为已支付(见 ADR 0009)。 + * 唯一事实来源是**支付渠道侧**:轮询 `GET /api/tender/pay-status`, + * 由后端向渠道查单后给出结论。不要退回 `mark-paid`——那个接口不查单, + * 用户点一下就能把订单置为已支付(见 ADR 0008)。 + * + * **渠道无关**:下面两个状态集合用的是后端 `PaymentStatus` 的枚举名。微信的 + * `trade_state` 与支付宝的 `trade_status` 都已由各自的支付策略映射到该枚举 + * (`WechatJsapiStrategy#convertWechatPaymentStatus` / `AlipayStrategy#convertAlipayPaymentStatus`)。 + * 因此**不要**在这里加支付宝的状态词表——那等于把渠道知识泄漏进 UI, + * 且下次接入新渠道还要再改一遍。 */ /** - * 微信 Native 支付码的有效期。 + * 支付码的有效期。 * - * 微信侧默认 2 小时,且**服务端不下发过期时间**(`PaymentResponse.wechatNative()` 不设 `expireTime`), + * 微信 Native 默认 2 小时;支付宝当面付的超时由下单时的 `timeout_express` 决定。 + * 服务端都不下发过期时刻(`PaymentResponse` 不设 `expireTime`), * 所以只能以「本次拿到支付码的时刻」本地计时;到点停止轮询并提示重新获取。 */ export const HJC_PAY_QR_TTL_MS = 2 * 60 * 60 * 1000 -/** 轮询间隔:查单是以微信为准的代价,取到「扫完到页面反应」不至于让人以为卡住 */ +/** 轮询间隔:查单是以渠道为准的代价,取到「扫完到页面反应」不至于让人以为卡住 */ const POLL_INTERVAL_MS = 3000 -/** 微信侧终态:不用再付了 */ +/** 渠道侧终态:不用再付了 */ const SETTLED_STATUS = new Set(['SUCCESS', 'REFUNDED']) -/** 微信侧终态(坏的那种):这单在微信那边已经付不了了,继续轮询没有意义 */ +/** 渠道侧终态(坏的那种):这单在渠道那边已经付不了了,继续轮询没有意义 */ const DEAD_STATUS = new Set(['FAILED', 'CANCELLED', 'TIMEOUT', 'REFUND_FAILED']) export interface HjcPayQueryResult { @@ -35,8 +43,13 @@ export interface HjcPayQueryResult { /** * @param redirect 401 跳登录页时带上,便于登录后回跳 + * @param channel 支付渠道(`'wechat'` / `'alipay'`),只用于把提示文案里的 + * 「微信侧 / 支付宝侧」说对。**状态词表不因此变化**——见文件头注释。 */ -export function useHjcPayStatus(redirect: () => string) { +export function useHjcPayStatus( + redirect: () => string, + channel: () => 'wechat' | 'alipay' = () => 'wechat' +) { const { handleAuthCode } = useHjcAuth() /** * 与 `orders.vue` 同理:服务端渲染期间发出的站内请求必须走 `useRequestFetch()`, @@ -45,6 +58,9 @@ export function useHjcPayStatus(redirect: () => string) { */ const requestFetch = useRequestFetch() + /** 提示文案里的渠道名;只影响措辞,不影响任何判定 */ + const channelLabel = computed(() => (channel() === 'alipay' ? '支付宝侧' : '微信侧')) + const status = ref(null) const paid = ref(false) const querying = ref(false) @@ -97,9 +113,9 @@ export function useHjcPayStatus(redirect: () => string) { paid.value = true stop() } else if (name && DEAD_STATUS.has(name)) { - // 微信侧已终态且不是成功:这张支付码已经没用了,继续轮询只是空转 + // 渠道侧已终态且不是成功:这张支付码已经没用了,继续轮询只是空转 stop() - error.value = '该支付单在微信侧已关闭,请重新获取二维码' + error.value = `该支付单在${channelLabel.value}已关闭,请重新获取二维码` } return { handled: false, status: name, settled: paid.value } } catch (e: any) { @@ -165,5 +181,5 @@ export function useHjcPayStatus(redirect: () => string) { document.removeEventListener('visibilitychange', onVisibilityChange) }) - return { status, paid, querying, error, expired, start, stop, query } + return { status, paid, querying, error, expired, channelLabel, start, stop, query } } diff --git a/app/pages/tender/pay.vue b/app/pages/tender/pay.vue index 9af7973..2c472ac 100644 --- a/app/pages/tender/pay.vue +++ b/app/pages/tender/pay.vue @@ -35,27 +35,68 @@
-

请使用微信扫码支付

+

请使用{{ channelLabel }}支付

订单号:{{ orderNo }}

{{ order?.projectName }}

¥{{ formatMoney(amount) }}

-