580 lines
20 KiB
Markdown
580 lines
20 KiB
Markdown
# 综合场馆新增业务前端对接设计
|
||
|
||
> 日期:2026-07-12
|
||
> 范围:共用小程序前端 `场馆小程序/miniprogram` 中的综合场馆模块
|
||
> 对接后端:`综合场馆小程序/backend`
|
||
|
||
## 1. 背景
|
||
|
||
综合场馆后端已经完成以下新增需求:
|
||
|
||
- 将会员端可预约对象从旧的课程记录拆分为“课程模板 + 排课 `CourseSession`”,会员端以排课为操作对象。
|
||
- 新增课包/次卡套餐购买、用户持卡、适用排课查询、次卡预约及使用流水。
|
||
- 新增储值卡商品、储值卡购买订单及支付后余额充值。
|
||
- 延续已有余额、余额流水、订单、普通课程预约、包场和门票能力。
|
||
|
||
共用小程序前端仍使用旧课程接口和旧字段,且尚无综合场馆的次卡、储值卡商城和次卡预约页面。因此需要调整现有课程链路,并新增商城、次卡和个人中心相关能力。
|
||
|
||
## 2. 目标
|
||
|
||
- 将综合场馆会员端课程链路统一迁移到排课接口和 `session_id`。
|
||
- 修复首页近期排课、普通课程预约列表和详情的字段兼容问题。
|
||
- 提供课包/次卡套餐浏览、购买、持卡查看、使用流水和次卡预约能力。
|
||
- 提供储值卡浏览、购买和微信支付能力。
|
||
- 在个人中心展示余额,并提供充值、我的次卡、余额流水和消费记录入口。
|
||
- 保持包场、门票、订单和冰场馆模块行为不变。
|
||
|
||
## 3. 非目标
|
||
|
||
- 不包含“场地页面按参考小程序重写/UI 对标”。
|
||
- 不实现或调整后台锁场功能。
|
||
- 不修改冰场馆页面、API、登录态或业务流程。
|
||
- 不重构门票、包场和订单为统一商品或统一预约领域模型。
|
||
- 不修改综合场馆后端的课程模板、排课、次卡或储值卡业务规则。
|
||
- 不在前端实现核销或人工取消;次卡预约的核销和取消由后台处理。
|
||
- 不在前端缓存计算余额、次卡剩余次数或排课剩余名额,以上数据以后端为准。
|
||
|
||
## 4. 方案选择
|
||
|
||
采用“独立业务模块 + 复用现有通用页面”方案:
|
||
|
||
- 保留综合场馆既有页面与 API 分层。
|
||
- 会员端课程对象统一命名为 `session`,但保留现有 `pages/comprehensive/courses` 路由目录,避免无业务价值的路由迁移。
|
||
- 新增独立的次卡和储值卡 API 模块。
|
||
- 新增商城、我的次卡、次卡可约排课和次卡预约详情页面。
|
||
- 复用现有订单支付页和订单列表,不额外建立第二套支付或消费记录系统。
|
||
- 普通课程预约与次卡预约分别建模和展示,不强行合并为一个含订单的前端对象。
|
||
|
||
该方案与现有 `modules/comprehensive` 目录结构一致,能明确区分课程模板 ID、排课 ID、普通订单预约和无订单的次卡预约,同时将改动限制在新增需求范围内。
|
||
|
||
## 5. 工程边界
|
||
|
||
综合场馆模块继续使用以下分层:
|
||
|
||
```text
|
||
src/pages/comprehensive/ 页面与交互
|
||
src/modules/comprehensive/api/ 接口请求与响应映射
|
||
src/modules/comprehensive/stores/ 登录会员状态
|
||
src/modules/comprehensive/utils/ 日期、金额和状态工具
|
||
```
|
||
|
||
新增 API 模块:
|
||
|
||
```text
|
||
src/modules/comprehensive/api/membership.js
|
||
src/modules/comprehensive/api/storedValue.js
|
||
```
|
||
|
||
新增页面:
|
||
|
||
```text
|
||
src/pages/comprehensive/mall/index.vue
|
||
src/pages/comprehensive/membership/cards.vue
|
||
src/pages/comprehensive/membership/card-detail.vue
|
||
src/pages/comprehensive/membership/available-sessions.vue
|
||
src/pages/comprehensive/membership/booking-detail.vue
|
||
```
|
||
|
||
以上页面需注册到 `src/pages.json`。
|
||
|
||
### 5.1 页面职责
|
||
|
||
| 页面 | 职责 |
|
||
|---|---|
|
||
| `mall/index` | 分区展示储值卡和课包/次卡;创建购买订单并跳转支付 |
|
||
| `membership/cards` | 展示用户持有的次卡、总次数、剩余次数和状态 |
|
||
| `membership/card-detail` | 展示次卡信息、适用课程、使用流水及“去预约”入口 |
|
||
| `membership/available-sessions` | 展示用户次卡覆盖的未来排课,支持选择用于预约的次卡 |
|
||
| `membership/booking-detail` | 展示次卡预约状态、排期和所用次卡,不展示订单信息 |
|
||
|
||
### 5.2 现有页面调整
|
||
|
||
- 首页读取 `upcoming_sessions`。
|
||
- 课程列表、详情和确认页使用排课接口及 `session_id`。
|
||
- 我的预约增加普通课程预约与次卡预约的切换入口。
|
||
- 普通课程预约列表和详情读取 `booking.session`。
|
||
- 个人中心增加余额、充值、我的次卡、余额流水和消费记录入口。
|
||
- 支付页识别储值卡订单,并强制使用微信支付。
|
||
- 我的订单继续作为消费记录页面,展示新增的会员卡和储值卡订单类型。
|
||
|
||
## 6. 排课模型与标识规则
|
||
|
||
会员端所有可预约课程均为排课 `session`:
|
||
|
||
- `session.id`:排课 ID,用于排课详情、普通课程预约和次卡预约。
|
||
- `session.course_id`:课程模板 ID,仅用于展示、关联和识别课程定义,不能作为预约请求参数。
|
||
- 页面路由中的课程详情 `id` 实际表示 `session.id`。
|
||
- 前端不得把 `course_id` 回退用作排课 ID。
|
||
|
||
统一排课视图模型:
|
||
|
||
```js
|
||
{
|
||
id,
|
||
course_id,
|
||
title,
|
||
cover_image,
|
||
coach_id,
|
||
coach_name,
|
||
start_at,
|
||
end_at,
|
||
capacity,
|
||
booked_count,
|
||
remaining_count,
|
||
price,
|
||
status,
|
||
status_label,
|
||
courts,
|
||
detail_html,
|
||
created_at,
|
||
updated_at
|
||
}
|
||
```
|
||
|
||
列表接口没有的详情字段使用空值填充,使列表和详情可以复用 `toSession()`,但页面不得依赖列表响应中的 `detail_html`。
|
||
|
||
## 7. 接口设计
|
||
|
||
所有接口继续使用综合场馆现有请求封装,基础路径为综合场馆后端的 `/api`,响应仍由请求层解包为 `body.data`。
|
||
|
||
### 7.1 排课
|
||
|
||
| 功能 | 方法与路径 | 参数 |
|
||
|---|---|---|
|
||
| 排课列表 | `GET /api/sessions` | `page`、`page_size`、`date`、`coach_id`、`court_type` |
|
||
| 排课详情 | `GET /api/sessions/{session_id}` | 排课 ID |
|
||
| 创建普通课程预约 | `POST /api/bookings/course` | `{ session_id }` |
|
||
|
||
原 `/api/courses` 不再使用。原普通预约请求中的 `{ course_id }` 改为 `{ session_id }`。
|
||
|
||
首页 `GET /api/contents/home` 返回 `upcoming_sessions`,前端使用同一个 `toSession()` 映射。
|
||
|
||
### 7.2 普通课程预约
|
||
|
||
| 功能 | 方法与路径 |
|
||
|---|---|
|
||
| 预约列表 | `GET /api/bookings/courses` |
|
||
| 预约详情 | `GET /api/bookings/courses/{booking_id}` |
|
||
| 用户取消 | `POST /api/bookings/courses/{booking_id}/cancel` |
|
||
|
||
普通预约视图模型:
|
||
|
||
```js
|
||
{
|
||
id,
|
||
session_id,
|
||
order_id,
|
||
status,
|
||
status_label,
|
||
expire_at,
|
||
checked_in_at,
|
||
cancelled_at,
|
||
cancel_by,
|
||
cancel_reason,
|
||
can_cancel,
|
||
cancel_deadline_at,
|
||
created_at,
|
||
session,
|
||
order
|
||
}
|
||
```
|
||
|
||
前端不再读取 `booking.course_id` 或 `booking.course`。
|
||
|
||
### 7.3 次卡套餐购买
|
||
|
||
| 功能 | 方法与路径 | 参数 |
|
||
|---|---|---|
|
||
| 套餐列表 | `GET /api/membership/plans` | 无 |
|
||
| 创建购买订单 | `POST /api/membership/orders` | `{ plan_id }` |
|
||
|
||
套餐视图模型包含:
|
||
|
||
```js
|
||
{
|
||
id,
|
||
name,
|
||
price,
|
||
total_count,
|
||
is_active,
|
||
courses: [{ id, title }],
|
||
created_at
|
||
}
|
||
```
|
||
|
||
创建成功后使用响应中的 `order.id` 跳转现有支付页。次卡购买订单允许余额支付和微信支付。只有后端确认订单支付成功后,用户持卡才可用于预约。
|
||
|
||
### 7.4 我的次卡与使用流水
|
||
|
||
| 功能 | 方法与路径 | 参数 |
|
||
|---|---|---|
|
||
| 我的次卡 | `GET /api/membership/cards` | `page`、`page_size` |
|
||
| 次卡使用流水 | `GET /api/membership/cards/{card_id}/usage-records` | `page`、`page_size` |
|
||
|
||
用户次卡视图模型:
|
||
|
||
```js
|
||
{
|
||
id,
|
||
plan_id,
|
||
plan_name,
|
||
total_count,
|
||
remaining_count,
|
||
status,
|
||
status_label,
|
||
order_id,
|
||
created_at
|
||
}
|
||
```
|
||
|
||
后端当前没有单张用户次卡详情接口。`card-detail` 使用从卡列表传入或重新在卡列表中查得的卡片数据,并单独请求使用流水。页面不得请求未定义的 `/membership/cards/{card_id}`。
|
||
|
||
使用流水重点展示 `kind_label`、`count`、`remark`、`booking_id`、`order_id` 和 `created_at`。
|
||
|
||
### 7.5 次卡可约排课与预约
|
||
|
||
| 功能 | 方法与路径 | 参数 |
|
||
|---|---|---|
|
||
| 次卡可约排课 | `GET /api/membership/available-courses` | `page`、`page_size` |
|
||
| 创建次卡预约 | `POST /api/membership/bookings` | `{ card_id, session_id }` |
|
||
| 次卡预约列表 | `GET /api/membership/bookings` | `page`、`page_size` |
|
||
| 次卡预约详情 | `GET /api/membership/bookings/{booking_id}` | 预约 ID |
|
||
|
||
`available-courses` 虽保留旧路径命名,但返回对象是排课。前端将其映射为 `availableSession`:
|
||
|
||
```js
|
||
{
|
||
id,
|
||
course_id,
|
||
title,
|
||
cover_image,
|
||
coach_name,
|
||
start_at,
|
||
end_at,
|
||
capacity,
|
||
booked_count,
|
||
remaining_count,
|
||
price,
|
||
available_card_ids
|
||
}
|
||
```
|
||
|
||
其中 `id` 为 `session_id`。前端不自行根据套餐课程计算是否可约,只使用后端返回的列表及 `available_card_ids`。
|
||
|
||
次卡预约视图模型:
|
||
|
||
```js
|
||
{
|
||
id,
|
||
card_id,
|
||
session_id,
|
||
status,
|
||
status_label,
|
||
checked_in_at,
|
||
cancelled_at,
|
||
cancel_reason,
|
||
created_at,
|
||
card,
|
||
session
|
||
}
|
||
```
|
||
|
||
次卡预约没有支付订单,不应补造空 `order` 对象,也不得跳转支付页。
|
||
|
||
### 7.6 储值卡
|
||
|
||
| 功能 | 方法与路径 | 参数 |
|
||
|---|---|---|
|
||
| 储值卡列表 | `GET /api/stored-value/cards` | 无 |
|
||
| 创建购买订单 | `POST /api/stored-value/orders` | `{ card_id }` |
|
||
|
||
储值卡视图模型:
|
||
|
||
```js
|
||
{
|
||
id,
|
||
name,
|
||
price,
|
||
face_value,
|
||
is_active,
|
||
created_at
|
||
}
|
||
```
|
||
|
||
页面必须区分售价 `price` 和充值到账面值 `face_value`。创建订单后使用响应中的 `order.id` 跳转现有支付页。
|
||
|
||
后端实际实现禁止储值卡订单使用余额支付。因此支付页检测到 `order.business_type === "stored_value"` 时:
|
||
|
||
- 不显示或禁用余额支付选项。
|
||
- 默认选择微信支付。
|
||
- 不调用 `/orders/{id}/pay/balance`。
|
||
- 支付完成后重新查询后端余额,不在前端直接加上面值。
|
||
|
||
### 7.7 个人中心
|
||
|
||
| 展示内容 | 数据来源 |
|
||
|---|---|
|
||
| 当前余额 | `GET /api/members/balance` |
|
||
| 余额流水 | `GET /api/members/balance-records` |
|
||
| 我的次卡 | `GET /api/membership/cards` |
|
||
| 消费记录 | `GET /api/orders` |
|
||
|
||
余额流水和消费记录保持为两个概念:
|
||
|
||
- 余额流水展示余额账户的充值、消费和退款等变动。
|
||
- 消费记录复用订单列表,展示课程、包场、门票、会员卡和储值卡订单。
|
||
|
||
储值卡支付成功后,余额流水由后端产生 `kind="recharge"`、`kind_label="充值"` 的正数记录,前端沿用通用余额流水映射和正负金额样式。
|
||
|
||
## 8. 业务流程
|
||
|
||
### 8.1 普通课程预约
|
||
|
||
```text
|
||
排课列表或首页
|
||
→ 排课详情(session.id)
|
||
→ 确认预约
|
||
→ POST /bookings/course { session_id }
|
||
→ 取得 order.id
|
||
→ 订单支付页
|
||
→ 余额支付或微信支付
|
||
→ 普通预约详情
|
||
```
|
||
|
||
### 8.2 次卡购买
|
||
|
||
```text
|
||
商城选择次卡套餐
|
||
→ POST /membership/orders { plan_id }
|
||
→ 取得 order.id
|
||
→ 订单支付页
|
||
→ 余额支付或微信支付
|
||
→ 刷新 /membership/cards
|
||
→ 我的次卡
|
||
```
|
||
|
||
### 8.3 次卡预约
|
||
|
||
```text
|
||
我的次卡详情或课程入口
|
||
→ GET /membership/available-courses
|
||
→ 选择排课
|
||
→ 确定 available_card_ids 中的 card_id
|
||
→ POST /membership/bookings { card_id, session_id }
|
||
→ 次卡预约详情
|
||
```
|
||
|
||
选择规则:
|
||
|
||
- `available_card_ids` 只有一个值时直接使用该卡。
|
||
- 有多个值时展示卡片选择器,由用户确认具体次卡。
|
||
- 从某张次卡详情进入时预选该卡,并过滤 `available_card_ids` 不包含该卡 ID 的排课。
|
||
- 预约成功只占名额,不立即减少次数。
|
||
- 后台核销后扣减次数;后台取消后释放该预约状态。
|
||
- 后端当前未提供会员自行取消次卡预约接口,前端不显示取消按钮。
|
||
|
||
### 8.4 储值卡购买
|
||
|
||
```text
|
||
商城选择储值卡
|
||
→ POST /stored-value/orders { card_id }
|
||
→ 取得 order.id
|
||
→ 订单支付页(仅微信支付)
|
||
→ 后端确认支付并按 face_value 充值
|
||
→ 重新查询余额和余额流水
|
||
```
|
||
|
||
关闭未支付储值卡订单不改变余额。
|
||
|
||
## 9. 我的预约展示
|
||
|
||
“我的预约”页面保留课程、包场和门票业务入口,并在课程预约内区分:
|
||
|
||
- 普通课程预约:来自 `/bookings/courses`,展示订单金额和订单状态,可按后端 `can_cancel` 取消。
|
||
- 次卡预约:来自 `/membership/bookings`,展示次卡名称和剩余次数,金额位置显示“次卡预约”,不展示订单操作。
|
||
|
||
两类预约分别维护请求状态和分页,不将次卡预约伪装成普通预约。切换分类时加载对应接口。
|
||
|
||
次卡预约状态包括:
|
||
|
||
- `booked`:已预约,等待到场处理。
|
||
- `checked_in`:已核销,后台已扣减次数。
|
||
- `cancelled`:已由后台取消。
|
||
|
||
## 10. 预约场地字段兼容
|
||
|
||
排课列表和排课详情返回 `courts`,可以正常展示场地。
|
||
|
||
普通预约与次卡预约响应中的嵌套 `session` 当前不包含 `courts`。本次前端实施采用以下规则:
|
||
|
||
- 预约列表和预约详情不依赖 `session.courts`,暂不展示场地名称。
|
||
- 显示标题、教练、上课时间、状态及订单或次卡信息。
|
||
- 映射函数可兼容接收未来新增的 `courts`,但不得假设该字段存在。
|
||
- 后端未来补充 `courts` 后,前端可再恢复预约详情中的场地展示。
|
||
|
||
## 11. 登录与访问控制
|
||
|
||
无需登录即可访问:
|
||
|
||
- 首页及排课列表、排课详情。
|
||
- 商城商品列表。
|
||
- 次卡套餐列表和储值卡列表。
|
||
|
||
必须登录才能执行:
|
||
|
||
- 创建普通课程预约。
|
||
- 购买次卡或储值卡。
|
||
- 使用次卡预约。
|
||
- 查看我的次卡、次卡流水、预约、余额、余额流水和订单。
|
||
|
||
受限操作发现未登录时调用现有综合场馆登录流程。登录成功后继续原操作,并保留当前选中的商品、排课和次卡;登录失败或用户取消时停留在当前页面。
|
||
|
||
401 或业务码 `40001` 继续由综合场馆请求层清理综合场馆 token,不影响冰场馆登录态。
|
||
|
||
## 12. 可用性与提交控制
|
||
|
||
### 12.1 普通预约
|
||
|
||
普通预约按钮至少满足以下条件才可用:
|
||
|
||
- `status === "published"`。
|
||
- `remaining_count > 0`。
|
||
- `start_at` 晚于当前时间。
|
||
|
||
最终可预约性以后端创建预约接口校验结果为准。
|
||
|
||
### 12.2 次卡预约
|
||
|
||
- 只从 `/membership/available-courses` 选择排课。
|
||
- 不在前端根据套餐课程列表推导可预约范围。
|
||
- 选中的 `card_id` 必须存在于该排课的 `available_card_ids`。
|
||
|
||
### 12.3 防重复提交
|
||
|
||
以下操作设置独立的 `isSubmitting` 或等价状态,并在请求期间禁用操作按钮:
|
||
|
||
- 创建普通课程预约。
|
||
- 创建次卡购买订单。
|
||
- 创建储值卡购买订单。
|
||
- 创建次卡预约。
|
||
- 发起订单支付。
|
||
|
||
提交状态在 `finally` 中恢复。接口成功后的页面跳转只执行一次。
|
||
|
||
## 13. 支付处理
|
||
|
||
- 余额支付接口成功后可视为后端已经完成支付及业务确认。
|
||
- 微信 `uni.requestPayment` 成功后重新查询订单详情,以后端订单状态为准。
|
||
- 微信支付取消或失败时保留待支付订单,用户可从我的订单再次进入支付。
|
||
- 储值卡订单仅允许微信支付。
|
||
- 次卡购买订单允许余额支付和微信支付。
|
||
- 支付成功后不在前端直接修改余额、持卡列表或剩余次数,而是重新请求对应接口。
|
||
|
||
## 14. 错误处理
|
||
|
||
请求层继续统一展示后端 `message`。页面在以下业务错误后刷新相关数据,避免保留过期按钮状态:
|
||
|
||
- 排课已开始、已取消或未上架。
|
||
- 排课名额已满。
|
||
- 用户已存在普通预约或次卡预约。
|
||
- 次卡不可用、次数已用完或不覆盖该课程。
|
||
- 次卡套餐或储值卡已下架。
|
||
- 余额不足。
|
||
- 订单已支付、已关闭或已过期。
|
||
|
||
页面级错误状态至少区分:
|
||
|
||
- 首次加载中。
|
||
- 正常内容。
|
||
- 空数据。
|
||
- 请求失败,可重试。
|
||
- 提交中,按钮禁用。
|
||
|
||
## 15. 分页与刷新
|
||
|
||
以下列表使用现有分页约定 `page`、`page_size`、`items`、`total`:
|
||
|
||
- 排课列表。
|
||
- 普通课程预约。
|
||
- 次卡预约。
|
||
- 我的次卡。
|
||
- 次卡使用流水。
|
||
- 余额流水。
|
||
- 消费记录。
|
||
|
||
下拉刷新时重置为第 1 页并替换列表;触底加载时追加下一页;以当前项目统一规则 `items.length < total` 判断是否还有更多数据。加载更多请求期间不得重复发起同一页请求。
|
||
|
||
次卡套餐列表和储值卡列表目前不分页,直接加载全部上架商品。
|
||
|
||
## 16. 验收标准
|
||
|
||
### 16.1 排课链路
|
||
|
||
- 首页读取并展示 `upcoming_sessions`。
|
||
- 排课列表筛选继续支持日期、教练和场地类型。
|
||
- 排课列表、详情和普通预约全程使用同一个 `session.id`。
|
||
- 普通预约请求发送 `{ session_id }`,成功后进入支付页。
|
||
- 普通预约列表和详情正确读取 `booking.session`,不再访问旧 `booking.course`。
|
||
|
||
### 16.2 次卡购买与持卡
|
||
|
||
- 商城可以展示上架的次卡套餐、价格、总次数和适用课程。
|
||
- 创建次卡订单后可以选择余额或微信支付。
|
||
- 支付成功后可以在“我的次卡”看到卡片及正确剩余次数。
|
||
- 次卡详情可以查看使用流水,并进入可约排课页面。
|
||
|
||
### 16.3 次卡预约
|
||
|
||
- 可约排课只显示后端返回的、用户次卡覆盖的未来排课。
|
||
- 一个排课有多张可用次卡时可以选择具体卡。
|
||
- 次卡预约请求发送 `{ card_id, session_id }`。
|
||
- 次卡预约成功后不创建前端支付流程,也不立即减少次数。
|
||
- 后台核销后刷新页面显示 `checked_in`,卡片剩余次数同步减少。
|
||
- 后台取消后刷新页面显示 `cancelled`。
|
||
- 前端不提供次卡预约取消按钮。
|
||
|
||
### 16.4 储值卡
|
||
|
||
- 商城正确区分售价和到账面值。
|
||
- 创建储值卡订单后支付页只允许微信支付。
|
||
- 支付成功后余额增加 `face_value`,而不是 `price`。
|
||
- 余额流水出现“充值”记录。
|
||
- 关闭未支付订单不会改变余额。
|
||
|
||
### 16.5 个人中心和消费记录
|
||
|
||
- 个人中心展示后端最新余额。
|
||
- 可以进入充值、我的次卡、余额流水和消费记录。
|
||
- 订单列表正确显示“会员卡”和“储值卡”业务类型。
|
||
- 余额流水与订单消费记录分开呈现。
|
||
|
||
### 16.6 回归
|
||
|
||
- 包场预约流程不受影响。
|
||
- 门票购买、持有和核销展示不受影响。
|
||
- 已有订单详情、关闭订单、余额支付和微信支付流程不受影响。
|
||
- 冰场馆模块的页面、接口、token 和状态不受影响。
|
||
|
||
## 17. 实施顺序
|
||
|
||
1. 修改排课 API、首页字段和普通预约映射,恢复现有课程链路。
|
||
2. 新增次卡 API 模块、商城套餐购买和我的次卡。
|
||
3. 新增次卡可约排课、创建预约、预约列表和详情。
|
||
4. 新增储值卡 API、商城展示和购买流程。
|
||
5. 修改支付页,落实储值卡仅微信支付。
|
||
6. 完善个人中心余额、充值、次卡、流水和消费记录入口。
|
||
7. 完成分页、刷新、错误状态和全链路回归验证。
|
||
|
||
## 18. 后端契约依赖
|
||
|
||
本设计以当前综合场馆后端实际实现为准,依赖以下既有行为:
|
||
|
||
- `/api/sessions` 返回会员端排课。
|
||
- 普通预约接收 `session_id`,预约响应嵌套字段名为 `session`。
|
||
- 次卡套餐绑定课程模板,但可约接口返回模板覆盖的具体排课。
|
||
- 次卡预约时占用名额,后台核销时扣减次数。
|
||
- 储值卡订单禁止余额支付,微信支付成功后按面值充值。
|
||
- 余额、余额流水和订单状态均可在支付或后台操作后重新查询。
|
||
|
||
普通预约和次卡预约的嵌套 `session` 暂无 `courts` 是已知契约限制,本次通过不依赖该字段完成前端对接,不阻塞实施。
|