返回作品集
💻 代码项目

格间 GridSpace · 共享空间预约系统

面向会议室 / 自习室 / 工位的时段预约小程序,核心是一张「日期 × 时段」二维网格,直观展示谁在何时占用空间。

2026年9月15日

微信小程序云开发 CloudBaseJavaScript并发控制scrypt端到端测试

定位

面向多人共享场地(会议室、自习室、工位、直播间)的时段预约。核心界面是「日期 × 时段」二维网格(07:00–23:00、30 分钟粒度、每天 32 个时段、默认 15 天视窗),格内显示「预约人昵称 + 事件名」,一眼看清占用情况。

功能预览

空间详情 —— 「日期 × 时段」二维网格,格内直接显示预约人昵称与事件名,四态图例区分空闲 / 已预约 / 我的 / 已过期
空间详情 —— 「日期 × 时段」二维网格,格内直接显示预约人昵称与事件名,四态图例区分空闲 / 已预约 / 我的 / 已过期
创建预约 —— 30 分钟粒度起止时段选择,当日占用条可视化辅助避让冲突,服务端强校验区间相交
创建预约 —— 30 分钟粒度起止时段选择,当日占用条可视化辅助避让冲突,服务端强校验区间相交
筛选日期 —— 起止日期筛选,单次最多查看 31 天,与 15 天默认视窗配合浏览历史与未来排期
筛选日期 —— 起止日期筛选,单次最多查看 31 天,与 15 天默认视窗配合浏览历史与未来排期
个人中心 —— 脱敏邮箱展示,聚合「我的空间」与「待开始预约」统计,提供跨空间的「我的预约」入口
个人中心 —— 脱敏邮箱展示,聚合「我的空间」与「待开始预约」统计,提供跨空间的「我的预约」入口

架构决策

  • 单一请求出口:utils/api.js 是唯一对外请求出口,页面只调语义化方法,不直接接触 wx.cloud;config.DATA_MODE 在 mock 与 cloud 间切换,页面代码零改动。
  • 双模式数据层:mockdb.js 约 1150 行复刻云端业务规则与错误码,内置 3 个空间 / 10 条预约种子数据,不配云环境也能开箱运行;两种模式共用同一套页面。
  • 按域聚合的云函数:4 个云函数(auth 10 / space 12 / booking 4 / user 1 个 action),统一 { code, msg, data } 响应;共享内核 lib/core.js 以四份内容一致的副本存在,用 SHA256 去重校验一致性。
  • 权限前置:所有集合设为「所有用户不可读写」,读写全经云函数(管理员身份运行),客户端不直连数据库——这是服务端权限校验的前提。

踩过的坑与权衡

  • 并发一致性三层防护:预检查询降低锁竞争 → 逐时段以 _id = {spaceId}_{date}_{slot} 抢锁(唯一约束兜底,任一时段写入失败即释放全部并返回 40901,不会出现半占用)→ 写入成功后回填 bookingId、取消时按 bookingId 精确释放。冲突判定用区间相交(startSlot < b.endSlot && endSlot > b.startSlot),相邻时段不误判。
  • 冗余字段换取索引能力:spaces 的 memberIds(扁平数组,支撑多值索引)与 members(展示信息)有意冗余,因为云开发不支持对数组内对象的字段建索引;两者必须在同一次写入中保持一致。
  • 测试驱动出真实缺陷:自研 Node 断言脚本(构建伪 wx 运行环境)跑端到端,qa-business-rules.js 77 项 + qa-invite-flow.js 48 项全部通过,测出 8 项缺陷。其中高优先级一项为 inviteExpireAt 字段写入却从未被校验,导致过期邀请链接永久有效(本地模拟层与云端云函数同时存在),修复方式是抽出统一校期函数并在三处调用。

技术栈

微信小程序原生开发、JavaScript(ES6)、原生 WXSS + CSS 自定义属性;微信云开发(CloudBase)云函数 + 云数据库 + 云存储、wx-server-sdk;nodemailer;scrypt 加盐哈希、HMAC-SHA256 票据。