3.0 KiB
3.0 KiB
后端工程师 经验记录 - 2026-03-12
1. persons 表 token 字段与 DB 迁移
问题
新增 @ 人物时报错:Unknown column 'token' in 'field list'。GORM model 已加 Token 字段,但数据库未执行迁移。
解决方案
- 迁移脚本:
soul-api/scripts/add-persons-token.sql - 执行:
node .cursor/scripts/db-exec/run.js -f soul-api/scripts/add-persons-token.sql - 内容:
ALTER TABLE persons ADD COLUMN token VARCHAR(36) NOT NULL DEFAULT '' AFTER person_id+ 唯一索引
规则
- Model 新增字段后:需编写并执行 ALTER 脚本,GORM AutoMigrate 不一定自动生效(取决于启动时机与连接)
- 迁移脚本位置:
soul-api/scripts/,命名add-xxx.sql - 执行方式:db-exec 脚本读取 soul-api/.env 的 DB_DSN
2. CKBLead 用 token 兑换真实密钥
targetUserId现为 persons.token(非 person_id)- 查询:
db.Where("token = ?", body.TargetUserID).First(&p) - 取
p.CkbApiKey调用存客宝
3. 9.9 买断与后端开关(hasFullBook)
场景
- 小程序已通过
hasFullBook标识「买断全书」,权限判断和文案都依赖该字段(由/api/miniprogram/user/purchase-status与/api/miniprogram/user/check-purchased返回)。 - 现在需要在用户资料里增加一个布尔开关:运维/客服手动打开后,相当于该用户已经买过 9.9,全书可看,后续不再需要支付。
设计要点
- 统一事实来源:9.9 买断是否生效完全由后端计算,前端只认:
purchase-status返回的hasFullBook = true;- 或
check-purchased返回isPurchased = true且reason = "has_full_book"。
- 用户资料开关:
- 在
users表或 user profile 中新增布尔字段(例如manual_fullbook,具体命名按现有规范调整)。 - 仅管理端/运维修改该字段,小程序不直接写入。
- 在
- 接口契约调整:
/api/miniprogram/user/purchase-status:- 计算
hasFullBook时,将订单表中的全书订单结果与manual_fullbook做 OR,只要任一为真就返回hasFullBook = true。
- 计算
/api/miniprogram/user/check-purchased:- 对章节做权限判断时,如果由
manual_fullbook推导出可看,应返回:isPurchased = truereason = "has_full_book"
- 前端的
chapterAccessManager.syncLocalCache会据此把app.globalData.hasFullBook = true并同步到userInfo.hasFullBook。
- 对章节做权限判断时,如果由
- 与 VIP 的边界:
hasFullBook(9.9 买断)与isVip(会员)继续解耦:手动开 fullbook 开关不会自动授予 VIP。- VIP 相关逻辑只看
isVip/vipExpireDate,不受manual_fullbook影响。
规则
- 不在前端增加「跳过支付」开关,所有免 9.9 行为都通过后端折叠到
hasFullBook/has_full_book暴露给小程序。 - 满足以上约定后,小程序现有代码无需修改即可支持「后台手动赠送 9.9 买断」。