百花同行 v2.0 更新

本项目唯一活档
项目路径:D:/Projects/BHTX(微信原生前端 + Node/Express 后端 server.js + MongoDB)
用户目标:①全面重构拼车模式(信息板→真撮合)②不碰资金(只做费用提示)③加数据埋点


进度总览

✅ 已完成(2026-08-10 ~ 08-11)

  • Phase 4 埋点:AnalyticsEvent 事件表 + trackEvent + 事件上报 + /api/stats/funnel 漏斗接口
  • Phase 1 撮合核心(后端):行程模型扩展(capacity/headcount/members/status五态/feeHint)、join/leave/members/joined/status 接口、并发原子防超卖、联系方式解锁(须已加入)、自定义ID(限频改)、2行程限制
  • Phase 1 撮合核心(前端):detail(加入/退出/成员列表/联系方式解锁)、mytrips(合并列表/下架)、mine(自定义ID修改)、index(满员标识/人数)
  • 费用提示:14 条路线价格表(实测:近郊10-16/城区20-30/车站机场100-300,只北区)+ 详情页展示
  • 迁移脚本:migrate-v1.3.js(已跑 ✅)
  • v2.0 发布页重构:单页上下滚动、即刻出发精简(默认30min)、拼1/2/3人三档、合并发布按钮(智能判断+ActionSheet)
  • members 脱敏:公开接口;未加入/游客显示"北化校友"无联系方式,成员/发起人显示实时 ID + 联系方式+复制
  • 座位机制作废:只限人数,成员线下分位置
  • 订阅消息:加入通知发起人(后端+前端代码完成,待模板 ID)
  • 多个 bug 修复:seat enum 空串、2行程双倍计数、memberLoading 卡死、改名实时生效
  • UI 打磨:CSS 头像(肩36%)、详情页 label+大字排版、大厅即刻置顶、x/y人、双滚动条修复
  • 版本号:about v2.0;用户协议更新:legal.wxml(v2.0 条款)
  • 协议交互(08-11):发布/加入协议默认不打勾 + 未勾选时弹窗一键「同意发布/同意加入」;详情页勾选框仅在未加入时显示(⚠️ wx.showModal confirmText 限 4 字,曾因 5 字静默失败排查多轮)
  • 统一退出按钮(08-11):详情页发起人/成员统一「退出行程」——发起人点击=解散全团(cancel 全员退出,toast 后回首页),成员点击=自己退出(leave,满员补位)
  • isOrganizer 修复(08-11):详情请求去掉 needAuth:false(不带 token 导致后端无法识别发起人身份,发起人被当成员走 leave 被拒)
  • 订阅消息已接入(08-11):模板「活动成行通知」12942(SX00atx2FNmRoQ5HyC9lsqeA8fZKNVeDP1PtBp6D2yc),thing4=路线/time3=时间/thing2=加入者ID/thing5=进展;发布成功弹授权(等用户操作完再跳转,8s 超时兜底);.env 已配 SUBSCRIBE_TEMPLATE_ID
  • 全量逻辑审查修复 3 个严重 bug(08-11):①拼3人容量被 Math.min(...,4) 截断→上限改5 ②myJoined 数组多条件无 $elemMatch 导致自己发布的行程有乘客加入后被误计数→两处改 $elemMatch ③订阅授权不绑定 tripId 会串行程→按 tripId 匹配
  • 中等问题全修(08-11):JoinStat TTL 1h、AnalyticsEvent TTL 90天(需手动建索引,Amadeus 已执行)、emailPrefix 格式校验、members.seat 去 enum、删除 inactive 死代码接口
  • 分享卡片升级(08-13):Canvas 动态生成行程专属分享封面(500×400,2倍分辨率)——白底 + 顶部蓝色装饰条、logo 110×110、品牌名「百花同行 · 拼车小程序」、路线大字(伪粗体)、橙色时间、人数、浅蓝底「点击加入行程」;群聊 + 朋友圈生效
  • 认证体验优化(08-13):验证码输入框下灰字提示「请在"企业微信 — 工作台 — 电子邮件"查收验证码」;发送成功去掉重复 toast
  • 解绑自动解散(08-13):解除邮箱认证时自动把发起的所有 active/full 行程 → cancelled + 全员退出;前端确认弹窗加后果提示

