11 KiB
11 KiB
当前小程序开发细则
汇总当前 Soul 创业派对小程序的架构、经验与规划,便于新人上手与后续迭代。
最后整理:2026-02
一、概述与定位
- 产品:Soul 创业派对 — 微信小程序,内容为《一场 SOUL 的创业实验场》章节阅读 + 找伙伴 + 分销。
- 技术:原生微信小程序(非 uni-app / Taro),与 Next.js 后端同仓,接口统一走
apiBase(如https://soul.quwanzhi.com)。 - 核心能力:章节阅读(免费/付费)、单章/全书支付、邀请码分销、找伙伴(匹配次数购买)、推广中心、我的订单/设置。
二、目录与页面结构
2.1 目录结构(miniprogram/)
miniprogram/
├── app.js / app.json / app.wxss # 入口、全局配置、样式
├── custom-tab-bar/ # 自定义底部 tabBar
├── pages/
│ ├── index/ # 首页(推荐章节、已读统计)
│ ├── chapters/ # 目录(全书章节列表)
│ ├── read/ # 阅读页(核心:权限、支付、分享)
│ ├── match/ # 找伙伴(匹配 + 购买次数)
│ ├── my/ # 我的(入口:订单、推广、设置)
│ ├── referral/ # 推广中心(邀请码、收益、海报)
│ ├── purchases/ # 我的订单(当前为本地已购章节列表)
│ ├── settings/ # 设置(提现、绑定账号等)
│ ├── search/ # 搜索
│ ├── about/ # 关于
│ └── addresses/ # 地址(若启用)
├── utils/
│ ├── chapterAccessManager.js # 章节权限与状态
│ ├── readingTracker.js # 阅读进度追踪
│ ├── payment.js # 旧支付封装(部分场景仍用)
│ └── util.js
└── assets/ # 图标等静态资源
2.2 TabBar 与主要页面
| Tab | 页面 | 说明 |
|---|---|---|
| 首页 | pages/index/index | 推荐章节、已读/待读、入口到阅读 |
| 目录 | pages/chapters/chapters | 全书章节列表 |
| 找伙伴 | pages/match/match | 匹配 + 购买匹配次数 |
| 我的 | pages/my/my | 已读/已购、推广中心、订单、设置 |
非 Tab 页:阅读页 read、推广中心 referral、订单 purchases、设置 settings、搜索 search、关于 about。
2.3 全局状态(app.js globalData)
userInfo:登录后用户信息(id、openId、nickname、purchasedSections、hasFullBook、referralCode、referralCount 等)。openId/isLoggedIn:微信登录态。readSectionIds:已读章节 ID 列表(有权限打开全文时打点)。pendingReferralCode:待绑定推荐码(带 ref 进入时写入,登录后绑定)。apiBase:后端 API 根地址。
三、核心流程与经验
3.1 阅读与章节权限
- 权威数据源:章节是否可读以服务端为准(
/api/user/check-purchased、/api/user/purchase-status),不依赖前端缓存做最终判断。 - 权限状态:设计上支持
unknown / free / locked_not_login / locked_not_purchased / unlocked_purchased / error(见《章节阅读付费标准流程设计》);阅读页通过chapterAccessManager与determineAccessState等做状态判断。 - 免费章节:来自后端配置(如
/api/db/config的 freeChapters),页面 onLoad 时拉取最新免费列表再判断;首帧可用本地默认 freeIds,拉取完成后需能刷新当前章状态,避免竞态误判。 - 已读 vs 已购:
- 已读:仅统计“有权限打开并看到全文”的章节(
canAccess=true时app.markSectionAsRead(sectionId)),存readSectionIds。 - 已购:来自服务端
userInfo.purchasedSections、hasFullBook及 orders 表,用于付费墙与购买按钮展示。
- 已读:仅统计“有权限打开并看到全文”的章节(
- 登录后防误解锁:登录成功(含支付流程中登录)后必须
refreshPurchaseFromServer(),再对当前章节做recheckCurrentSectionAndRefresh()(先拉最新免费列表,再请求 check-purchased),避免“刚登录”时误用旧缓存解锁付费章。 - 内容接口:当前
GET /api/book/chapter/[id]不校验登录与购买,前端按canAccess控制展示全文或预览;若未来开放 Web/API,建议章节接口侧做鉴权。
详见:开发文档/8、部署/章节阅读付费标准流程设计.md。
3.2 支付流程(章节 + 找伙伴)
- 统一入口:章节支付
pages/read/read.js调POST /api/miniprogram/pay;找伙伴支付pages/match/match.js同样调该接口,传productType: 'match'。 - 订单先行:支付前必须先创建订单并插入
orders表(status=created),再调微信统一下单;即使插库失败也继续支付流程,避免用户卡在“创建订单失败”。 - 请求体约定:
openId、userId、productType(section/fullbook/match)、productId、amount、description;必须带referralCode(见下节)。 - 支付成功:依赖微信回调
POST /api/miniprogram/pay/notify更新订单为paid、解锁用户权限、分佣、清理同产品未支付订单;前端支付成功后调用refreshUserPurchaseStatus()再initSection()刷新当前页。 - 兜底:若回调丢失,依赖订单状态同步定时任务(如每 5 分钟调
GET /api/cron/sync-orders)查询微信侧状态并同步到本地 orders,保证最终一致。详见开发文档/8、部署/宝塔面板配置订单同步定时任务.md。
3.3 邀请码与分销(必传、必记)
- 绑定逻辑:带
ref或referralCode的链接进入 →app.js的handleReferralCode写入pendingReferralCode并同步写入referral_code(wx.setStorageSync('referral_code', refCode));登录后调用/api/referral/bind完成绑定(30 天有效、可续期/抢夺)。 - 支付必带邀请码:章节支付、找伙伴支付创建订单时都要传
referralCode,来源为wx.getStorageSync('referral_code');后端据此(或先查 referral_bindings)写入订单的referrer_id与referral_code(下单时使用的邀请码,便于对账与后台展示)。 - 订单表字段:
orders.referrer_id(推荐人用户ID)、orders.referral_code(下单时邀请码)。若表尚未加字段,需执行scripts/add_orders_referrer_id.py、scripts/add_orders_referral_code.py。 - 推荐人 vs 邀请码:全局只认「推荐人 = 用户ID」;邀请码仅用于解析出 referrer_id,不会混用。分佣以
referral_bindings为准,不依赖订单上的 referrer_id。详见开发文档/8、部署/邀请码分销规则说明.md。
3.4 分享与落地
- 阅读页分享:
onShareAppMessage/onShareTimeline带id=章节ID&ref=当前用户邀请码,落地后 ref 写入 storage,绑定与订单归属同上。 - 文章/章节分销与全局同一套:不按“哪篇文章带来”单独分成或统计,仅按“谁发的链接(ref=谁)”归属。
四、数据与接口约定
4.1 关键接口
| 接口 | 用途 |
|---|---|
| POST /api/miniprogram/login | 微信登录,返回 userInfo(含 purchasedSections、referralCode 等) |
| GET /api/user/purchase-status | 拉取购买状态(已购章节、全书) |
| GET /api/user/check-purchased | 校验指定章节/全书是否已购买 |
| POST /api/miniprogram/pay | 创建订单 + 微信预支付,需传 referralCode |
| POST /api/miniprogram/pay/notify | 微信支付回调(服务端) |
| GET /api/cron/sync-orders | 订单状态同步(定时任务,需 secret) |
| POST /api/referral/bind | 绑定推荐关系 |
| GET /api/db/config | 免费章节等配置 |
4.2 Storage 约定
referral_code:落地 ref 或 app 检测到 ref 时写入;支付时读取并传后端。pendingReferralCode/boundReferralCode:待绑定/已绑定推荐码(app 层)。readSectionIds:已读章节 ID 列表。openId、用户信息等由 app 与登录逻辑维护。
五、已知问题与修复要点
- 免费章节配置竞态:onLoad 时若未 await 免费列表再 initSection,首帧可能用默认 freeIds 误判;建议先拉配置再判断当前章,或拉取完成后对当前页再刷一次权限。
- check-purchased 失败降级:失败时应保守设为无权限(不信任本地缓存),避免误解锁。
- 支付回调丢失:必须部署订单同步定时任务(如宝塔 crontab 调
/api/cron/sync-orders),否则会出现“已扣款但订单仍 created、内容未解锁”。 - 订单表缺字段:新环境或老库需执行
add_orders_referrer_id.py、add_orders_referral_code.py,否则下单可能 fallback 成不写这两列(功能仍可用,但订单无推荐人/邀请码记录)。
六、部署与运维
- 后端:Next.js 部署至 soul.quwanzhi.com,小程序
app.globalData.apiBase指向该域名。 - 订单同步:生产环境配置 crontab 每 5 分钟请求
GET /api/cron/sync-orders?secret=YOUR_SECRET(如宝塔定时任务),保证回调丢失时仍能同步为 paid 并解锁。见开发文档/8、部署/宝塔面板配置订单同步定时任务.md。 - 数据库:orders 表需含
referrer_id、referral_code;若为已有表,执行上述两个 Python 迁移脚本。 - 小程序发布:按微信后台流程上传代码、提交审核;注意域名白名单、支付商户号与回调 URL 配置。
七、规划与待办(可选)
- 我的订单页:当前
purchases页为本地已购章节列表;若需“真实订单列表+邀请码展示”,可对接GET /api/orders?userId=xxx并展示订单维度数据。 - 阅读进度:已设计阅读进度状态与
readingTracker、可上报服务端;是否全量接入与埋点可按产品需求推进。 - 章节接口鉴权:若开放 Web 或对外 API,建议在章节内容接口侧按用户与购买记录返回全文/预览,防止直连拿全文。
- 按文章/章节维度的分销统计:当前未实现;若需要“某章节带来的访问/订单数”,需在访问或订单上增加来源章节等字段并在报表中汇总。
八、相关文档索引
| 文档 | 说明 |
|---|---|
| 开发文档/8、部署/邀请码分销规则说明.md | 分销规则、订单 referrer_id/referral_code、推荐人 vs 邀请码 |
| 开发文档/8、部署/章节阅读付费标准流程设计.md | 阅读状态机、权限判断、阅读进度设计 |
| 开发文档/4、前端/ui/06-分销系统说明.md | 分销规则与推广方式 |
| 开发文档/4、前端/ui/08-支付系统说明.md | 支付方式与价格体系 |