更新记录

1.0.0(2026-09-17)

首次发布 SlotBoard X。支持单日多资源预约时段展示、独占与共享容量、预约前后缓冲、停用时段及冲突原因提示;提供受控候选、数据版本重校验和可取消的分段网格计算。组件仅向业务页面返回预约候选,不创建订单。


平台兼容性

uni-app x(5.24)

Chrome Safari Android iOS 鸿蒙 微信小程序
153.0.8010.48 - 16.0 - - -

SlotBoard X · 规则核心与组件开发

用于 UTC+8 单日、多资源容量、准备/清理缓冲与停用时间的预约选择组件开发。当前包含 JavaScript 参考内核和完整同步 UTS 模块;UTS 最终基线已在 HBuilderX 5.24 Web 与 Android 16/API 36、x86_64 模拟器真实编译运行通过,见完整报告。这不是已上架商品:可视组件、主线程分段计算与取消、发行及加密授权仍按商品规格分别开发验收,当前状态见GATES。分段计算方案不是后台线程,不把同步算法通过扩写为 UI 或商业关卡通过。

本页以下记录 JavaScript 同步 API,零第三方运行依赖,可被支持 ES modules 的浏览器导入;命令行测试使用 Node.js 内置测试运行器。声明 Node.js 22+ 为预期运行范围,目前实际运行证据覆盖 Node.js v25.9.0,以及从 GitHub 全新克隆后运行的 v22.22.2 / Windows 11,未测试版本不能计为已验证兼容。uni-app x 消费者使用根 index.uts导出及UTS 模块契约,不要直接引入内部文件。总外部预算 500 CNY;截至 2026-09-17 支出/承诺 0 CNY,实际净收入 0 USD。

用户已完成 HBuilderX 登录并提供真实 AppID __UNI__3D0563F。规则宿主和商品演示工程均已成功导出本地 Web 发行包(关闭托管上传);规则发行包的 1812/50/16/5/6 与新增 11 组分段任务已在浏览器通过。商品 UI、Android 新增任务、干净安装与付费授权继续验收,见新增报告。本人协助步骤和换机方式见指南

本地运行

在本目录执行(不需要 npm install):

