diff --git a/.specs/prds/user-creator-income-center.md b/.specs/prds/user-creator-income-center.md new file mode 100644 index 00000000..c65ab946 --- /dev/null +++ b/.specs/prds/user-creator-income-center.md @@ -0,0 +1,291 @@ +# 用户创作收益中心 + +## Problem Statement + +当前用户中心的“创作中心”主要承担文章发布与管理,尚未提供付费文章作者收益的统一查看和结算状态反馈;现有“收益中心”又主要面向推广返佣,容易让用户混淆两类收益来源。 + +本需求将“创作中心”改造成只面向付费文章作者收益的页面,展示作者从付费内容订单中获得的现金和积分分成,并提供创作分成说明与收入明细。文章发布、草稿、审核、编辑和删除等管理功能本次不再显示于用户中心。 + +创作分成功能需要独立开关。关闭后,用户中心隐藏创作中心入口,停止新作者收益生成、自动结算和手动结算;已有收益记录仍保留在后台供查询,不新增兼容读取或历史迁移逻辑。 + +## Current State + +系统已有用户中心面板注册与 REST 延迟加载机制,可用于实现无刷新页面切换;已有付费订单、积分余额、现金余额、作者收益台账、结算服务及支付后台配置体系。 + +现有创作中心页面包含文章管理功能,现有收益中心主要展示推广返佣。现有作者收益能力尚未完整接入付费文章作者视图,也未提供现金与积分分开统计、按收益记录分页筛选及退款冲正状态展示。 + +## Solution + +### 用户中心入口与页面定位 + +- 保留用户中心侧栏中的“创作中心”入口,将其内容完全改造成付费文章作者收益页面。 +- 保留“收益中心”入口,继续用于推广返佣;两者分别处理,不合并数据、不互相替代。 +- 入口关闭时不显示“创作中心”;“收益中心”不受创作分成功能开关影响。 +- 创作中心仅对登录用户开放,每位用户只能读取自己的作者收益。 +- 本次移除用户中心内原有文章管理页面展示,不提供文章发布、编辑、草稿、审核、删除或管理入口。 + +### 顶部收益卡片 + +页面顶部显示两个大卡片,视觉和交互参考 Zibll 用户收益页面,但不实现“我的收入”卡片中的提现按钮。 + +#### 今日收入 + +- 统计当天产生的有效作者分成记录,包括待结算和已入钱包的收益。 +- 现金收益与积分收益分栏展示,不进行汇率换算或合并。 +- 退款、取消及已冲正的记录不计入有效收入。 +- 无当日收益时显示零值和合理的空状态,不隐藏卡片。 + +#### 我的收入 + +- 展示用户历史累计的有效作者分成。 +- 现金与积分分别展示。 +- 每种货币分别显示待结算金额和已入对应钱包金额。 +- 现金收益提供“超过 50 元可申请现金提现”的提示文案,但不显示提现按钮,也不在本需求中新增提现流程。 +- 积分收益不受 50 元提现提示影响。 +- 卡片不混入推广返佣数据。 + +### 主内容 Tab + +页面主体包含两个 Tab,不设置 Tab 侧边滚动栏: + +1. 创作分成 +2. 收入明细 + +Tab 切换、收入明细分页和筛选均使用 Ajax/REST 局部加载,不刷新整个用户中心页面;切换后保留当前用户中心布局,并同步更新浏览器历史状态。 + +#### 创作分成 Tab + +允许后台配置 HTML 格式的说明内容。默认内容为: + +> 在本站发布付费内容,获得的收益将参与收入分成
+> 发布付费内容,请注意以下事项
+> 普通用户分成比例为:60%
+> 黄金会员分成比例为:70%
+> 钻石会员分成比例为:80%
+> 分成比例的计算方式为:付费文章实际收益x分成比例
+> 获得收入超过50元后可申请现金提现
+> 申请提现后,需后台人工处理,一般2-3小时,请耐心等待
+ +实际显示的比例和会员名称应根据后台当前配置渲染;收益记录使用生成时锁定的比例,不因后续配置修改而改变。 + +#### 收入明细 Tab + +按单笔作者收益记录展示付费文章收益,默认按产生时间倒序排列,每页 20 条。每条记录至少包含: + +- 付费文章标题,并链接至文章详情。 +- 实际支付金额及货币类型(现金或积分)。 +- 作者分成金额及对应货币类型。 +- 订单号、购买时间和订单状态。 +- 作者收益状态:待结算、已入钱包、已取消/退款或待追缴。 + +支持以下筛选,并通过 Ajax 无刷新更新列表: + +- 货币类型:全部、现金、积分。 +- 收益状态:全部、待结算、已入钱包、已取消/退款、待追缴。 +- 日期范围。 + +无记录时显示统一空状态;请求失败时显示可重试的错误提示,不破坏已加载的卡片和 Tab 布局。 + +### 作者收益规则 + +- 只有付费文章订单产生作者收益;非付费内容、推广返佣和其他订单类型不进入本页面。 +- 订单支付成功且权益发放完成后创建一条待结算作者收益记录。 +- 购买者不能同时作为该订单的作者收益接收者。 +- 作者收益金额为订单实际支付金额乘以作者当时适用的分成比例。 +- 普通用户默认 60%,一级会员默认 70%,二级会员默认 80%。这些比例在创作中心中独立配置,不跟随其他会员或商品分成设置变化。 +- 生成收益记录时锁定分成比例及适用等级;历史收益不因后台比例或用户等级后续变化而重新计算。 +- 现金订单只生成现金作者收益,积分订单只生成积分作者收益。 +- 两种货币共用普通用户、一级会员、二级会员三档比例,但分别统计、分别建立台账、分别结算。 +- 现金作者收益结算至现金余额,积分作者收益结算至积分余额。 +- 50 元仅作为现金提现提示,不作为作者收益进入钱包的结算门槛;积分收益不受该提示影响。 + +### 结算策略 + +- 默认收益产生后延迟 24 小时进入可处理状态。 +- 后台可选择自动处理或手动处理。 +- 自动处理模式由定时任务处理已达到延迟小时数的待结算收益;默认延迟时间为 24 小时,后台可配置延迟小时数。 +- 手动处理模式下,管理员在现有支付中心“创作分成”运营页面中查询、筛选并逐笔或批量结算收益。 +- 自动和手动处理均必须保证每条收益只能成功结算一次,现金和积分分别执行原子入账。 +- 结算成功后更新收益状态并写入对应余额流水;失败时保留待结算状态和错误信息供后台重试。 + +### 退款与冲正 + +- 退款或取消订单后,对应作者收益标记为已取消/退款,不再计入有效收入。 +- 尚未入钱包的作者收益直接取消,不得继续结算。 +- 已入钱包的作者收益执行对应货币的原子冲正:现金从现金余额扣回,积分从积分余额扣回。 +- 余额不足时不得静默扣成负数;收益记录进入待追缴状态,并保留后台处理入口、原始收益、应冲正金额和处理审计信息。 +- 冲正和结算必须具备幂等性,重复退款通知或重复后台操作不能重复扣款或重复改变状态。 + +## User Stories + +1. 作为登录用户,我可以从用户中心进入创作中心,查看付费文章产生的作者收益。 +2. 作为作者,我可以在顶部同时看到今日现金收益、今日积分收益及其累计状态,而不会将两种货币混为一个数字。 +3. 作为作者,我可以查看创作分成规则,并看到后台配置的最新说明内容。 +4. 作为作者,我可以按订单级别查看每笔付费文章收益,确认文章、订单、支付金额、货币和收益状态。 +5. 作为作者,我可以按货币、收益状态和日期筛选收入明细,并通过分页加载更多记录而不刷新页面。 +6. 作为无收益用户,我可以看到清晰的零值和空状态,而不是空白页面或错误。 +7. 作为作者,我可以看到待结算收益与已入钱包收益的区别,并知道现金提现提示不等同于作者收益结算门槛。 +8. 作为管理员,我可以独立开启或关闭创作分成功能;关闭后前台入口和收益处理流程均停止。 +9. 作为管理员,我可以配置普通用户、一级会员和二级会员的作者分成比例,默认值分别为 60%、70% 和 80%。 +10. 作为管理员,我可以配置自动或手动处理收益,并配置默认 24 小时的延迟处理时间。 +11. 作为管理员,我可以在现有支付中心创作分成运营页面查看作者、文章、货币、状态和时间,并手动逐笔或批量结算。 +12. 作为管理员,我可以查看退款、取消和待追缴记录,并区分已入钱包后的冲正情况。 +13. 作为作者,订单退款后可以看到对应收益被取消或冲正,而不会继续获得已失效收入。 +14. 作为作者,即使余额不足以完成退款冲正,系统也不会产生负余额,而会将记录标记为待追缴。 +15. 作为用户,创作中心与推广返佣收益中心仍然是两个独立入口,页面数据不会相互混淆。 +16. 作为未登录访客,我不能访问创作中心收益数据或其他用户的收入明细。 + +## Implementation Decisions + +### New Modules + +#### Creator income service + +负责作者收益的统一业务入口,隐藏订单筛选、比例快照、金额计算、状态转换、结算和冲正细节。 + +主要接口: + +- `create_from_paid_order(order)`:支付成功且权益完成后创建待结算作者收益。 +- `get_user_summary(user_id, date)`:返回今日与累计的现金/积分有效收益、待结算和已入钱包金额。 +- `get_user_records(user_id, filters, page, per_page)`:返回作者本人分页明细及总数。 +- `settle(record_ids, actor)`:按货币原子结算指定收益记录。 +- `cancel_or_reverse(order_id, reason)`:处理未结算取消或已结算冲正。 +- `get_admin_records(filters, page, per_page)`:为现有支付中心运营页面提供管理员查询数据。 + +#### Creator income view model and renderers + +负责将收益服务数据转换为用户中心卡片、Tab 内容、明细行、分页、筛选项和空/错状态所需的前台结构。创作分成说明内容必须经过允许 HTML 的清洗后输出。 + +#### Creator income REST endpoints + +提供用户中心作者收益摘要、创作分成说明和收入明细的局部加载接口。所有接口要求登录并将查询范围绑定到当前用户;管理员运营接口使用现有支付中心权限模型。 + +#### Settlement scheduler + +负责扫描已达到延迟小时数的待结算收益,在自动模式下触发现金/积分分别结算。任务必须可重复执行且具备锁定、幂等和失败重试行为。 + +#### Refund reversal handler + +负责监听付费订单退款或取消事件,取消未结算收益,或调用现金/积分余额服务完成冲正;余额不足时写入待追缴状态。 + +### Architectural Decisions + +- 复用现有用户中心面板注册和 REST 延迟加载机制,不新建第二套用户中心页面系统。 +- 复用现有付费订单、作者收益、现金余额和积分余额服务;作者收益业务以新的、明确的作者收益语义为准,不读取推广返佣数据。 +- 收益明细以作者收益记录为中心,订单作为来源信息;每笔支付订单最多对应一条作者收益记录,重复支付通知不得重复生成。 +- 现金和积分使用同一收益规则与比例配置,但在金额、状态、余额入账和流水层面完全分开。 +- 收益生成时保存实际使用的货币、原始支付金额、作者分成比例、作者分成金额和适用会员等级,作为不可变的历史计算依据。 +- 前台只允许当前登录用户读取自己的数据;后台运营查询必须通过管理员权限校验。 +- 所有余额变动必须通过现有原子积分/余额服务完成,不直接修改用户余额字段。 +- 关闭创作分成后,前台隐藏入口并停止新收益生成、自动结算和手动结算;已有记录保留后台查询,但不建立旧数据迁移或双路兼容读取。 +- 用户中心继续保留推广返佣“收益中心”入口,与创作中心作者收益严格分开。 + +### Schema Changes + +在“支付&付费 > 创作中心”下集中配置: + +- 创作分成独立开关,默认关闭或沿用产品确定的启用初始状态。 +- 普通用户作者分成比例,默认 60%。 +- 一级会员作者分成比例,默认 70%。 +- 二级会员作者分成比例,默认 80%。 +- 收益处理模式:自动或手动。 +- 自动处理延迟小时数,默认 24 小时。 +- 现金提现提示阈值,默认 50,仅用于前台说明文案,不参与钱包结算门槛。 +- 创作分成 Tab 的 HTML 说明内容,默认填充需求中的说明文案。 + +作者收益记录需要能够保存: + +- 作者、订单、文章和购买者关联。 +- 原始实际支付金额及货币。 +- 生成时锁定的分成比例和会员等级。 +- 作者分成金额及结算货币。 +- 待结算、已入钱包、已取消/退款、待追缴等状态。 +- 生成、到期、结算、取消、冲正时间。 +- 冲正金额、错误信息和后台处理审计信息。 + +新增或调整存储结构时直接采用最终结构并更新数据库 schema 版本;不对旧结构增加兼容字段、双读路径或数据迁移层。现有历史收益只作为后台已有记录处理,不纳入新作者收益统计口径。 + +### API Contracts + +用户端接口应提供: + +- 作者收益摘要:现金/积分今日收益、累计收益、待结算和已入钱包金额。 +- 创作分成说明:经过安全 HTML 处理的配置内容及当前比例展示数据。 +- 收入明细:支持货币、状态、日期范围、页码和每页数量;返回记录列表、总数、当前页和分页信息。 + +收入记录响应至少包含: + +- 文章标题和安全详情链接。 +- 订单号、订单状态、支付时间。 +- 原始支付金额与货币。 +- 作者分成金额与货币。 +- 收益状态及必要的取消、退款或待追缴说明。 + +所有用户接口必须验证登录状态、规范化分页参数、限制日期范围和筛选值,并将作者 ID 从当前认证用户上下文取得,不接受客户端传入的任意作者 ID。 + +管理员接口应复用现有支付中心“创作分成”运营页面的权限和数据入口,支持按作者、文章、货币、收益状态、订单状态和时间查询,并支持逐笔或批量结算。每个 REST 路由必须具备权限回调。 + +### Navigation + +- 用户中心侧栏继续显示“创作中心”和“收益中心”两个独立入口。 +- 创作中心入口由独立创作分成开关控制。 +- 创作中心页面只显示作者收益内容,不再显示原文章管理内容。 +- 文章管理入口本次从用户中心移除,不新增替代入口。 +- 后台配置导航为“支付&付费 > 创作中心”。 +- 后台收益处理继续使用支付中心现有“创作分成”运营页面,不新增独立后台工作台。 + +## Testing Decisions + +### 收益服务测试 + +- 普通用户、一级会员、二级会员分别按 60%、70%、80% 正确计算。 +- 生成收益后修改后台比例,不改变已生成记录的金额。 +- 现金订单只进入现金收益,积分订单只进入积分收益。 +- 订单支付成功且权益完成时生成收益;重复通知不重复生成。 +- 非付费文章、其他订单类型、作者购买自己的文章不会生成作者收益。 +- 今日统计按站点时间计算,累计统计排除取消、退款和待追缴的无效金额。 +- 默认 24 小时前不可自动结算,达到延迟时间后可结算。 +- 自动和手动结算均不能重复入账;现金和积分余额流水分别正确写入。 +- 退款前结算和退款后结算两种路径都能正确取消或冲正。 +- 余额不足时不产生负余额,收益进入待追缴并保留审计信息。 +- 重复退款通知、重复结算请求和并发任务均保持幂等。 + +### 前台交互测试 + +- 创作分成开关关闭时,侧栏入口隐藏、页面不可访问、新收益不生成且不执行结算。 +- 登录用户只能看到自己的摘要和明细;未登录访问被拒绝或按用户中心既有规则处理。 +- 顶部两张卡片正确分栏显示现金与积分,并显示待结算和已入钱包金额。 +- 创作分成说明支持安全 HTML 输出,并正确展示默认内容和后台修改内容。 +- 两个 Tab Ajax 切换无整页刷新,不出现 Tab 侧边滚动栏。 +- 收入明细默认 20 条、时间倒序,翻页无刷新并保持筛选条件。 +- 货币、状态、日期筛选组合正确,空结果显示空状态,请求失败显示可重试提示。 +- 文章链接、订单信息、支付金额、作者分成金额和收益状态显示正确。 +- 退款、取消和待追缴记录在明细中可见且不计入有效收入卡片。 +- 创作中心与推广返佣收益中心数据和页面入口保持独立。 +- 移动端沿用用户中心现有抽屉/Tab 行为,卡片和明细不发生横向溢出。 + +### 后台配置与运营测试 + +- 创作中心配置页面正确加载默认值、保存合法值并拒绝无效比例和负数延迟时间。 +- 比例、开关、处理模式、延迟小时数、提现提示阈值和 HTML 说明可独立保存。 +- 自动模式按延迟小时数处理到期收益,手动模式不会被定时任务自动结算。 +- 手动结算支持逐笔和批量操作,并正确反馈成功、失败和已处理记录。 +- 后台列表支持作者、文章、货币、收益状态、订单状态和时间查询。 +- 管理员可查看退款冲正和待追缴记录,普通用户不能访问运营接口。 +- 配置和路由契约审计通过:`php tools/audit-admin-contracts.php`。 +- 按项目现有条件完成 PHP 静态检查、前端构建和人工/运行时验证;若测试环境不具备 WordPress 或外部 Docker harness,应明确记录未执行项,不以静态通过替代运行验证。 + +## Out of Scope + +- 本次不实现“我的收入”卡片提现按钮,也不新增提现申请、审核或支付流程。 +- 本次不改造或合并推广返佣收益中心。 +- 本次不恢复或迁移用户中心内的文章发布、草稿、审核、编辑、删除和文章管理入口。 +- 本次不实现按文章汇总的“我的商品”列表;收入明细固定按单笔作者收益记录展示。 +- 本次不提供作者收益导出、图表、趋势分析、排行榜或销售漏斗。 +- 本次不提供站内作者与购买者之间的订单争议处理流程。 +- 本次不允许现金与积分互相兑换、折算或合并统计。 +- 本次不设置作者收益进入钱包的 50 元结算门槛;该金额只用于现金提现提示。 +- 本次不允许余额因冲正而变为负数,也不实现自动追缴扣款之外的催收流程。 +- 本次不为旧收益结构增加兼容读取、双路实现或历史数据迁移。 +- 本次不新增独立后台收益工作台,后台运营继续复用现有支付中心“创作分成”页面。 +- 本次不引入新的前端框架、支付网关或货币体系。