⏳ 待做

  • 重新部署最新 server.js(2026-08-11 已部署:含全部 bug 修复/容量/$elemMatch/订阅配置/协议/统一退出/TTL;TTL 索引 Amadeus 已建)
  • ⏳ 前端上传体验版 → 双人流程测试(发布/加入/满员/联系方式/解散)→ 通过后提审正式发布
  • ⏳ 订阅消息模板审核(已选用「活动成行通知」12942,等审核通过后通知功能才生效)
  • Phase 2:后端搜索过滤 + 路线快捷筛选
  • 发布页选路线时的实时费用提示(可选,费用展示已下线)

📦 项目迁移(2026-08-10)

  • BHTX 已搬至 D:/Projects/BHTX(164 文件全齐,.git/.env/未提交的 v2.0 改动完好,桌面源已删)
  • 个人网站已搬至 D:/Projects/Prom1seCN(改名)
  • git token 清理(2026-08-11):remote 改回 HTTPS(无嵌入 token),认证走系统凭据管理器;GitHub 网站上旧 token 已撤销;SSH key 未配(不阻塞)
  • 桌面「百花同行」文件夹里剩余:BHTX 副本/BHTXold/nginx配置/文档/PPT等(未搬,需要再说)

📊 埋点漏斗看板(2026-08-11 上线)

  • server.js 加静态托管 app.use(express.static("public"));funnel.html 已传服务器 bhtx-backend/public/funnel.html
  • 访问:https://bhtx.prom1se.cn/funnel.html,填 ADMIN_KEY(服务器 .env 的 ADMIN_KEY)即可看 浏览→发布→加入 漏斗 + 8 种事件独立用户数
  • 本地副本:D:/Projects/BHTX/public/funnel.html(以后改完同步上去)