node --test tests/*.test.mjs
node scripts/benchmark.mjs
npm run check

tests/results/ 保存本次真实运行的记录。所有样例与基准数据均为合成数据。

API

import { validateCandidate, createValidationSession } from './core/index.mjs';

const input = {
  schemaVersion: 1,
  serviceDate: '2026-10-01',
  timezone: 'UTC+08:00',
  resources: [{ id: 'court-a', label: '球场 A', capacity: 1 }],
  bookings: [
    {
      id: 'b1',
      resourceId: 'court-a',
      startMinute: 600,
      endMinute: 660,
      quantity: 1,
    },
  ],
  blocked: [],
  rules: {
    openMinute: 480,
    closeMinute: 1200,
    stepMinute: 15,
    minDuration: 30,
    maxDuration: 180,
    bufferBefore: 0,
    bufferAfter: 0,
  },
  dataVersion: 'v1',
  loading: false,
};
const candidate = {
  resourceId: 'court-a',
  startMinute: 660,
  endMinute: 690,
  quantity: 1,
};
validateCandidate(input, candidate);
// { valid: true, code: 'OK', messageKey: 'slotboard.ok',
//   remainingCapacity: 1, dataVersion: 'v1' }

validateCandidate(input, { ...candidate, startMinute: 630 });
// { valid: false, code: 'CAPACITY_EXCEEDED',
//   messageKey: 'slotboard.capacity_exceeded', remainingCapacity: 0,
//   dataVersion: 'v1' }

validateCandidate(input, candidate) 同步返回校验结果,不修改输入、创建订单、写入数据库或发送网络请求。输入是普通 JSON 形状的数据,不支持有副作用的 getter、Proxy 或函数。字段类型见 core/types.mjs

remainingCapacity 表示候选有效区间内,添加候选前的最低剩余容量。只有 OKCAPACITY_EXCEEDED 返回数值,其余为 null,避免 UI 把未知余量显示成可预约。无可用版本时 dataVersionnulldetails.pathdetails.reason 用于定位非法输入,不包含原始业务记录;其文案可随原型改进,公开错误码保持稳定。

数据约束

  • schemaVersion 只支持数值 1serviceDate 必须是有效公历日期 YYYY-MM-DD,年份为 0001–9999。timezone 必须精确为 UTC+08:00。不存在系统本地时区换算或夏令时推断。
  • 所有分钟为整数,原始预约、候选和停用区间满足 0 <= startMinute < endMinute <= 1440,使用半开区间 [start,end)。00:00 对应 0,24:00 只允许作为结束时间 1440。
  • 资源和订单 ID 分别全局唯一,区分大小写,必须是非空字符串;标签和版本也必须是非空字符串,最长 128 个字符。字段不自动修剪、转数字或改名。
  • capacityquantity 是正安全整数。资源引用必须存在。停用区间可重复或重叠,其效果仍是整体不可用。
  • 规则包含所有 7 个分钟字段;营业起点严格早于终点;步长和最短/最长时长均为正整数,最短不大于最长;缓冲为非负整数;每个规则分钟字段不大于 1440。
  • 起点以营业起点为步长锚点,即 (startMinute - openMinute) % stepMinute === 0;持续时间需为步长的整数倍。营业时间为 08:07、步长 15 时,08:07 与 08:22 是合法网格起点。
  • 已有预约无需对齐步长,也可以在营业时间外,但原始区间仍须在同一日内。所有预约都按当前全局缓冲规则扩展,不静默截断至营业时间或日边界;候选扩展后的整个区间必须落在营业时间内。停用区间本身不扩展缓冲。
  • 原型上限是 20 个资源、2,000 个订单、2,000 个停用区间。超限返回 INVALID_INPUT,不截断数据。资源列表不能为空。
  • 未知额外字段会被忽略,不能影响校验。日期、资源、订单、规则改变时,调用方必须更新版本并重新校验。

容量语义与错误顺序

事件扫描按资源分别计算同时占用峰值;同一分钟先处理结束再处理开始。不能把所有与候选相交的订单简单相加。比如两个相邻的数量 1 订单 [600,630)[630,660) 对候选 [600,660) 的最大同时占用为 1。

已有订单的任何资源出现超容量,将整个输入视为不一致,返回 INVALID_INPUT 这是本原型的输入一致性策略,与候选预约占用超容量时的 CAPACITY_EXCEEDED 不同,也不意味着把不同资源的占用相加。全局缓冲改变后可能使原先相邻的已有订单发生冲突,调用方必须先处理该数据问题。

校验顺序为:输入结构和引用 → 加载状态 → 显式过期状态 → 已有容量一致性 → 候选结构 → 候选版本 → 时长 → 步长 → 营业时间 → 停用时间 → 可用容量。同一输入同时违反多条规则时,返回第一条错误。加载中的数据仍须有完整合法的结构;可沿用上一快照并设置 loading: true

错误码 含义
OK 本地快照允许该候选
INVALID_INPUT 非法结构、引用、日期、数值、重复 ID、大小超限或已有超容量
DATA_LOADING loading: true,此时不能提交选择
DATA_STALE stale: true 或候选可选 dataVersion 与输入不同
DURATION_INVALID 候选时长超出最短/最长范围
STEP_INVALID 起点或时长不符合步长
OUT_OF_HOURS 包含缓冲的候选区间不在营业时间内
RESOURCE_BLOCKED 包含缓冲的候选区间与同资源停用时间相交
CAPACITY_EXCEEDED 候选数量大于当前剩余容量

版本、加载与过期合同

dataVersion 是调用方提供的不透明、非空快照标识,原型不会从版本字符串猜测时间先后,也无法推断服务器是否已出现新订单。调用方获知数据过期时设置可选的 stale: true;候选可携带可选 dataVersion,用于拒绝基于旧快照提交的选择。

受控 UI 可以使用同步适配器:

const session = createValidationSession(input);
session.select(candidate); // 返回状态:候选、合法选择、校验结果
session.update({ ...input, dataVersion: 'v2', loading: true });
// selection 为 null,validation.code 为 DATA_LOADING,不保留旧余量。
session.update({ ...input, dataVersion: 'v3', loading: false });
// 对上一候选重新校验;只有新结果合法时 selection 才有值。
session.getState();
session.clear();

select()update()clear() 返回 { generation, candidate, selection, validation }candidate 是上一尝试,selection 仅在当前校验合法时非空,且始终携带与 validation.dataVersion 相同的当前快照版本;validation 未执行时为空。update() 即使收到相同版本也重算;重算时移除上一候选的版本标签,并使用最新输入版本生成结果与带版本的 selection。向后续步骤传递合法选择时应使用 selection,而不是无版本保证的原始 candidate。快照与返回值通过 structuredClone 隔离,调用方不能用对象引用修改会话内部数据。

generation 在每次 select()update()clear() 时递增,包括被拒绝的选择。同一数据快照下连续选择两个不同候选也会得到不同 generation。异步消费者必须丢弃旧 generation 的结果;本页的同步会话 API 本身不提供后台线程或中途取消,不能把版本失效冒充 A09 的分段/取消验收。正在开发的 UTS 可取消网格采用主线程分段让出;同步准备和单格校验不能被中途抢占,具体接口与验收见PRD。业务下单仍需由调用方服务器重新校验并原子写入,本地组件不防止并发超卖。

已验证与未验证

本轮包含 A01–A08 固定回归、无效输入边界、日期与数字边界、1600 组固定种子的逐分钟独立 oracle 比对。随机测试失败会输出 seed、case、输入及候选以便复现;oracle 不导入生产容量函数,不使用排序或事件扫描。

性能脚本生成 20 个资源、2,000 个订单,预热 30 次,测量 200 次完整同步校验(包括结构检查与全资源一致性检查)。输出真实环境与 p50/p95/最大耗时,不当作营销承诺。结果见 tests/results/benchmark.json

完整 UTS 同步核心已有最终 Web 1812/50/16/5/6、Android 1812/50/11/5/3 五组运行证据(依次为规则、会话、运行值、隔离、新增边界),实际源码/环境和失败修复记录见对照报告。Web easycom 最小接口也有独立宿主报告;简单容量 smoke 不替代完整算法,算法测试页不替代最终商品交互。

仍待完成或按最新证据更新:最终商品 UI、可取消分段任务的两端运行、干净安装和发行、平台试用/正式加密授权、实际支持渠道、真实客户与销售验证。实体 Android 设备和其他系统版本未自动验证。以兼容表GATES记录每项实际状态,不从 Node 测试推断平台通过。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无,组件不申请额外系统权限。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

组件仅在调用方应用内存中处理传入的预约快照,不采集、上传或持久化数据;不向任何服务器发送预约数据,不包含第三方采集 SDK。插件的构建与付费授权可能使用 DCloud 平台服务,依平台流程处理。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无,组件不包含广告。

暂无用户评论。