diff --git a/src/api/apidoc/startDevice.md b/src/api/apidoc/startDevice.md new file mode 100644 index 0000000..a6d8be2 --- /dev/null +++ b/src/api/apidoc/startDevice.md @@ -0,0 +1,93 @@ + + +## 开台操作 + + +**接口地址**:`/api/v2/TablesDev/start_device` + + +**请求方式**:`POST` + + +**请求数据类型**:`application/x-www-form-urlencoded,application/json,text/json,application/*+json` + + +**响应数据类型**:`text/plain` + + +**接口描述**: + + +**请求示例**: + + +```javascript +{ + "grpSn": "", + "openId": "", + "ctrlType": 0, + "amount": 0, + "payType": 0, + "durationHours": 0, + "couponCode": "", + "remark": "", + "attach": "" +} +``` + + +**请求参数**: + + +**请求参数**: + + +| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 | schema | +| -------- | -------- | ----- | -------- | -------- | ------ | +|startGroupDevRequestDto|开台请求参数|body|true|StartGroupDevRequestDto|StartGroupDevRequestDto| +|  grpSn|设备编码||true|string|| +|  openId|OpenId||true|string|| +|  ctrlType|操作类型\n押金开台(1)、余额开台(2)、定时开台(3)、信用开台(4)、团购券开台(5)、\n立即关台(6)、续费(7)、关灯重开(8)、替人付费关台(9)||false|integer(int32)|| +|  amount|消费金额||false|number(double)|| +|  payType|支付方式 \n微信支付(1)、支付宝(2)、银联支付(3)、余额支付(4)、银行卡支付(5)||false|integer(int32)|| +|  durationHours|开台时长(小时),定时开台使用||false|number(double)|| +|  couponCode|团购券码,团购券开台使用||false|string|| +|  remark|备注||false|string|| +|  attach|附加数据(JSON格式)||false|string|| + + +**响应状态**: + + +| 状态码 | 说明 | schema | +| -------- | -------- | ----- | +|200|OK|StartDeviceResponse| +|400|Bad Request|| +|404|Not Found|| +|500|Internal Server Error|| + + +**响应参数**: + + +| 参数名称 | 参数说明 | 类型 | schema | +| -------- | -------- | ----- |----- | +|consumptionId|消费记录ID|integer(int32)|integer(int32)| +|outTradeNo|商户订单号|string|| +|payParameters|支付参数|string|| +|mwebUrl|H5支付URL|string|| +|payUrl|支付URL(用于扫码支付)|string|| +|errorMessage|描述消息|string|| + + +**响应示例**: +```javascript +{ + "consumptionId": 0, + "outTradeNo": "", + "payParameters": {}, + "mwebUrl": "", + "payUrl": "", + "errorMessage": "" +} +``` \ No newline at end of file diff --git a/src/api/startDevice.ts b/src/api/startDevice.ts index b46a803..ccaddba 100644 --- a/src/api/startDevice.ts +++ b/src/api/startDevice.ts @@ -2,12 +2,13 @@ * 开台操作相关 API * 接口地址:/api/v2/TablesDev/start_device */ -import { post } from '../services/request' +import { get, post } from '../services/request' import { StartGroupDevRequestDto, StartDeviceResponse, WechatPayParameters, PriceRequestDto, + TableScanResponseDto, CtrlType, PayType, } from '../types/startDevice' @@ -179,6 +180,16 @@ export const turnOffRestart = (grpSn: string, openId: string) => { }) } +/** + * 扫码后获取开台信息(球台状态、价格、可用开台方式、当前订单等) + * @param sn 设备 SN(即 grpSn) + * @param openId 用户 OpenId + * @param source 来源(可选) + */ +export const getTableInfo = (sn: string, openId?: string, source?: string) => { + return get('/TablesDev/qrcode', { sn, openId, source }) +} + /** * 根据用户获取台球桌实际价格(VIP/普通用户价格不同) * @param openId 用户 OpenId @@ -205,6 +216,7 @@ export default { renewFee, turnOffRestart, getTablePrice, + getTableInfo, CtrlType, PayType, } diff --git a/src/pageScan/closeTable/index.tsx b/src/pageScan/closeTable/index.tsx index a11636d..8df7ae1 100644 --- a/src/pageScan/closeTable/index.tsx +++ b/src/pageScan/closeTable/index.tsx @@ -25,19 +25,14 @@ const CloseTable = observer(() => { const grpSn = tableStore.getGrpSn(router.params.grpSn) const operationId = tableStore.getOperationId(Number(router.params.operationId)) + const scanInfo = tableStore.scanInfo + const opInfo = scanInfo?.opInfo + const priceInfo = scanInfo?.price + useLoad(() => { console.log('关台页面加载,类型:', type, '设备编码:', grpSn, '操作记录ID:', operationId) - - // 保存到 store - if (grpSn) { - tableStore.setCurrentGrpSn(grpSn) - } - if (operationId) { - tableStore.setCurrentOperationId(operationId) - } - - // TODO: 这里应该调用接口获取订单详情 - // 根据 grpSn 和 operationId 获取订单信息 + if (grpSn) tableStore.setCurrentGrpSn(grpSn) + if (operationId) tableStore.setCurrentOperationId(operationId) }) // 拨打电话 @@ -71,14 +66,14 @@ const CloseTable = observer(() => { {/* 台球桌标题和使用状态 */} - 来力.山岩-A03/3号球桌 - 使用中... + {scanInfo?.tableInfo?.name || '--'} + {scanInfo?.tableInfo?.statusDescription || '使用中...'} {/* 位置信息 */} - 北京黑八大师联盟球厅店 + {scanInfo?.shopName || '--'} @@ -87,7 +82,7 @@ const CloseTable = observer(() => { {/* 顶部:开台方式和详情按钮 */} - 开台方式 + {opInfo?.ctrlTypeDescription || '开台方式'} 详情 @@ -102,11 +97,11 @@ const CloseTable = observer(() => { {/* 订单统计 */} - 1小时56分 + {opInfo?.usedTime || '--'} 已消费时长 - 100.00元 + {opInfo ? `${opInfo.currentAmount.toFixed(2)}元` : '--'} 已消费金额 @@ -118,12 +113,14 @@ const CloseTable = observer(() => { 价格: - 90.00元/小时 - - - 折扣价: - 80.00元/小时 + {priceInfo ? `${priceInfo.standard.toFixed(2)}元/小时` : '--'} + {priceInfo && priceInfo.memberPrice > 0 && ( + + 折扣价: + {priceInfo.memberPrice.toFixed(2)}元/小时 + + )} @@ -135,31 +132,31 @@ const CloseTable = observer(() => { {/* 支付信息卡片 */} 支付信息 - + 在线总支付: - 0元 + {opInfo ? `${opInfo.deposit.toFixed(2)}元` : '0元'} 押金 - 0元 + {opInfo ? `${opInfo.deposit.toFixed(2)}元(${opInfo.depositStatus})` : '--'} 订单原价 - 92.80元 + {opInfo ? `${opInfo.currentAmount.toFixed(2)}元` : '--'} {/* 优惠券抵扣 - 可展开 */} setCouponExpanded(!couponExpanded)}> 优惠券抵扣 - 不可用 - -96.00元 - {opInfo && opInfo.discountAmount > 0 ? '已使用' : '不可用'} + {opInfo && opInfo.discountAmount > 0 ? `-${opInfo.discountAmount.toFixed(2)}元` : '-0.00元'} + { {/* 优惠券展开内容 */} {couponExpanded && ( - 美团:2小时通用券(新人奖励) - -96.00元 + {opInfo && opInfo.discountAmount > 0 + ? 优惠金额:{opInfo.discountAmount.toFixed(2)}元 + : 暂无优惠券 + } )} 待结算: - 92.8元 + {opInfo ? `${opInfo.payableAmount.toFixed(2)}元` : '--'} @@ -187,34 +186,34 @@ const CloseTable = observer(() => { 门店信息 - XXXXXX店 + {scanInfo?.shopName || '--'} 桌台信息 - 中式台球 来力.山岩-A03/3号球桌 + {scanInfo?.tableInfo?.name || '--'} 开始时间 - 2025-01-01 00:00:00 + {opInfo?.startTime || '--'} 使用时长 - 1小时56分 + {opInfo?.usedTime || '--'} 订单编号 - 987654321012345678 + {opInfo?.orderNo || '--'} {/* 收费标准 - 可展开 */} setPriceExpanded(!priceExpanded)}> 收费标准 - 80元/小时 + {priceInfo ? `${priceInfo.currentPrice.toFixed(2)}元/小时` : '--'} { {/* 收费标准展开内容 */} {priceExpanded && ( - 1分钟以内不计费,超过1分钟按6.67元/5分钟计费 - • 00:00-11:00 原价90元/小时,折扣价80元/小时 - • 11:00-24:00 原价100元/小时,折扣价90元/小时 + {priceInfo?.descript && {priceInfo.descript}} + {priceInfo?.timePrices?.map((tp, i) => ( + • {tp.startTime}-{tp.endTime} {tp.description || `${tp.price}元/小时`} + ))} )} 支付方式 - 微信支付 + {opInfo?.payTypeDescription || '--'} diff --git a/src/pageScan/couponStart/index.tsx b/src/pageScan/couponStart/index.tsx index e3a86b0..9fbf5b7 100644 --- a/src/pageScan/couponStart/index.tsx +++ b/src/pageScan/couponStart/index.tsx @@ -5,7 +5,7 @@ import { View, Text, Image, Input } from '@tarojs/components' import Taro, { useLoad, useRouter } from '@tarojs/taro' import { useState } from 'react' import { observer } from 'mobx-react' -import { couponStart, invokeWechatPay, getTablePrice } from '../../api/startDevice' +import { couponStart, invokeWechatPay } from '../../api/startDevice' import { userStore, tableStore } from '../../store' import './index.scss' @@ -34,11 +34,13 @@ interface Coupon { const CouponStart = observer(() => { const router = useRouter() + const scanInfo = tableStore.scanInfo + const priceInfo = scanInfo?.price + const [couponCode, setCouponCode] = useState('') // 券码 const [selectedCouponType, setSelectedCouponType] = useState(CouponType.THIRD_PARTY) const [selectedCouponId, setSelectedCouponId] = useState(1) // 选中的券ID const [loading, setLoading] = useState(false) // 加载状态 - const [pricePerHour, setPricePerHour] = useState(0) // 每小时价格(从接口获取) // 从路由参数获取设备信息,如果没有则从 store 获取 const grpSn = tableStore.getGrpSn(router.params.grpSn) @@ -71,25 +73,9 @@ const CouponStart = observer(() => { useLoad(() => { console.log('团购券开台页面加载, 设备编码:', grpSn) - - // 保存设备编码到 store if (grpSn) { tableStore.setCurrentGrpSn(grpSn) } - - // 获取该用户对应的台球桌价格 - const openId = userStore.userInfo?.wxOpenId || Taro.getStorageSync('openId') - if (openId && grpSn) { - getTablePrice(openId, grpSn) - .then((res) => { - if (res.data) { - setPricePerHour(res.data) - } - }) - .catch((err) => { - console.error('获取价格失败:', err) - }) - } }) // 拨打电话 @@ -253,7 +239,7 @@ const CouponStart = observer(() => { {/* 顶部:店名和电话 */} - 北京黑八大师联盟球厅店 + {scanInfo?.shopName || '--'} 联系店长 @@ -262,24 +248,24 @@ const CouponStart = observer(() => { {/* 台球桌标题 */} - [中式台球]来力.山岩-A03/3号球桌 + {scanInfo?.tableInfo?.name || '--'} {/* 价格信息 */} - ¥{pricePerHour > 0 ? pricePerHour.toFixed(2) : '--'} + ¥{priceInfo ? priceInfo.currentPrice.toFixed(2) : '--'} /小时 押金 - ¥100.00 + ¥{priceInfo ? priceInfo.deposit.toFixed(2) : '--'} {/* 价格时段 */} - 价格时段:00:00-24:00 + 价格时段:{priceInfo?.pricePeriod || '--'} diff --git a/src/pageScan/renewFee/index.tsx b/src/pageScan/renewFee/index.tsx index 5cd058e..f52cc00 100644 --- a/src/pageScan/renewFee/index.tsx +++ b/src/pageScan/renewFee/index.tsx @@ -6,7 +6,7 @@ import Taro, { useLoad, useRouter } from '@tarojs/taro' import { useState } from 'react' import { observer } from 'mobx-react' import { Stepper } from '@taroify/core' -import { renewFee, invokeWechatPay, getTablePrice, PayType } from '../../api/startDevice' +import { renewFee, invokeWechatPay, PayType } from '../../api/startDevice' import { userStore, tableStore } from '../../store' import './index.scss' @@ -16,10 +16,14 @@ const locationIcon = require('../../assets/icon/locationIcon.png') const RenewFee = observer(() => { const router = useRouter() - const [renewAmount, setRenewAmount] = useState(100) // 续费金额(修改初始值为100) + const scanInfo = tableStore.scanInfo + const opInfo = scanInfo?.opInfo + const priceInfo = scanInfo?.price + const pricePerHour = priceInfo?.currentPrice || 0 + + const [renewAmount, setRenewAmount] = useState(priceInfo?.deposit || 100) // 续费金额,默认押金额 const [paymentMethod] = useState('微信支付') // 支付方式 const [loading, setLoading] = useState(false) // 加载状态 - const [pricePerHour, setPricePerHour] = useState(0) // 每小时价格(从接口获取) // 从路由参数获取设备信息和操作记录ID,如果没有则从 store 获取 const grpSn = tableStore.getGrpSn(router.params.grpSn) @@ -27,28 +31,8 @@ const RenewFee = observer(() => { useLoad(() => { console.log('续费页面加载, 设备编码:', grpSn, '操作记录ID:', operationId) - - // 保存到 store - if (grpSn) { - tableStore.setCurrentGrpSn(grpSn) - } - if (operationId) { - tableStore.setCurrentOperationId(operationId) - } - - // 获取该用户对应的台球桌价格 - const openId = userStore.userInfo?.wxOpenId || Taro.getStorageSync('openId') - if (openId && grpSn) { - getTablePrice(openId, grpSn) - .then((res) => { - if (res.data) { - setPricePerHour(res.data) - } - }) - .catch((err) => { - console.error('获取价格失败:', err) - }) - } + if (grpSn) tableStore.setCurrentGrpSn(grpSn) + if (operationId) tableStore.setCurrentOperationId(operationId) }) // 拨打电话 @@ -187,14 +171,14 @@ const RenewFee = observer(() => { {/* 台球桌标题和使用状态 */} - 来力.山岩-A03/3号球桌 - 使用中... + {scanInfo?.tableInfo?.name || '--'} + {scanInfo?.tableInfo?.statusDescription || '使用中...'} {/* 位置信息 */} - 北京黑八大师联盟球厅店 + {scanInfo?.shopName || '--'} @@ -210,15 +194,15 @@ const RenewFee = observer(() => { {/* 订单统计 */} - 1小时56分 + {opInfo?.usedTime || '--'} 已消费时长 - 100.00元 + {opInfo ? `${opInfo.currentAmount.toFixed(2)}元` : '--'} 已消费金额 - 6分钟 + -- 剩余时长 @@ -230,12 +214,14 @@ const RenewFee = observer(() => { 价格: - 90.00元/小时 - - - 折扣价: - 80.00元/小时 + {priceInfo ? `${priceInfo.standard.toFixed(2)}元/小时` : '--'} + {priceInfo && priceInfo.memberPrice > 0 && ( + + 折扣价: + {priceInfo.memberPrice.toFixed(2)}元/小时 + + )} @@ -248,7 +234,7 @@ const RenewFee = observer(() => { 续费金额(元) { const router = useRouter() - const [deposit, setDeposit] = useState(100) // 押金金额 + const scanInfo = tableStore.scanInfo + const priceInfo = scanInfo?.price + const defaultDeposit = priceInfo?.deposit || 100 + + const [deposit, setDeposit] = useState(defaultDeposit) // 押金金额 const [paymentMethod, setPaymentMethod] = useState<'微信支付' | '余额支付'>('微信支付') // 支付方式 const [loading, setLoading] = useState(false) // 加载状态 - const [pricePerHour, setPricePerHour] = useState(0) // 每小时价格(从接口获取) // 从路由参数获取设备信息,如果没有则从 store 获取 const grpSn = tableStore.getGrpSn(router.params.grpSn) @@ -28,33 +31,11 @@ const SelfStart = observer(() => { useLoad(() => { console.log('自助开台页面加载, 设备编码:', grpSn) - - // 保存设备编码到 store if (grpSn) { tableStore.setCurrentGrpSn(grpSn) } - - // 获取该用户对应的台球桌价格 - const openId = userStore.userInfo?.wxOpenId || Taro.getStorageSync('openId') - if (openId && grpSn) { - getTablePrice(openId, grpSn) - .then((res) => { - if (res.data) { - setPricePerHour(res.data) - } - }) - .catch((err) => { - console.error('获取价格失败:', err) - }) - } - - // 显示提示 Toast setTimeout(() => { - Taro.showToast({ - title: '开台后需要手动进行关台哦!', - icon: 'none', - duration: 2000, - }) + Taro.showToast({ title: '开台后需要手动进行关台哦!', icon: 'none', duration: 2000 }) }, 300) }) @@ -72,6 +53,8 @@ const SelfStart = observer(() => { setDeposit(value) } + const pricePerHour = priceInfo?.currentPrice || 0 + // 根据押金和实际价格计算预计时长 const calculateDuration = () => { if (!pricePerHour) return '-' @@ -225,7 +208,7 @@ const SelfStart = observer(() => { {/* 顶部:店名和电话 */} - 北京黑八大师联盟球厅店 + {scanInfo?.shopName || '--'} 联系店长 @@ -234,7 +217,7 @@ const SelfStart = observer(() => { {/* 台球桌标题 */} - [中式台球]来力.山岩-A03/3号球桌 + {scanInfo?.tableInfo?.name || '--'} {/* 价格信息 */} @@ -245,13 +228,13 @@ const SelfStart = observer(() => { 押金 - ¥100.00 + ¥{priceInfo ? priceInfo.deposit.toFixed(2) : '--'} {/* 价格时段 */} - 价格时段:00:00-24:00 + 价格时段:{priceInfo?.pricePeriod || '--'} @@ -262,7 +245,7 @@ const SelfStart = observer(() => { 押金(元) 押金直接开台或支付开台', - }, - { - id: 2, - title: '定时开台', - description: '设定开台时长', - }, - { - id: 3, - title: '信用开台', - description: '信用分≥550,直接开台,关台时结账', - }, - { - id: 4, - title: '团购券开台', - description: '使用美团、抖音等团购券开台', - }, -] +// optionCode → 跳转路径映射 +const OPTION_URL_MAP: Record = { + [CtrlType.DepositStart]: '/pageScan/selfStart/index', + [CtrlType.TimedStart]: '/pageScan/timedStart/index', + [CtrlType.CouponStart]: '/pageScan/couponStart/index', +} + +const StartTable = observer(() => { + const router = useRouter() + const grpSn = router.params.grpSn || tableStore.currentGrpSn + const scanInfo = tableStore.scanInfo -const StartTable = () => { useLoad(() => { - console.log('开台页面加载') + console.log('开台页面加载, grpSn:', grpSn) }) - // 拨打电话 const handlePhoneCall = () => { - Taro.makePhoneCall({ - phoneNumber: '100-666-XXXX', - }).catch((err) => { - console.error('拨打电话失败:', err) - }) + Taro.makePhoneCall({ phoneNumber: '100-666-XXXX' }).catch(() => {}) } - // 去开台 - const handleStartTable = (method: any) => { - console.log('选择开台方式:', method) - - // 如果是自助开台,跳转到自助开台页面 - if (method.id === 1) { - Taro.navigateTo({ - url: '/pageScan/selfStart/index' - }) - return - } - - // 如果是定时开台,跳转到定时开台页面 - if (method.id === 2) { - Taro.navigateTo({ - url: '/pageScan/timedStart/index' - }) + const handleStartTable = (optionCode: number, available: boolean) => { + if (!available) { + Taro.showToast({ title: '当前条件不满足,无法使用该开台方式', icon: 'none', duration: 2000 }) return } - - // 如果是团购券开台,跳转到团购券开台页面 - if (method.id === 4) { - Taro.navigateTo({ - url: '/pageScan/couponStart/index' - }) - return + const url = OPTION_URL_MAP[optionCode] + if (url) { + Taro.navigateTo({ url: `${url}?grpSn=${grpSn}` }) + } else { + Taro.showToast({ title: '功能开发中', icon: 'none', duration: 2000 }) } - - // 其他方式暂时提示功能开发中 - Taro.showToast({ - title: '功能开发中', - icon: 'none', - duration: 2000 - }) } + const price = scanInfo?.price + const tableInfo = scanInfo?.tableInfo + const openOptions = scanInfo?.openOptions || [] + return ( - {/* 内容区域 */} {/* 台球桌信息卡片 */} - {/* 顶部:店名和电话 */} - 北京黑八大师联盟球厅店 + {scanInfo?.shopName || '--'} 联系店长 - {/* 台球桌标题 */} - [中式台球]来力.山岩-A03/3号球桌 + {tableInfo?.name || '--'} - {/* 价格信息 */} - ¥28.80 + ¥{price ? price.currentPrice.toFixed(2) : '--'} /小时 押金 - ¥100.00 - - - VIP ¥20.00 + ¥{price ? price.deposit.toFixed(2) : '--'} + {price && price.memberPrice > 0 && ( + + VIP ¥{price.memberPrice.toFixed(2)} + + )} - {/* 价格时段 */} - 价格时段:00:00-24:00 + 价格时段:{price?.pricePeriod || '--'} {/* 开台方式列表 */} - {startTableMethods.map((method) => ( - - - {method.title} - {method.description} - - - handleStartTable(method)} - > - 去开台 + {openOptions.length > 0 ? ( + openOptions.map((option, index) => ( + + + {option.title} + {option.description} + {!option.available && option.condition && ( + {option.condition} + )} + + + handleStartTable(option.optionCode, option.available)} + > + {option.available ? option.actionText || '去开台' : '不可用'} + + )) + ) : ( + // 接口数据未加载时显示占位 + + 加载中... - ))} + )} ) -} +}) export default StartTable diff --git a/src/pageScan/timedStart/index.tsx b/src/pageScan/timedStart/index.tsx index ac12844..1de4916 100644 --- a/src/pageScan/timedStart/index.tsx +++ b/src/pageScan/timedStart/index.tsx @@ -5,7 +5,7 @@ import { View, Text, Image } from '@tarojs/components' import Taro, { useLoad, useRouter } from '@tarojs/taro' import { useState } from 'react' import { observer } from 'mobx-react' -import { timedStart, invokeWechatPay, getTablePrice, PayType } from '../../api/startDevice' +import { timedStart, invokeWechatPay, PayType } from '../../api/startDevice' import { userStore, tableStore } from '../../store' import './index.scss' @@ -26,35 +26,22 @@ const durationOptions = [ const TimedStart = observer(() => { const router = useRouter() + const scanInfo = tableStore.scanInfo + const priceInfo = scanInfo?.price + const pricePerHour = priceInfo?.currentPrice || 0 + const [selectedDuration, setSelectedDuration] = useState(1) // 选中的时长 const [paymentMethod] = useState('微信支付') // 支付方式 const [loading, setLoading] = useState(false) // 加载状态 - const [pricePerHour, setPricePerHour] = useState(0) // 每小时价格(从接口获取) // 从路由参数获取设备信息,如果没有则从 store 获取 const grpSn = tableStore.getGrpSn(router.params.grpSn) useLoad(() => { console.log('定时开台页面加载, 设备编码:', grpSn) - - // 保存设备编码到 store if (grpSn) { tableStore.setCurrentGrpSn(grpSn) } - - // 获取该用户对应的台球桌价格 - const openId = userStore.userInfo?.wxOpenId || Taro.getStorageSync('openId') - if (openId && grpSn) { - getTablePrice(openId, grpSn) - .then((res) => { - if (res.data) { - setPricePerHour(res.data) - } - }) - .catch((err) => { - console.error('获取价格失败:', err) - }) - } }) // 拨打电话 @@ -110,6 +97,11 @@ const TimedStart = observer(() => { return } + if (!pricePerHour) { + Taro.showToast({ title: '价格信息加载中,请稍后重试', icon: 'none', duration: 2000 }) + return + } + setLoading(true) try { @@ -192,7 +184,7 @@ const TimedStart = observer(() => { {/* 顶部:店名和电话 */} - 北京黑八大师联盟球厅店 + {scanInfo?.shopName || '--'} 联系店长 @@ -201,7 +193,7 @@ const TimedStart = observer(() => { {/* 台球桌标题 */} - [中式台球]来力.山岩-A03/3号球桌 + {scanInfo?.tableInfo?.name || '--'} {/* 价格信息 */} @@ -214,7 +206,7 @@ const TimedStart = observer(() => { {/* 价格时段 */} - 价格时段:00:00-24:00 + 价格时段:{priceInfo?.pricePeriod || '--'} diff --git a/src/pageScan/turnOffRestart/index.tsx b/src/pageScan/turnOffRestart/index.tsx index b6526de..4e60d0f 100644 --- a/src/pageScan/turnOffRestart/index.tsx +++ b/src/pageScan/turnOffRestart/index.tsx @@ -21,16 +21,14 @@ const TurnOffRestart = observer(() => { const grpSn = tableStore.getGrpSn(router.params.grpSn) const operationId = tableStore.getOperationId(Number(router.params.operationId)) + const scanInfo = tableStore.scanInfo + const opInfo = scanInfo?.opInfo + const priceInfo = scanInfo?.price + useLoad(() => { console.log('关灯重开页面加载, 设备编码:', grpSn, '操作记录ID:', operationId) - - // 保存到 store - if (grpSn) { - tableStore.setCurrentGrpSn(grpSn) - } - if (operationId) { - tableStore.setCurrentOperationId(operationId) - } + if (grpSn) tableStore.setCurrentGrpSn(grpSn) + if (operationId) tableStore.setCurrentOperationId(operationId) }) // 拨打电话 @@ -159,14 +157,14 @@ const TurnOffRestart = observer(() => { {/* 台球桌标题和使用状态 */} - 来力.山岩-A03/3号球桌 - 使用中... + {scanInfo?.tableInfo?.name || '--'} + {scanInfo?.tableInfo?.statusDescription || '使用中...'} {/* 位置信息 */} - 北京黑八大师联盟球厅店 + {scanInfo?.shopName || '--'} @@ -188,11 +186,11 @@ const TurnOffRestart = observer(() => { {/* 订单统计 */} - 1小时56分钟 + {opInfo?.usedTime || '--'} 消费时长 - 100.00元 + {opInfo ? `${opInfo.currentAmount.toFixed(2)}元` : '--'} 消费金额 @@ -204,12 +202,14 @@ const TurnOffRestart = observer(() => { 价格: - 90.00元/小时 - - - 折扣价: - 80.00元/小时 + {priceInfo ? `${priceInfo.standard.toFixed(2)}元/小时` : '--'} + {priceInfo && priceInfo.memberPrice > 0 && ( + + 折扣价: + {priceInfo.memberPrice.toFixed(2)}元/小时 + + )} diff --git a/src/pages/qrHandler/index.tsx b/src/pages/qrHandler/index.tsx index e793042..6584166 100644 --- a/src/pages/qrHandler/index.tsx +++ b/src/pages/qrHandler/index.tsx @@ -12,6 +12,8 @@ import Taro, { useLoad, useRouter } from '@tarojs/taro' import { useState } from 'react' import { Loading } from '@taroify/core' import { parseQRCode, handleQRCodeNavigation, QRCodeType } from '@/utils/qrCodeHandler' +import { getTableInfo } from '@/api/startDevice' +import { tableStore, userStore } from '@/store' import './index.scss' // 页面配置 @@ -61,7 +63,31 @@ const QRHandlerPage = () => { throw new Error('无法识别的二维码格式') } - // 执行跳转逻辑 + // 台球桌二维码:先调接口获取完整信息,再根据 scanType 路由 + if ( + qrData.type === QRCodeType.TABLE_START || + qrData.type === QRCodeType.TABLE_CLOSE + ) { + const sn = qrData.grpSn || '' + const openId = userStore.userInfo?.wxOpenId || Taro.getStorageSync('openId') || undefined + + if (!sn) { + throw new Error('二维码中未找到设备编码') + } + + const res = await getTableInfo(sn, openId) + tableStore.setScanInfo(res.data) + + const scanType = res.data.scanType + if (scanType === 'open') { + await Taro.navigateTo({ url: `/pageScan/startTable/index?grpSn=${sn}` }) + } else { + await Taro.navigateTo({ url: `/pageScan/closeTable/index?grpSn=${sn}` }) + } + return + } + + // 其他类型(存杆柜、团购券等)走原有逻辑 await handleQRCodeNavigation(qrData) } catch (error: any) { diff --git a/src/store/table.ts b/src/store/table.ts index a84ed42..ccf2e1a 100644 --- a/src/store/table.ts +++ b/src/store/table.ts @@ -3,7 +3,7 @@ */ import { makeAutoObservable } from 'mobx' import Taro from '@tarojs/taro' -import { TableInfo, OrderInfo } from '../types/startDevice' +import { TableInfo, OrderInfo, TableScanResponseDto } from '../types/startDevice' class TableStore { /** 当前设备编码 */ @@ -12,11 +12,14 @@ class TableStore { /** 当前操作记录ID */ currentOperationId: number = 0 - /** 台球桌信息 */ + /** 台球桌信息(旧字段,保留兼容) */ tableInfo: TableInfo | null = null - /** 订单信息 */ + /** 订单信息(旧字段,保留兼容) */ orderInfo: OrderInfo | null = null + + /** 扫码后获取的完整开台信息(包含球台、价格、开台选项、当前订单) */ + scanInfo: TableScanResponseDto | null = null /** 加载状态 */ isLoading: boolean = false @@ -36,10 +39,13 @@ class TableStore { const tableInfo = Taro.getStorageSync('tableInfo') const orderInfo = Taro.getStorageSync('orderInfo') + const scanInfo = Taro.getStorageSync('scanInfo') + if (grpSn) this.currentGrpSn = grpSn if (operationId) this.currentOperationId = operationId if (tableInfo) this.tableInfo = tableInfo if (orderInfo) this.orderInfo = orderInfo + if (scanInfo) this.scanInfo = scanInfo } catch (error) { console.error('读取台球桌信息失败:', error) } @@ -85,6 +91,23 @@ class TableStore { } } + /** + * 设置扫码开台信息(扫码后由 qrHandler 调用) + */ + setScanInfo = (info: TableScanResponseDto | null) => { + this.scanInfo = info + if (info) { + Taro.setStorageSync('scanInfo', info) + // 同步 grpSn + if (info.tableInfo?.sn) { + this.currentGrpSn = info.tableInfo.sn + Taro.setStorageSync('currentGrpSn', info.tableInfo.sn) + } + } else { + Taro.removeStorageSync('scanInfo') + } + } + /** * 设置加载状态 */ @@ -101,10 +124,12 @@ class TableStore { this.tableInfo = null this.orderInfo = null + this.scanInfo = null Taro.removeStorageSync('currentGrpSn') Taro.removeStorageSync('currentOperationId') Taro.removeStorageSync('tableInfo') Taro.removeStorageSync('orderInfo') + Taro.removeStorageSync('scanInfo') } /** diff --git a/src/types/startDevice.ts b/src/types/startDevice.ts index d5690a1..453e8c1 100644 --- a/src/types/startDevice.ts +++ b/src/types/startDevice.ts @@ -167,3 +167,122 @@ export interface PriceRequestDto { /** 设备序列号 */ groupDevSn: string } + +// ─── 获取开台信息接口相关类型 ─────────────────────────────────────────────── + +/** + * 分时价格 + */ +export interface TimePriceDto { + startTime: string + endTime: string + price: number + description: string +} + +/** + * 价格信息 + */ +export interface PriceInfoDto { + /** 标准价格(元/小时) */ + standard: number + /** 会员价格 */ + memberPrice: number + /** 价格单位 */ + unit: string + /** 押金 */ + deposit: number + /** 每分钟价格 */ + pricePerMinute: number + /** 会员每分钟价格 */ + memberPricePerMinute: number + /** 当前时段适用价格 */ + currentPrice: number + /** 计价规则说明 */ + descript: string + /** 价格时段说明 */ + pricePeriod: string + /** 分时价格列表 */ + timePrices: TimePriceDto[] +} + +/** + * 球台设备信息 + */ +export interface TableInfoDto { + id: number + sn: string + name: string + tableNumber: string + status: number + statusDescription: string + isShared: boolean + currentSession: string + area: string + chanNum: number + startChan: number +} + +/** + * 开台方式选项 + */ +export interface OptionDto { + title: string + /** 开台类型(对应 CtrlType 枚举值) */ + type: number + description: string + actionText: string + refundPolicy: string + /** 是否可用(false 时显示为禁用) */ + available: boolean + optionCode: number + icon: string + condition: string + actionUrl: string +} + +/** + * 当前开台订单信息 + */ +export interface OpInfoDto { + /** 操作记录 ID */ + opId: number + orderNo: string + startTime: string + /** 已消费时长(后端已格式化,如"2小时30分钟") */ + usedTime: string + usedMinutes: number + ctrlType: number + ctrlTypeDescription: string + payType: number + payTypeDescription: string + /** 已消费金额 */ + currentAmount: number + /** 押金金额 */ + deposit: number + /** 押金状态描述 */ + depositStatus: string + /** 优惠金额 */ + discountAmount: number + /** 应付金额 */ + payableAmount: number +} + +/** + * 扫码获取开台信息响应(对应 data 字段) + */ +export interface TableScanResponseDto { + /** open-可开台;close-已开台需关台 */ + scanType: 'open' | 'close' + shopName: string + shopCode: string + instSn: string + tableInfo: TableInfoDto + price: PriceInfoDto + businessHours: string + openOptions: OptionDto[] + recommendedOption: string + scanTime: string + /** 已开台时有值,可开台时为 null */ + opInfo: OpInfoDto | null +}