🖥️ 服务器现状(2026-08-11 更新)

  • BHTX 路径:/home/ubuntu/bhtx-backend/已部署 v2.0 最新版 server.js,含全部修复)
  • pm2 进程:bhtx(重启 pm2 restart bhtx,无响应兜底 pm2 kill && pm2 start ecosystem.config.js
  • MongoDB:docker 容器 bhtx-mongo,连接串 mongodb://localhost:27017/bhtx
  • 数据量:users 204 / trips 164 / contactcopies 145 / auths 34
  • 端口:3000(nginx 反代 80/443);https://bhtx.prom1se.cn/api/... 可达
  • .env:含 WX_APP_SECRET/JWT_SECRET/SMTP_USER/SMTP_PASS/ADMIN_KEY + SUBSCRIBE_TEMPLATE_ID(08-11 加)
  • TTL 索引已建(Amadeus 执行):joinstats 1h、analytics_events 90 天
  • 漏斗看板:https://bhtx.prom1se.cn/funnel.html(public 静态托管)

一、核心机制:先加入,后解锁联系方式

现状是"复制联系方式→线下组队",系统不知道谁加入了。重构后:

加入行程(系统记录)→ 加入成功 → 才解锁查看联系方式

加入成为站内动作,满员、提醒、统计都从这一步生长。这是整个重构的地基,Phase 1 必做。


二、已确认的产品细节(用户拍板)

座位机制(2026-08-11 作废自动分配)

  • 副驾/后排右/后排左自动分配作废:座位由成员线下自行协商,系统不管
  • 系统只保留人数上限:拼1人=总3座、拼2人=总4座、拼3人=总5座(capacity = 司机位 + 同学位,可加入数 = capacity-1)
  • 成员列表显示所有人(含发起人),发起人用橙色/加粗标注

行程生命周期

  • 状态机:active(招募中)→ full(满员,2人已加入)→ completed / cancelled / expired
  • 时间到了自动变灰:出发时间过 → 状态自动置 expired → 大厅显示灰色、不可加入、不可编辑
  • 满员后不再接受加入,但成员可退出补位(满员→退出→回到招募中)

联系方式可见性

  • 必须认证本校用户才能加入(复用现有邮箱认证)
  • 加入成功后:成员之间互相可见联系方式(含发起人 ↔ 成员、成员 ↔ 成员)
  • 未加入者:看不到任何联系方式
  • 限频保留:2小时最多复制5次

自定义用户ID

  • 默认 ID:"北化校友"(现有)
  • 可自定义修改,不改就是默认
  • 限频修改:1 天最多改一次(用户 08-11 从 30 天放宽;ID 仅展示名,唯一身份=openid+邮箱认证)
  • 用于成员列表展示,方便互相认人;修改后所有行程成员列表实时生效(后端实时读 User 表)

行程数量限制

  • 发布 + 加入 都算,每个用户同时最多 2 个进行中行程
  • 进行中 = status 为 active 或 full(不算已完成/已取消/已过期)
  • 超出则拒绝发布/加入

明确不做(用户确认)

  • ❌ 不碰资金(费用只做提示:预估价+人均试算,固定合规话术)
  • ❌ 不做用户互评机制(Phase 3 砍掉)
  • ❌ 头像不做(上传图片麻烦,昵称/ID 足够认人)

三、v2.0 发布页设计(2026-08-10 已实现)

单页上下滚动,去掉选项卡

  • 上:即刻出发(简短版)——只需 路线 2选1 + 联系方式不选时间,默认 30 分钟后出发,发布后挂出 30 分钟可被拼车(走"过期即灰"逻辑,后端无需改动)
  • 下:预约同行(完整版)——日期/时间(半小时粒度 00/30)/出发地/目的地/联系方式/拼车人数/备注
  • 底部双按钮:「立即出发」(橙色)「预约发布」(蓝色),各自独立校验与提交,协议勾选共用
  • 即刻出发默认拼 2 个同学(capacity=4),人数选择只在预约同行
  • 即刻/预约联系方式字段隔离(immediateContact / form.contact),互不覆盖,均记忆上次填写(lastContact)

四、费用提示(不碰资金)

  • 内置"常用路线→预估价区间"小表(高频路线实测填,低频留空)
  • 发布页:选完路线提示"该路线预估价约 X-Y 元";随加入人数实时算"人均约 A-B 元"(当前仅发布成功后 toast / 详情页展示,发布页实时提示待做)
  • 详情页:显示"预计人均约 A-B 元/人(N 人分摊)"
  • 固定话术写死:"预估价仅供参考,平台不提供车辆、不参与结算、不收取任何费用,费用线下协商分摊"
  • 红线:全程禁"司机/派单/支付/收款/转账"字眼("司机"只在座位说明里指代空缺座位,文案注意措辞)

五、数据埋点(已实现)

  • 新建"事件表"(AnalyticsEvent):浏览详情 / 发布 / 加入 / 退出 / 取消 / 完成 / 自动过期 / 复制联系方式
  • 服务端每次动作成功顺手记一条(fire-and-forget,失败不影响主流程);前端仅进详情页上报一次"浏览"
  • 管理接口按天统计独立用户:浏览→发布→加入→成行,直接画漏斗(/api/stats/funnel,ADMIN_KEY 鉴权)
  • 复用现有 CopyStat + 管理密钥模式

六、部署流程(用户问的"还要做什么")

除了微信提交审核、上传 server.js、重启 pm2,还需要:

  1. MongoDB 数据迁移脚本(最关键,容易漏):老行程补默认值——capacity=4、headcount=0、members=[发起人]、status 保持 active(migrate-v1.3.js 已写好)
  2. 老用户默认 ID 初始化:User 集合给所有用户补 displayName:"北化校友" 默认值
  3. 新增环境变量(如有):无新增敏感配置,但确认 server.js 用到的 MongoDB 连接、密钥不受影响
  4. 订阅消息模板(Phase 2 用):先在微信公众平台申请模板,类目匹配,审核 2-4 周,尽早提
  5. 前端发布新版:微信开发者工具上传 → 提审 → 通过后灰度(老版本用户 contact 接口会 403,靠版本更新缓解)
  6. 隐私政策更新:✅ 已完成(legal.wxml v2.0)
  7. 备份:改 server.js 前先备份线上副本,迁移脚本先跑在测试库

七、实施顺序

  1. Phase 4 埋点(已完成)
  2. Phase 1 撮合核心(已完成)
    • 行程模型扩展(席位/成员/状态/座位顺序)
    • join/leave/members/joined/status 接口
    • 并发边界:抢最后一席原子操作、防重复加入
    • 联系方式解锁校验(成员间互看)
    • 自定义ID + 限频修改
    • 每用户2行程限制
    • detail/publish/mytrips 前端改造
  3. v2.0 发布页重构(已完成,见第三节)
  4. 部署:迁移脚本 + 上传 + 重启 + 提审(隐私政策已更新)
  5. Phase 2 匹配效率:后端搜索过滤、订阅消息提醒(尽早提审)

八、用户协议更新内容(2026-08-10)

pages/legal/legal.wxml

  • 第 1 节修正:原文"不参与行程撮合"与新增加入功能矛盾 → 改为"提供行程信息的发布、浏览与加入匹配服务,不提供运输服务、不指派司机、不调度车辆、不收取佣金"
  • 第 5 节补充:自定义昵称、匿名行为统计(不包含可识别个人身份的信息)
  • 新增第 6 节「行程撮合与成员互动」:加入后成员互看联系方式、未加入不可见;同时最多参与 2 个进行中行程;可随时退出/取消/标记完成;出发时间到自动失效
  • 协议头部标注版本:v2.0(2026-08-10)

九、红线与风险

  1. 审核:禁"司机/派单/接单/支付/收款"字眼(座位文案用"副驾驶/后排"描述,避免"司机"定位);否则被认定网约车平台要经营许可证
  2. 隐私:成员列表脱敏(只露自定义ID);联系方式仅成员可见;隐私政策已更新
  3. 兼容:后端只增不改旧接口;contact 加"须已加入"校验导致老版本 403 → 靠小程序灰度更新缓解
  4. 明确不做:站内聊天、真实支付、WebSocket、抢单算法、司机认证、地图选点、可视化大屏

关键文件

  • server.js(模型/接口/埋点/订阅全部后端改动)
  • pages/detail/*(加入/退出/成员/联系方式解锁/座位展示)
  • pages/publish/*(v2.0 单页:即刻出发精简 + 预约同行完整表单 + 双按钮)
  • pages/mytrips/*(我发布的/我加入的两个tab)
  • pages/mine/*(自定义ID修改入口)
  • pages/index/*(满员标识/拼车人数/过期置灰展示)
  • pages/about/*(版本号 v2.0、开发者名 Prom1seCN)
  • pages/legal/*(用户协议 v2.0)
  • 新增 migrate-v1.3.js(数据迁移脚本)
  • 删除 utils/trip-store.js(死代码)

进度日志(实时记录)

2026-08-10

  • 上午:Phase 4 埋点 + Phase 1 撮合核心(后端+前端)+ 费用提示 + 迁移脚本全部完成,语法全通过
  • 下午:v2.0 发布页重构完成(去 tab、即刻出发精简、双按钮、协议更新、版本号 v2.0)
  • 下午:写服务器现状核查提示词(已发给 Amadeus 询问文件状态/pm2/MongoDB/端口/磁盘/部署命令)
  • 下午:项目迁移——BHTX → D:/Projects/BHTX ✅;个人网站 → D:/Projects/Prom1seCN(后台执行中,完成后补确认);约定代码项目统一放 D:/Projects(已记入用户级记忆)
  • 下午:发布页微调——即刻出发副标题改「30分钟内出发」;预约同行拼车人数 picker 改标签点击选择(seat-tags 样式)
  • 待办:本地测试 → 部署

2026-08-11

  • 凌晨:git token 安全清理(remote 改 HTTPS + GCM 凭据,GitHub 撤销旧 token);漏斗看板上线(public 静态托管);拼车人数口径定案「再拼1/2/3人」(=空位数,同伴线下同行无需加入);费用展示全下线(费用参考/平台倡导卡片→灰色小字);协议交互重构(默认不打勾+弹窗一键同意);统一退出按钮(发起人=解散全团);README 重写 v2.0 科技感版(删版本叙事/快速开始)
  • 凌晨:订阅消息模板选用「活动成行通知」12942,字段映射配置完成(thing4/time3/thing2/thing5)
  • 上午:修复「发布跳转打断订阅授权」(跳转移入授权回调+8s兜底);confirmText 5字超限静默失败 bug(弹窗不出现,console 捕获 errMsg 定位,改 4 字「同意发布/同意加入」);isOrganizer 识别修复(详情请求带 token)
  • 下午:全量逻辑审查——修复 3 个严重 bug(拼3人容量截断 / myJoined 无 $elemMatch 误计数 / 订阅不绑定行程串授权)+ 中等问题全修(TTL×2 / emailPrefix 校验 / seat 去 enum / 删 inactive 死代码)
  • 下午:server.js 重新部署(Amadeus 上传+建 TTL 索引+重启);发布页底部留白 210→300rpx(提示完整展示)
  • 进行中:单人自测 → 前端上传体验版 → 双人流程测试(叫同学)→ 提审

2026-08-13

  • 凌晨:分享卡片升级——Canvas 动态生成行程专属封面(白底品牌卡片,logo/路线/时间/人数/底部标语,反复调优至定稿);认证页加企业微信查收验证码灰字提示 + 去重复 toast;解绑邮箱自动解散自己发起的进行中行程(后端 unbind + 前端确认文案)
  • 凌晨~03:20:化工五块专线全量实现(V2.1,设计→开发一气呵成):
    • 后端:Trip schema 加 special{lineId,direction,periodIndex}SPECIAL_LINE 常量(双向+时段4-6/6-8+carSize3);expireOverdueTrips 专线车按时段结束过期;新接口 GET /api/special/today(双向×时段×车队,脱敏车长)/ POST /api/special/join(有未满车加入、无则惰性创建当车长,复用限流+2上限+订阅通知)/ GET /api/mytrips/active(首页置顶,发起+加入去重);详情接口加 specialPeriodLabel
    • 前端:新页面 pages/special/*(方向切换+时段分组+车列表 n/3 一键加入/3/3 已满/0/3 你来当车长,当车长首次填联系方式缓存复用);首页改版(我的行程置顶区→化工五块横幅→即刻出发→预约同行);详情页专线车显示时段不显示精确时间;trip-formatter 加 isSpecial
    • 全部 node --check 通过、JSON 校验通过;README 双份(BHTX + 笔记副本)功能表补化工五块
    • ⚠️ 待办:本地预览→前端上传体验版→双人测试→提审(与 v2.0 一起);server.js 部署到服务器(Amadeus)
  • 03:00 后:V2.1.1 布局调整——化工五块页去掉方向 tab,改为 4 卡片平铺(去4-6/去6-8/回4-6/回6-8,每卡内展示该组合车队+0/3当车长)
  • 线上诊断(用户说"没网络链接"):curl 实测 GET /api/trips → 200 正常(服务器/MongoDB/pm2 在线);GET /api/special/today404 Cannot GET(Express 无此路由)→ 线上仍是旧 server.js,上传/重启未生效。已给排查命令(grep 服务器文件是否含 special → pm2 restart → curl 复验)
  • 03:03:首页排序定案 V2.1.2——化工五块入口改为底部固定通栏(调大:标题44rpx/padding30rpx,bottom=160rpx+safe-area);筛选面板回归顶部;专线车进首页列表:状态徽标「化工五块」(蓝色 special-card/special-status)、时间显示时段 label、人数按 n/3(含车长);排序:我的行程置顶 → 即刻出发 → 化工五块+预约同行按时间混排(专线车排序基准 sortTime:4-6按16:00、6-8按20:00,后端 /api/trips 下发)
  • 03:08:产品定位澄清 V2.1.3——化工五块页=便捷发起/加入操作台:已满的车不再展示(满员车去同行大厅看),只留可加入未满车 + 0/3 当车长位;文案「满3人即走」→「3人即走」
  • 线上诊断续(重要):用户称 server 已最新,但直连 curl(绕 Clash 代理)/api/special/today 仍 404 → pm2 进程跑的不是新文件。排查法:pm2 describe bhtx | grep "script path" 看真实路径 → grep -c "api/special" <路径>(应=2)→ 用 WinSCP 把本地 server.js 覆盖到该路径 → pm2 restart bhtx --update-env → curl 复验。若文件对还 404 → pm2 delete bhtx && pm2 start 重建进程
  • 排查落地(03:10):用户执行后确认 pm2 script path=/home/ubuntu/bhtx-backend/server.js ✅、进程 online ✅、但服务器文件 grep -c "api/special" = 0根因锁定:服务器文件是旧的(本地 1533 行/54.7KB/2 处)。已给三步:WinSCP 覆盖 → pm2 restart → grep+curl 复验
  • 03:13:UI 主题色 V2.1.4——三种模式主题色:即刻出发·橙红(不变)/ 化工五块·蓝 / 预约同行·绿(新增 scheduled-card 绿色左边缘,标签已默认绿);化工五块专线页:4 张固定卡片蓝色渐变底白字,具体行程 car-card 白底仅蓝色左边缘;README×2 加「模式主题色」行
  • 03:17:首页布局再调 V2.1.5——最终结构:①筛选面板(最顶)→ ②我的行程置顶区 → ③大厅行程列表(底部化工五块 dock 不变)
  • 03:21:V2.1.6 视觉统一——服务器部署成功(404 解决);①所有卡片统一大小(trip-card/my-trip-card/car-card/captain-card 均加 min-height 150/120/150/150rpx);②我的行程里的化工五块修正为主题蓝(原误用橙红 #ff6b35→#2563eb,标签同步);③化工五块页卡片去掉时间范围只留时段名「下午4-6点」;④详情页专线车时间改为显示具体时段 16:00-18:00(后端 /api/trips/:id 新增 specialPeriodRange 下发)
  • ⚠️ 本轮又改了 server.js(specialPeriodRange),需再次上传覆盖+重启才能生效
  • 03:26:V2.1.7 首页细节——我的行程卡片 min-height 120→150rpx(全卡片统一 150);大厅行程区块顶部加灰色小标题(复用 section-title);人数文字颜色随模式主题色(immediate 橙/special 蓝/scheduled 绿,覆盖默认蓝 #2678ff)。纯前端改动,无需再传服务器
  • 03:28:版本统一 v2.0.0 + 卡片同款化——①用户确认:所有更改都属于 v2.0.0(未发布,超级大更新),代码注释/README/about 页全部版本号统一为 v2.0.0(sed 批量替换,无残留);②我的行程卡片与大厅行程完全同款(复用 trip-card 结构:右上角状态标签+时间+路线+人数,删除 my-trip-card 旧样式);③化工五块人数修正 1/3(我的行程 total 改为专线 capacity=3,原误用 capacity-1=2 显示 1/2)
  • 03:33~03:35:时段全站统一数字时间——化工五块页卡片时段「下午4-6点」→「16:00-18:00」(字号 24→32rpx);大厅列表/我的行程/详情页全部统一为 16:00-18:00:trip-formatter.js 加 SPECIAL_PERIOD_RANGES 兜底映射 + getSpecialRange 导出 + formatTrip 附加 specialPeriodRange(优先后端值);index.js/wxml 改用 range;server.js mytrips/active 补下发 specialPeriodRange。前端兜底使本地预览立即生效,不依赖服务器部署
  • 03:40:化工五块时间展示与预约同行完全统一——大厅列表「8月13日 16:00-18:00出发」;我的行程「8/13 16:00-18:00出发」;详情页改「出发日期:8月13日 + 出发时间:16:00-18:00(时段内自由出发)」(去掉原"发车时段/出行提示"特殊分支,结构对齐预约同行,仅时间值是范围非时刻)。纯前端
  • 03:50~04:10:全系统测试(用户交办)+ 修 3 个 bug——线上实测特殊接口/鉴权链路全部正常(Node crypto 手签 JWT 测 token 接口);修复:①订阅通知"拼车进展"专线车 1/2→n/3(server.js,待部署)②mytrips 页专线车状态名"预约同行"→"化工五块"③mytrips 页专线车主题色/时间 range/人数 n/3 全套补齐
  • 待办:双人测试 → 提审

高峰拼车专场 · 设计定稿 v1.2(08-13)✅ 已实现(后端+前端全落地,待部署联调)

用户决策:B 班次时刻表 + 按经验预置班次 + 第一人自动当车长(惰性创建)
v1.1(02:40):时段选择制(4-6/6-8);每车固定 3 人(车长+2);循环车队机制(满员即开新车,永不空场)
v1.2(02:44):路线收敛为一条专线「北化北区 ↔ 昌平西山口」(双向);当天模式(只展示今天的车,无周几概念);新模式定名「化工五块」(用户起名:化工=北化,五块=人均拼车费约 5 元);首页置顶「我的行程」(进行中:加入的+发起的全展示)

核心思路

现有流程门槛 = 精确时间匹配 + 文案负担 + 不确定性;专线 = 把"精确行程"降维成"今天×方向×时段"的撮合,发布端字段归零。联系方式解锁机制原样保留:先加入 → 解锁 → 复制联系方式 → 加微信聊(用户强调)。

0. 三种行程模式并列(新模式名「化工五块」)

模式 路线 时间 门槛
即刻出发 任意 30 分钟内
预约同行 任意 自定义
化工五块 固定:北化北区 ↔ 昌平西山口 今天 + 时段(4-6/6-8) 极低(零输入)

命名由来:化工=北京化工大学,五块=人均拼车费约 5 元(口语梗,传播性强)。专线页可配灰色小字「人均约 5 元(参考)」呼应名字(沿用费用灰色小字策略,不喧宾夺主)。

1. 专线模型 SpecialLine(现仅 1 条,结构支持扩展多条)

SpecialLine {
  name: "北化北区 ↔ 昌平西山口",
  directions: [                    // 双向
    { key: "out",  label: "北化北区 → 昌平西山口" },
    { key: "back", label: "昌平西山口 → 北化北区" }
  ],
  periods: [                       // 时段(当天两个)
    { from: "16:00", to: "18:00", label: "下午 4-6 点" },
    { from: "18:00", to: "20:00", label: "晚上 6-8 点" }
  ],
  carSize: 3,                      // 每车固定 3 人 = 车长 + 2 加入者
  active: true
}

结构按"多专线"设计:以后加「北化→北京南站」等专线只需插一条配置。

2. 当天模式 + 循环车队机制(核心)

  • 车 = Tripspecial: { lineId, direction, periodIndex } + date(当天 yyyy-mm-dd),route/capacity(3) 由专线定义,用户零输入
  • 只展示今天:接口按 date 过滤,无周几/预约概念;次日自动清零重来
  • 时段下多车并发:未满车 n/3(1/3、2/3)→ 一键加入;满车 3/3「已满发车」归档
  • 循环:恒有 0/3「你来当车长」车位 → 点它当车长(惰性创建,第一人自动发起)→ 2 人加入 → 3/3 满员 → 新 0/3 出现 → 循环往复
  • 惰性创建:0/3 是 UI 占位,点击才建 Trip(不产生僵尸空车)
  • 时段结束(period.to 过了)→ 该时段全部车走 expired(判断基准 = 时段结束时刻)

3. 接口

  • GET /api/special/today → 专线 + 今天双向的时段车队(每车 n/3、状态、车长脱敏)+ 待发车位
  • POST /api/special/join(body: {direction, periodIndex})→ 该方向时段有未满车则加入;无 → 惰性创建新车(当前用户=车长)再加入(一个接口)
  • GET /api/mytrips/active → 我的进行中行程(发起+加入,含专线车与普通行程)→ 供首页置顶
  • 列表/首页对带 special 字段行程加徽标
  • 复用全部现有机制:2行程上限 / 1h5次限流 / 脱敏解锁 / 订阅通知 / 状态机(active→full(3/3)→completed/expired)

4. 前端

  • 首页顶部「我的行程」置顶区:进行中行程卡片(含专线车+普通行程,显示方向/时段/人数,点击进详情);无行程时隐藏或引导「去看看今天的专线」
  • 首页模式入口三选:即刻出发 / 预约同行 / 化工五块
  • 专线页(化工五块页):方向切换(去/回)→ 时段分组(下午4-6 / 晚上6-8)→ 车列表:未满车 n/3「一键加入」;满车 3/3「已满」;待发车位 0/3「你来当车长」
  • 详情页专线车不显示精确时间,显示时段 label + 提示「加入后和车长/成员复制联系方式加微信约具体时间」
  • 普通发布流程原样保留

5. 规则边界

  • 时段结束 → 该时段车 expired;满员 full 照常;车长退出=解散该车;成员退出=自己退出(全复用)
  • 专线车计入 2 行程上限,不额外限制

6. 埋点验证(新增 4 事件)

special_enter(专线进入)/ slot_click(方向/时段点击)/ slot_join(一键加入)/ slot_beCaptain(当车长)→ 看板加专线漏斗;重点看「循环是否转起来」= 满员车数 / 当车长人数;对比专线加入率 vs 普通发布成行率

7. 上线顺序

后端(SpecialLine+专线接口+惰性创建+mytrips/active)→ 前端(首页置顶区+专线页+入口+详情页适配)→ 埋点+看板 → 单人自测 → 体验版 → 双人测试(与 v2.0 提审一起办)

  • 10:37:文档同步——README×2 功能表更新(联系方式互看含复制、首页我的行程与大厅同款渲染、行程历史改名、分享卡片三模式主题色、加入限流每天10次);安全设计补"加入限流每天10次";server.js 顶部版本备注更新为 V2.0.0 完整更新日志(化工五块/成员联系方式/首页架构统一/限流/主题色/排序)

  • 08-18 09:33:费用分摊功能 V2.0.0——详情页路线卡与成员卡之间插入费用卡:预估人均(按路线 COST_TABLE 自动)→ 实际总费用(任何成员可填/可编辑,0-999,传空清除)→ 人均自动计算(实际÷人数,人数变动重算,未填按预估显示);后端 Trip.actualCost + PUT /api/trips/:id/cost(仅成员)+ detail 返回 costInfo/isMember;费用进埋点(publish/join/slot 埋点带 fee,实际优先未填按预估中值)+ 漏斗看板加"人均费用"指标;README×2 + server 备注同步

  • 08-19 11:23:邀请拼车功能定稿(原「社恐举牌」改名:凸显功能而非标签化,按钮文案「邀请拼车」,地铁口场景"不熟不敢开口"→替你开口):首页右下角胶囊 FAB「邀请拼车」(化工五块 dock 上方,游客可用):全屏大字「同学,一起拼车去 XX 吗?费用AA」替你开口;默认正向、点翻转 180° 反向(地铁口面对面举牌);目的地原生 picker(全站地点库 17 项,默认北化北区,下划线+▾ 暗示可点);无分享;README×2 + 目录已同步

  • 08-19:新用户引导页(服务扫楼/扫码冷启动):首次进入小程序自动弹引导页(guide_seen 标记只弹一次)——三步说明:①发布或加入行程(高亮化工五块一键上车)②加入后互看联系方式加微信 ③一起打车 AA 分摊;游客额外提示"认证后才能发布/加入"+「先去认证北化邮箱」按钮;已认证直接「开始使用」。首页 index maybeShowGuide 触发;README×2 目录结构同步

  • 08-19:漏斗看板费用统计改版(用户需求"希望统计钱,用户填了实际金额更好"):/api/stats/funnel 的费用统计从"埋点快照"改为"实时从 Trip 聚合"——行程已填实际费用(actualCost)→ 用实际值÷人数;未填 → 按 COST_TABLE 预估区间中值兜底;返回 avgPerPerson(预估+实际混合)+ actualAvg/actualSamples(仅实际填写样本,更可信);funnel.html 费用区改为双指标卡「人均费用(预估+实际混合)」+「实际填写人均」;内存 Mongo 播种两类行程实测通过(实际15 + 预估66.7 → 混合40.8)。需同步上传 server.js + public/funnel.html 到服务器

  • 08-19:使用教程文案重构(用户反馈"要更简洁明了,介绍三种拼车模式"):页面改版为——三种模式卡片(即刻⚡橙/预约📅绿/化工五块🚌蓝,图标+一句话,主题色与全站一致)+ 玩法流程条(加入行程 → 互加微信 → 打车平摊,一行看懂);邮箱认证提示放最后一步作行动收尾(先讲价值再索取;认证只卡发布/加入,游客可先逛);已认证直接「开始使用」。README×2 特性表同步

  • 08-19:品牌文案全站统一(用户定稿)——口号「百花同行——不再一个人出发」+ 简介「加入行程,在线联系;预约同行,即刻出发;化工五块,拒绝黑车」(将三种模式装进简介)+ 介绍「BUCT公益拼车小程序」:

    • README×2 头部前三行居中更新(口号/介绍/简介)
    • 使用教程页 guide:品牌头改 百花同行 /(蓝)不再一个人出发 /(灰)BUCT公益拼车小程序;流程条改「加入行程 → 预约同行 → 费用平摊」
    • 关于页 about:主标题改 百花同行 /(蓝)不再一个人出发 /(灰)BUCT公益拼车小程序(去掉原"BUCT校友拼车互助平台")
    • 公众号文章:正文「让对的人,在对的时间,拼到一辆车」→ 三句对句简介版
  • 08-19:①免单推广活动放弃(用户决策:公益项目不为补贴搞复杂,截留微信红包直发即可)②强制更新接入:app.js wx.getUpdateManager()——新版本下载完成弹窗「立即更新」一键 applyUpdate 重启,微信平台不允许"不升级禁用"这已是行业标配强更新③使用教程入口:个人中心新增常驻入口「使用教程」(邮箱认证下、意见反馈上),navigateBack 返回适配(首次进入/个人中心两条路径均可用),README×2 特性表+目录同步

  • 08-19:提审过审改名(应对审核"社交-笔记类目"驳回 2.1)——个人主体小程序无法开放社交类目,弱化产品社交观感再提审:

    • 全局 「车长」→「发起人」(special.wxml 界面文案/server 接口报错消息/README×2/代码注释,全库 0 残留)
    • 联系方式提示词 →「仅用于拼车联系」(publish.wxml 两处,去掉"请输入联系方式"前缀)
    • 配套申诉文案已给:论证"非社交产品(无动态/评论/私信/内容流),仅固定字段表单撮合,联系方式未认证+未加入不可见",删除"最早功能/公益"等无效论点
    • ⏳ 后续可选(未做):详情页成员列表默认折叠、成员互看入口进二级——先以本轮改动提审看结果
  • 08-19:认证门控(审核攻坚方案)——核心思路:审核员以游客身份永远见不到 UGC 界面(游客无北化邮箱,无法完成认证),把产品从'公开信息发布'变为'仅认证校友可见的封闭服务':①tabBar 发布+按钮未认证→拦截跳认证 ②special 未认证隐藏'一键加入/你来发起'→🔒'认证后可拼车' ③detail 未认证加入按钮→'认证后可参与' ④publish 页 onLoad 双重保险(直接输入路径也 redirect auth)⑤index 提示中性化 ⑥hero/cost-hint/guide 流程条去'联系方式/加入行程'字样改'同行报名/认证校友' ⑦onShow 同步 isVerified(认证返回实时生效)。游客仍可用:列表浏览/班次查看/行程查看/认证页。