From 9df77e6ed2b7d11d2bd35ab083a621df34316f50 Mon Sep 17 00:00:00 2001 From: DU Date: Sat, 6 Jun 2026 18:12:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BC=80=E5=8F=B0=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E4=BB=A5=E5=8F=8A=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/startDevice.ts | 34 ++++++++++---- .../closeTable/components/FooterButtons.tsx | 11 ++--- src/pageScan/closeTable/index.tsx | 2 +- src/pageScan/renewFee/index.tsx | 19 ++++---- src/pageScan/selfStart/index.tsx | 19 +++++++- src/pageScan/turnOffRestart/index.tsx | 11 ++--- src/types/startDevice.ts | 47 +++++++++++++++++++ 7 files changed, 111 insertions(+), 32 deletions(-) diff --git a/src/api/startDevice.ts b/src/api/startDevice.ts index ccaddba..d32bfa9 100644 --- a/src/api/startDevice.ts +++ b/src/api/startDevice.ts @@ -1,6 +1,7 @@ /** - * 开台操作相关 API - * 接口地址:/api/v2/TablesDev/start_device + * 台球桌设备操作相关 API + * 开台接口:/api/v2/TablesDev/start_device + * 关台/续费/关灯重开接口:/api/v2/TablesDev/stop */ import { get, post } from '../services/request' import { @@ -11,6 +12,8 @@ import { TableScanResponseDto, CtrlType, PayType, + StopGroupDevRequestDto, + StopGroupDevResponseDto, } from '../types/startDevice' /** 小程序 JSAPI 支付固定交易类型 */ @@ -132,13 +135,27 @@ export const couponStart = (grpSn: string, openId: string, couponCode: string) = }) } +/** + * 关台操作基础接口(对应 /api/v2/TablesDev/stop) + * 统一处理立即关台、续费、关灯重开三种操作 + */ +export const stopDevice = (data: StopGroupDevRequestDto) => { + return post('/TablesDev/stop', { + tradeType: MINI_PROGRAM_TRADE_TYPE, + ...data, + }, { + showLoading: true, + loadingText: '处理中...', + }) +} + /** * 立即关台 * @param grpSn 设备编码 * @param openId 用户OpenId */ export const immediateClose = (grpSn: string, openId: string) => { - return startDevice({ + return stopDevice({ grpSn, openId, ctrlType: CtrlType.ImmediateClose, @@ -149,21 +166,21 @@ export const immediateClose = (grpSn: string, openId: string) => { * 续费 * @param grpSn 设备编码 * @param openId 用户OpenId - * @param amount 续费金额 + * @param renewalAmount 续费金额(元) * @param payType 支付方式 */ export const renewFee = ( grpSn: string, openId: string, - amount: number, + renewalAmount: number, payType: PayType = PayType.WechatPay ) => { - return startDevice({ + return stopDevice({ grpSn, openId, ctrlType: CtrlType.Renew, - amount, payType, + renewalAmount, }) } @@ -173,7 +190,7 @@ export const renewFee = ( * @param openId 用户OpenId */ export const turnOffRestart = (grpSn: string, openId: string) => { - return startDevice({ + return stopDevice({ grpSn, openId, ctrlType: CtrlType.TurnOffRestart, @@ -207,6 +224,7 @@ export { CtrlType, PayType } // 导出所有方法和类型 export default { startDevice, + stopDevice, invokeWechatPay, depositStart, balanceStart, diff --git a/src/pageScan/closeTable/components/FooterButtons.tsx b/src/pageScan/closeTable/components/FooterButtons.tsx index 0f55b19..b99cc30 100644 --- a/src/pageScan/closeTable/components/FooterButtons.tsx +++ b/src/pageScan/closeTable/components/FooterButtons.tsx @@ -64,18 +64,17 @@ const FooterButtons = ({ type, grpSn, operationId }: FooterButtonsProps) => { console.log('关台接口返回:', result) - const consumptionId = result.data.consumptionId - const outTradeNo = result.data.paymentResponseDto?.outTradeNo + const { operationId: responseOperationId, outTradeNo, needPay, payParameters } = result.data // 判断是否需要支付(可能需要补差价) - if (result.data.paymentResponseDto?.payParameters) { + if (needPay && payParameters) { // 调起微信支付 try { - await invokeWechatPay(result.data.paymentResponseDto.payParameters) + await invokeWechatPay(payParameters) - // 轮询服务端确认支付结果 + // 轮询服务端确认支付结果(responseOperationId 对应后端 operationId,需确认与 consumptionId 语义一致) Taro.showLoading({ title: '确认支付中...', mask: true }) - const paid = await pollTablePaymentStatus(consumptionId) + const paid = await pollTablePaymentStatus(responseOperationId) Taro.hideLoading() if (paid) { diff --git a/src/pageScan/closeTable/index.tsx b/src/pageScan/closeTable/index.tsx index 8df7ae1..b24cc1e 100644 --- a/src/pageScan/closeTable/index.tsx +++ b/src/pageScan/closeTable/index.tsx @@ -142,7 +142,7 @@ const CloseTable = observer(() => { 押金 - {opInfo ? `${opInfo.deposit.toFixed(2)}元(${opInfo.depositStatus})` : '--'} + {opInfo ? `${opInfo.deposit.toFixed(2)}元${opInfo.depositStatus ? `(${opInfo.depositStatus})` : ''}` : '--'} diff --git a/src/pageScan/renewFee/index.tsx b/src/pageScan/renewFee/index.tsx index 27cdff4..13b4161 100644 --- a/src/pageScan/renewFee/index.tsx +++ b/src/pageScan/renewFee/index.tsx @@ -20,9 +20,11 @@ const RenewFee = observer(() => { const scanInfo = tableStore.scanInfo const opInfo = scanInfo?.opInfo const priceInfo = scanInfo?.price - const pricePerHour = priceInfo?.currentPrice || 0 + const pricePerHour = priceInfo?.standard || 0 - const [renewAmount, setRenewAmount] = useState(priceInfo?.deposit || 100) // 续费金额,默认押金额 + // 续费最小金额:优先用 opInfo.deposit(close 状态下 price.deposit 可能为0) + const minDeposit = opInfo?.deposit || priceInfo?.deposit || 100 + const [renewAmount, setRenewAmount] = useState(minDeposit) const [paymentMethod] = useState('微信支付') // 支付方式 const [loading, setLoading] = useState(false) // 加载状态 @@ -101,18 +103,17 @@ const RenewFee = observer(() => { console.log('续费接口返回:', result) - const consumptionId = result.data.consumptionId - const outTradeNo = result.data.paymentResponseDto?.outTradeNo + const { operationId: responseOperationId, outTradeNo, needPay, payParameters } = result.data // 判断是否需要支付 - if (result.data.paymentResponseDto?.payParameters) { + if (needPay && payParameters) { // 调起微信支付 try { - await invokeWechatPay(result.data.paymentResponseDto.payParameters) + await invokeWechatPay(payParameters) - // 轮询服务端确认支付结果 + // 轮询服务端确认支付结果(responseOperationId 对应后端 operationId,需确认与 consumptionId 语义一致) Taro.showLoading({ title: '确认支付中...', mask: true }) - const paid = await pollTablePaymentStatus(consumptionId) + const paid = await pollTablePaymentStatus(responseOperationId) Taro.hideLoading() if (paid) { @@ -228,7 +229,7 @@ const RenewFee = observer(() => { 续费金额(元) { setDeposit(value) } - const pricePerHour = priceInfo?.currentPrice || 0 + const pricePerHour = priceInfo?.currentPrice || priceInfo?.standard || 0 // 根据押金和实际价格计算预计时长 const calculateDuration = () => { @@ -158,6 +158,14 @@ const SelfStart = observer(() => { Taro.hideLoading() if (paid) { + // 支付成功后重新拉取台桌信息,更新 scanInfo(opInfo 会有完整数据) + try { + const openId2 = userStore.userInfo?.wxOpenId || Taro.getStorageSync('openId') + const freshInfo = await getTableInfo(grpSn, openId2) + tableStore.setScanInfo(freshInfo.data) + } catch (_) { + // 刷新失败不阻断流程,关台页会显示 '--' 但功能正常 + } Taro.showToast({ title: '开台成功', icon: 'success', duration: 2000 }) setTimeout(() => { Taro.redirectTo({ @@ -184,6 +192,13 @@ const SelfStart = observer(() => { } } else { // 无需支付(余额支付等场景) + try { + const openId2 = userStore.userInfo?.wxOpenId || Taro.getStorageSync('openId') + const freshInfo = await getTableInfo(grpSn, openId2) + tableStore.setScanInfo(freshInfo.data) + } catch (_) { + // 刷新失败不阻断流程 + } Taro.showToast({ title: '开台成功', icon: 'success', duration: 2000 }) setTimeout(() => { Taro.redirectTo({ diff --git a/src/pageScan/turnOffRestart/index.tsx b/src/pageScan/turnOffRestart/index.tsx index 8d84ec4..2e3ca57 100644 --- a/src/pageScan/turnOffRestart/index.tsx +++ b/src/pageScan/turnOffRestart/index.tsx @@ -87,18 +87,17 @@ const TurnOffRestart = observer(() => { console.log('关灯重开接口返回:', result) - const consumptionId = result.data.consumptionId - const outTradeNo = result.data.paymentResponseDto?.outTradeNo + const { operationId: responseOperationId, outTradeNo, needPay, payParameters } = result.data // 判断是否需要支付 - if (result.data.paymentResponseDto?.payParameters) { + if (needPay && payParameters) { // 调起微信支付 try { - await invokeWechatPay(result.data.paymentResponseDto.payParameters) + await invokeWechatPay(payParameters) - // 轮询服务端确认支付结果 + // 轮询服务端确认支付结果(responseOperationId 对应后端 operationId,需确认与 consumptionId 语义一致) Taro.showLoading({ title: '确认支付中...', mask: true }) - const paid = await pollTablePaymentStatus(consumptionId) + const paid = await pollTablePaymentStatus(responseOperationId) Taro.hideLoading() if (paid) { diff --git a/src/types/startDevice.ts b/src/types/startDevice.ts index 453e8c1..845b244 100644 --- a/src/types/startDevice.ts +++ b/src/types/startDevice.ts @@ -286,3 +286,50 @@ export interface TableScanResponseDto { /** 已开台时有值,可开台时为 null */ opInfo: OpInfoDto | null } + +// ─── 关台接口(/api/v2/TablesDev/stop)相关类型 ─────────────────────────────── + +/** + * 关台操作请求参数(对应 /api/v2/TablesDev/stop 接口) + * ctrlType 使用 CtrlType 枚举:5-立即关台、6-续费、7-关灯重开、8-替人付费关台 + */ +export interface StopGroupDevRequestDto { + /** 设备序列号(必填) */ + grpSn: string + /** 用户 OpenId(必填) */ + openId: string + /** 操作类型:5-立即关台、6-续费、7-关灯重开、8-替人付费关台 */ + ctrlType?: CtrlType + /** 支付方式:1-微信支付、2-支付宝、3-银联支付、4-余额支付、5-银行卡支付(可选) */ + payType?: PayType + /** 交易类型:1-JSAPI小程序、2-Native扫码、3-APP、4-付款码、5-H5(可选) */ + tradeType?: number + /** 续费金额(单位:元),仅 ctrlType=6(续费) 时需要 */ + renewalAmount?: number +} + +/** + * 关台操作响应数据(对应 /api/v2/TablesDev/stop 接口 data 字段) + */ +export interface StopGroupDevResponseDto { + /** 设备序列号 */ + grpSn: string + /** 操作 ID(用于支付轮询) */ + operationId: number + /** 关台时间 */ + stopTime: string + /** 最终消费金额 */ + finalAmount: number + /** 退款金额 */ + refundAmount: number + /** 操作类型(对应 CtrlType:5-立即关台、6-续费、7-关灯重开) */ + stopType: CtrlType + /** 续费时返回新的结束时间 */ + newStopTime: string + /** 微信支付参数(needPay=true 时有值,否则为 null) */ + payParameters: WechatPayParameters | null + /** 是否需要前端调起支付 */ + needPay: boolean + /** 商户订单号,前端轮询用 */ + outTradeNo: string +}