diff --git a/.cursor/README.md b/.cursor/README.md index 9226bac7..5e26ce95 100644 --- a/.cursor/README.md +++ b/.cursor/README.md @@ -1,127 +1,21 @@ -# Soul 创业派对 - .cursor 配置说明 +# Soul 创业派对 · `.cursor` 速览 -本目录按 **cursor标准模板** 重构,rules、skills、agent 为**开发团队**服务,用于约束开发、防止互窜、经验升级。 +## 路径约定 ---- +- 所有 Skill、会议纪要、agent 经验路径均以 **本 Git 仓库根** 为基准(与 `miniprogram/`、`soul-api/` 同级)。 +- Rules 中「必须 Read」的路径形如 `.cursor/skills/{name}/SKILL.md`。 +- Python 脚本统一可用 `config/paths.py` 的 `ROOT`、`SKILLS`、`AGENT`、`MEETING`。 -## 目录结构 +## 入口优先级 -``` -.cursor/ -├── README.md # 本说明(入口) -├── config/ # 配置(paths.py、workspace.txt、model_switch.json) -├── rules/ # 规则(boundary、checklist、助理、会议、老板分身-索引) -├── skills/ # Skills(按角色分配) -├── agent/ # 智能体(标准开发团队结构) -│ ├── 老板分身/ # 最高权限,协调所有角色 -│ ├── 开发助理/ # 规则进化、通用经验、项目索引、bat 入口 -│ │ ├── evolution/ # 通用经验池 -│ │ ├── script/ # 一键-列出经验池.bat、一键-添加经验.bat 等 -│ │ └── 项目索引/ # 各角色开发进度(小程序.md、管理端.md 等) -│ ├── 小程序开发工程师/ -│ ├── 管理端开发工程师/ -│ ├── 后端工程师/ -│ ├── 产品经理/ -│ ├── 软件测试/ -│ └── 团队/ # 跨角色共享经验 -├── scripts/ # 共享脚本(evolution.py、经验模板.md、db-exec) -├── docs/ # 文档(职责定义、边界、分析) -├── process/ # 工作流 -├── meeting/ # 会议纪要(橙子生成) -└── archive/ # 历史归档 -``` +1. **三端开发**:`rules/soul-project-boundary.mdc` + `skills/*-dev` / `change-checklist`。 +2. **派对 AI**:若存在仓库根目录 `派对AI/`,可补充读其 `BOOTSTRAP.md`;与 `.cursor` 冲突时 **以 `.cursor` 三端约定为准**(见 `rules/party-ai-dev.mdc`)。 ---- +## 噪声与体积 -## 开发团队 +- `meeting/`、`agent/`:历史纪要/evolution 会增多,属正常;需要时可按月归档到子目录或压缩备份。 +- `scripts/db-exec/node_modules/`:已在 `.cursorignore` 与 `.gitignore` 中排除,首次使用在 `db-exec` 下执行 `npm install`。 -| 角色 | 负责 | 主 Skill | Agent 目录 | -|------|------|----------|------------| -| 小程序开发工程师 | miniprogram/ | SKILL-小程序开发.md | agent/小程序开发工程师/ | -| 管理端开发工程师 | soul-admin/ | SKILL-管理端开发.md | agent/管理端开发工程师/ | -| 后端开发 | soul-api/ | SKILL-API开发.md | agent/后端工程师/ | -| 产品经理 | 开发文档/1、需求/、临时需求池/ | SKILL-产品经理.md | agent/产品经理/ | -| 测试人员 | miniprogram、soul-admin、soul-api | SKILL-测试.md | agent/软件测试/ | -| 助理橙子 | 讨论后记录、经验升级 | SKILL-助理橙子-文档同步.md | agent/开发助理/ | +## 文档 -**经验**:每角色 `agent/{角色}/evolution/`,团队共享 `agent/团队/evolution/`。用户说「吸收经验」「升级 skills」→ 入库 + 升级 Skill;说「保存开发进度」「任务完成」→ 更新 `agent/开发助理/项目索引/{角色}.md`。 - ---- - -## 快速决策(必须 Read = 使用 Read 工具读取完整内容) - -| 编辑/场景 | 必须 Read 的 Skill | 自动加载的 Rule | -|-----------|-------------------|----------------| -| miniprogram/ | `SKILL-小程序开发.md` | soul-miniprogram-boundary | -| soul-admin/ | `SKILL-管理端开发.md` | soul-admin-boundary | -| soul-api/ | `SKILL-API开发.md` | soul-api | -| 开发文档/1、需求/、临时需求池/ | `SKILL-产品经理.md` | product-manager | -| 测试、测试用例、回归测试、功能测试、QA | `SKILL-测试.md` | - | -| 小橙、橙子、讨论完毕、记录、同步文档 | `SKILL-助理橙子-文档同步.md` | assistant-xiaofeng | -| 吸收经验、升级 skills、保存开发进度、任务完成、搞定了 | `SKILL-助理橙子-文档同步.md` | assistant-xiaofeng | -| 跨端功能开发 | `SKILL-角色流程控制.md` | - | -| 变更完成 | `SKILL-变更关联检查.md` | soul-change-checklist | -| 开个会、团队会议、需求评审、方案讨论 | `SKILL-团队会议.md` | soul-meeting | -| 会议结束、散会 | `SKILL-助理橙子-文档同步.md`(会议收尾) | soul-meeting | - ---- - -## Rules 一览 - -| 规则 | 生效范围 | 用途 | -|------|----------|------| -| soul-project-boundary | `**`(alwaysApply) | 项目组成、核心原则、会话自检 | -| 老板分身-索引 | `**`(alwaysApply) | 经验自动收集、Soul 角色推断、编码习惯 | -| soul-change-checklist | miniprogram、soul-admin、soul-api | 变更后必过 | -| assistant-xiaofeng | 触发词 | 小橙触发器 → SKILL-助理橙子-文档同步 | -| soul-miniprogram-boundary | miniprogram/** | 只调 /api/miniprogram/* | -| soul-admin-boundary | soul-admin/** | 只调 /api/admin/*、/api/db/* | -| soul-api | soul-api/** | 路由边界 + 编码规范(合并版) | -| product-manager | 开发文档/1、需求/、临时需求池/ | 产品经理 glob 触发 | -| soul-meeting | 触发词 | 开个会、团队会议、需求评审 → SKILL-团队会议 | - ---- - -## Skills 一览 - -### 角色主 Skill - -| 角色 | 主 Skill | 辅助 Skill | -|------|----------|------------| -| 小程序开发工程师 | SKILL-小程序开发 | 三端架构 → API开发 → 变更关联检查 | -| 管理端开发工程师 | SKILL-管理端开发 | 三端架构 → API开发 → 变更关联检查 | -| 后端开发 | SKILL-API开发 | soul-api 规范 → 三端架构 → 变更关联检查 → MySQL直接操作 | -| 产品经理 | SKILL-产品经理 | 需求汇总、运营与变更 | -| 测试人员 | SKILL-测试 | 变更关联检查、小程序/管理端/API 规范 | -| 助理橙子 | SKILL-助理橙子-文档同步 | - | - -### 场景 Skill - -| 场景 | Skill | -|------|-------| -| 跨端协同 | SKILL-角色流程控制 | -| 变更检查 | SKILL-变更关联检查、soul-change-checklist | -| 文档同步、经验升级 | SKILL-助理橙子-文档同步 | -| **多角色会议** | **SKILL-团队会议** | -| next-project | SKILL-next-project仅预览 | -| 项目拆解 | SKILL-Next全栈拆解为前后端分离与小程序 | - ---- - -## 文档与脚本 - -| 文档 | 说明 | -|------|------| -| [开发团队职责定义](./docs/开发团队职责定义.md) | 六角色职责、Skills 分配 | -| [三角色边界定义](./docs/三角色边界定义.md) | 开发三角色源码与业务边界 | -| [config/目录地图](./config/目录地图.md) | paths.py 路径别名 | -| [meeting/](./meeting/) | 会议纪要(橙子生成) | -| [经验清单](./agent/开发助理/经验清单.md) | 跨角色经验索引 | -| evolution 脚本 | `python .cursor/scripts/evolution.py list` 列出经验池;`add --stdin` 添加经验 | -| 一键 bat | `agent/开发助理/script/一键-列出经验池.bat` 等 | - ---- - -## 会话启动自检 - -新 Cursor 打开本项目时,优先执行 soul-project-boundary 中的「会话启动自检」:仅沿用本项目的 rules、skills、开发风格与配置,排除无关规则。 +- 架构与迭代说明:`docs/cursor规则与架构分析及优化建议.md` diff --git a/.cursor/agent/产品经理/evolution/2026-03-10.md b/.cursor/agent/产品经理/evolution/2026-03-10.md new file mode 100644 index 00000000..e5f77d22 --- /dev/null +++ b/.cursor/agent/产品经理/evolution/2026-03-10.md @@ -0,0 +1,13 @@ +# 产品经理 经验记录 - 2026-03-10 + +## 管理端迁移 Mycontent-temp:信息架构与验收口径 + +- **主导航收敛**:侧栏只保留运营主链路 5 项(概览/内容/用户/找伙伴/推广),系统设置固定在底部;其余能力不删除但不占主导航入口。 +- **入口承载策略**:非主菜单页面(订单/提现/推广设置/VIP角色/导师等)通过“概览卡片/页面内按钮/系统设置 Tab”进入,确保可达且路径更短。 +- **验收标准**: + - 菜单与布局一致(新规范) + - 隐藏页面路由仍可访问(功能不丢) + - author/admin 设置统一在 `/settings?tab=...` 承载,旧路径可兼容跳转 + +> 详见会议纪要:`.cursor/meeting/2026-03-10_管理端迁移Mycontent-temp菜单布局讨论.md` + diff --git a/.cursor/agent/产品经理/evolution/2026-03-11.md b/.cursor/agent/产品经理/evolution/2026-03-11.md new file mode 100644 index 00000000..74e49660 --- /dev/null +++ b/.cursor/agent/产品经理/evolution/2026-03-11.md @@ -0,0 +1,7 @@ +# 产品经理 经验记录 - 2026-03-11 + +## 需求基准:以界面定需求 + +- 需求与验收以《开发文档/1、需求/以界面定需求》为准;新增/变更功能时先对齐界面再更新《需求汇总》需求清单。 +- 小程序与管理端界面清单、主要接口、业务逻辑对齐(用户/VIP 资料展示、三端 API 边界等)已落档,作为验收基准。 +- 详见团队共享:`agent/团队/evolution/2026-03-11.md`。 diff --git a/.cursor/agent/产品经理/evolution/2026-03-16.md b/.cursor/agent/产品经理/evolution/2026-03-16.md new file mode 100644 index 00000000..19b7585b --- /dev/null +++ b/.cursor/agent/产品经理/evolution/2026-03-16.md @@ -0,0 +1,7 @@ +# 产品经理 经验记录 - 2026-03-16 + +## new-soul 派对AI 与 Mycontent 定位差异(会议:new-soul 新需求与当前项目差异分析) + +- **new-soul 派对AI**:内容运营侧 AI 助手,服务于《一场soul的创业实验》的派对→录屏→剪辑→成片→分发→文章→小程序全链路 +- **当前 Mycontent**:产品侧,面向创业者的社区/工具型小程序,核心是内容→会员→导师变现、存客宝对接、分销等 +- **结论**:两者是同一业务的不同层面(运营 vs 产品),互补非替代 diff --git a/.cursor/agent/产品经理/evolution/2026-03-17.md b/.cursor/agent/产品经理/evolution/2026-03-17.md new file mode 100644 index 00000000..f7603afe --- /dev/null +++ b/.cursor/agent/产品经理/evolution/2026-03-17.md @@ -0,0 +1,13 @@ +# 产品经理 经验记录 - 2026-03-17 + +## 稳定版源码质量优化(会议:2026-03-17) + +- **验收标准**:优化后现有功能行为不变,三端联调通过 +- **优先级**:高优(安全)→ 中优(可维护)→ 低优(性能/结构) +- **原则**:源码质量优化按安全→可维护→性能分批,用户无感知 + +--- + +## 会议收尾(2026-03-17) + +- 10 项优化全部完成;测试流程与报告模板已定稿;开发文档已同步 diff --git a/.cursor/agent/产品经理/evolution/2026-03-18.md b/.cursor/agent/产品经理/evolution/2026-03-18.md new file mode 100644 index 00000000..6612125c --- /dev/null +++ b/.cursor/agent/产品经理/evolution/2026-03-18.md @@ -0,0 +1,38 @@ +# 产品经理 经验记录 - 2026-03-18 + +## 文档归档与需求口径(界面驱动) + +### 需求基准(验收口径) +- **需求以界面为准**:以 `开发文档/1、需求/以界面定需求.md` 的“界面清单 + 业务逻辑对齐”为验收基准。 +- **需求清单与变更记录**: + - 需求清单:`开发文档/1、需求/需求汇总.md` + - 近期讨论/决议:`开发文档/10、项目管理/运营与变更.md` + - 里程碑执行层:`开发文档/10、项目管理/项目落地推进表.md` + +### 归档原则(避免文档发散) +- 新增/改版功能必须同步更新: + - 《以界面定需求》(界面与主要接口) + - 《需求汇总》(需求清单条目:日期/描述/状态/备注) + - 《运营与变更》(决议与实现摘要) +- 旧方案文档若已过时:在 `开发文档/README.md` 的“已移除文档”里登记清理原因,避免重复讨论。 + +### 功能需求整理(按产品域) +- **内容阅读与付费**:预览与解锁规则、VIP 全章免费、余额支付与微信支付链路、阅读统计与埋点。 +- **代付分享**:发起人支付后分享;好友打开阅读页自动领取并解锁;发起人可查看领取进度与明细。 +- **推广分销与提现**:分润规则可配置(会员 20%/非会员 10%、内容 90%)、提现闭环(申请→审核/打款→回写→订阅消息)。 +- **找伙伴/存客宝**:@mention/#标签自动创建与同步;留资与匹配流程;限频与风控边界。 + +### 分享场景强约束(验收必测) +- **好友分享 vs 朋友圈分享(singlePage)**: + - 朋友圈进入可能是单页模式,页面能力不完整 + - 验收必须覆盖:单页模式不触发支付/自动领取等强动作,且明确引导“前往小程序”进入完整版 + +## 超级个体开通后自动创建@人与资料引导(会议决议) + +### 业务目标与规则 +- **自动创建 @人**:用户开通超级个体后,管理端「链接人与事」自动创建一条 Person 记录,展示名与用户**当前昵称一致**。 +- **资料完善拦截**:支付超级个体前若昵称/头像为默认值,必须引导至仅头像+昵称的引导页完成修改;开通后进入权益/成功页也需再次检测兜底。 + +### 待确认 +- 昵称变更后的同步规则:是否强制同步更新 Person.name,是否需要保留历史别名/展示区分。 + diff --git a/.cursor/agent/产品经理/evolution/2026-03-24.md b/.cursor/agent/产品经理/evolution/2026-03-24.md new file mode 100644 index 00000000..4820706f --- /dev/null +++ b/.cursor/agent/产品经理/evolution/2026-03-24.md @@ -0,0 +1,16 @@ +# 产品经理 经验记录 - 2026-03-24 + +## 开发进度同步会议 + +### 文档同步原则 +- 实现变更后需同步更新:《需求汇总》《运营与变更》及对应角色项目索引。 +- 项目索引「最后更新」应与实际变更日期一致,避免滞后。 + +### 当前状态 +- 2026-03-20 需求(提现、我的收益、推广设置等)已与实现对齐。 +- 主需求、落地推进表已基本同步;项目索引已补齐至 2026-03-24。 + +## 需求与进度及三端闭环评审 + +- 区分「用户主路径闭环」与「规则/风控闭环」;后者缺口见《产品意图与功能闭环分析》,用清单驱动排期而非推翻里程碑。 +- 待确认:VIP 支付前是否强制完善头像昵称(与当前 vip.js 策略二选一)。 diff --git a/.cursor/agent/产品经理/evolution/2026-03-31.md b/.cursor/agent/产品经理/evolution/2026-03-31.md new file mode 100644 index 00000000..c0ec575f --- /dev/null +++ b/.cursor/agent/产品经理/evolution/2026-03-31.md @@ -0,0 +1,6 @@ +# 产品经理 经验记录 - 2026-03-31 + +## 会议:超级个体列表与 @ 列表融合 + +- 超级个体(VIP 曝光)与 @ 人物(内容引用)应视为同一业务的两面;融合优先统一运营心智与验收口径,再决定 UI 是否单页。 +- 一期验收需明确:无 @ 人物的有效 VIP 的提示策略、管理端跳转路径是否满足运营闭环。 diff --git a/.cursor/agent/产品经理/evolution/2026-04-02.md b/.cursor/agent/产品经理/evolution/2026-04-02.md new file mode 100644 index 00000000..b670821d --- /dev/null +++ b/.cursor/agent/产品经理/evolution/2026-04-02.md @@ -0,0 +1,7 @@ +# 产品经理 经验记录 - 2026-04-02 + +## 会议:工作进度与需求同步会 + +- **场景**:4 月初全员同步进度,衔接 2026-03-31 超级个体与 @ 列表融合待办。 +- **要点**:融合类需求需同步明确「一期验收口径」(UsersPage @ 状态、列表入口是否收敛),并写入需求汇总/运营与变更,避免实现先行、验收滞后。 +- **待办**:问题与作答区 Q1 由产品补充作答后闭环。 diff --git a/.cursor/agent/产品经理/evolution/索引.md b/.cursor/agent/产品经理/evolution/索引.md index fbdc760a..fb0c36ef 100644 --- a/.cursor/agent/产品经理/evolution/索引.md +++ b/.cursor/agent/产品经理/evolution/索引.md @@ -4,3 +4,5 @@ |------|------|------| | 2026-03-05 | 分支冲突后需求文档与实现一致性核对 | [2026-03-05.md](./2026-03-05.md) | | 2026-03-05 | 文章详情@某人高亮与一键加好友验收标准与待确认 | [2026-03-05.md](./2026-03-05.md) | +| 2026-03-10 | 管理端迁移 Mycontent-temp:主导航收敛与隐藏页面入口承载策略 | [2026-03-10.md](./2026-03-10.md) | +| 2026-03-24 | 开发进度同步会议:文档同步原则、项目索引补齐 | [2026-03-24.md](./2026-03-24.md) | diff --git a/.cursor/agent/后端工程师/evolution/2026-03-10.md b/.cursor/agent/后端工程师/evolution/2026-03-10.md new file mode 100644 index 00000000..8755e1dd --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-10.md @@ -0,0 +1,67 @@ +# 后端工程师 经验记录 - 2026-03-10 + +## 管理端迁移 Mycontent-temp:后端视角注意点 + +- **接口边界不变**:管理端迁移/重构只允许调用 `/api/admin/*`、`/api/db/*`、`/api/orders`,严禁引入 `/api/miniprogram/*`。 +- **概览聚合接口可选**:`/api/admin/dashboard/overview` 可作为“优化项”提供更轻量的统计聚合,但必须保留**降级策略**(用 `/api/db/users` + `/api/orders` 拼)以免阻塞前端迁移与部署节奏。 +- **鉴权一致性**:页面入口/菜单变化不影响鉴权口径,仍以 `GET /api/admin` 作为 session/token 校验;401 统一跳登录并清 token。 + +> 详见会议纪要:`.cursor/meeting/2026-03-10_管理端迁移Mycontent-temp菜单布局讨论.md` + +--- + +## 新增聚合接口 UserDashboardStats + +**场景**:小程序「我的」页需要一个聚合接口返回阅读统计,避免多次请求。 + +**接口**:`GET /api/miniprogram/user/dashboard-stats?userId=xxx` + +**数据来源**: +- `readSectionIds` / `readCount` → `reading_progress` WHERE `user_id = userId` +- `totalReadMinutes` → `SUM(duration) / 60`(秒转分,最小值 1 分钟) +- `recentChapters` → `reading_progress` ORDER BY `last_open_at DESC` JOIN `chapters`(最近 5 条**去重**) +- `matchHistory` → `match_records` COUNT WHERE `user_id = userId` + +**三处 bug 修复点**(对比 Mycontent-temp 参考版发现): + +| Bug | 错误做法 | 正确做法 | +|-----|---------|---------| +| 最近阅读重复 | 直接取前 5 条(同章节可重复) | `seenRecent` map 去重,保证 5 条不重复 | +| 阅读时长最小值 | 不足 60 秒返回 0 | `if totalReadSeconds > 0 && totalReadMinutes == 0 { totalReadMinutes = 1 }` | +| DB 错误状态码 | 返回 200 + `success:false` | 返回 HTTP 500 `InternalServerError` | + +**规则沉淀**:新增聚合接口时,先参考已有版本实现,对比 diff 后修复潜在 bug,再提交。 + +> 详见会议纪要:`.cursor/meeting/2026-03-10_小程序新旧版对比与dashboard接口新增.md` + +--- + +## chapters 表新增 hot_score 字段 + +### 问题 + +前端 `ContentPage.tsx` 保存章节时传递 `hotScore` 字段,但后端 model 和数据库均缺少该列,导致: +``` +Error 1054 (42S22): Unknown column 'hot_score' in 'field list' +``` + +### 修复步骤 + +1. 执行迁移 SQL(`soul-api/scripts/add-hot-score.sql`): + ```sql + ALTER TABLE chapters ADD COLUMN hot_score INT NOT NULL DEFAULT 0; + ``` +2. 同步 model(`internal/model/chapter.go`): + ```go + HotScore int `gorm:"column:hot_score;default:0" json:"hotScore"` + ``` +3. 重启后端服务生效 + +### 规则沉淀 + +- **model 与 DB 必须同步**:前端传入新字段时,必须先确认 DB 列存在,再确认 model struct 中有对应字段,缺一不可 +- **变更流程**:前端加字段 → ALTER TABLE → 更新 model struct → 重启服务 +- 迁移 SQL 统一放 `soul-api/scripts/` 目录,文件名格式 `add-{描述}.sql` + +> 详见会议纪要:`.cursor/meeting/2026-03-10_Toast通知系统全局落地.md` + diff --git a/.cursor/agent/后端工程师/evolution/2026-03-11.md b/.cursor/agent/后端工程师/evolution/2026-03-11.md new file mode 100644 index 00000000..679a4fc0 --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-11.md @@ -0,0 +1,8 @@ +# 后端工程师 经验记录 - 2026-03-11 + +## 数据库迁移:users 仅 VIP 身份/状态,chapters 补 hot_score + +- users 表:迁移脚本只添加 is_vip、vip_expire_date、vip_activated_at、vip_sort、vip_role;不再添加 vip_name、vip_avatar、vip_project、vip_contact、vip_bio(小程序已改为直接读用户资料)。 +- chapters 表:SQL 导出仅有 hot_score_override,Model 使用 hot_score;迁移脚本增加 hot_score 列。 +- 脚本:`soul-api/scripts/sync-users-vip-and-schema.sql`;说明:`soul-api/scripts/README-schema-sync.md`。 +- 详见团队共享:`agent/团队/evolution/2026-03-11.md`。 diff --git a/.cursor/agent/后端工程师/evolution/2026-03-12.md b/.cursor/agent/后端工程师/evolution/2026-03-12.md new file mode 100644 index 00000000..c0d5bca9 --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-12.md @@ -0,0 +1,61 @@ +# 后端工程师 经验记录 - 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 = true` + - `reason = "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 买断」。 diff --git a/.cursor/agent/后端工程师/evolution/2026-03-13.md b/.cursor/agent/后端工程师/evolution/2026-03-13.md new file mode 100644 index 00000000..4590c530 --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-13.md @@ -0,0 +1,45 @@ +# 2026-03-13 - 文章详情预览统一与内容安全 + +## 问题 / 场景 + +- 文章详情目前小程序侧只展示约 20% 内容作为预览,再引导用户付费解锁。 +- 历史实现中前端本地按 20% 计算预览,后端曾同时返回外层 `content`(预览)和 `data.content`(全文),存在「接口约定不统一」和「误用 data.content 泄露全文」的风险。 +- 需求:统一由后端按业务规则截取预览(改为 50%),小程序只按「是否已付费」选择用预览还是全文;未付费时,无论字段层级都不能拿到全文。 + +## 解决方案 + +- 在 `internal/handler/book.go` 中调整章节预览逻辑: + - `previewContent` 改为按字符数取正文前 50%(`total/2`),同时保证预览不少于 100 个字符; + - 预览结尾统一追加 `……(购买后阅读完整内容)` 作为提示文案。 +- 在 `findChapterAndRespond` 中统一内容返回策略: + - 先根据 system_config.free_chapters / chapter_config.freeChapters / chapters.is_free / price 判断章节是否免费; + - 免费章节:`returnContent = ch.Content`(全文); + - 付费章节: + - 若 `checkUserChapterAccess` 判断用户已购买 / VIP / 全书:`returnContent = ch.Content`(全文); + - 否则:`returnContent = previewContent(ch.Content)`(仅预览); + - 构造响应时,将 `chForResponse.Content = returnContent`,并通过: + - 外层 `content: returnContent`, + - 内层 `data: chForResponse`(其中 `content` 也为 `returnContent`), + - 确保未授权用户在任意字段上都拿不到完整正文。 + +## 与前端的接口约定 + +- 小程序阅读页通过 `userId` 查询章节详情,`accessManager` 基于返回的章节信息与用户购买状态计算 `accessState`: + - 当 `accessState` 为 `free` 或 `unlocked_purchased` 时,前端使用 `res.data.content ?? res.content` 渲染全文; + - 当 `accessState` 为未登录 / 未购买时,前端只使用 `res.content` 渲染预览。 +- 预览比例完全由后端控制(当前为 50%),小程序不再自行用 20% 做二次截断,只是把后端提供的预览完整展示出来。 + +## 代码位置 + +- 后端: + - `soul-api/internal/handler/book.go` +- 小程序(前端配合): + - `miniprogram/pages/read/read.js` + - `miniprogram/pages/read/read.wxml` + +## 对后续开发的约定 + +- 预览长度(包括比例、最小字符数、提示文案)统一由后端控制;如需调整比例,只需修改 `previewContent`,保持接口字段含义不变。 +- 任何需要「只返回部分内容预览」的场景,应优先复用「外层 `content` + 内层 `data.content` 保持一致」的安全模式,避免在不同字段中混放全文与预览内容。 +- 涉及付费内容时,优先在后端用「权限判断 + 统一内容裁剪」实现安全边界,前端只根据状态选择展示预览还是全文。 + diff --git a/.cursor/agent/后端工程师/evolution/2026-03-14.md b/.cursor/agent/后端工程师/evolution/2026-03-14.md new file mode 100644 index 00000000..b8db6779 --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-14.md @@ -0,0 +1,33 @@ +# 2026-03-14 - 内容排名算法修正(排名分公式) + +## 问题 / 场景 + +- 管理端「内容排行」与小程序「精选推荐」共用 `computeArticleRankingSections`,原算法错误: + - 使用「原始数值 × 权重」:`hot = readCnt×readWeight + payCnt×payWeight + recencyScore×recencyWeight` + - `recencyScore` 为 0–1 的天数衰减,非排名分 +- 管理端修改权重后,列表不刷新(只调了 loadList,未调 loadRanking)。 + +## 解决方案 + +### 算法修正(db_book.go computeSectionsWithHotScore) + +- **公式**:热度积分 = 阅读权重×阅读排名分 + 新度权重×新度排名分 + 付款权重×付款排名分(三权重之和须为 1) +- **排名分规则**: + - 阅读量前 20 名:第 1 名=20 分 … 第 20 名=1 分,其余 0 分 + - 最近更新前 30 篇:第 1 名=30 分 … 第 30 名=1 分,其余 0 分 + - 付款数前 20 名:第 1 名=20 分 … 第 20 名=1 分,其余 0 分 +- **权重配置**:从 `system_config.article_ranking_weights` 读取 readWeight、recencyWeight、payWeight +- **手动覆盖**:若 `chapters.hot_score > 0`,则优先使用该值 + +### 与前端约定 + +- 管理端保存权重后需同时调用 `loadList()` 和 `loadRanking()`,并关闭弹窗,列表才能立即刷新。 + +## 代码位置 + +- `soul-api/internal/handler/db_book.go`:`computeSectionsWithHotScore`、`computeArticleRankingSections` +- 管理端 `ContentPage.tsx`:`handleSaveRankingWeights` 中 loadRanking + setShowRankingAlgorithmModal(false) + +## 影响 + +- 管理端内容排行榜、小程序精选推荐(`/api/miniprogram/book/recommended`)均复用该算法,修正后两端同步生效。 diff --git a/.cursor/agent/后端工程师/evolution/2026-03-16.md b/.cursor/agent/后端工程师/evolution/2026-03-16.md new file mode 100644 index 00000000..0cbeba71 --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-16.md @@ -0,0 +1,17 @@ +# 后端工程师 经验记录 - 2026-03-16 + +## ParseAutoLinkContent 必须输出 data-label + +- TipTap Mention 仅从 `data-label` 解析显示名,缺则回退显示 `data-id`(token) +- 新建 mention span:`@名字` +- 已损坏内容(span 内为 token):用 token 查 persons 取真实名字补回 data-label + +## 存客宝创建计划参数 + +- planType=1、sceneId=9、scenario=9、status=1 +- 管理端添加、文章 @ 自动创建两处均已同步 + +## new-soul 派对AI 与 content_upload.py(会议:new-soul 新需求与当前项目差异分析) + +- content_upload.py 直连 DB 与 soul-api 并存,需核对 chapters 表结构与字段一致性 +- 中长期可规划将文章上传迁移到 soul-api admin/db 接口,统一数据入口 diff --git a/.cursor/agent/后端工程师/evolution/2026-03-17.md b/.cursor/agent/后端工程师/evolution/2026-03-17.md new file mode 100644 index 00000000..c82615fe --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-17.md @@ -0,0 +1,73 @@ +# 后端 - 2026-03-17 + +## 代付 PayNotify 权益归属修复 + +### 问题 + +代付支付回调中,`buyerUserID` 由 openID 解析得到,即**代付人**。权益激活(全书、VIP、章节、余额充值)和分佣均用 `buyerUserID`,导致权益错误给到代付人,而非发起人。 + +### 修复 + +引入 `beneficiaryUserID`(权益归属人): + +- **代付订单**:`beneficiaryUserID = order.UserID`(发起人) +- **普通订单**:`beneficiaryUserID = buyerUserID`(付款人) + +权益激活、分佣、取消未支付订单等逻辑统一改用 `beneficiaryUserID`。 + +### 经验 + +- 代付场景:`order.user_id` = 发起人,`payer_user_id` = 代付人;权益与分佣必须按 `order.user_id` 处理 +- PayNotify 中 openID 解析得到的是实际付款人,代付时需以 order 的 user_id 为权益归属 + +--- + +## gift-pay detail 返回 initiatorUserId + +- 供小程序区分发起人/好友,展示不同 UI +- 字段:`initiatorUserId`(发起人 user_id) + +--- + +## 新版管理端迁移 - 后端任务(会议:2026-03-17) + +- **router 补齐**:迁移前注册 5 个路由:`db.GET("/users/rfm")`、`db.GET("/users/journey-stats")`、`admin.GET("/shensheshou/query")`、`admin.POST("/shensheshou/enrich")`、`admin.POST("/shensheshou/ingest")` +- **待确认**:/api/admin/settings 是否已支持 ossConfig,若不支持需补充 + +--- + +## 稳定版源码质量优化(会议:2026-03-17) + +- **敏感配置**:生产环境(MODE=release)强制校验,缺敏感 env 则 Fatal +- **user/track 鉴权**:新增 GET /api/admin/user/track + AdminAuth,原 /api/user/track 保留给小程序 POST 埋点 +- **AdminWithdrawTest**:非 develop 环境返回 404 或拒绝 + +--- + +## 会议收尾(2026-03-17) + +- 源码优化 10 项全部完成;开发环境测试 10 通过 2 跳过 + +--- + +## 性能优化与 Redis 缓存方案落地(2026-03-17) + +### Redis 缓存 + +- **internal/cache**:Get/Set/Del、GetString/SetString;Redis 不可用时回退 DB +- **已缓存**:book/parts、hot、recommended、stats、config、章节 content +- **失效**:InvalidateBookParts、InvalidateBookCache、InvalidateConfig、InvalidateChapterContent + +### OSS 上传 + +- **internal/oss**:LoadConfig、Upload、Delete;失败回退本地 +- 配置从 system_config.oss_config 读取 + +### /health + +- 返回 database、redis 连接状态(ok/disconnected/disabled) + +### 经验 + +- Redis 容灾:未配置或失败时回退 DB,不阻塞业务 +- 缓存 key:soul:{业务}:{标识} diff --git a/.cursor/agent/后端工程师/evolution/2026-03-18.md b/.cursor/agent/后端工程师/evolution/2026-03-18.md new file mode 100644 index 00000000..608b550a --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-18.md @@ -0,0 +1,41 @@ +# 后端工程师 经验记录 - 2026-03-18 + +## 功能需求口径整理(按接口契约与风险) + +### 需求基准(后端视角) +- 以 `开发文档/1、需求/以界面定需求.md` 的“界面→接口”映射为准: + - 小程序只用 `/api/miniprogram/*` + - 管理端只用 `/api/admin/*`、`/api/db/*`、`/api/orders` 等 + +### 核心功能域(必须稳定) +- **阅读与权限**: + - 未授权只返回预览;授权返回全文 + - VIP 全章免费信号必须后端折叠输出,前端只认统一字段(避免各端各自判断) +- **支付链路**: + - 下单→支付→回调→解锁/分润,必须具备幂等与可追溯(订单号、来源、日志) +- **代付分享(发起人支付,好友领取)**: + - 发起人支付后产生可分享 requestSn + - 好友领取必须并发安全(名额扣减原子、重复领取幂等) + - 权益归属必须正确(代付场景 beneficiaryUserID=发起人) +- **推广/分润/提现**: + - 分润规则可配置,计算口径一致 + - 提现流转:申请→审核/打款→回写状态→订阅消息 + +### 分享场景风险点(联调/验收必测) +- **朋友圈 singlePage**:属于前端能力限制,但后端要做到: + - 接口幂等(前端重试/重复进入会更频繁) + - 错误码与提示文案清晰(便于前端引导“前往小程序”) + +### 文档归档(后端相关) +- 里程碑推进表:`开发文档/10、项目管理/项目落地推进表.md` +- 测试流程与回归口径:`scripts/test/功能测试流程.md` + +## 超级个体开通后自动创建@人(Person)与资料完善 flags + +### 幂等与建模建议 +- 自动创建 Person 建议以业务主键(`userId`)作为**幂等键**,避免仅依赖昵称导致重名/改名混乱。 +- 倾向在 `persons` 增加 `user_id`(并做唯一索引/约束),后续昵称变更时可按 `user_id` 同步更新 `name`。 + +### 端上资料完善判断 +- 默认头像/昵称判定不建议只靠前端字符串规则;后端可在用户资料/登录态接口返回明确布尔值(如 `profileNeedComplete` / `isDefaultAvatar` / `isDefaultNickname`),小程序仅消费并跳转引导页。 + diff --git a/.cursor/agent/后端工程师/evolution/2026-03-24.md b/.cursor/agent/后端工程师/evolution/2026-03-24.md new file mode 100644 index 00000000..66e0c449 --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-24.md @@ -0,0 +1,22 @@ +# 后端工程师 经验记录 - 2026-03-24 + +## 开发进度同步会议 + +### 提现相关(2026-03-20 已落地,与文档一致) +- 审批逻辑:doApproveWithdrawal 校验「累计-已提现>=待审核」,-0.01 浮点容差。 +- referral_config:withdrawFee、enableAutoWithdraw、minWithdrawAmount 使用正确。 +- admin_withdrawals:fail_reason、error_message 落库。 + +### router 缺失 handler 补齐(编译通过) +- `BookRanking`:`book.go`,复用 `computeArticleRankingSections`,`?limit=` 默认 50、最大 200;字段与 `sectionListItem` 对齐(无 `titles` 字段)。 +- `DBPersonPinnedToken` / `CKBPinnedPerson`:`db_person.go`,置顶人物 `Order("updated_at DESC").First`,与 `DBPersonPinnedList` 首条一致;小程序无置顶返回 `data: null`。 +- `AdminDashboardLeads`:`admin_dashboard.go`,`ckb_lead_records` / `ckb_submit_records` 总量、今日量、留资去重用户数。 + +### 待办 +- router 补齐:users/rfm、users/journey-stats、shensheshou 共 5 个。 +- 确认 /api/admin/settings 是否支持 ossConfig。 + +## 需求与进度及三端闭环评审 + +- 三端路由分组未被破坏;缺口为业务校验:提现 wechat_id、CKBJoin investor 付费、MatchUsers 发起者资料。 +- 失败响应需带 `needBindWechat` / `errorCode` 等稳定字段,配合小程序 `err.response` 约定(详见团队 evolution 与 meeting 纪要)。 diff --git a/.cursor/agent/后端工程师/evolution/2026-03-31.md b/.cursor/agent/后端工程师/evolution/2026-03-31.md new file mode 100644 index 00000000..c9a3563d --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-03-31.md @@ -0,0 +1,6 @@ +# 后端工程师 经验记录 - 2026-03-31 + +## 会议:超级个体列表与 @ 列表融合 + +- 列表融合优先在现有聚合接口(如 `/api/db/vip-members`)上增加 Person 关联只读字段,避免新表与重复「谁算超级个体」规则;注意批量查询、路由组边界不变。 +- 字段命名宜与 read-extras / mention 侧对齐,便于管理端一行展示。 diff --git a/.cursor/agent/后端工程师/evolution/2026-04-02.md b/.cursor/agent/后端工程师/evolution/2026-04-02.md new file mode 100644 index 00000000..6e77f07b --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-04-02.md @@ -0,0 +1,8 @@ +# 后端工程师 经验记录 - 2026-04-02 + +## 会议:工作进度与需求同步会 + +- **场景**:进度同步 + deploy 目录变更与业务待续项并行。 +- **要点**:`soul-api/deploy` 改动合并前应用 compose(或等价)验证,README 与 compose 环境变量保持一致;vip-members 聚合 Person 字段优先,满足管理端 UsersPage 联调。 +- **路由**:miniprogram / admin / db 分组边界不变。 +- **待办**:问题与作答区 Q2、Q3 作答后闭环。 diff --git a/.cursor/agent/后端工程师/evolution/索引.md b/.cursor/agent/后端工程师/evolution/索引.md index a3f19dbe..99584d5c 100644 --- a/.cursor/agent/后端工程师/evolution/索引.md +++ b/.cursor/agent/后端工程师/evolution/索引.md @@ -4,3 +4,9 @@ |------|------|------| | 2026-03-05 | soul-api 合并状态确认;orders、distribution 接口核对 | [2026-03-05.md](./2026-03-05.md) | | 2026-03-05 | 文章详情@某人:content 内嵌 @ 标记、miniprogram 添加好友接口 | [2026-03-05.md](./2026-03-05.md) | +| 2026-03-10 | 管理端迁移 Mycontent-temp:接口边界不变;overview 聚合接口可选但需降级 | [2026-03-10.md](./2026-03-10.md) | +| 2026-03-12 | persons token 字段与 DB 迁移;CKBLead 用 token 兑换 ckb_api_key | [2026-03-12.md](./2026-03-12.md) | +| 2026-03-14 | 内容排名算法修正:排名分公式(阅读/新度/付款前 N 名),支持 hot_score 手动覆盖 | [2026-03-14.md](./2026-03-14.md) | +| 2026-03-16 | ParseAutoLinkContent data-label;存客宝 create planType/sceneId/status | [2026-03-16.md](./2026-03-16.md) | +| 2026-03-17 | 代付 PayNotify beneficiaryUserID 权益归发起人;gift-pay detail 返回 initiatorUserId | [2026-03-17.md](./2026-03-17.md) | +| 2026-03-24 | router 缺失四 handler:BookRanking、DBPersonPinnedToken、CKBPinnedPerson、AdminDashboardLeads | [2026-03-24.md](./2026-03-24.md) | diff --git a/.cursor/agent/团队/evolution/2026-03-08.md b/.cursor/agent/团队/evolution/2026-03-08.md new file mode 100644 index 00000000..ef457126 --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-08.md @@ -0,0 +1,20 @@ +# 团队共享 经验记录 - 2026-03-08 + +## 文章阅读付费规则澄清与后端修复 + +### 业务规则(全团队共识) + +1. **非会员专属文章**:免费,无需登录/付费;以管理端「系统设置 → 免费章节」配置为准 +2. **VIP 会员**:开通 VIP 后,所有文章免费阅读;`check-purchased` 按 `is_vip=1` 且 `vip_expire_date>NOW` 返回 `isPurchased: true` + +### 技术实现 + +- **免费章节**:soul-api `book.go` 从 `system_config.free_chapters` 或 `chapter_config.freeChapters` 读取,优先于 chapters 表 +- **VIP 全章免费**:`user.go` 的 `UserCheckPurchased` 已实现,无需改动 + +### 影响角色 + +- 后端:book.go 变更,部署后需重启 +- 管理端:确保免费章节配置正确 +- 产品:作为验收规则 +- 小程序:无变更 diff --git a/.cursor/agent/团队/evolution/2026-03-10.md b/.cursor/agent/团队/evolution/2026-03-10.md new file mode 100644 index 00000000..4e7ab4f2 --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-10.md @@ -0,0 +1,67 @@ +# 团队共享 经验记录 - 2026-03-10 + +## 管理端迁移 Mycontent-temp:菜单/布局新规范基线 + +### 决议(团队共享) + +- **目标态基线**:以 `Mycontent-temp/soul-admin` 的 `AdminLayout` + `SettingsPage` 作为“新规范基线”,后续管理端所有菜单/布局调整按该基线执行,避免两套后台并行发散。 +- **主导航收敛**:侧栏只保留 5 个主入口(概览/内容/用户/找伙伴/推广),系统设置固定底部,取消“更多”折叠入口。 +- **功能不丢但入口收敛**:订单/提现/推广设置/VIP角色/导师等页面保留路由可达,入口通过概览卡片或页面内跳转承载;作者/管理员设置并入 `/settings?tab=author|admin`。 + +### 实施建议 + +- 迁移时优先保证:**鉴权一致(GET /api/admin)**、**路由可达性**、**菜单一致性**,再逐步优化概览聚合接口与快捷入口。 + +--- + +## 新旧版代码对比方法论(Mycontent-temp vs miniprogram) + +### 场景 + +存在两个并行代码库(主线 + 预览版),需要判断哪个版本更可靠,以及如何安全地吸收另一版的优点。 + +### 最佳实践 + +1. **批量 diff 优先于逐文件比较**:用 PowerShell 批量对比 WXSS/JS/WXML 文件,精确列出「相同/有差异」的文件清单,再聚焦差异文件逐一分析。 +2. **以功能完整性为基准**:不以「新/旧」日期判断优劣,而以**功能是否完整**为主要依据;本次判断旧版(miniprogram)才是功能更完整的版本。 +3. **差异归类**: + - **旧版有、新版没有** → 旧版是主线,保留旧版 + - **新版有、旧版没有** → 评估是否需要移植(如 dashboard-stats 调用) + - **样式差异** → 对比具体行数,判断是改进还是遗漏 +4. **接口对比时对照新版参考修复 bug**:新版的接口实现即使存在,也可能有遗漏;参考后自行修复(去重、最小值、错误码等)再提交。 + +### 适用场景 + +- 分支合并前的功能完整性分析 +- 迁移预览版到主线时的取舍决策 +- 跨版本 bug 溯源 + +> 同时影响:小程序开发工程师、后端工程师 +> 详见会议纪要:`.cursor/meeting/2026-03-10_小程序新旧版对比与dashboard接口新增.md` + +--- + +## Toast 通知系统 & DB 变更 SOP(团队共享) + +### Toast 批量替换方法论 + +使用 PowerShell 正则脚本批量替换 alert → toast,**替换后必须人工复查 `toast.info()`**: +- 验证提示类("请输入/请填写/密码至少/ID已存在")被脚本误判为 info,应改为 error +- 核查方式:`grep -r "toast.info(" src/` 逐条确认语义 + +### DB 变更 SOP(前后端联动) + +当前端新增字段时,完整变更流程: + +| 步骤 | 执行方 | 操作 | +|------|--------|------| +| 1 | 后端 | 执行 `ALTER TABLE` 或用 `db-exec` 脚本 | +| 2 | 后端 | 更新 `internal/model/*.go` struct | +| 3 | 后端 | 重启服务验证 | +| 4 | 管理端 | 确认保存请求不再报 1054 | + +若跳过任一步骤,GORM 写入时必报 `Unknown column`。 + +> 同时影响:管理端开发工程师、后端工程师 +> 详见会议纪要:`.cursor/meeting/2026-03-10_Toast通知系统全局落地.md` + diff --git a/.cursor/agent/团队/evolution/2026-03-11.md b/.cursor/agent/团队/evolution/2026-03-11.md new file mode 100644 index 00000000..2223b98a --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-11.md @@ -0,0 +1,30 @@ +# 团队共享 经验记录 - 2026-03-11 + +## 以界面定需求与业务逻辑对齐(全团队) + +### 背景 + +用户要求开发团队对齐业务逻辑,并更新开发文档和需求文档,**以界面来定需求**。 + +### 决议与产出 + +1. **新增《以界面定需求》** + - 路径:`开发文档/1、需求/以界面定需求.md` + - 内容:原则(界面即需求、三端路由隔离、用户/VIP 展示以用户资料为准);小程序界面清单(每页功能要点与主要 /api/miniprogram/* 接口);管理端界面清单(每页功能要点与主要 /api/admin/*、/api/db/*、/api/orders 等);业务逻辑对齐(用户与 VIP 资料展示、三端 API 边界、免费章与 VIP、分销提现)。 + +2. **需求基准** + - 需求以《以界面定需求》为准;《需求汇总》增加「需求基准(必读)」节,新增/变更功能先对齐界面再更新需求清单。 + - 开发文档 README 增加《以界面定需求》链接;运营与变更第九部分记录本次对齐。 + +3. **用户/VIP 资料规则(与界面一致)** + - 展示以**用户资料**为准(nickname、avatar、projectIntro、phone 等);不再单独存 vip_name、vip_avatar、vip_project、vip_contact、vip_bio;数据库迁移脚本不再新增上述五列;VIP 身份/状态(is_vip、vip_expire_date、vip_activated_at、vip_sort、vip_role)仍保留。 + +### 适用角色 + +- 产品经理:需求与验收以《以界面定需求》为准。 +- 小程序 / 管理端 / 后端:开发与联调以界面清单中的功能要点与主要接口为准;业务规则以《以界面定需求》第四节为准。 +- 测试:功能与回归以界面清单与业务逻辑对齐节为验收范围。 + +### 会议纪要 + +- `.cursor/meeting/2026-03-11_开发团队对齐业务逻辑与以界面定需求会议收尾.md` diff --git a/.cursor/agent/团队/evolution/2026-03-12.md b/.cursor/agent/团队/evolution/2026-03-12.md new file mode 100644 index 00000000..d16d87de --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-12.md @@ -0,0 +1,47 @@ +# 团队共享 经验记录 - 2026-03-12 + +## 密钥/token 设计:关联小程序与 @ 人物 + +### 背景 + +- **关联小程序**:添加时生成 32 位英文+数字密钥,链接标签存 key,小程序点击 # 时用 key 查 appId 再跳转 +- **@ 人物**:添加时生成 32 位 token,文章 @ 时存 token,小程序点击 @ 时用 token 兑换真实 ckb_api_key 后加好友 + +### 设计原则 + +1. **不暴露真实密钥**:管理端配置的真实密钥(appId、ckb_api_key)不写入文章内容,仅存可对外传递的 token/key +2. **服务端兑换**:小程序端只传 token/key,后端用其查表得到真实密钥再调用第三方 +3. **不兼容旧数据**:项目未上架,无需兼容 person_id、appId 等旧格式 + +### 数据流 + +| 场景 | 添加时 | 内容存储 | 小程序点击 | 后端兑换 | +|------|--------|----------|------------|----------| +| 关联小程序 | 生成 key | data-mp-key | 传 mpKey | 查 linked_miniprograms 得 appId | +| @ 人物 | 生成 token | data-id | 传 targetUserId | 查 persons 得 ckb_api_key | + +### 适用角色 + +- 后端:persons.token、linked_miniprograms.key、CKBLead 兑换逻辑 +- 管理端:链接标签选 key、@ 人物 id=token、列表展示 +- 小程序:contentParser 解析 mpKey、onLinkTagTap/onMentionTap 传 key/token + +--- + +## 9.9 买断与团队级约定 + +### 结论 + +- 「9.9 买断全书」在三端的唯一来源是后端的 `hasFullBook`/`has_full_book` 信号: + - 小程序:只看 `/user/purchase-status` 的 `hasFullBook` 和 `/user/check-purchased` 的 `reason = "has_full_book"`。 + - 后端:可以通过订单或用户资料开关(如 `manual_fullbook`)计算该状态。 + - 管理端:如需赠送 9.9 买断,应只改后端用户资料中的开关,不直接改前端逻辑。 + +### 约定 + +- 任意「免 9.9」或「赠送全书」能力都必须: + - 由后端在 purchase-status/check-purchased 中折叠为统一的 `hasFullBook/has_full_book`。 + - 不允许在小程序或管理端各自新增本地开关绕过后端逻辑。 +- VIP 与 9.9 买断继续分离: + - `hasFullBook` → 只代表书的权限; + - `isVip` → 代表会员权益(案例库、增值版等),两者可以独立打开。 diff --git a/.cursor/agent/团队/evolution/2026-03-13.md b/.cursor/agent/团队/evolution/2026-03-13.md new file mode 100644 index 00000000..54b080de --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-13.md @@ -0,0 +1,42 @@ +# 2026-03-13 - 文章详情预览规则统一(小程序 + 后端) + +## 场景 + +- 文章详情页采用「部分内容预览 + 付费解锁全文」的收费模式。 +- 历史实现中,预览比例由小程序本地按 20% 行数截取,后端可能同时返回预览与全文两个 content 字段,存在: + - 三端对「预览长度」的理解不一致; + - 前端误用 `data.content` 导致未付费用户拿到全文的潜在风险。 +- 本次目标:将「预览长度 + 安全边界」下沉到后端统一控制,小程序只按「是否已解锁」选择展示预览或全文。 + +## 团队级决策 + +- 预览长度统一由 **soul-api** 控制: + - 当前规则:对付费章节,未解锁用户默认看到正文前 **50%**,且不少于 100 个字符,末尾追加「购买后阅读完整内容」提示; + - 未来如需改为 40% / 30% 等,只需调整后端 `previewContent`,前端逻辑保持不变。 +- 接口约定统一: + - 章节详情接口(含 `/api/miniprogram/book/chapter/:id`、`/api/miniprogram/book/chapter/by-mid/:mid`)返回的: + - 外层 `content` 字段, + - 内层 `data.content`(Chapter.Content)字段, + - **在同一次响应中必须保持一致**: + - 免费或已解锁:两处都是全文; + - 未解锁:两处都是预览(50%)。 + - 不允许出现「外层是预览、`data.content` 是全文」这类混合返回,避免前端误用泄露付费内容。 +- 小程序阅读页约定: + - 只根据 `accessState` 判断是否有权看全文; + - 有权限时使用 `data.content` / `content` 渲染全文; + - 无权限时仅使用后端返回的预览内容,不再在前端重新按 20% 行数切割。 + +## 影响角色 + +- **后端工程师(soul-api)**: + - 负责实现和维护 `previewContent` 预览算法及权限判断逻辑; + - 在新增/修改与付费内容相关的接口时,必须遵守「外层 content 与 data.content 一致」的安全约定。 +- **小程序开发工程师**: + - 阅读页不自行决定预览比例,只展示后端返回的预览内容; + - 通过 `accessManager` 与章节详情响应判断权限,严格按照 `accessState` 切换「预览 / 全文」视图。 + +## 对后续迭代的提示 + +- 若未来引入「增值版内容」「章节试读长度差异化」等新收费形态,优先在后端扩展 `previewContent` 与权限判断逻辑,对前端暴露统一、稳定的字段语义。 +- 若管理端需要控制预览比例或提示文案,可在配置中心增加相关配置项,由后端读取后影响 `previewContent` 行为,保持三端一致。 + diff --git a/.cursor/agent/团队/evolution/2026-03-14.md b/.cursor/agent/团队/evolution/2026-03-14.md new file mode 100644 index 00000000..346a20cc --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-14.md @@ -0,0 +1,17 @@ +# 2026-03-14 - 内容排名算法跨端复用约定 + +## 业务规则 + +- **热度积分公式**:阅读权重×阅读排名分 + 新度权重×新度排名分 + 付款权重×付款排名分(三权重之和须为 1) +- **排名分规则**:阅读量前 20 名(20~1 分)、最近更新前 30 篇(30~1 分)、付款数前 20 名(20~1 分) + +## 跨端复用 + +- **管理端**:`/api/db/book?action=ranking` → `computeArticleRankingSections` +- **小程序**:`/api/miniprogram/book/recommended` → `computeArticleRankingSections`(取前 3 条) +- 两者共用同一套算法、权重配置(`article_ranking_weights`)、置顶配置(`pinned_section_ids`) + +## 约定 + +- 排名算法修改只需改 soul-api 一处,管理端与小程序自动同步。 +- 管理端保存权重后必须调用 `loadRanking()` 刷新列表,否则用户看不到变化。 diff --git a/.cursor/agent/团队/evolution/2026-03-16.md b/.cursor/agent/团队/evolution/2026-03-16.md new file mode 100644 index 00000000..95ed1a02 --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-16.md @@ -0,0 +1,12 @@ +# 团队 经验记录 - 2026-03-16 + +## TipTap Mention 显示规则 + +- **data-label 必填**:TipTap Mention 的 label 仅从 `data-label` 解析,不解析 span 内文本 +- 后端 ParseAutoLinkContent 输出 mention 时必须含 data-label,否则管理端重开后显示 token 而非名字 + +## new-soul 派对AI 与 Mycontent 关系(会议:new-soul 新需求与当前项目差异分析) + +- new-soul 派对AI(魂AI)9 技能 5 组:魂资/魂流/魂产/魂码/魂质 +- 与 Mycontent 三端(soul-api、soul-admin、miniprogram)为同一业务不同层面:运营侧 vs 产品侧 +- 路径差异(Mac vs Windows)需在文档中说明 diff --git a/.cursor/agent/团队/evolution/2026-03-17.md b/.cursor/agent/团队/evolution/2026-03-17.md new file mode 100644 index 00000000..6c54aae8 --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-17.md @@ -0,0 +1,66 @@ +# 团队 - 2026-03-17 + +## 代付美团式流程与权益归属约定 + +### 流程约定 + +1. **入口**:读页「找好友代付」→ 创建请求 → **跳转代付详情页**(不再弹窗) +2. **代付页**:发起人看到「分享给好友」,好友看到「帮他付款」 +3. **后端**:detail 返回 `initiatorUserId`,前端据此区分 + +### 权益与分佣约定 + +- 代付订单:`order.user_id` = 发起人,`payer_user_id` = 代付人 +- 权益(全书、VIP、章节、余额充值)归属发起人 +- 分佣按发起人的推荐关系计算 +- PayNotify 中 openID 解析得到的是代付人,权益与分佣必须用 `order.user_id` + +### 同时影响 + +- 小程序:代付详情页双态 UI、读页跳转 +- 后端:PayNotify beneficiaryUserID、detail initiatorUserId + +--- + +## 新版管理端迁移到稳定版(会议:2026-03-17) + +### 决议 + +- **内容管理**:以稳定版为主,不采纳新版 +- **新版独有**:API 文档 Tab、api-docs 独立页、OSS 配置、编辑时手机号禁用、鉴权逻辑 → **全部吸纳** +- **后端**:迁移前补 router(users/rfm、journey-stats、shensheshou 共 5 个) + +### 影响角色 + +- 管理端开发工程师:主导迁移 +- 后端开发:router 补齐、ossConfig 确认 +- 测试人员:迁移后验收 + +--- + +## 稳定版源码质量优化(会议:2026-03-17) + +- **原则**:增量修复、不改功能逻辑;高优安全项优先,中优可维护项次之,低优可后续迭代 +- **影响角色**:后端、管理端、小程序、测试 + +--- + +## 会议收尾(2026-03-17) + +- 源码优化 10 项全部完成;功能测试流程定稿;开发环境测试 10 通过 2 跳过 + +--- + +## 性能优化与 Redis 缓存方案落地(2026-03-17) + +### 架构约定 + +- **Redis 容灾**:不可用时回退 DB,不阻塞业务 +- **缓存 key**:soul:{业务}:{标识} +- **OSS 上传**:优先 OSS,失败回退本地 + +### 影响角色 + +- 后端开发:cache、oss 包;/health 增强 +- 管理端开发工程师:OSS 配置后上传自动优先 OSS +- 测试人员:test_upload.py、/health 验证、部署后回归缓存接口 diff --git a/.cursor/agent/团队/evolution/2026-03-18.md b/.cursor/agent/团队/evolution/2026-03-18.md new file mode 100644 index 00000000..85ffb62e --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-18.md @@ -0,0 +1,24 @@ +# 团队 经验记录 - 2026-03-18 + +## 分享链路统一规则:兼容朋友圈 singlePage(单页模式) + +### 背景 +微信“朋友圈分享”点进小程序页可能是 **singlePage**,能力不完整;如果不做判断,容易出现支付/登录/领取等链路断裂,引发转化损失与投诉。 + +### 团队级决议(跨端共识) +- **任何“分享进入”的关键流程**(支付、代付、领取、绑定等)都要: + - **识别 singlePage**:`wx.getSystemInfoSync().mode === 'singlePage'`(并允许通过 `app.globalData.isSinglePageMode` 兜底标记) + - **做能力降级**:单页模式不执行强动作(支付/自动领取/自动登录等) + - **给出明确引导**:提示用户点击底部 **「前往小程序」** 进入完整版后再操作 + +### 落地建议 +- UI/交互层:统一封装 `ensureFullAppMode()`(或页面内统一判断),避免每个按钮散落实现导致漏判 +- 测试层:新增用例覆盖“朋友圈 singlePage 打开 + 点击关键按钮”应出现引导而非报错/卡死 + +## 超级个体开通后自动创建@人与资料完善拦截(跨端共识) + +### 团队级决议 +- “可被 @ 的人”统一走 Person 体系,避免为超级个体另建一套 mention 逻辑。 +- 幂等键应绑定业务主键(优先 `userId`),展示名同步为昵称(具体同步规则由产品确认)。 +- 默认资料判定尽量由后端提供明确 flags,前端仅做跳转与阻断,并保留兜底规则。 + diff --git a/.cursor/agent/团队/evolution/2026-03-24.md b/.cursor/agent/团队/evolution/2026-03-24.md new file mode 100644 index 00000000..8322cfa9 --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-24.md @@ -0,0 +1,22 @@ +# 团队 经验记录 - 2026-03-24 + +## 开发进度同步会议 - 文档同步原则(跨角色共识) + +### 团队级决议 +- **实现变更后**需同步更新:`开发文档/1、需求/需求汇总.md`、`开发文档/10、项目管理/运营与变更.md` 及对应角色 `agent/开发助理/项目索引/{角色}.md`。 +- **项目索引**:每次开发完成或会议收尾后,在开发进度表追加一行(含日期),并将「最后更新」改为当前日期。 +- 避免文档与实现脱节:索引滞后会导致下次同步会议重复盘点。 + +### 落地建议 +- 各角色在完成功能开发或吸收经验时,主动更新项目索引。 +- 橙子收尾时统一检查并补齐索引。 + +## 需求与进度及三端闭环评审(跨角色) + +### 结论摘要 +- **主业务闭环**:阅读/付费/代付/分销/提现主链路在文档与里程碑上成立;**规则闭环**有已知缺口,以《产品意图与功能闭环分析》《需求未补齐清单》为准。 +- **三端配套**:小程序页面域与管理端路由域整体对齐;**miniprogram/admin/db 边界未被破坏**。 +- **工程契约**:统一「失败时 body 可解析」约定(`err.response`),否则后端 errorCode 设计无法在前端落地。 + +### 详见 +- `.cursor/meeting/2026-03-24_需求与进度及三端闭环评审.md` diff --git a/.cursor/agent/团队/evolution/2026-03-31.md b/.cursor/agent/团队/evolution/2026-03-31.md new file mode 100644 index 00000000..d6b023f9 --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-03-31.md @@ -0,0 +1,7 @@ +# 团队 经验记录 - 2026-03-31 + +## 会议:超级个体列表与 @ 列表融合 + +- **架构决议**:先 **数据与入口融合(接口字段 + 管理端互链)**,再视需求做单页;不先合并数据库表。 +- **路由约定不变**:小程序仅 `/api/miniprogram/*`,管理端 `/api/db/*` 聚合;详见 `meeting/2026-03-31_超级个体与@列表融合.md`。 +- **业务澄清(@ 列表与绑定)**:@ 列表已承载超级个体与人物的绑定;**合并后不应再单独保留「超级个体绑定」这一层**,以 @ 人物 ↔ 用户为真源,运营字段(排序/Webhook/获客等)挂在用户侧展示即可。 diff --git a/.cursor/agent/团队/evolution/2026-04-02.md b/.cursor/agent/团队/evolution/2026-04-02.md new file mode 100644 index 00000000..1f07a9b0 --- /dev/null +++ b/.cursor/agent/团队/evolution/2026-04-02.md @@ -0,0 +1,8 @@ +# 团队 经验记录 - 2026-04-02 + +## 会议:工作进度与需求同步会 + +- **跨角色决议**: + - 融合方案落地顺序:后端 vip-members 聚合 → 管理端 UsersPage → 测试全量回归清单;小程序回归为主。 + - 部署变更与业务 PR 区分 scope,deploy 合并前环境验证必做。 +- **详见**:`.cursor/meeting/2026-04-02_工作进度与需求同步会.md` diff --git a/.cursor/agent/团队/evolution/索引.md b/.cursor/agent/团队/evolution/索引.md index 72a8adf9..115c0ae5 100644 --- a/.cursor/agent/团队/evolution/索引.md +++ b/.cursor/agent/团队/evolution/索引.md @@ -5,3 +5,9 @@ | 日期 | 摘要 | 文件 | |------|------|------| | 2026-03-05 | 分支冲突后各端完整性自查流程 | [2026-03-05.md](./2026-03-05.md) | +| 2026-03-10 | 管理端迁移 Mycontent-temp:菜单/布局新规范基线与入口收敛规则 | [2026-03-10.md](./2026-03-10.md) | +| 2026-03-12 | 密钥/token 设计:关联小程序 key、@ 人物 token,不暴露真实密钥、服务端兑换 | [2026-03-12.md](./2026-03-12.md) | +| 2026-03-14 | 内容排名算法跨端复用:管理端内容排行与小程序精选推荐共用 computeArticleRankingSections | [2026-03-14.md](./2026-03-14.md) | +| 2026-03-16 | TipTap Mention 需 data-label,否则显示 token | [2026-03-16.md](./2026-03-16.md) | +| 2026-03-17 | 代付美团式流程与权益归属约定:读页→代付页→分享;权益/分佣归发起人 | [2026-03-17.md](./2026-03-17.md) | +| 2026-03-24 | 文档同步原则:实现变更后同步需求/运营与变更/项目索引 | [2026-03-24.md](./2026-03-24.md) | diff --git a/.cursor/agent/安全工程师/evolution/.gitkeep b/.cursor/agent/安全工程师/evolution/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.cursor/agent/安全工程师/evolution/2026-03-20-挖矿与服务器Skills.md b/.cursor/agent/安全工程师/evolution/2026-03-20-挖矿与服务器Skills.md new file mode 100644 index 00000000..8fd33519 --- /dev/null +++ b/.cursor/agent/安全工程师/evolution/2026-03-20-挖矿与服务器Skills.md @@ -0,0 +1,32 @@ +# 挖矿病毒排查与服务器操作 Skills 创建 + +**日期**:2026-03-20 + +## 背景 + +基于 agent 记录(3b9e0fa0、bc781e1b、1c1a81c3 等)中挖矿病毒排查经验,以及本地部署脚本(devloy.py、master.py、soul-admin/deploy.py、Cunkebao/miner_guard_install.py 等),将经验吸收转化为 Skills。 + +## 新增 Skills + +### 1. security-miner-guard + +- **路径**:`.cursor/skills/security-miner-guard/SKILL.md` +- **触发词**:挖矿病毒、xmrig、服务器被入侵、miner_guard、安全排查、杀挖矿 +- **内容**:挖矿病毒特征、入侵链路、排查脚本、加固建议、miner_guard 安装与检查 + +### 2. security-server-ops + +- **路径**:`.cursor/skills/security-server-ops/SKILL.md` +- **触发词**:部署、服务器操作、SSH、宝塔、devloy、master、Cunkebao 部署 +- **内容**:服务器索引、部署脚本索引、环境变量一览、常用操作(不含明文密码) + +## 配置更新 + +- `paths.py`:新增 `AGENT_SECURITY`、`ROLE_TO_AGENT["安全工程师"]` +- `老板分身-索引.mdc`:经验自动收集推断增加「挖矿/安全/服务器操作→安全工程师」 +- `soul-project-boundary.mdc`:按语义触发词增加安全工程师及对应 Skills + +## 安全提醒 + +- Skills 中**不写入明文密码**,仅说明配置来源(环境变量、脚本 get_cfg()) +- 建议将 master.py、devloy.py 等中的默认密码迁移到环境变量 diff --git a/.cursor/agent/安全工程师/evolution/2026-03-20-管理端部署触发词.md b/.cursor/agent/安全工程师/evolution/2026-03-20-管理端部署触发词.md new file mode 100644 index 00000000..b8464d04 --- /dev/null +++ b/.cursor/agent/安全工程师/evolution/2026-03-20-管理端部署触发词.md @@ -0,0 +1,26 @@ +# 管理端部署触发词约定 + +**日期**:2026-03-20 + +## 场景 + +用户说「管理端帮我部署到xx环境」时,安全工程师应语义化解析 xx,直接执行对应部署脚本。 + +## 解决方案 + +- **触发词**:管理端帮我部署到xx环境(语义化,理解意图即可) +- **脚本映射**: + - 含「正式」「线上」「生产」→ `cd soul-admin && python master.py`(正式环境,/www/wwwroot/self/soul-admin) + - 含「测试」「dev」→ `cd soul-admin && python deploy.py`(测试环境,/www/wwwroot/self/soul-admin-dev) + +## soul-admin 部署脚本 + +| 脚本 | 环境 | 目标目录 | 构建命令 | +|------|------|----------|----------| +| master.py | 正式 | soul-admin | pnpm build | +| deploy.py | 测试 | soul-admin-dev | pnpm run build:dev | + +## 已升级 Skills + +1. **security-server-ops**:何时使用表、2.2 soul-admin 脚本索引、4.4/4.5 常用操作 +2. **soul-project-boundary**:按场景触发词表新增 diff --git a/.cursor/agent/安全工程师/evolution/2026-03-20-部署API触发词.md b/.cursor/agent/安全工程师/evolution/2026-03-20-部署API触发词.md new file mode 100644 index 00000000..63fb2dc4 --- /dev/null +++ b/.cursor/agent/安全工程师/evolution/2026-03-20-部署API触发词.md @@ -0,0 +1,18 @@ +# 部署 API 触发词约定 + +**日期**:2026-03-20 + +## 场景 + +用户说「帮我部署api到线上」时,安全工程师应直接执行部署脚本,无需再询问或选择。 + +## 解决方案 + +- **触发词**:帮我部署api到线上 +- **动作**:直接执行 `cd soul-api && python master.py` +- **脚本**:`soul-api/master.py`(soul-api 正式环境部署) + +## 已升级 Skills + +1. **security-server-ops**:何时使用表新增该触发词,明确直接执行命令 +2. **soul-project-boundary**:按场景触发词表新增,加载 security-server-ops 后执行 diff --git a/.cursor/agent/安全工程师/evolution/索引.md b/.cursor/agent/安全工程师/evolution/索引.md new file mode 100644 index 00000000..905caa6a --- /dev/null +++ b/.cursor/agent/安全工程师/evolution/索引.md @@ -0,0 +1,9 @@ +# 安全工程师 经验索引 + +> 挖矿病毒排查、服务器加固、部署与运维相关经验。 + +| 日期 | 摘要 | 文件 | +|------|------|------| +| 2026-03-20 | 挖矿病毒排查经验转化为 Skills;服务器操作 Skill 创建 | 2026-03-20-挖矿与服务器Skills.md | +| 2026-03-20 | 「帮我部署api到线上」→ 执行 soul-api/master.py | 2026-03-20-部署API触发词.md | +| 2026-03-20 | 「管理端帮我部署到xx环境」→ 语义化解析,正式→master.py,测试→deploy.py | 2026-03-20-管理端部署触发词.md | diff --git a/.cursor/agent/小程序开发工程师/evolution/2025-03-14-文本长按复制.md b/.cursor/agent/小程序开发工程师/evolution/2025-03-14-文本长按复制.md new file mode 100644 index 00000000..c58cb917 --- /dev/null +++ b/.cursor/agent/小程序开发工程师/evolution/2025-03-14-文本长按复制.md @@ -0,0 +1,40 @@ +# 阅读页文本长按选中复制 + +> 问题→解决闭环,已升级 miniprogram-dev SKILL + +--- + +## 问题 + +小程序阅读页正文长按时无法选中、复制文本。 + +--- + +## 解决方案 + +使用 `text` 组件的 **`user-select`** 属性(基础库 2.12.1+,官方推荐;`selectable` 已废弃): + +```html +{{seg.text}} +``` + +--- + +## 实施范围(read.wxml) + +- 章节标题:`` +- 正文片段:text / mention / linkTag 均加 `user-select` +- 预览段落:`{{item}}`(原为 view 内直接 `{{item}}`,需用 text 包裹) + +--- + +## 备选方案 + +- **selectable**:已废弃但多数环境仍可用,若 `user-select` 导致布局异常(inline-block 换行)可回退 +- **wx.setClipboardData + bindlongpress**:iOS 原生选中失效时,可做长按整段复制兜底 + +--- + +## Skill 升级 + +已写入 miniprogram-dev SKILL §10 文本可选与复制。 diff --git a/.cursor/agent/小程序开发工程师/evolution/2025-03-14-联网吸收小程序最新开发规则与API.md b/.cursor/agent/小程序开发工程师/evolution/2025-03-14-联网吸收小程序最新开发规则与API.md new file mode 100644 index 00000000..3067584a --- /dev/null +++ b/.cursor/agent/小程序开发工程师/evolution/2025-03-14-联网吸收小程序最新开发规则与API.md @@ -0,0 +1,90 @@ +# 联网吸收:微信小程序最新开发规则与 API(2025-03) + +> 来源:微信开放文档、基础库更新日志、Skyline 文档、隐私合规指南等 + +--- + +## 一、基础库版本与更新节奏 + +- **当前最新**:v3.14.2(2026-01-22),v3.14.3 灰度中 +- **建议**:在 `app.json` 中设置 `"useExtendedLib": { "weui": true }` 或指定 `libVersion`,关注灰度版本说明 +- **兼容**:使用 `wx.canIUse('api.xxx')` 做能力检测,避免在低版本报错 + +--- + +## 二、新增 / 重要 API(基础库 3.14 系列) + +| API | 用途 | 基础库 | +|-----|------|--------| +| `wx.rewriteRoute` | 路由重写 | 3.14+ | +| `wx.openOfficialAccountProfile` | 打开公众号 | 3.14+ | +| `wx.openOfficialAccountChat` | 跳转公众号会话 | 3.14+ | +| `wx.openInquiriesTopic` | 跳转问一问话题 | 3.14.0 | +| `wx.loadBuiltInFontFace` | 加载微信内置字体 | 3.14+ | +| `wx.onUserOffTranslation` | 监听用户关闭翻译 | 3.14.3 灰度 | + +**其他能力**: +- 鼠标右键点击事件支持(PC 端) +- 图片分享朋友圈 +- 半屏小程序 `openEmbeddedMiniProgram` 上限提升到 100 +- TCPSocket 支持 `TCP_NODELAY` + +--- + +## 三、Skyline 渲染引擎(可选升级) + +- **定位**:新一代渲染引擎,以性能为首要目标,仍用 WXML/WXSS +- **配置**:页面级 `page.json` 中 `"renderer": "skyline"` +- **性能**:启动耗时降约 20%,跳页耗时降约 50%;长列表 `scroll-view` 仅渲染屏内节点 +- **注意**:CSS 特性精简,只保留更现代的集合;鸿蒙 OS 已灰度支持 +- **Soul 项目**:当前为 WebView 渲染,若需性能优化可逐步按页面接入 Skyline + +--- + +## 四、隐私合规(2025 重要变更) + +### 4.1 核心变化:从集中授权改为按需授权 + +- **旧**:首次启动一次性请求所有权限 +- **新**:必须在用户**实际触发相关功能时**才发起对应授权请求 +- **影响**:需拆分授权逻辑到具体业务场景,不能集中在 `app.onLaunch` 里 + +### 4.2 必须完成的步骤 + +1. **后台配置**:在小程序管理后台填写《小程序用户隐私保护指引》,声明处理的用户信息类型及用途 +2. **查询与展示**:`wx.getPrivacySetting` 查询授权状态,`wx.openPrivacyContract` 打开隐私协议 +3. **获取同意**:使用 ` + +``` + +```css +.avatar-wrap { position: relative; } +.avatar-overlay-btn { + position: absolute; top: 0; left: 0; + width: 130rpx; height: 130rpx; /* 与头像一致 */ + padding: 0; margin: 0; + background: transparent; border: none; +} +.avatar-overlay-btn::after { border: none; } +``` + +## 要点 + +- **同级关系**:button 与展示元素是 sibling,不是 parent-child +- **绝对定位**:`position: absolute` 覆盖在目标区域上,不参与文档流 +- **透明无内容**:button 仅负责点击事件,样式完全透明 +- **适用**:chooseAvatar、open-type 等需 button 触发的原生能力 + +## 升级 Skill + +已写入 `miniprogram-dev` SKILL §12。 diff --git a/.cursor/agent/小程序开发工程师/evolution/2026-03-20-手机号登录与公用组件.md b/.cursor/agent/小程序开发工程师/evolution/2026-03-20-手机号登录与公用组件.md new file mode 100644 index 00000000..1df4e174 --- /dev/null +++ b/.cursor/agent/小程序开发工程师/evolution/2026-03-20-手机号登录与公用组件.md @@ -0,0 +1,39 @@ +# 手机号一键登录与登录弹窗公用组件 + +> 日期:2026-03-20 | 角色:小程序开发工程师 + +## 问题与场景 + +1. **getPhoneNumber 不弹窗**:点击手机号登录按钮时,无法弹出手机号选择界面,也无法获取手机号 +2. **登录弹窗重复**:read、my、gift-pay/detail 三处各自维护一套登录弹窗,逻辑重复、维护成本高 +3. **登录后手机号未同步**:手机号登录后若响应中 user.phone 为空,本地 userInfo 未更新 + +## 解决方案 + +### 1. getPhoneNumber 必须与隐私协议耦合 + +- **open-type**:`open-type="getPhoneNumber|agreePrivacyAuthorization"`(基础库 2.32.3+) +- **onNeedPrivacyAuthorization**:app.js 中需将使用 getPhoneNumber 的页面加入支持列表,否则会 `resolve({ event: 'disagree' })` 导致获取失败 +- **支持页面**:avatar-nickname、profile-edit、read、my、gift-pay/detail、index、settings +- **隐私弹窗**:当 onNeedPrivacyAuthorization 触发时,页面需有 `showPrivacyModal` + `