座位状态与保留类型

Seatmap.pro 通过双层状态模型跟踪每个活动的每个座位。第一层是固定的生命周期状态集合,预订引擎用它处理并发和可用性;第二层是按组织定义的开放字符串 holdType,描述业务背景:为何保留座位、谁能释放、在座位图中如何显示。

两个层级

层级 字段 值 控制内容
生命周期 state 固定枚举 并发、可用性
保留类型 holdType 开放字符串 释放策略、支付、显示

预订引擎仅根据座位是否为 ACTIVE 判断能否锁定。holdType 是控制该座位周边业务流程的元数据。

生命周期状态

平台固定提供三种状态。

状态 含义 可预订
ACTIVE 可选择 是
LOCKED 不可用,原因由 holdType 说明 否
SOLD 已确认并完成 否

典型购物车流程为 ACTIVE → LOCKED → SOLD;放弃购物车则 LOCKED → ACTIVE。损坏、视线受阻或其他停售座位使用 LOCKED,并以保留类型记录原因。目前由 RESERVED 覆盖此场景,专用默认类型 OUT_OF_SERVICE 尚在计划中。

注意 API 的 state 枚举还包含 BLOCKED。平台不会设置该值,也不会返回此状态的座位,且正在弃用它。按 state 分支处理时,请将其视为不可用。

GET /api/private/v2.0/events/{id}/seats/ 返回活动中每个座位的状态、排、区域和价格。此端点支持增量读取:将已见到的最大 updatedAt 作为 lastUpdated 传回,即可仅获取此后的变化。

保留类型

座位离开 ACTIVE 时可附加字符串 holdType。它与生命周期状态并列,描述座位被保留的原因。

平台默认值

内置两种保留类型:

保留类型 有效状态 可释放者 支付 显示
CART LOCKED 顾客、管理员、系统 需要 In Cart
RESERVED LOCKED 管理员 不需要 Reserved

CART 是 v2 /lock 端点的默认值,请求省略 holdType 时使用它。

RESERVED 用于运营人员在销售流程之外保留的座位,例如为指定客户预留或停售的座位,只能通过显式 /unlock 释放。

警告 下文的 ttlSeconds 字段可以作为保留类型定义的一部分接收并存储,但当前不会强制执行到期自动释放。保留会持续到显式调用 /unlock、/sale 或 /revertsale。不要依赖保留自动解除。

定义自有保留类型

除两个默认值外,自定义保留类型由 Seatmap.pro 为组织配置。将所需定义发送给我们,可应用到组织,或应用到租户并由其下所有组织继承。

注意 目前没有自助定义保留类型的端点,请联系支持团队提供所需定义。

定义结构:

{
  "holdTypes": {
    "PARTNER_HOLD": {
      "validStates": ["LOCKED"],
      "ttlSeconds": 3600,
      "releaseApi": "ADMIN,API",
      "paymentRequired": true,
      "displayName": "Partner Hold",
      "displayColor": "#8B008B"
    },
    "COMP": {
      "validStates": ["LOCKED", "SOLD"],
      "ttlSeconds": null,
      "releaseApi": "ADMIN",
      "paymentRequired": false,
      "displayName": "Complimentary",
      "displayColor": "#FFD700"
    }
  }
}

字段参考:

字段 类型 说明
validStates 字符串数组 此保留类型适用的生命周期状态;无效组合会被拒绝。
ttlSeconds 整数或 null 预期自动释放时间窗,单位秒。目前仅作为配置元数据存储,不执行自动释放;null 表示保留至显式释放。
releaseApi 字符串 允许释放的角色,以逗号分隔:CUSTOMER、ADMIN、SYSTEM、API。
paymentRequired 布尔值 转为 SOLD 前是否需要支付。
skipLockedState 布尔值 为 true 时直接从 ACTIVE 转为 SOLD,用于售票处流程。
displayName 字符串 管理界面显示的人类可读标签。
displayColor 字符串 渲染器样式的十六进制颜色。
displayIcon 字符串 可选渲染器图片或图标引用。

租户级继承

组织属于租户时,可在租户层定义一次,供其下所有组织使用。组织覆盖按字段优先,例如只修改 CART 的 displayColor,无需重写整个定义。

查找优先级为:组织定义、租户定义、平台默认值。三层会合并;组织只覆盖 displayColor 时,其他字段继续从租户或平台继承。

在 Booking API 中使用保留类型

v2 锁定请求接受可选 holdType:

POST /api/private/v2.0/booking/lock?eventId=123e4567-e89b-12d3-a456-426614174000
Content-Type: application/json

{
  "sessionId": "abc123",
  "seats": [{ "id": 42 }],
  "holdType": "PARTNER_HOLD"
}

座位离开 ACTIVE 时会校验保留类型:

  • 必须通过平台默认值、租户定义或组织定义对调用组织可用。
  • validStates 必须包含目标生命周期状态。

未知或不匹配的保留类型返回 400 Bad Request。/unlock 和 /revertsale 不接受 holdType;座位回到 ACTIVE 时,会清除附加的保留类型。

并发

每次状态变更都会检查座位当前状态是否符合预期。两个并发请求不能同时成功锁定同一座位:后执行者发现状态不符,将该座位列入失败尝试列表。无论购物车流程如何重叠,都可防止重复预订,调用方无需额外协调。

审计记录

每次成功状态转换均以不可变记录保存:

  • 原生命周期状态和新状态。
  • 转换时的保留类型。
  • 会话 ID(如有)。
  • 受影响座位或座位组。
  • 时间戳。

记录可支持转化报告,例如某周有多少比例的 CART 保留变为 SOLD。目前不通过 API 提供。若您的管理工具需要单座位转换历史,请联系支持团队讨论范围。

Renderer 集成

预订渲染器默认按 ACTIVE、LOCKED、SOLD 生命周期状态绘制座位。

若要用自己的颜色、动画或图标显示 holdType 或其他业务区别,可使用 SDK 的 setSeatsState(seats, stateKey)、clearSeatsState(seats),配合声明式 theme.seatStyles。

重要 座位端点目前返回生命周期 state,但不返回每个座位的 holdType。请在自己的系统中跟踪已应用的保留类型,并在绘图时映射到渲染器状态键。在座位载荷中返回 holdType 尚在计划中。

完整 API、类型及示例见**自定义座位状态(Renderer SDK)**。

  • Booking Renderer 自定义座位状态:在浏览器中应用任意座位状态及样式。
  • Booking Renderer 区域状态与样式:区域轮廓的高亮、选中、不可用及过滤状态。
  • Admin Renderer Admin Renderer:基于相同座位模型的选择模式和工作人员工具。

输入功能、设置、端点或 SDK 方法。