# 百特拓客 — 任务服务平台系统设计方案

> **版本**: v1.2  
> **日期**: 2026-07-18  
> **状态**: 开发基线（开发过程中按页面复核调整）  
> **部署目标**: Ubuntu 4 核 4G / 3M / 50G，与“智聚大脑”错峰隔离运行  
> **开发目录**: `C:\Users\刘先生\Desktop\codex\自动化\task`  

---

## 目录

1. [项目概述](#1-项目概述)
2. [现有资产盘点](#2-现有资产盘点)
3. [技术选型](#3-技术选型)
4. [架构设计](#4-架构设计)
5. [页面与路由设计](#5-页面与路由设计)
6. [组件体系设计](#6-组件体系设计)
7. [数据模型设计](#7-数据模型设计)
8. [API 设计](#8-api-设计)
9. [消息与通知刷新方案](#9-消息与通知刷新方案)
10. [用户流程设计](#10-用户流程设计)
11. [权限与安全设计](#11-权限与安全设计)
12. [分阶段实施计划](#12-分阶段实施计划)
13. [部署方案](#13-部署方案)
14. [风险评估](#14-风险评估)

---

## 1. 项目概述

### 1.1 项目定位

一个面向设计师、开发者、文案作者、数据标注员等服务提供者的**任务服务平台**。发布者向“百特拓客”购买任务服务并付款；百特拓客统一组织接单者完成任务，在验收后以经营资金向接单者支付报酬。平台不为用户开立可充值、可转让的资金钱包。

### 1.2 核心功能

```
任务发布 → 服务订单付款 → 平台审核 → 公开展示 → 接单人领取 → 成果提交 → 发布者验收
                                                                  ↓
                                                     待结算报酬 → 商家转账
                              站内消息与状态通知（全程伴随）
```

### 1.3 用户角色

| 角色 | 职责 | 核心页面 |
|------|------|---------|
| **普通用户 (User)** | 浏览、接单、提交成果、聊天 | 任务大厅、消息、个人中心 |
| **发布者 (Publisher)** | 向百特拓客购买任务服务、发布需求、验收成果 | + 发布任务页 |
| **管理员 (Admin)** | 审核任务/用户、管理平台、处理纠纷 | 管理后台 |

---

## 2. 现有资产盘点

### 2.1 现有页面清单

| 文件 | 大小 | 角色 | 核心模块 |
|------|------|------|---------|
| `task-apple-ui.html` | 45.7 KB | 用户端 | 任务大厅 + 统计卡片 + Tab切换 + 分类筛选 + 详情抽屉 + 我的任务 |
| `login.html` | 16.7 KB | 通用 | 支付宝单一登录 + 首次授权提示 + 最近账号选择 |
| `publish-task.html` | 22.2 KB | 发布者 | 标题/分类/标签/描述/附件上传/佣金滑块/截止日期/确认弹窗 |
| `messages.html` | 22.0 KB | 用户端 | 聊天Tab + 系统通知Tab + 平台公告Tab + 聊天抽屉 |
| `profile.html` | 16.0 KB | 用户端 | 个人信息头 + 2×2统计 + 功能菜单列表 + 退出登录 |
| `admin.html` | 44.2 KB | 管理端 | 侧边栏 + 仪表盘 + 任务管理 + 用户管理 + 审核管理 + 编辑弹窗 |

**总计**: ~171 KB，6 个页面，纯静态 HTML，零外部依赖。

### 2.2 设计系统（可提炼的 Design System）

所有 6 个页面共享一套高度一致的 CSS 变量体系。以下是从现有页面中提炼出的 Design Tokens：

```css
:root {
  /* 颜色 - 背景 */
  --bg: #F2F2F7;
  --card: rgba(255, 255, 255, 0.72);

  /* 颜色 - 文字 */
  --text: #1C1C1E;           /* 主文字 */
  --text-secondary: #8E8E93; /* 辅助文字 */
  --text-tertiary: #C7C7CC;  /* 禁用/占位文字 */

  /* 颜色 - 品牌 */
  --accent: #007AFF;
  --accent-gradient: linear-gradient(135deg, #007AFF, #5856D6);

  /* 颜色 - 语义 */
  --red: #FF3B30;
  --orange: #FF9500;
  --green: #34C759;
  --blue: #007AFF;
  --purple: #AF52DE;

  /* 颜色 - 其他 */
  --divider: rgba(60, 60, 67, 0.08);

  /* 圆角阶梯 */
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 22px;
  --radius-xl: 28px;

  /* 阴影层级 */
  --shadow-sm: 0 1px 3px rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.06);
  --shadow-md: 0 4px 14px rgba(0,0,0,0.06), 0 2px 6px rgba(0,0,0,0.04);
  --shadow-lg: 0 20px 50px rgba(0,0,0,0.12);

  /* 字体 */
  --font: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', sans-serif;

  /* 动画 */
  --transition: 0.2s cubic-bezier(0.25, 0.1, 0.25, 1);
}
```

### 2.3 现有问题（待重构解决）

| 问题 | 严重程度 | 说明 |
|------|:--:|------|
| CSS/JS 代码完全重复 | 🔴 高 | 6 个页面各自独立复制全套样式，改一个颜色要改 6 处 |
| 页面联动不完整 | 🟡 中 | 已有 `login→任务大厅`、`发布任务→任务大厅`、`profile→login`、`admin→profile`；消息、发布入口和个人中心入口仍需逐页接通 |
| 数据硬编码 | 🔴 高 | 所有任务列表、消息内容、用户数据均为静态 HTML |
| 命名不一致 | 🟡 中 | 手机容器有 `.app-container` 和 `.phone-frame` 两个名字 |
| 背景装饰不一致 | 🟡 中 | messages 只有 1 个光晕而其他页面都是双光晕 |
| 无后端与数据库 | 🔴 高 | 无数据持久化，刷新全部丢失 |
| 无用户认证 | 🔴 高 | 登录成功只是 toast 提示 + 前端跳转 |
| profile 页面无入口 | 🟡 中 | 任务大厅的用户按钮跳到了页内 Tab 而不是 profile.html |

### 2.4 渐进式开发基线

- 现有 6 个 HTML 页面是视觉与交互基线，不整体推翻重做。
- 按“登录 → 任务大厅 → 发布任务 → 消息 → 个人中心 → 管理后台”的顺序逐页开发。
- 每完成一个页面，先验证该页面及其与已完成页面的导航、登录态和数据联动，再进入下一页。
- 未进入当前开发范围的页面继续保留原文件，不提前重构。
- 共用组件只在第二个页面产生真实复用时提取，避免一次性搭建过大的组件库。
- 页面验收至少覆盖桌面端、移动端、空状态、加载状态、失败状态和登录失效状态。
- 开发代码、依赖缓存、测试产物和临时文件均保存在本项目 `task/` 目录内，不写入其他项目目录。

### 2.5 支付宝登录已确认基线（2026-07-17）

- 首次访问登录页只保留支付宝授权登录，不再提供邮箱/手机号密码、注册、找回密码、微信或 Apple 登录。
- 首次进入自动提示“需要支付宝授权登录，否则无法提现。”；支付宝授权成功后的二次登录不重复提示。
- 再次访问优先显示最近账号，可一键登录或使用其他支付宝账号重新授权。
- 普通登录状态按 30 天滑动续期、最长 90 天强制重新授权；提现始终执行独立验证。
- 详细交互、安全和异常规则以 `docs/superpowers/specs/2026-07-17-alipay-login-design.md` 为准；本节覆盖本文后续残留的旧登录描述。

### 2.6 实名通道已确认基线（2026-07-17）

- 首次提现前执行姓名与身份证号二要素核验，首个供应商采用腾讯云应用市场商品 `17684`。
- 前端只调用百特拓客 `/api/identity-verifications`，供应商请求、签名和密钥全部留在服务端。
- 后台通过统一 `IdentityVerificationProvider` 适配器隔离供应商，后期更换通道不修改前端和业务接口。
- 完整身份链路为“支付宝 `open_id` + 二要素实名 + 支付宝转账姓名校验”，转账使用 `identity_type=ALIPAY_OPEN_ID`，三项状态分别记录。
- 详细接口、安全和切换规则以 `docs/superpowers/specs/2026-07-17-identity-verification-provider-design.md` 为准。

### 2.7 正式上线前强制审查门禁（2026-07-18）

#### 触发条件

满足任一条件时必须自动触发，不依赖用户再次提醒：

- 全部页面、后端接口、数据库、文件存储、支付宝登录、实名和结算链路开发完成；
- 进入本设计“阶段七：部署与整体验收”；
- 用户提出“开发完成”“准备上线”“正式部署”或同等含义的要求。

审查未完成前，不得声称系统“具备上线标准”；存在阻断项时不得建议正式部署。

#### 强制检查范围

1. **功能完整性**：逐项对照需求、设计基线和浏览器批注，检查是否漏做、错做或发生回退。
2. **页面与交互**：覆盖桌面端、移动端、登录失效、空数据、加载、失败、重复点击、刷新、返回、超时和中断恢复。
3. **跨页面与状态机**：验证登录、实名、任务发布、上下架、接单、提交、审核、邀请奖励、待结算、支付、退款和消息通知的完整闭环及非法状态跳转。
4. **认证与授权**：检查 Session、Cookie、登录回调、管理员权限、资源归属和接口级鉴权，重点排查越权访问与 IDOR。
5. **输入与接口安全**：检查 XSS、CSRF、SQL 注入、命令注入、路径遍历、SSRF、开放重定向、参数篡改、批量赋值、重放和接口限流。
6. **文件安全**：检查扩展名、MIME 与文件签名、大小和数量限制、对象键生成、私有桶、签名 URL、上传凭证权限、恶意文件和过期文件清理。
7. **资金与邀请安全**：金额只用整数分并由服务端计算；检查支付与转账验签、主动查单、幂等、重复回调、重复付款、并发竞态、佣金篡改、自邀、重复邀请和新用户奖励套利。
8. **数据与隐私**：检查密钥、数据库口令、实名信息、身份证、支付宝标识、日志脱敏、最小权限、数据留存和删除机制，不读取或输出生产密钥明文。
9. **依赖与供应链**：锁定版本，执行依赖漏洞、许可证、静态代码和容器镜像检查；清理开发依赖、调试入口、测试账号和示例密钥。
10. **部署与隔离**：检查 HTTPS、安全响应头、反向代理、端口、防火墙、容器权限、环境变量、数据库与对象存储权限，以及与智聚大脑的目录、网络、资源和运行时间隔离。
11. **性能与稳定性**：在 4 核 4G / 3M 环境按预期容量执行关键接口、页面和文件直传验证，检查内存、CPU、磁盘、连接池、超时、重试、限流和任务积压。
12. **备份与恢复**：验证数据库备份可恢复、对象存储数据可追溯、迁移可向前兼容、上一版镜像可回滚，并记录恢复时间和操作步骤。
13. **监控与审计**：验证健康检查、错误日志、管理员审计日志、支付异常、验签失败、重复回调、磁盘和内存告警能够实际触发并定位问题。
14. **合规与外部条件**：核对营业主体、支付宝产品准入、实名服务材料、用户协议、隐私政策、任务与结算规则、ICP备案等正式收款前置条件。

安全测试只允许针对本项目自有的本地、测试或已获授权环境执行。未经明确授权，不对第三方或线上生产目标进行主动扫描、攻击性测试或数据修改。

#### 最低验证手段

- 全量单元、集成、端到端和浏览器回归测试；
- TypeScript、Lint、构建和数据库迁移验证；
- 依赖漏洞、静态代码、容器镜像和密钥泄露扫描；
- 在测试环境执行授权、输入校验、文件上传、支付回调和并发幂等专项测试；
- 对自有测试环境执行受控动态安全扫描，并人工复核高风险结果；
- 真实小额支付、退款、转账失败、重复回调、对账和恢复演练；
- 备份恢复、版本回滚和智聚大脑同时运行场景验证。

#### 放行标准

- `严重（Critical）` 或 `高（High）` 风险必须全部修复并重新验证，否则结论只能是“不建议上线”；
- `中（Medium）` 风险应修复；确实无法在上线前修复时，必须记录影响、缓解措施、负责人和完成期限，并由用户明确接受；
- `低（Low）` 风险进入上线后整改清单，不得隐瞒；
- 全量测试、生产构建、迁移、备份恢复、回滚和关键业务闭环必须有本次执行证据，不能引用过期结果；
- 所有生产密钥、域名、回调地址、数据库、对象存储和支付配置必须使用正式环境值并完成验签验证；
- 只有在无阻断项且上述证据齐全时，才能给出“建议上线”结论。

#### 强制交付物

开发完成时必须生成一份《百特拓客上线前检查报告》，至少包含：

- 检查范围、环境、版本和时间；
- 功能、交互、结构、安全、性能、数据、部署和合规检查结果；
- 每个问题的证据、风险等级、影响、复现步骤和修复状态；
- 未解决风险及缓解措施；
- `建议上线 / 有条件上线 / 不建议上线` 的明确结论；
- 部署步骤、监控观察项和回滚步骤。

安全审查只能降低风险，不能承诺系统绝对不会被破解或篡改。最终结论必须说明已验证范围、未覆盖范围和残余风险。

### 2.8 任务接口层与用户联动已实现基线（2026-07-19）

- 管理后台和用户任务大厅统一通过 `task-api.js` 访问任务数据；当前使用 `localStorage + IndexedDB` 本地适配器，后续替换真实 HTTP API 时保持页面调用契约不变。
- 任务新增 `totalSlots` 和 `completedCount`；名额范围为 `1～1000000`，首次上架后任务名称、分类、任务佣金、任务名额和邀请奖励金额锁定。
- 用户端只展示已上架、未过期、可接且有剩余名额的任务；后台上架、下架和跨标签页变更会同步刷新用户端。
- 任务详情展示流程步骤、参考图片、提交说明、邀请固定金额文案、名额和截止时间；后台任务字段使用 DOM API 安全渲染。
- 成果提交支持“仅文字、仅图片、文字或图片、文字和图片”四种配置，图片限制为 JPG/PNG/WebP、单张不超过 5MB；当前只做前端格式校验，不保存正式提交记录。
- 用户端不再保留硬编码的可接任务卡片；后台窄屏改为顶部横向导航，页面和任务编辑弹窗在 `650×898` 下无整页横向溢出和按钮重叠。
- 2026-07-19 验收结果：后台上架后用户端可接任务数从 3 变为 4，下架后自动恢复为 3；邀请说明、流程、组合提交校验和图片预览均通过浏览器检查；全量自动化测试 `164/164` 通过。
- 本基线不代表已具备正式登录、接单占额、成果持久化、审核、邀请结算、支付、数据库、云存储或上线能力；正式部署前仍必须执行 2.7 的强制审查门禁。

### 2.9 任务多分类标签已确认基线（2026-07-23）

- 系统设置不再提供“任务分类管理”，分类不依赖全局预设、启停或排序配置。
- 管理员新建任务时直接输入分类，按 Enter 生成标签并可继续添加；最多 5 个，每个最多 20 个字符，忽略首尾空格，禁止大小写不敏感的重复标签，并支持逐个删除。
- 编辑草稿或未首次上架任务时可调整分类；任务首次上架后分类与其他已确认发布锁定字段一起锁定。
- 旧任务仍保留 `categoryId` 兼容读取，并在加载时迁移为中文 `categories` 数组；新逻辑以 `categories` 为准。
- 用户端任务卡片沿用原标签位置和视觉样式，只显示前两个标签；任务详情显示全部标签。
- 用户端顶部分类筛选不再硬编码，由当前任务标签动态去重生成，选择任一标签均可筛出包含该标签的任务。
- 2026-07-23 自动化验证：全量测试 `158/158` 通过；仍需按本轮交付步骤完成人工浏览器验收。

### 2.10 外部服务接口配置已确认基线（2026-07-23）

- 系统设置提供五个独立适配器：数据库、外部对象存储、API 自动审核、支付宝支付、公告发送；每个适配器可单独启停、选择供应商、修改接口地址和服务标识，后续更换供应商不改业务页面。
- 当前原型只保存供应商、接口地址、应用或 Bucket 标识和服务器密钥引用；数据库密码、Secret Key、API Key、支付宝私钥等敏感值不得进入浏览器、`localStorage`、页面 HTML 或日志。
- 自动审核支持手动审核、硅基流动和自建审核 API 选项；支付宝支持商家转账、沙箱和人工发放降级选项；公告支持系统内通知、企业微信机器人、企业微信应用消息和自建 Webhook。外部服务“测试连接”现在调用管理员真实测试路由；未部署后端适配器或未配置凭据时必须显示失败，不得显示模拟通过。
- 正式后端接入时，配置 API 必须增加管理员鉴权、审计日志、字段级脱敏、环境隔离和服务端密钥读取；真实支付上线前仍受 2.7 正式上线前强制审查门禁约束。
- 2026-07-23 自动化验证：全量测试 `166/166` 通过，`admin.html` 与 `system-settings.js` 语法检查通过。

### 2.11 待审核任务详情弹窗已确认基线（2026-07-23）

- 首页和审核管理页的待审核任务名称均提供“查看详情”入口；点击任务名称或“审核”按钮打开同一审核弹窗。
- 弹窗显示任务要求、提交人、提交时间、佣金、截止日期、用户文字成果和已提交文件；桌面端双栏展示，移动端自动单栏排列。
- “通过审核”当前为模拟操作；“驳回并说明”必须填写修改原因后才允许完成，说明框用于后续通知用户如何改正。
- 当前使用页面模拟数据，后续接入真实提交记录时保持弹窗字段和动作契约不变。
- 2026-07-23 自动化验证：全量测试 `165/165` 通过。

### 2.12 审核队列与模拟数据基线（2026-07-23）

- 审核列表操作顺序固定为“审核、驳回、详情”；“详情”按钮位于驳回按钮右侧，任务名称不再追加伪链接文案。
- 同一任务允许存在多条待审核提交；审核通过或驳回后，若该任务仍有待审核提交，弹窗保持打开并自动进入下一条。
- 当前原型提供“DeepSeek 注册体验任务”10 条模拟待审核提交，用于验证队列切换；模拟状态只保存在当前页面，不代表真实提交数据。
- 提交图片在审核弹窗内直接显示缩略图，点击放大，再次点击恢复；非图片附件继续以文件标签显示。
- 系统设置的外部服务卡片在宽屏下使用两列网格，窄屏回退单列，保持现有 Apple UI 视觉变量和响应式规则。
- 2026-07-23 自动化验证：全量测试 `166/166` 通过。

### 2.13 公告发布与用户提醒基线（2026-07-24）

- 后台新增“公告管理”页面，只发布平台公告，可配置标题、正文、是否弹窗和启用状态；公告历史支持停用与重新启用。系统通知不提供人工类型选择，由审核、支付、任务状态等业务事件自动触发。
- 公告通过 `betterTask.announcements.v1` 共享数据键同步到用户端；任务大厅监听跨页面更新，启用且允许弹窗的公告按公告 ID 对同一浏览器只提醒一次。
- 用户端已读状态写入 `betterTask.announcement.read.v1`；任务大厅顶部消息入口跳转消息页，消息页“平台”Tab读取同一份启用公告，避免后台与前端内容分叉。
- 当前公告发送仍为本地模拟闭环；系统通知自动触发接口和企业微信机器人、企业微信应用消息、自建 Webhook 仅保留在适配器层，真实发送必须由服务端鉴权、审计和密钥托管后接入。
- 2026-07-24 验证结果：公告模块单元测试与现有测试共 `168/168` 通过；本地浏览器已验证发布、首次弹窗、消息页同步和停用流程。

### 2.14 用户聊天功能开关基线（2026-07-24）

- 用户端聊天功能默认关闭；后台系统设置提供“启用用户聊天”开关，关闭时消息页隐藏聊天 Tab 和聊天记录，仅保留系统通知、平台公告。
- 开关使用 `betterTask.feature.chatEnabled.v1` 同步，跨页面变更即时生效；正式部署时改由服务端功能配置和权限策略控制。
- 系统通知不因聊天开关关闭而受影响；聊天消息数据在功能关闭期间不删除，重新开启后可继续展示。

### 2.15 用户任务大厅展示基线（2026-07-24）

- 用户端“任务大厅”只展示后台当前已上架、未过期且仍有余量的可接任务。
- 进行中和已完成任务不再混入任务大厅；用户自己的进行中、已完成任务继续放在“我的任务”Tab。
- 任务大厅上方只保留“可接任务”统计；任务列表和分类筛选、搜索只作用于可接任务，进行中和已完成内容进入“我的任务”。

### 2.16 消息 Tab 滑动交互基线（2026-07-24）

- 消息页支持点击和左右滑动切换聊天、系统、平台内容；聊天关闭时仅在系统与平台之间切换。
- 左右滑动采用横向距离与纵向距离阈值判断，普通上下滚动不会误触发 Tab 切换；切换后内容平滑滚动到顶部并播放轻量进入动画。
- 聊天关闭时，系统 Tab 滑块位于第一栏（0%），平台 Tab 滑块位于第二栏（100%）；点击和滑动后的内容状态与滑块位置保持同步。

### 2.17 任务大厅分类入口基线（2026-07-24）

- 用户端顶部“任务分类”筛选栏隐藏，任务分类数据、后台分类输入和筛选逻辑保留，不删除任务类型能力。
- 可接任务卡片继续显示任务类型标签；点击或键盘确认类型标签时，按该类型筛选当前可接任务，点击标签不会误打开任务详情。
- 分类筛选仍只作用于任务大厅中的可接任务，保持现有任务卡片布局和 Apple UI 视觉风格。

### 2.18 消息卡片详情基线（2026-07-24）

- 系统通知和平台公告卡片点击后打开详情底部弹窗，显示完整标题、正文和时间；动态发布的公告使用同一交互。
- 聊天卡片继续打开聊天详情；消息详情弹窗支持点击遮罩、关闭按钮和 Escape 关闭，并在打开时标记对应通知为已读。

### 2.19 任务状态 Tab 基线（2026-07-24）

- 用户端任务 Tab 显示“可接任务（数量）”“进行中（数量）”“已完成（数量）”三个状态入口，保留原有滑块过渡效果。
- 可接任务继续使用后台已上架、未过期且有余量的数据；进行中和已完成分别展示“我的任务”对应分区，不改变任务大厅只显示可接任务的规则。

### 2.20 任务大厅重复标题基线（2026-07-24）

- 任务列表内不再重复显示“可接任务”分区标题和数量；状态名称与数量统一由顶部三状态 Tab 承载。

### 2.21 任务状态数字颜色基线（2026-07-24）

- 顶部状态 Tab 的数量颜色按状态区分：可接任务使用绿色，进行中使用橙色，已完成使用灰色。

### 2.22 任务大厅导航操作基线（2026-07-24）

- 任务大厅右上角仅保留通知入口，个人中心按钮从任务大厅头部移除；个人中心页面和其他既有入口不受影响。

### 2.23 进行中列表标题基线（2026-07-25）

- 进行中任务列表内不再重复显示“进行中”标题和数量胶囊，状态名称与数量统一由顶部 Tab 承载。

### 2.24 任务大厅搜索入口基线（2026-07-25）

- 任务大厅移除页面固定搜索栏，顶部导航仅保留放大镜搜索按钮和消息通知按钮。
- 搜索按钮位于消息通知按钮左侧；点击后展开搜索弹出框并自动聚焦输入框。
- 搜索仍作用于可接任务列表，输入即时筛选；关闭搜索或按 Escape 清空关键词并恢复列表。

### 2.25 任务大厅个人中心入口基线（2026-07-25）

- 任务大厅顶部不再显示“任务大厅”大标题，左侧改为圆形用户头像入口。
- 点击头像进入 `profile.html` 个人中心，搜索和消息通知按钮继续位于右侧。

### 2.26 个人中心资料简介基线（2026-07-25）

- 个人中心资料卡移除个人简介文案，仅保留头像、姓名、认证状态和统计信息。

### 2.27 用户端轮播与后台配置基线（2026-07-27）

- 用户端原顶部三项统计卡片替换为运营轮播；下方“可接任务、进行中、已完成”状态 Tab 的位置、数量颜色和滑块效果保持不变。
- 轮播在可接任务、进行中、已完成三个页面持续显示，支持自动轮播、圆点切换、左右滑动和站内/HTTP/HTTPS 跳转。
- 后台“公告管理”增加用户端轮播配置，支持新增、编辑、排序、主题颜色、状态页跳转、页面链接、启用停用、删除和恢复默认。
- 后台与用户端通过 `betterTask.promoSlides.v1` 共享轮播配置，用户端监听跨标签页更新；正式上线时由服务端配置接口替换本地存储适配器。
- “公告历史”不再常驻公告管理页面，发布公告下方保留查看入口，点击后在弹窗中查看并启用或停用历史公告。
- 已完成任务列表不再重复显示“已完成”标题和数量，状态名称与数量由顶部 Tab 统一承载。
- 2026-07-27 验收：全部自动化测试 `203/203` 通过；后台轮播列表、编辑回填、公告历史弹窗及用户端轮播读取均通过浏览器验证。

### 2.28 公告历史删除基线（2026-07-27）

- 公告历史弹窗中，每条公告的“停用/启用”旁增加“删除”按钮；删除前必须二次确认，确认后永久移除该公告并同步清理其本地已读记录。
- 删除完成后立即刷新公告历史和后台公告角标；取消确认时不修改任何数据。
- 2026-07-27 验收：全部自动化测试 `206/206` 通过；浏览器确认删除按钮顺序、弹窗排版和取消删除后的数据保留均正常，控制台无报错。

### 2.29 公告发布与轮播配置排版基线（2026-07-27）

- 公告发布表单置于“新增用户端轮播”表单下方，与其位于同一左列并保持相同宽度；右侧“用户端轮播列表”位置与宽度不变。

### 2.30 用户端轮播图片基线（2026-07-27）

- 后台轮播配置在跳转链接上方提供图片插入入口，支持 JPG、PNG、WebP，单张最大 5MB；图片由本地 IndexedDB 图片存储管理。
- 轮播配置有图片时，用户端仅渲染该图片，不显示小标题、标题、说明或按钮文字；点击图片仍按原跳转链接或任务状态切换规则执行。
- 2026-07-27 验收：全部自动化测试 `209/209` 通过；后台图片入口、纯图片用户端渲染和跳转保留逻辑已覆盖自动化测试。

### 2.31 外部接口健康面板折叠基线（2026-07-27）

- 外部接口健康面板仅在全部服务均已启用、配置校验通过且最近检测状态正常时自动收起，并显示正常数量汇总。
- 存在未启用、配置异常、待检测或检测失败时强制展开；全部正常时允许管理员手动展开查看明细，重新执行全部检测后恢复自动收起。

### 2.32 外部接口健康面板默认筛选基线（2026-08-01）

- 面板默认只显示未启用、配置异常、待检测或检测失败的接口；已正常接口不在默认列表中重复显示。
- 存在被隐藏的正常接口时，标题区域提供“展开详情”，点击后显示全部接口；再次点击恢复默认筛选。
- 全部接口正常时自动收起列表，但仍可通过“展开详情”查看完整状态；重新执行全部检测后恢复默认筛选视图。
- 2026-07-27 验收：全部自动化测试 `210/210` 通过；折叠条件、异常强制展开和手动展开逻辑已覆盖后台页面测试。

### 2.32 系统安全告警与佣金发放锁基线（2026-07-27）

- 后台打开时自动检查运行告警；存在高优先级或警告状态时自动打开系统告警弹窗，每次页面打开仅自动弹出一次，顶部铃铛红点与当前告警同步。
- 运行告警覆盖系统攻击、疑似入侵、收款账户劫持、外部存储/数据库不可用或容量达到 90%、审核 API 不可用或余额不足、支付通道不可用和支付账户余额不足。
- 系统攻击、疑似入侵、收款账户劫持、数据库不可用或达到严重容量阈值、支付通道不可用、支付余额不足时统一锁定佣金发放；财务页横幅、表格按钮、详情按钮和实际发放函数均执行同一锁检查。
- “多个账号共用收款账号”风控动作固定为“停止发放并人工复核”，不能只告警后继续支付。
- 本地原型通过 `betterTask.runtimeHealth.v1` 保存模拟监控状态，并支持正式服务端使用 `window.__BETTER_TASK_RUNTIME_HEALTH__` 注入同结构状态；本地模拟数据不得解释为真实安全检测结果。
- 活跃运行告警同步进入通知中心；持续存在的运行告警不能通过“全部标为已读”隐藏，只能在异常解除后消失。
- 2026-07-27 验收：全部自动化测试 `216/216` 通过；规则阈值、自动弹窗、通知同步、发放锁和实际函数拦截均有测试覆盖。本轮未执行浏览器视觉验收。

### 2.33 后台与用户端共享模拟任务基线（2026-07-27）

- 共享默认数据新增 10 条模拟任务，编号为 `T20260727-010` 至 `T20260727-019`，覆盖体验测试、文案、图片处理、数据整理、字幕、小程序测试、语音转写、前端开发、品牌设计和客服知识库等场景。
- 状态分布固定为可接任务 6 条、进行中 2 条、待审核 1 条、已完成 1 条；用户端任务大厅仍只展示已发布、未过期、有剩余名额的可接任务，不展示平台全量任务。
- 后台和用户端通过版本化补种逻辑向已有浏览器数据追加缺失任务；相同任务 ID 不覆盖、重复刷新不重复插入，并保留用户已有任务和修改。
- `admin-task-persistence.js`、`task-defaults.js` 和 `task-api.js` 使用 `20260727-demo-seed-1` 资源版本参数，避免旧浏览器缓存造成补种接口或模拟数据未更新。
- 2026-07-27 验收：全部自动化测试 `219/219` 通过；后台实际浏览器数据从 11 条补齐为 21 条，10 条新增任务及状态均已核对。用户端 `file://` 页面受浏览器自动化安全策略限制，动态展示由任务筛选、补种和页面渲染测试覆盖。

### 2.34 用户端进行中任务审核状态基线（2026-07-27）

- 用户端保持“可接任务、进行中、已完成”三个状态 Tab，不新增“待审核”Tab；进行中数量包含待提交、草稿、审核中和驳回修改任务。
- 进行中卡片右侧按任务状态显示“提交成果”“继续编辑”“审核中”或“修改后提交”；审核中使用低干扰蓝灰状态，驳回修改使用红色警示状态。
- 点击审核中卡片查看已提交成果详情，不能重复提交；审核通过后进入已完成，审核驳回后保留在进行中并转为修改后提交。
- 进行中任务由统一状态映射和渲染函数生成，Tab 数量取实际任务数组长度，不再由静态卡片和固定数量分别维护。
- 进行中列表按操作状态稳定分组：提交成果优先，其次为继续编辑和修改后提交，审核中统一置后；同一状态内保持原接单顺序。
- 2026-07-27 验收：全部自动化测试 `222/222` 通过；本地浏览器确认四种状态无重叠、页面无运行错误，审核中卡片点击提示正常。

### 2.35 用户端接单、提交、结算与赚更多基线（2026-07-27）

- 后台任务是发布与提交要求的数据源；用户接单记录单独保存在版本化用户任务存储中，单个用户接单不得把多人任务整体改成进行中。
- 点击“立即接单”后生成唯一用户任务记录，并从该用户的可接任务中移除；同一用户不能重复领取同一任务。
- 待提交、草稿和驳回任务可编辑成果；“保存草稿”保留文字和成果图片，“提交成果”校验后台配置的提交模式后进入审核中，审核中在存储层锁定，不能重复编辑或提交。
- 成果图片写入现有 IndexedDB 图片存储，用户任务记录只保存图片 ID 和名称；保存失败时清理本次新增图片，避免孤立文件。
- 审核通过并结算的任务进入已完成列表，显示实际结算佣金和结算时间；已完成数量与累计收入按结算记录动态汇总。
- 邀请奖励按任务完成时配置做快照。仅当后台已启用邀请且奖励大于 0 时，已结算右侧显示“赚更多”，点击后可复制邀请文案和带任务标识的邀请链接。
- 2026-07-28 验收：全部自动化测试 `227/227` 通过；本地浏览器已验证立即接单、草稿保存与回填、图文成果提交、审核中只读查看、结算汇总、邀请奖励显示条件及“赚更多”邀请信息复制，控制台无报错。
- 2026-08-01 任务流程交互：后台步骤编辑器支持复制“详细说明”编辑框原文；用户端流程步骤同步复制说明正文，步骤右侧“复制”使用系统灰色降低视觉干扰；流程参考图片加载后支持“保存本地”，下载使用已读取的 Blob，不暴露对象存储地址。自动化测试 `264/264` 通过。
- 2026-08-01 可接任务详情：状态行仅在后台启用且配置正数邀请奖励时显示“完成任务可赚更多”，不带感叹号；提醒文字与佣金统一使用橙色，并与下方佣金共用详情内容区右边缘。佣金与任务名称同排展示，二者字号统一为 `20px`，不再单独占行，也不再展示邀请金额说明卡。流程标题改为居中的“步骤预览”，步骤序号使用独立的浅色数字圆标，不再把圈号和顿号拼入标题；说明文字和参考图片与标题文字对齐。最后一步与“提交要求”之间增加分割线，“提交要求”与步骤标题同为 `15px` 并以暖色区分，下方说明使用灰色弱化层级。
- 2026-08-01 分享详情：移除返回按钮下方重复的“赚更多”状态行；奖励主文案精简为“好友完成，你再赚 X 元”，新用户奖励说明改为“如果是新用户首单，你额外再得X元邀请奖励。”，金额继续读取后台任务配置；未配置新用户奖励时显示通用邀请说明。
- 2026-08-01 个人中心任务统计：原“已接任务”错误读取用户档案内的演示完成数，现改为“进行中任务”，直接统计与任务大厅一致的用户任务活跃状态（待提交、草稿、驳回重提、审核中）；已完成和已超时放弃不计入，点击仍进入大厅“进行中”。
- 2026-08-01 个人中心佣金流水：移除静态“我的收藏”和演示收藏任务，改为读取平台佣金账本的“佣金流水”。入口动态显示当前用户流水笔数；详情展示最近 50 笔佣金的任务名、记账时间、入账状态和金额，后台审核产生的新账本记录会通过共享存储同步更新。
- 2026-08-01 个人中心公开内容配置：后台“设置”分组新增“个人中心内容”，可编辑帮助简介、1–8 条常见问题、工单按钮文字，以及平台名称、简介、版本、服务协议和隐私政策链接。配置使用独立版本化存储 `betterTask.profile.content.v1`；个人中心动态读取并跨标签同步，协议链接仅允许 HTTP/HTTPS（含安全相对地址），配置损坏时只读回退默认内容且不覆盖原数据；帮助与关于弹层支持顶部和底部关闭操作。

---

## 3. 技术选型

### 3.1 选型对比

| 层面 | 候选方案 | 最终选择 | 弃用理由 |
|------|---------|---------|---------|
| **框架** | Next.js / Vue / Nuxt / 纯 HTML | **Next.js 当前稳定版（锁定精确版本）** | 沿用 React/TypeScript 方案；部署前固定版本，避免自动升级 |
| **样式** | Tailwind / CSS Modules / styled-components / Panda CSS | **Tailwind CSS + CSS Variables** | 保留 Apple 色彩变量，原子化开发效率高，零运行时 |
| **认证** | Auth.js / 自建 Session / Supabase Auth | **服务端 Session + HttpOnly Cookie** | 不依赖 Supabase；权限统一在服务端校验 |
| **数据库** | 本机 PostgreSQL / 托管 PostgreSQL / Supabase | **外部托管 PostgreSQL** | 释放 4G 服务器内存，数据库备份与应用故障隔离 |
| **ORM** | Prisma / Drizzle / SQL | **Prisma** | 统一 Schema、迁移和事务，适合任务与资金状态机 |
| **消息刷新** | WebSocket / SSE / 短轮询 | **按页面短轮询** | A 级容量无需 Redis 和常驻实时服务，结构更简单 |
| **文件存储** | 七牛云 / 又拍云 / 腾讯云 COS | **七牛云 Kodo** | 早期免费额度和外网流量成本更合适；客户端直传绕过 3M 带宽 |
| **支付结算** | 平台钱包 / 支付宝商家转账 / 人工转账 | **支付宝“商家转账”** | 使用支付宝登录取得的 `open_id` 作为收款标识；不自建储值钱包 |
| **部署** | Docker Compose / systemd 直装 / Vercel | **Ubuntu + Docker Compose** | 与智聚大脑隔离依赖、目录、端口和环境变量，运行开销可控 |

### 3.2 最终技术栈

```
前端  : Next.js App Router + TypeScript + Tailwind CSS（锁定精确版本）
样式  : CSS Variables (Apple Design Tokens) + Tailwind 原子类
认证  : 服务端 Session + HttpOnly/SameSite Cookie
数据库: 外部托管 PostgreSQL
ORM   : Prisma（Schema + Migration + Transaction）
消息  : 活跃聊天 3-5 秒轮询，通知 15-30 秒轮询
文件  : 七牛云 Kodo，客户端使用短期上传凭证直传
支付  : 发布者收款渠道独立申请 + 支付宝商家转账（佣金报酬场景）
部署  : Ubuntu + Docker Compose + 现有反向代理
```

试运营阶段认证采用支付宝单一登录和服务端 Session。当前静态页面只实现前端状态原型；取得支付宝开放平台应用、准入资质和密钥后再接入真实授权、回调和验签，不用模拟成功代替生产认证。首次支付宝用户在授权成功后进入独立的手机号绑定步骤。

---

## 4. 架构设计

### 4.1 系统架构图

```
用户浏览器
   │ HTTPS
   ▼
现有反向代理（仅新增百特拓客域名配置）
   │
   ▼
百特拓客 Docker Compose 项目
   ├── Next.js Web / API（单实例）
   ├── Prisma（事务、迁移、连接池）
   └── 一次性维护任务（非长期驻留 Worker）
          │
          ├──────────→ 外部托管 PostgreSQL
          │             业务数据、订单、结算、幂等记录
          │
          ├──────────→ 七牛云 Kodo
          │             附件、成果、头像；浏览器短期凭证直传
          │
          └──────────→ 微信支付
                        发布者付款、支付回调、商家转账、主动查单

同一 Ubuntu 服务器上的“智聚大脑”保持原状。两个系统不共享目录、
容器网络、端口、环境变量、数据库或文件桶。智聚大脑通常深夜执行，
百特拓客主要白天使用，通过时间错峰避免资源竞争，不建设复杂调度系统。
智聚大脑现有本地数据和自动清理逻辑不纳入本项目，也不做任何修改。
```

### 4.2 目录结构

```
task/
├── .env.local                      # 仅本地开发使用，不提交 Git
├── .env.example                    # 环境变量模板
├── compose.yml                     # 百特拓客独立 Compose 项目
├── Dockerfile                      # 生产镜像，在本地或 CI 构建
├── next.config.js
├── tailwind.config.ts              # Tailwind 配置（注入 Apple Design Tokens）
├── tsconfig.json
├── package.json
├── prisma/
│   ├── schema.prisma               # 数据库 Schema
│   └── migrations/                 # 迁移文件（自动生成）
├── public/
│   ├── og-image.png
│   └── favicon.svg
└── src/
    ├── app/
    │   ├── layout.tsx              # 根布局（注入全局样式 + Auth Provider）
    │   ├── page.tsx                # 首页 → 任务大厅
    │   ├── login/
    │   │   └── page.tsx            # 支付宝单一登录/最近账号选择
    │   ├── tasks/
    │   │   ├── [id]/
    │   │   │   └── page.tsx        # 任务详情（底部抽屉式）
    │   │   └── publish/
    │   │       └── page.tsx        # 发布任务表单
    │   ├── messages/
    │   │   └── page.tsx            # 消息中心（聊天/系统/平台三Tab）
    │   ├── profile/
    │   │   └── page.tsx            # 个人中心
    │   ├── admin/
    │   │   └── page.tsx            # 管理后台
    │   └── api/
    │       ├── tasks/
    │       │   ├── route.ts        # GET (列表) + POST (创建)
    │       │   └── [id]/
    │       │       └── route.ts    # GET/PATCH/DELETE 单个任务
    │       ├── messages/
    │       │   └── route.ts        # GET (列表) + POST (发送)
    │       ├── submissions/
    │       │   └── route.ts        # 成果提交/验收
    │       ├── notifications/
    │       │   └── route.ts        # 通知列表/标记已读
    │       ├── storage/
    │       │   └── upload-token/
    │       │       └── route.ts    # 七牛云短期上传凭证
    │       ├── payments/
    │       │   └── callback/
    │       │       └── route.ts    # 收款回调（验签 + 幂等）
    │       ├── settlements/
    │       │   ├── route.ts        # 申请收款/查询状态
    │       │   └── callback/
    │       │       └── route.ts    # 支付宝商家转账回调（验签 + 幂等）
    │       └── identity-verifications/
    │           └── route.ts        # 统一实名接口，不暴露供应商字段
    ├── components/
    │   ├── ui/                     # 基础 UI 组件库
    │   │   ├── PhoneFrame.tsx      # 手机框架容器 (428×900)
    │   │   ├── GlassCard.tsx       # 毛玻璃卡片
    │   │   ├── NavBar.tsx          # 导航栏（统一返回按钮 + 标题 + 右侧操作）
    │   │   ├── SearchBar.tsx       # 搜索栏
    │   │   ├── TabRow.tsx          # Tab 切换（带动画滑动背景）
    │   │   ├── StatCard.tsx        # 统计卡片
    │   │   ├── TaskCard.tsx        # 任务卡片（含状态/标签/接单人进度）
    │   │   ├── StatusBadge.tsx     # 状态徽标
    │   │   ├── CategoryChip.tsx    # 分类标签
    │   │   ├── ProgressRing.tsx    # 环形进度图（SVG 渐变描边）
    │   │   ├── BottomSheet.tsx     # 底部滑出抽屉
    │   │   ├── Toast.tsx           # 顶部浮动提示
    │   │   ├── FAB.tsx             # 悬浮操作按钮
    │   │   ├── Modal.tsx           # 居中弹窗
    │   │   ├── ChatBubble.tsx      # 聊天气泡
    │   │   ├── EmptyState.tsx      # 空状态占位
    │   │   ├── HomeIndicator.tsx   # 底部 Home 指示条
    │   │   └── BackgroundGlow.tsx  # 背景光晕装饰
    │   ├── auth/
    │   │   ├── AlipayLoginView.tsx # 首次访问支付宝单一登录
    │   │   ├── SavedAccountPicker.tsx # 二次访问最近账号选择
    │   │   └── FirstVisitNotice.tsx # 首次授权与提现关系提示
    │   ├── identity/
    │   │   └── IdentityVerificationForm.tsx # 首次提现实名表单
    │   ├── hall/
    │   │   ├── HallContent.tsx     # 任务大厅主体
    │   │   ├── TaskFilters.tsx     # 分类/状态筛选栏
    │   │   └── MyTasks.tsx         # 我的任务 Tab 内容
    │   ├── detail/
    │   │   ├── TaskDetail.tsx      # 任务详情抽屉内容
    │   │   └── ClaimerCard.tsx     # 接单人信息卡片
    │   ├── publish/
    │   │   ├── PublishForm.tsx     # 发布任务表单
    │   │   ├── BudgetSlider.tsx    # 佣金滑块
    │   │   ├── SkillTagPicker.tsx  # 技能标签选择器
    │   │   └── FileUpload.tsx      # 文件上传组件
    │   ├── messages/
    │   │   ├── MsgList.tsx         # 消息列表（三Tab）
    │   │   ├── MsgCard.tsx         # 消息卡片
    │   │   ├── ChatSheet.tsx       # 聊天详情抽屉
    │   │   └── SystemMsg.tsx       # 系统通知卡片
    │   ├── profile/
    │   │   ├── ProfileHeader.tsx   # 个人信息头部
    │   │   ├── StatsGrid.tsx       # 数据统计 2×2 面板
    │   │   └── MenuList.tsx        # 功能菜单列表
    │   └── admin/
    │       ├── Sidebar.tsx         # 侧边栏导航
    │       ├── Dashboard.tsx       # 仪表盘
    │       ├── TaskTable.tsx       # 任务管理表格
    │       ├── UserTable.tsx       # 用户管理表格
    │       └── ReviewTable.tsx     # 审核管理表格
    ├── lib/
    │   ├── auth/
    │   │   ├── session.ts          # Session 创建、轮换和注销
    │   │   └── permissions.ts      # 服务端角色与资源归属校验
    │   ├── db/
    │   │   └── prisma.ts           # Prisma 单例与连接池
    │   ├── storage/
    │   │   └── qiniu.ts            # 上传凭证、对象键和下载签名
    │   ├── payments/
    │   │   ├── wechat.ts           # 微信支付请求、验签与查单
    │   │   └── idempotency.ts      # 支付/转账幂等控制
    │   ├── hooks/
    │   │   ├── useAuth.ts          # 认证状态 Hook
    │   │   ├── useTasks.ts         # 任务列表 Hook（分页与条件刷新）
    │   │   ├── useMessages.ts      # 消息 Hook（活跃页面短轮询）
    │   │   └── useToast.ts         # Toast 状态管理
    │   ├── types.ts                # TypeScript 类型定义
    │   ├── constants.ts            # 常量（分类、状态映射等）
    │   └── utils.ts                # 工具函数（日期格式化、金额格式化等）
    └── styles/
        ├── globals.css             # 全局样式入口
        └── tokens.css              # Apple Design Tokens (CSS Variables)
```

### 4.3 组件树

```
layout.tsx (根布局)
├── BackgroundGlow              ← 蓝+橙双色光晕（body::before/::after）
├── Toast                       ← 全局浮动提示
├── AuthProvider                ← 服务端 Session 状态
│
├── page.tsx (任务大厅 / )
│   └── PhoneFrame
│       ├── NavBar (标题"任务大厅" + 消息铃铛 + 个人头像)
│       ├── SearchBar
│       ├── StatCard × 3 (可接/进行中/已完成)
│       ├── TabRow (任务大厅 / 我的任务)
│       ├── (Tab: 任务大厅)
│       │   ├── CategoryChip × 7 (全部/设计/开发/文案/数据/图片/翻译)
│       │   ├── SectionLabel ("可接任务" N)
│       │   ├── TaskCard × N (列表)
│       │   │   ├── CardHeader → title + StatusBadge
│       │   │   ├── CardDesc
│       │   │   ├── CardFooter → time + Tag + Reward
│       │   │   └── ClaimerRow (进行中才显示) → avatar + name + ProgressRing
│       │   └── EmptyState
│       ├── (Tab: 我的任务)
│       │   ├── MyProgressCard × N (进度环 + 提交/编辑按钮)
│       │   └── IncomeSummary
│       ├── FAB (发布任务 +)
│       └── HomeIndicator
│
├── login/page.tsx
│   └── PhoneFrame
│       ├── AlipayLoginView → Logo + 支付宝授权 + 协议确认
│       ├── SavedAccountPicker → 最近账号 + 使用其他支付宝账号
│       └── FirstVisitNotice → 首次授权与提现关系提示
│
├── tasks/publish/page.tsx
│   └── PhoneFrame
│       ├── NavBar (返回 + "发布任务" + 存草稿)
│       ├── PublishForm
│       │   ├── 基础信息 (标题 + 分类下拉 + SkillTagPicker)
│       │   ├── 任务描述 (textarea)
│       │   ├── 附件上传 (FileUpload + 预览 + 删除)
│       │   ├── 预算 (BudgetSlider + 预设按钮)
│       │   ├── 截止日期 + 需求人数
│       │   └── 联系方式
│       └── BottomBar (预览 + 发布任务)
│
├── messages/page.tsx
│   └── PhoneFrame
│       ├── NavBar (返回 + "消息" + 全部已读)
│       ├── TabRow (聊天 / 系统 / 平台)
│       ├── MsgList → MsgCard × N (含未读标记 + 徽标数)
│       └── ChatSheet (底部抽屉) → ChatBubble × N + 输入栏
│
├── profile/page.tsx
│   └── PhoneFrame
│       ├── NavBar (返回 + "个人中心" + 设置)
│       ├── ProfileHeader (头像 + 认证徽章 + 姓名 + 角色 + 简介)
│       ├── StatsGrid 2×2 (已接/收入/好评率/等级)
│       ├── MenuList (待结算报酬/收款记录/技能/收藏/认证)
│       ├── MenuList (帮助/关于)
│       └── 退出登录按钮
│
└── admin/page.tsx
    ├── Sidebar (Logo + 导航分组 + 角标 + 管理员信息)
    └── MainContent
        ├── TopBar (面包屑 + 搜索 + 通知 + 时间)
        ├── Dashboard
        │   ├── StatCard × 4 (总任务/进行中/今日新增/收入)
        │   ├── TaskTable (最近任务)
        │   ├── ChartBars (7天趋势)
        │   └── ActivityList (最近动态)
        ├── TaskTable (全量任务管理 + 筛选 + 新建弹窗)
        ├── UserTable (用户管理 + 认证审核)
        └── ReviewTable (审核管理 + 通过/退回)
```

---

## 5. 页面与路由设计

### 5.1 路由表

| 路由 | 页面名称 | 认证要求 | 对应现有文件 | 说明 |
|------|---------|:--:|-------------|------|
| `/` | 任务大厅 | 否（浏览）/ 是（操作） | task-apple-ui.html | 含"任务大厅"与"我的任务" Tab 切换 |
| `/login` | 支付宝登录 | 否 | login.html | 首次支付宝授权 + 二次访问最近账号选择 |
| `/tasks/[id]` | 任务详情 | 否（查看）/ 是（操作） | 无独立页面（目前是抽屉） | 底部抽屉式详情，含接单人信息 |
| `/tasks/publish` | 发布任务 | 是（发布者+） | publish-task.html | 完整表单 + 附件上传 |
| `/messages` | 消息中心 | 是 | messages.html | 聊天 + 系统通知 + 平台公告 三 Tab |
| `/messages/[id]` | 消息详情 | 是 | 无独立页面（目前是抽屉） | 聊天详情抽屉 |
| `/profile` | 个人中心 | 是 | profile.html | 个人资料 + 数据统计 + 菜单 |
| `/admin` | 管理后台 | 是（管理员） | admin.html | 仪表盘 + 任务管理 + 用户管理 + 审核管理 |

### 5.2 页面间导航关系

```
                    ┌──────────────┐
                    │   登录/注册   │
                    │   /login     │
                    └──────┬───────┘
                           │ 登录成功
                           ▼
                    ┌──────────────┐
            ┌──────│  任务大厅 (/) │──────┐
            │      └──────┬───────┘      │
            │             │              │
     ┌──────▼──────┐     │      ┌───────▼──────┐
     │  消息中心    │     │      │  发布任务     │
     │  /messages  │◄────┘      │ /tasks/publish│
     └──────┬──────┘            └───────────────┘
            │
     ┌──────▼──────┐     ┌───────────────┐
     │  个人中心    │     │  管理后台      │
     │  /profile   │     │  /admin       │
     └─────────────┘     │ (仅管理员可见)  │
                         └───────────────┘
```

**导航交互方式**：

| 导航 | 方式 | 说明 |
|------|------|------|
| 任务大厅 → 任务详情 | 点击卡片 → 底部抽屉 | 同页面内 Bottom Sheet，不跳转 |
| 任务大厅 → 发布任务 | 点击 FAB → 路由跳转 | `router.push('/tasks/publish')` |
| 任务大厅 → 消息 | 点击铃铛 → 路由跳转 | `router.push('/messages')` |
| 任务大厅 → 个人中心 | 点击头像 → 路由跳转 | `router.push('/profile')` |
| 子页面返回 | 返回按钮 → 上一页 | `router.back()` |
| 退出登录 | 点击退出 → 跳转登录 | `router.push('/login')` |

### 5.3 每个页面的状态管理

| 页面 | 状态变量 | 类型 |
|------|---------|------|
| 任务大厅 | `tasks`, `activeTab`, `activeCategory`, `activeStatusFilter`, `searchQuery` | `useTasks` Hook |
| 登录 | `loginView`, `savedAccounts`, `agreementAccepted`, `showFirstVisitNotice` | 服务端 Session + 本地展示 state |
| 发布任务 | `formData {title, category, tags[], reward, deadline, count, desc, files[], contact}`, `showConfirmModal` | 本地 state + 七牛云直传 |
| 消息 | `activeMsgTab`, `messages`, `unreadCount`, `chatPartner`, `chatMessages` | `useMessages` Hook |
| 个人中心 | `user`, `stats`, `settlements`, `menuItems` | Session + 服务端数据 |
| 管理后台 | `activePage`, `tasks`, `users`, `reviews`, `stats`, `showTaskModal` | 服务端数据 + 本地 state |

---

## 6. 组件体系设计

### 6.1 UI 基础组件

#### PhoneFrame
```typescript
// 手机框架容器 — 428×900 毛玻璃卡片
// Props: { children, className? }
// 对应现有: .app-container / .phone-frame
// 统一: 全部使用 <PhoneFrame>
```

#### GlassCard
```typescript
// 毛玻璃卡片 — 统一的白底毛玻璃效果
// Props: { children, className?, onClick?, padding?, radius? }
// 对应现有: 所有页面的卡片背景
// CSS: backdrop-filter: blur(24px); background: rgba(255,255,255,0.72);
```

#### NavBar
```typescript
// 导航栏 — 统一页面头部
// Props: { title, showBack?, backHref?, rightAction?: ReactNode }
// 变体:
//   - 任务大厅: title="任务大厅", showBack=false, rightAction=<Bell + Avatar>
//   - 发布任务: title="发布任务", showBack=true, rightAction=<保存草稿>
//   - 消息页:   title="消息", showBack=true, rightAction=<全部已读>
//   - 个人中心: title="个人中心", showBack=true, rightAction=<设置>
```

#### SearchBar
```typescript
// 搜索入口 — 导航放大镜展开毛玻璃底输入框
// Props: { value, onChange, placeholder?, onClear? }
// 对应现有: .nav-btn[title="搜索任务"] + .search-popover
```

#### TabRow
```typescript
// Tab 切换 — 带滑动背景
// Props: { tabs: {label, value}[], activeTab, onChange }
// 对应现有: .tab-row > .tab-bg + .tab-btn
// tab-bg 在 activeTab 切换时 translateX 滑动
```

#### StatCard
```typescript
// 统计卡片
// Props: { value, label, color?, onClick?, active? }
// 对应现有: .stat-card
// active 状态: 蓝色焦点环 (box-shadow: 0 0 0 2.5px rgba(0,122,255,0.35))
```

#### TaskCard
```typescript
// 任务卡片
// Props: { task: Task, onToggleComplete?, onClick? }
// 变体:
//   - 可接单: StatusBadge=green "可接单", 点击→详情抽屉
//   - 进行中: StatusBadge=orange "进行中", 含 ClaimerRow
//   - 已完成: StatusBadge=gray "已完成", opacity=0.78
// 交互: 点击水波纹 (ripple effect)
```

#### StatusBadge
```typescript
// 状态徽标
// Props: { status: 'open' | 'claimed' | 'submitted' | 'done' | 'disputed' }
// 颜色映射:
//   open → 绿底绿字, claimed → 橙底橙字
//   submitted → 蓝底蓝字, done → 灰底灰字, disputed → 红底红字
```

#### CategoryChip
```typescript
// 分类标签 — 胶囊形按钮
// Props: { label, active?, onClick? }
// 对应现有: .category-chip
// active: 黑底白字, 否则: 浅灰底灰字
```

#### ProgressRing
```typescript
// 环形进度 — SVG 渐变描边
// Props: { percent, size?, gradientId?, label? }
// 对应现有: .progress-ring-wrap > svg
// 两种渐变色: blue (蓝紫), orange (橙红)
```

#### BottomSheet
```typescript
// 底部滑出抽屉
// Props: { open, onClose, children }
// 对应现有: .overlay + .detail-sheet
// 含: 拖拽手柄 (.sheet-handle), 毛玻璃遮罩
```

#### Toast
```typescript
// 顶部浮动提示 — 全局 Context
// Props: 无 (全局单例)
// 方法: showToast(message: string, duration?: number)
// 交互: 从顶部滑入，1.8s 后自动消失
```

#### FAB
```typescript
// 悬浮操作按钮
// Props: { onClick, icon?, label? }
// 对应现有: .fab — 渐变蓝紫色圆形按钮 + 阴影
```

#### Modal
```typescript
// 居中弹窗
// Props: { open, onClose, title, children, actions? }
// 对应现有: .modal-overlay > .modal-card
```

#### ChatBubble
```typescript
// 聊天气泡
// Props: { text, sender: 'sent' | 'received', time? }
// sent: 蓝紫渐变底 + 白色文字 + 右侧对齐
// received: 浅灰底 + 黑色文字 + 左侧对齐
```

#### EmptyState
```typescript
// 空状态占位
// Props: { icon?, title, description }
// 对应现有: .empty-state
```

### 6.2 业务组件

| 组件 | 说明 | 来源页面 |
|------|------|---------|
| `AlipayLoginView` | 首次访问支付宝授权、协议确认和安全提示 | login.html |
| `SavedAccountPicker` | 最近账号一键登录和使用其他支付宝账号 | login.html |
| `FirstVisitNotice` | 首次访问授权与提现关系提示 | login.html |
| `HallContent` | 可接/进行中/已完成 分区任务列表 | task-apple-ui.html |
| `TaskFilters` | 分类 chips + Section Labels | task-apple-ui.html |
| `MyTasks` | 进度环卡片 + 已完成列表 + 收入汇总 | task-apple-ui.html |
| `TaskDetail` | 状态徽标+标题+佣金+描述+标签+信息列表 | task-apple-ui.html |
| `ClaimerCard` | 接单人信息+进度条 | task-apple-ui.html |
| `PublishForm` | 标题/分类/标签/描述/附件/预算/日期 | publish-task.html |
| `BudgetSlider` | range input + 快捷预设按钮 | publish-task.html |
| `SkillTagPicker` | 多选标签 chips | publish-task.html |
| `FileUpload` | 拖拽上传 + 预览 + 删除 | publish-task.html |
| `MsgList` | 按日期分组的消息列表 | messages.html |
| `MsgCard` | 头像+发送者+预览+时间+未读标记 | messages.html |
| `ChatSheet` | 气泡对话流 + 输入栏 + 发送按钮 | messages.html |
| `SystemMsg` | 系统通知卡片 (带彩色点+标题+描述) | messages.html |
| `ProfileHeader` | 头像+认证徽章+姓名+角色 | profile.html |
| `StatsGrid` | 2×2 数据统计面板 | profile.html |
| `MenuList` | iOS 风格设置列表 (图标+标题+副标题+箭头) | profile.html |
| `Sidebar` | 左侧固定导航 + 分组 + 角标 | admin.html |
| `Dashboard` | 4 统计卡 + 任务表 + 趋势图 + 动态 | admin.html |
| `TaskTable` | 可筛选的表格 + 行操作按钮 | admin.html |
| `UserTable` | 用户表格 + 认证状态 + 封禁操作 | admin.html |
| `ReviewTable` | 审核表格 + 通过/退回操作 | admin.html |

---

## 7. 数据模型设计

### 7.1 ER 图

```
User ──< Session
  │
  ├──< Task（发布者）──1 PaymentOrder（发布者向百特拓客付款）
  │       │
  │       ├──< TaskClaim >── User（接单者，支持多人）
  │       ├──< Submission >─ User
  │       ├──< Settlement >─ User（每位接单者一笔报酬）
  │       └──< Review
  │
  ├──< Message（发送/接收）
  └──< Notification

WebhookEvent 独立记录发布者支付和支付宝商家转账回调，用 provider + providerEventId
建立唯一约束，防止重复回调造成重复记账或重复结算。
```

### 7.2 Prisma 核心 Schema（开发时以迁移文件为准）

```prisma
// ========== 用户 ==========
model User {
  id           String    @id @default(uuid())
  phone        String?   @unique
  email        String?   @unique
  passwordHash String?
  name         String
  avatarUrl    String?
  role         Role      @default(USER)
  status       UserStatus @default(ACTIVE)
  bio          String?
  skills       String[]
  verified     Boolean   @default(false)
  rating       Float     @default(0)
  totalEarned  Decimal   @default(0)  @db.Decimal(10, 2)
  completed    Int       @default(0)
  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt

  // 关联
  publishedTasks   Task[]         @relation("Publisher")
  taskClaims       TaskClaim[]
  submissions      Submission[]
  sentMessages     Message[]      @relation("Sender")
  receivedMessages Message[]      @relation("Receiver")
  notifications    Notification[]
  reviews          Review[]
  paymentOrders    PaymentOrder[] @relation("PayerOrders")
  settlements      Settlement[]   @relation("RecipientSettlements")
  sessions         Session[]
  storedObjects    StoredObject[]
}

enum Role {
  USER      // 普通用户（接单人）
  PUBLISHER // 发布者
  ADMIN     // 管理员
}

enum UserStatus {
  ACTIVE
  SUSPENDED
  CLOSED
}

model Session {
  id         String   @id @default(uuid())
  userId     String
  user       User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  tokenHash  String   @unique
  expiresAt  DateTime
  lastSeenAt DateTime @default(now())
  createdAt  DateTime @default(now())
}

// ========== 任务 ==========
model Task {
  id           String     @id @default(uuid())
  title        String
  description  String
  category     Category
  tags         String[]
  reward       Decimal    @db.Decimal(10, 2)
  deadline     DateTime
  count        Int        @default(1)      // 需求人数
  status       TaskStatus @default(OPEN)
  publicationStatus TaskPublicationStatus @default(DRAFT)

  // 关联键
  publisherId  String
  publisher    User       @relation("Publisher", fields: [publisherId], references: [id])
  createdAt    DateTime   @default(now())
  updatedAt    DateTime   @updatedAt

  submissions  Submission[]
  claims       TaskClaim[]
  reviews      Review[]
  paymentOrder PaymentOrder?
  settlements  Settlement[]
}

enum Category {
  DESIGN    // UI 设计
  DEV       // 程序开发
  WRITE     // 文案写作
  DATA      // 数据标注
  PHOTO     // 图片处理
  TRANSLATE // 翻译
  OTHER     // 其他
}

enum TaskStatus {
  OPEN      // 可接单
  CLAIMED   // 名额已满或已停止继续领取（进行中）
  SUBMITTED // 所有有效领取记录均已提交（待验收）
  COMPLETED // 已验收；是否已付款以 Settlement 状态为准
  DISPUTED  // 纠纷中
}

enum TaskPublicationStatus {
  DRAFT
  PENDING_PAYMENT
  PENDING_REVIEW
  PUBLISHED
  REJECTED
  CLOSED
}

// 多人任务以 TaskClaim 为事实来源：存在剩余名额时 Task 保持 OPEN；
// 名额已满后为 CLAIMED；全部有效领取均提交后为 SUBMITTED；
// 全部领取均完成验收或关闭后为 COMPLETED。

// ========== 领取记录（支持一项任务多人领取） ==========
model TaskClaim {
  id         String          @id @default(uuid())
  taskId     String
  task       Task            @relation(fields: [taskId], references: [id], onDelete: Cascade)
  userId     String
  user       User            @relation(fields: [userId], references: [id])
  status     TaskClaimStatus @default(ACTIVE)
  claimedAt  DateTime        @default(now())
  updatedAt  DateTime        @updatedAt

  @@unique([taskId, userId])
}

enum TaskClaimStatus {
  ACTIVE
  SUBMITTED
  APPROVED
  REJECTED
  CANCELLED
}

// ========== 成果提交 ==========
model Submission {
  id        String           @id @default(uuid())
  taskId    String
  task      Task             @relation(fields: [taskId], references: [id], onDelete: Cascade)
  userId    String
  user      User             @relation(fields: [userId], references: [id])
  content   String           // 提交说明
  files     String[]         // 七牛云对象键列表，不保存永久公开 URL
  status    SubmissionStatus @default(PENDING)
  createdAt DateTime         @default(now())
}

enum SubmissionStatus {
  PENDING   // 待验收
  APPROVED  // 已通过
  REJECTED  // 已驳回
}

// ========== 对象存储元数据 ==========
model StoredObject {
  id         String             @id @default(uuid())
  ownerId    String
  owner      User               @relation(fields: [ownerId], references: [id])
  objectKey  String             @unique
  bucket     String
  mimeType   String
  sizeBytes  Int
  status     StoredObjectStatus @default(UPLOADED)
  boundAt    DateTime?
  deletedAt  DateTime?
  createdAt  DateTime           @default(now())
}

enum StoredObjectStatus {
  UPLOADED
  BOUND
  QUARANTINED
  DELETED
}

// ========== 消息 ==========
model Message {
  id         String   @id @default(uuid())
  senderId   String
  sender     User     @relation("Sender", fields: [senderId], references: [id])
  receiverId String
  receiver   User     @relation("Receiver", fields: [receiverId], references: [id])
  content    String
  read       Boolean  @default(false)
  taskId     String?  // 关联的任务（可选）
  createdAt  DateTime @default(now())
}

// ========== 通知 ==========
model Notification {
  id        String           @id @default(uuid())
  userId    String
  user      User             @relation(fields: [userId], references: [id], onDelete: Cascade)
  type      NotificationType
  title     String
  content   String
  read      Boolean          @default(false)
  link      String?          // 点击跳转链接（如 /tasks/xxx）
  createdAt DateTime         @default(now())
}

enum NotificationType {
  SYSTEM   // 系统通知
  TASK     // 任务相关
  REVIEW   // 审核相关
  PAYMENT  // 支付相关
}

// ========== 评价 ==========
model Review {
  id        String   @id @default(uuid())
  taskId    String
  task      Task     @relation(fields: [taskId], references: [id], onDelete: Cascade)
  userId    String
  user      User     @relation(fields: [userId], references: [id])
  rating    Int      // 1-5 星
  comment   String?
  createdAt DateTime @default(now())

  @@unique([taskId, userId]) // 每个任务每人只能评价一次
}

// ========== 发布者付款订单 ==========
model PaymentOrder {
  id                  String             @id @default(uuid())
  taskId              String             @unique
  task                Task               @relation(fields: [taskId], references: [id])
  payerId             String
  payer               User               @relation("PayerOrders", fields: [payerId], references: [id])
  taskRewardTotal     Decimal            @db.Decimal(10, 2)
  platformServiceFee  Decimal            @db.Decimal(10, 2)
  amount              Decimal            @db.Decimal(10, 2) // 发布者实际支付总额
  status              PaymentOrderStatus @default(PENDING)
  provider            String             @default("WECHAT_PAY")
  merchantOrderNo     String             @unique
  providerOrderNo     String?            @unique
  idempotencyKey      String             @unique
  paidAt              DateTime?
  closedAt            DateTime?
  createdAt           DateTime           @default(now())
  updatedAt           DateTime           @updatedAt
}

enum PaymentOrderStatus {
  PENDING
  PAID
  CLOSED
  REFUNDING
  REFUNDED
  FAILED
}

// ========== 接单者报酬结算 ==========
model Settlement {
  id                  String           @id @default(uuid())
  taskId              String
  task                Task             @relation(fields: [taskId], references: [id])
  recipientId         String
  recipient           User             @relation("RecipientSettlements", fields: [recipientId], references: [id])
  grossAmount         Decimal          @db.Decimal(10, 2) // 税前/扣减前报酬
  withholdingAmount   Decimal          @default(0) @db.Decimal(10, 2)
  amount              Decimal          @db.Decimal(10, 2) // 实际转账金额
  status              SettlementStatus @default(ELIGIBLE)
  provider            String           @default("ALIPAY_TRANSFER")
  merchantTransferNo  String           @unique
  providerTransferId  String?          @unique
  idempotencyKey      String           @unique
  failedReason        String?
  requestedAt         DateTime?
  paidAt              DateTime?
  createdAt           DateTime         @default(now())
  updatedAt           DateTime         @updatedAt

  @@unique([taskId, recipientId])
}

enum SettlementStatus {
  ELIGIBLE      // 已验收，可申请收款
  REQUESTED     // 用户已申请
  PROCESSING    // 微信处理中
  PAID          // 已到账
  FAILED        // 失败，可人工复核后重试
  FROZEN        // 纠纷或风控冻结
}

// ========== 外部回调幂等记录 ==========
model WebhookEvent {
  id             String   @id @default(uuid())
  provider       String
  providerEventId String
  eventType      String
  payloadHash    String
  processedAt    DateTime?
  createdAt      DateTime @default(now())

  @@unique([provider, providerEventId])
}
```

### 7.3 服务端授权与数据隔离

- 浏览器不直连 PostgreSQL，所有读写必须经过 Next.js 服务端。
- 每个写接口同时校验登录态、角色、资源归属和当前状态，不只检查前端按钮是否可见。
- 领取任务在事务内检查有效 `TaskClaim` 数量小于 `Task.count` 后再插入；验收、付款确认和生成结算单同样使用条件更新，防止重复执行。
- 资金记录不做物理删除；退款、失败和冲正通过追加状态与审计记录表达。
- 生产数据库账号仅授予百特拓客数据库权限，不接触智聚大脑任何数据。
- 管理员高风险操作记录操作者、时间、来源 IP、变更前后值和原因。

---

## 8. API 设计

### 8.1 REST API 端点

所有 API 路由位于 `src/app/api/` 下，作为 Ubuntu 常驻 Next.js 服务中的 Route Handlers。写接口统一支持请求 ID；资金接口必须使用幂等键。

#### 任务 API

| 方法 | 路径 | 说明 | 认证 | 参数 |
|------|------|------|:--:|------|
| `GET` | `/api/tasks` | 获取任务列表 | 否 | `?status=&category=&search=&page=&limit=` |
| `POST` | `/api/tasks` | 创建新任务 | 是 | body: `{title, description, category, tags, reward, deadline, count}` |
| `GET` | `/api/tasks/[id]` | 获取任务详情 | 否 | - |
| `PATCH` | `/api/tasks/[id]` | 更新任务 | 是 | body: 部分字段 |
| `DELETE` | `/api/tasks/[id]` | 删除任务 | 管理员 | - |
| `POST` | `/api/tasks/[id]/claim` | 领取任务 | 是 | - |
| `POST` | `/api/tasks/[id]/submit` | 提交成果 | 是 | body: `{content, files}` |
| `POST` | `/api/tasks/[id]/approve` | 验收通过 | 发布者 | - |
| `POST` | `/api/tasks/[id]/reject` | 验收驳回 | 发布者 | body: `{reason}` |

公开任务列表只返回 `publicationStatus=PUBLISHED` 的记录；执行状态 `TaskStatus` 与付款/审核状态 `TaskPublicationStatus` 分开维护。

#### 消息 API

| 方法 | 路径 | 说明 | 认证 |
|------|------|------|:--:|
| `GET` | `/api/messages` | 获取消息列表 | 是 |
| `POST` | `/api/messages` | 发送消息 | 是 |
| `PATCH` | `/api/messages/[id]/read` | 标记已读 | 是 |
| `PATCH` | `/api/messages/read-all` | 全部标为已读 | 是 |

#### 通知 API

| 方法 | 路径 | 说明 | 认证 |
|------|------|------|:--:|
| `GET` | `/api/notifications` | 获取通知列表 | 是 |
| `PATCH` | `/api/notifications/[id]/read` | 标记已读 | 是 |
| `PATCH` | `/api/notifications/read-all` | 全部标为已读 | 是 |

#### 用户 API

| 方法 | 路径 | 说明 | 认证 |
|------|------|------|:--:|
| `GET` | `/api/users/me` | 获取当前用户信息 | 是 |
| `PATCH` | `/api/users/me` | 更新个人信息 | 是 |
| `GET` | `/api/users/me/stats` | 获取个人统计数据 | 是 |

#### 实名 API

| 方法 | 路径 | 说明 | 认证 |
|------|------|------|:--:|
| `POST` | `/api/identity-verifications` | 首次提现姓名+身份证二要素核验 | 是 |
| `GET` | `/api/identity-verifications/me` | 获取当前实名状态和脱敏信息 | 是 |

实名接口只返回 `VERIFIED`、`MISMATCH`、`NO_RECORD`、`RETRYABLE_ERROR`、`REJECTED` 等统一状态。浏览器不接触供应商地址、密钥、原始错误码或完整响应；供应商通过 `IdentityVerificationProvider` 选择。

#### 管理 API

| 方法 | 路径 | 说明 | 认证 |
|------|------|------|:--:|
| `GET` | `/api/admin/stats` | 平台统计数据 | 管理员 |
| `GET` | `/api/admin/users` | 用户列表管理 | 管理员 |
| `PATCH` | `/api/admin/users/[id]` | 管理用户（封禁/解封/认证） | 管理员 |
| `PATCH` | `/api/admin/tasks/[id]/review` | 审核任务（通过/退回） | 管理员 |
| `POST` | `/api/admin/integration-tests` | 使用服务端凭据执行外部服务真实连通测试 | 管理员 |

#### 文件 API

| 方法 | 路径 | 说明 | 认证 |
|------|------|------|:--:|
| `POST` | `/api/storage/upload-token` | 生成限定对象键、大小和有效期的七牛云上传凭证 | 是 |
| `POST` | `/api/storage/complete` | 确认直传结果并登记对象元数据 | 是 |
| `DELETE` | `/api/storage/[id]` | 删除本人未绑定业务或允许删除的文件 | 是 |

#### 支付与结算 API

| 方法 | 路径 | 说明 | 认证 |
|------|------|------|:--:|
| `POST` | `/api/payments/orders` | 创建发布者付款订单 | 发布者 |
| `POST` | `/api/payments/callback` | 微信支付回调，验签并幂等更新订单 | 微信验签 |
| `GET` | `/api/payments/orders/[id]` | 查询本平台订单及微信侧状态 | 本人/管理员 |
| `POST` | `/api/payments/orders/[id]/refund` | 审核后发起退款 | 管理员 |
| `POST` | `/api/payments/refund-callback` | 微信退款回调，验签并幂等更新订单 | 微信验签 |
| `POST` | `/api/settlements` | 对已验收任务申请收款 | 接单者 |
| `GET` | `/api/settlements/[id]` | 查询报酬结算状态 | 本人/管理员 |
| `POST` | `/api/settlements/callback` | 支付宝商家转账回调，验签并幂等更新结算单 | 支付宝验签 |
| `POST` | `/api/admin/settlements/[id]/retry` | 人工复核后重试失败转账 | 管理员 |

资金接口约束：

- 金额全部由服务端根据任务和订单计算，拒绝使用浏览器提交的最终金额。
- 创建订单、申请收款和人工重试均要求 `Idempotency-Key`。
- 回调先验签、再登记 `WebhookEvent`，同一外部事件只处理一次。
- 超时不能直接判定失败，必须主动查询对应支付渠道或支付宝侧最终状态。
- 数据库不可用、状态不合法或验签失败时禁止继续结算。

### 8.2 API 响应格式

```typescript
// 成功响应
{
  "success": true,
  "data": { ... },
  "meta?": { "total": 89, "page": 1, "limit": 20 }
}

// 错误响应
{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED" | "NOT_FOUND" | "VALIDATION_ERROR" | "FORBIDDEN" |
            "CONFLICT" | "IDEMPOTENCY_CONFLICT" | "PAYMENT_UNAVAILABLE",
    "message": "中文错误描述"
  }
}
```

---

## 9. 消息与通知刷新方案

### 9.1 架构原理

试运营阶段不部署 Supabase Realtime、Redis 或自建 WebSocket。所有消息和通知先写入 PostgreSQL，再由当前页面按需短轮询。这样在 A 级容量下更容易部署、排障和恢复。

```
用户操作 → 事务写入业务数据和 Notification → API 返回
                                           ↓
前端活跃页面按 lastSeenAt / cursor 增量查询 ← PostgreSQL
```

轮询频率：

- 活跃聊天窗口：3-5 秒；切到后台或页面不可见后暂停。
- 消息列表和系统通知：15-30 秒；用户手动刷新时立即查询。
- 任务大厅：进入页面、切换筛选或完成操作后刷新，不持续高频轮询。
- 支付与结算：回调为主，超时或状态不明时由服务端主动查单，不由浏览器猜测结果。

### 9.2 前端 Hook 设计

```typescript
// useMessages.ts — 仅在聊天窗口可见时增量轮询
function useMessages(conversationId: string) {
  const isVisible = usePageVisibility()
  return usePollingQuery({
    key: ['messages', conversationId],
    intervalMs: 4000,
    enabled: isVisible,
    fetcher: ({ cursor }) => fetchMessages(conversationId, cursor),
  })
}
```

### 9.3 通知触发时机

| 事件 | 谁收到通知 | 通知内容 |
|------|-----------|---------|
| 任务被领取 | 发布者 | "{claimerName} 领取了你的任务「{taskTitle}」" |
| 任务被提交 | 发布者 | "{submitterName} 提交了任务「{taskTitle}」的成果" |
| 任务验收通过 | 接单人 | "你的任务「{taskTitle}」已通过验收，报酬 ¥{reward} 可申请收款" |
| 任务验收驳回 | 接单人 | "你的任务「{taskTitle}」需要修改，原因：{reason}" |
| 新任务通过审核 | 发布者 | "你的任务「{taskTitle}」已通过审核，已在任务大厅展示" |
| 收到新消息 | 接收方 | 消息中心显示未读状态；浏览器通知后续按需增加 |
| 账号被认证 | 用户 | "你的账号已通过{认证类型}认证" |
| 佣金到账 | 接单人 | "¥{amount} 已到账，来自任务「{taskTitle}」" |

---

## 10. 用户流程设计

### 10.1 核心流程：浏览→接单→提交→验收

```
[任务大厅]                      [接单人]                       [发布者]
    │                              │                              │
    ├─ 浏览任务列表                 │                              │
    ├─ 筛选（分类/状态/搜索）        │                              │
    ├─ 点击任务卡片                 │                              │
    │                              │                              │
    ▼                              │                              │
[任务详情 (Bottom Sheet)]           │                              │
    ├─ 查看完整描述                 │                              │
    ├─ 查看接单人进度（进行中）       │                              │
    │                              │                              │
    ├─ 点击"立即接单" ──────────→  │                              │
    │   POST /api/tasks/[id]/claim │                              │
    │   → 创建 TaskClaim；名额满后 Task OPEN→CLAIMED              │
    │   → 写入站内通知 ───────────────────────────────────────→  │
    │                              │              收到通知          │
    │                              │                              │
    │       [我的任务 Tab]  ←───────┤                              │
    │         ├─ 进度环显示         │                              │
    │         ├─ "提交成果" ──────→ │                              │
    │         │   POST /api/tasks/[id]/submit                     │
    │         │   → TaskClaim ACTIVE→SUBMITTED                   │
    │         │   → 写入站内通知 ───────────────────────────────→ │
    │         │                              │       收到提交通知   │
    │         │                              │                    │
    │         │                              │    验收通过/驳回     │
    │         │                              │    POST approve/reject
    │         │   ←── 前端刷新通知 ──────────┘                    │
    │         │   收到验收结果                                     │
    │         │   通过→TaskClaim APPROVED，生成待结算报酬            │
    │         │   驳回→TaskClaim REJECTED，修改后重新提交             │
```

### 10.2 发布任务流程

```
[任务大厅]
    ├─ 点击 FAB + ──→ /tasks/publish
    │
    ▼
[发布任务页面]
    ├─ 填写标题 (必填)
    ├─ 选择分类 (必填，下拉)
    ├─ 选择技能标签 (多选 chips)
    ├─ 填写描述 (textarea)
    ├─ 上传附件 (图片/PDF/ZIP，≤20MB，七牛云短期凭证直传)
    ├─ 设置佣金 (¥100-20,000，滑块+预设按钮)
    ├─ 设置截止日期 (date picker)
    ├─ 设置需求人数 (1-10人下拉)
    ├─ 联系方式 (选填)
    │
    ├─ 点击"预览" → 预览抽屉
    ├─ 点击"发布任务" → 确认弹窗 → 提交
    │
    ▼
[提交成功]
    → 服务端创建付款订单并跳转微信支付
    → 微信回调验签并确认 PAID
    → 已付款任务进入审核队列
    → 审核通过后公开展示
    → 通知发布者
```

### 10.3 消息与通知流程

```
[消息中心]
    │
    ├─ Tab 1: 聊天
    │   ├─ 与接单人/发布者的一对一聊天
    │   ├─ 点击 → ChatSheet 底部抽屉
    │   ├─ 发送消息 → POST /api/messages → 接收方短轮询获取
    │   └─ 蓝色未读圆点 + 数量徽标
    │
    ├─ Tab 2: 系统
    │   ├─ 任务被领取/提交/验收的通知
    │   ├─ 佣金到账通知
    │   └─ 带彩色圆点（红/橙/绿/蓝）区分类型
    │
    └─ Tab 3: 平台
        ├─ 版本升级公告
        ├─ 运营活动通知
        └─ 平台规则变更
```

### 10.4 收款与报酬结算流程

百特拓客作为任务服务方统一向发布者收款，并从自己的经营资金向接单者支付报酬。系统不提供用户充值钱包、余额转让或用户资金托管。

```
发布者创建任务 → 服务端创建 PaymentOrder → 微信支付收款
    → 支付回调验签与幂等入账 → 任务进入可审核/可发布状态

接单者完成任务 → 发布者验收 → 创建 Settlement(ELIGIBLE)
    → 首次收款完成二要素实名 → 接单者点击“申请收款”
    → 支付宝商家转账(open_id + 已核验姓名)
    → 回调或主动查单确认 → Settlement(PAID)
```

- 页面展示“待结算报酬”，不展示可充值或可转让的平台钱包余额。
- `Task.reward` 表示单个接单名额承诺的税前报酬；发布者总付款由任务报酬合计和平台服务费组成。
- 结算单分别记录税前报酬、依法代扣或业务扣减金额、实际转账金额，禁止覆盖原始金额。
- 个体工商户的开票、成本凭证、个人劳务报酬或经营所得处理方式须在正式收款前由会计或税务专业人员按实际合同关系确认。
- 同一任务的同一接单者只能存在一张有效结算单，同一幂等键不能重复发起转账。
- 转账失败进入 `FAILED`，由管理员核对失败原因后人工重试，禁止无限自动重试。
- 纠纷、退款、账户异常或数据库不可用时冻结结算。
- 试运营阶段只支持管理员审核后的原路全额退款；部分退款在产生明确业务需求后再扩展独立退款明细模型。
- 订单、任务、验收、退款、结算和微信回单至少能够一对一追溯。

---

## 11. 权限与安全设计

### 11.1 权限矩阵

| 操作 | 未登录 | 普通用户 | 发布者 | 管理员 |
|------|:--:|:--:|:--:|:--:|
| 浏览任务大厅 | ✅ | ✅ | ✅ | ✅ |
| 查看任务详情 | ✅ | ✅ | ✅ | ✅ |
| 搜索/筛选任务 | ✅ | ✅ | ✅ | ✅ |
| 登录/注册 | ✅ | - | - | - |
| 发布任务 | ❌ | ❌ | ✅ | ✅ |
| 领取任务 | ❌ | ✅ | ✅ | ✅ |
| 提交成果 | ❌ | ✅ | ✅ | ✅ |
| 验收任务 | ❌ | ❌ | ✅（仅自己的任务） | ✅ |
| 发送消息 | ❌ | ✅ | ✅ | ✅ |
| 查看消息 | ❌ | ✅ | ✅ | ✅ |
| 管理个人资料 | ❌ | ✅ | ✅ | ✅ |
| 查看管理后台 | ❌ | ❌ | ❌ | ✅ |
| 审核任务 | ❌ | ❌ | ❌ | ✅ |
| 管理用户 | ❌ | ❌ | ❌ | ✅ |
| 处理纠纷 | ❌ | ❌ | ❌ | ✅ |

### 11.2 安全措施

| 层面 | 措施 | 说明 |
|------|------|------|
| **传输层** | HTTPS | 复用现有反向代理，只新增百特拓客独立域名配置 |
| **认证** | 服务端 Session | HttpOnly、Secure、SameSite Cookie；登录后轮换会话标识 |
| **密码** | Argon2id 哈希 + 登录限流 | 不保存明文或可逆密码；连续失败触发短时限制并记录安全日志 |
| **数据库** | 服务端唯一入口 | 浏览器不持有数据库凭证，API 校验角色、资源归属和状态 |
| **API** | Middleware + Handler 双重校验 | Middleware 做登录门禁，Handler 做业务级授权和幂等 |
| **文件上传** | 短期凭证 + 类型/大小白名单 | 客户端直传七牛云；对象键由服务端生成，默认私有访问，单文件最大 20MB |
| **支付** | 渠道验签 + 主动查单 + 幂等事务 | 金额由服务端计算，回调重复投递不得重复记账或转账 |
| **个人信息** | 最小化收集 + 分级访问 | 实名仅服务端处理；真实姓名加密，身份证按合规需要加密留存或仅保存 HMAC/末四位 |
| **XSS** | React 默认转义 | JSX 内容自动转义 |
| **CSRF** | SameSite Cookie + Origin 校验 | 所有状态变更接口仅接受允许来源 |
| **环境变量** | 独立生产 env 文件 | 权限设为仅部署用户可读，不提交 Git，不与智聚大脑共享 |

### 11.3 Middleware 实现

```typescript
// src/middleware.ts（路由门禁；资源归属仍必须在 Route Handler 内校验）
import { NextResponse } from 'next/server'
import { readSessionCookie } from '@/lib/auth/session'
import { isProtectedPath } from '@/lib/auth/permissions'

export async function middleware(req: Request) {
  const session = await readSessionCookie(req)
  const path = new URL(req.url).pathname

  if (isProtectedPath(path) && !session) {
    return NextResponse.redirect(new URL('/login', req.url))
  }
  if (path.startsWith('/admin') && session?.role !== 'ADMIN') {
    return NextResponse.redirect(new URL('/', req.url))
  }
  return NextResponse.next()
}
```

---

## 12. 分阶段实施计划

### 12.1 交付规则

1. 一个阶段只主攻一个页面；页面完成、联动验证通过后再进入下一页。
2. 每个阶段先写当前页面的最小测试，再实现真实数据，不长期保留两套业务逻辑。
3. 当前页面需要的共用组件可以提取，未被第二处复用的组件不提前抽象。
4. 每阶段保留可运行状态，失败时能够回退到上一版镜像，不回滚数据库已执行的迁移。
5. 具体工期和文件级步骤在开发前另写实施计划，本节只定义交付顺序和验收边界。

### 阶段零：工程基线与现有联动盘点

- 固定 Node、Next.js 和依赖版本，建立本地测试、构建与 Docker 镜像流程。
- 逐一记录 6 个现有 HTML 的入口、出口、按钮和当前页面跳转关系。
- 建立全局样式、数据库连接、Session、错误响应和测试基线。
- 产出：空壳应用可运行，现有 HTML 保持可查看，尚不迁移业务页面。

### 阶段一：登录页面 `login.html`

- 迁移支付宝单一登录、首次授权提示、最近账号选择和首次手机号绑定，并接入服务端 Session。
- 验证未登录门禁、授权取消、登录后跳转、账号切换、退出登录和会话过期。
- 产出：登录页与任务大厅入口形成第一条真实联动。

### 阶段二：任务大厅 `task-apple-ui.html`

- 迁移任务列表、筛选、搜索、详情抽屉和“我的任务”。
- 接入 PostgreSQL 分页查询和领取任务事务。
- 产出：登录用户可以浏览、领取和查看自己的任务。

### 阶段三：发布任务 `publish-task.html`

- 迁移表单、预览、草稿和确认流程。
- 接入七牛云短期凭证直传；服务器不接收附件内容。
- 接入发布者付款订单，但未支付订单不进入公开审核队列。
- 产出：发布、付款、审核、任务大厅展示形成闭环。

### 阶段四：消息中心 `messages.html`

- 迁移聊天、系统通知和平台公告三个 Tab。
- 活跃聊天使用短轮询，页面不可见时暂停轮询。
- 产出：领取、提交、验收等事件能够生成并展示站内通知。

### 阶段五：个人中心 `profile.html`

- 迁移资料、任务统计、待结算报酬和收款记录。
- 接入统一实名通道、支付宝商家转账申请、状态查询和失败提示。
- 产出：验收通过 → 申请收款 → 到账/失败状态形成闭环。

### 阶段六：管理后台 `admin.html`

- 迁移任务审核、用户管理、纠纷处理、付款与结算复核。
- 高风险操作增加二次确认和审计日志。
- 产出：管理员能够处理异常订单、冻结结算和人工重试。

### 阶段七：部署与整体验收

- 自动触发“2.7 正式上线前强制审查门禁”，生成《百特拓客上线前检查报告》；门禁未通过时停止正式部署。
- 在 Ubuntu 上以独立 Compose 项目安装，不修改智聚大脑目录和任务计划。
- 配置域名、HTTPS、环境变量、日志轮转、健康检查和数据库备份。
- 逐页执行桌面/移动端截图检查，并走通发布者与接单者完整流程。
- 在智聚大脑深夜任务运行期间验证百特拓客基础 Web 和支付回调仍可用。

---

## 13. 部署方案

### 13.1 本地与生产目录

本地开发的代码、依赖缓存、构建产物、测试结果和临时文件全部位于：

```text
C:\Users\刘先生\Desktop\codex\自动化\task
```

生产服务器只新增以下目录，且不读取或挂载智聚大脑目录：

```text
/opt/better-task/          # compose、部署配置和版本文件
/var/lib/better-task/tmp/  # 短期临时文件，最大 1GB
/var/log/better-task/      # 应用日志，最大 200MB，保留 7 天
```

### 13.2 运行隔离与资源策略

- 独立 Linux 部署用户、Compose 项目名、Docker 网络、容器名、内部端口和环境变量文件。
- 复用现有反向代理时只新增独立域名配置，不覆盖智聚大脑配置。
- 百特拓客主要白天使用；智聚大脑任务主要深夜运行，运维任务按时间错峰。
- 百特拓客不建设自动扩缩容、Redis、MinIO 或常驻监控集群。
- Web 容器正常约 200-500MB，内存硬上限 1.5GB；CPU 按需共享，峰值不超过约 3 核。
- 服务器设置约 2GB Swap 仅用于突发保护，正常运行不得持续依赖 Swap。
- 非必要维护任务不安排在智聚大脑执行窗口；具体时间在部署时根据其现有计划确认。

### 13.3 外部服务

| 服务 | 推荐 | 用途与约束 |
|------|------|-----------|
| PostgreSQL | 与服务器同地域的国内托管 PostgreSQL | 仅百特拓客使用；启用自动备份、SSL 和来源 IP 白名单 |
| 对象存储 | 七牛云 Kodo | 私有 Bucket；附件直传；下载使用短期签名 URL |
| 支付 | 支付宝开放平台商家转账 | 使用登录获得的 `open_id` + 已核验真实姓名；最终以支付宝审核为准 |
| 实名 | 腾讯云应用市场商品 `17684` | 首个二要素通道；通过统一 Provider 隔离，取得合规材料后上线 |

对象存储备选：腾讯云 COS 的生态集成更完整，但当前标准外网下行单价高于七牛云；又拍云适合同时重度使用 CDN 的场景。试运营阶段默认七牛云，供应商通过统一 `StorageProvider` 接口隔离，避免业务代码绑定 SDK。

支付资格核验说明：支付宝商家转账用于真实商家向个人支付佣金/服务款等场景，不能替代用户储值钱包或第三方交易资金清分。个体工商户能否开通及额度以支付宝实际审核为准；未取得商家转账权限前不得把模拟接口用于生产。

### 13.4 环境变量

```bash
APP_ORIGIN=https://任务系统域名
DATABASE_URL=postgresql://...
SESSION_SECRET=...

QINIU_ACCESS_KEY=...
QINIU_SECRET_KEY=...
QINIU_BUCKET=...
QINIU_PRIVATE_DOMAIN=...

WECHAT_PAY_MCH_ID=...
WECHAT_PAY_APP_ID=...
WECHAT_PAY_API_V3_KEY=...
WECHAT_PAY_PRIVATE_KEY_PATH=/run/secrets/wechat_private_key
WECHAT_PAY_PLATFORM_CERT_PATH=/run/secrets/wechat_platform_cert

ALIPAY_APP_ID=...
ALIPAY_PRIVATE_KEY_PATH=/run/secrets/alipay_private_key
ALIPAY_PUBLIC_KEY_PATH=/run/secrets/alipay_public_key
ALIPAY_TRANSFER_NOTIFY_URL=https://任务系统域名/api/settlements/callback

IDENTITY_VERIFICATION_PROVIDER=tencent-marketplace-17684
IDENTITY_VERIFICATION_TIMEOUT_MS=5000
TENCENT_MARKET_IDENTITY_API_URL=https://ap-beijing.cloudmarket-apigw.com/service-18c38npd/idcard/VerifyIdcardv2
TENCENT_MARKET_IDENTITY_CREDENTIALS_FILE=/run/secrets/tencent_market_identity.json
```

- `.env.example` 只保留变量名和说明，不放真实值。
- 生产密钥使用只读文件或 Docker secrets 挂载，权限仅部署用户可读。
- 支付私钥、API Key、实名通道密钥、数据库密码和七牛 Secret Key 不写日志、不返回浏览器。

### 13.5 部署与回滚

1. 在本地或 CI 执行测试并构建不可变镜像，生产服务器不运行高内存前端构建。
2. 部署前自动备份数据库并检查磁盘、内存、端口和智聚大脑运行计划。
3. 先执行向前兼容的 Prisma migration，再启动新镜像并执行健康检查。
4. 健康检查通过后切换反向代理；失败则恢复上一版镜像。
5. 数据库迁移不使用破坏性自动回滚；需要删除字段时分“停止写入 → 数据迁移 → 后续版本删除”完成。

### 13.6 清理、备份与告警

- 七牛云直传成功后立即删除本地临时文件；每 6 小时清理超时残留，目录达到 1GB 时拒绝继续写入并告警。
- 应用日志按大小轮转，单文件和总量均受限；禁止记录密码、证件、完整支付报文和密钥。
- 托管 PostgreSQL 开启每日自动备份；每周执行一次恢复演练或校验备份可用性。
- 重点告警：容器重启、磁盘超过 80%、内存持续超过 85%、数据库不可用、支付验签失败、重复回调异常和待处理转账积压。

### 13.7 A 级容量与成本判断

目标：500 用户以内、每天 50 个任务以内、同时在线 20 人以内、文件累计 100GB 以内。

- 现有 4 核 4G 服务器足以运行一套百特拓客 Web/API，前提是数据库和附件外置。
- 七牛云当前公开价格包含每月 10GB 标准存储等免费额度；超出后按存储、请求和流量计费。
- 腾讯云 PostgreSQL 价格受地域、规格、购买周期和活动影响，部署前必须用官方计算器重新核价，不在文档中写死促销价格。
- 成本升级触发条件：数据库 CPU/连接数持续超过 70%、同时在线接近 100、文件流量显著超过资源包或出现稳定后台任务积压。

### 13.8 正式收款前置条件

- 完成个体工商户登记、经营账户和与实际业务一致的经营范围确认。
- 准备支付宝开放平台应用并通过“商家转账”产品审核；发布者收款渠道另行按实际选择申请，审核未通过时不得把模拟接口用于生产。
- 与实名服务商签署适用的数据处理协议，确认数据来源、留存、删除和 SLA；未取得材料前只允许测试数据联调。
- 若服务器和域名位于中国大陆，根据服务器所在地及主管部门要求完成适用的域名实名认证、ICP备案和公安联网备案，以官方审核要求为准。
- 完成七牛云实名、私有 Bucket、跨域规则、生命周期规则和域名配置。
- 与会计或税务专业人员确认平台收入、接单者报酬、代扣、开票和成本凭证处理方式。
- 上线用户协议、隐私政策、任务服务规则、退款规则、纠纷处理规则和接单者报酬结算规则。
- 在真实小额环境完成收款、退款、验签、重复回调、商家转账、转账失败和对账演练。

---

## 14. 风险评估

| 风险 | 概率 | 影响 | 缓解措施 |
|------|:--:|:--:|------|
| **与智聚大脑资源竞争** | 低 | 中 | 两套系统目录和进程隔离，智聚深夜运行、百特拓客白天使用，维护任务错峰 |
| **4G 内存峰值/OOM** | 中 | 高 | 数据库和附件外置，生产机不构建镜像，Web 容器限制 1.5GB，Swap 仅作保护 |
| **3M 带宽被附件占满** | 高 | 高 | 浏览器使用短期凭证直传七牛云，服务器不代理文件内容 |
| **托管数据库不可用** | 低 | 高 | 健康检查、连接超时、自动备份；不可用时禁止付款和结算 |
| **重复回调或重复转账** | 中 | 高 | 唯一订单号、幂等键、WebhookEvent、事务条件更新和主动查单 |
| **个体工商户支付能力审核失败** | 中 | 高 | 一期保留人工结算与凭证登记作为受控降级，不伪造场景；后续可升级有限公司 |
| **自建钱包形成合规风险** | 中 | 高 | 只记录待结算报酬，不提供充值、余额转让或用户资金托管 |
| **逐页迁移产生联动回归** | 中 | 中 | 一个页面一个阶段，每页完成后验证与全部已完成页面的导航和数据联动 |
| **对象存储供应商锁定** | 低 | 中 | 业务只保存对象键，通过 StorageProvider 封装上传凭证和签名下载 |
| **Apple 风格还原偏差** | 中 | 中 | 现有 HTML 作为视觉基线，保留 CSS Variables，逐页截图对比 |

---

## 15. 工单处理闭环基线（2026-07-28）

### 15.1 已确认范围

- 后台原“申诉与客服”统一改为“工单处理”，覆盖任务审核、支付、实名认证、账号、任务规则、技术和其他问题。
- 用户个人中心增加“我的工单”入口；用户端和后台使用同一版本化存储 `betterTask.support.tickets.v1`，演示数据仅首次初始化，不覆盖已有工单。
- 用户端支持新建、筛选、查看沟通记录、补充回复、重新打开和确认解决；等待用户回复时在个人中心显示数量角标。
- 后台支持搜索、状态筛选、接手、负责人调整、优先级调整、回复并等待用户、回复并解决、重新打开、代用户新建和 CSV 导出。
- 工单状态固定为：`open`、`in_progress`、`waiting_user`、`resolved`、`closed`；待处理超过 24 小时计入超时未响应。
- 任一页面写入后通过同源 `localStorage` 与 `storage` 事件同步到另一页面；损坏数据采用失败关闭策略，不重置、不覆盖原始记录。

### 15.2 当前原型边界

- 当前共享存储用于本地原型联动。生产实现必须替换为服务端数据库、登录态用户 ID、权限校验和审计日志，不能信任浏览器传入的负责人、用户 ID 或状态。
- 工单回复、状态迁移和关联任务校验应由服务端事务完成，并通过唯一请求 ID 保证重试幂等。
- 附件上传、消息通知和客服 SLA 暂未纳入本次原型；后续接入时沿用现有工单 ID 和状态机，不另建一套申诉数据。

---

## 附录

### A. 关键文件对照表（现有 HTML → Next.js 组件）

| 现有 HTML 片段 | Next.js 组件 |
|---------------|-------------|
| `.app-container` / `.phone-frame` | `<PhoneFrame>` |
| 所有卡片的 `backdrop-filter: blur()` | `<GlassCard>` |
| `.nav` + `.nav-title` + `.nav-back` | `<NavBar>` |
| `.nav-btn[title="搜索任务"]` + `.search-popover` | `<SearchBar>` |
| `.tab-row > .tab-bg + .tab-btn` | `<TabRow>` |
| `.stat-card` | `<StatCard>` |
| `.task-card` (整体) | `<TaskCard>` |
| `.status-badge` | `<StatusBadge>` |
| `.category-chip` | `<CategoryChip>` |
| `.progress-ring-wrap > svg` | `<ProgressRing>` |
| `.overlay + .detail-sheet` | `<BottomSheet>` |
| `.toast` | `<Toast>` |
| `.fab` | `<FAB>` |
| `.modal-overlay > .modal-card` | `<Modal>` |
| `.auth-header + .auth-form` | `<LoginForm>` / `<RegisterForm>` |
| `.form-section` (发布任务) | `<PublishForm>` |
| `.msg-card` | `<MsgCard>` |
| `.chat-overlay > .chat-sheet` | `<ChatSheet>` |
| `.profile-header` | `<ProfileHeader>` |
| `.sidebar` (admin) | `<Sidebar>` |
| `.stat-cards` (admin) | `<Dashboard>` |

### B. 参考资源链接

- [Next.js App Router 文档](https://nextjs.org/docs/app)
- [Prisma 文档](https://www.prisma.io/docs)
- [Docker Compose 文档](https://docs.docker.com/compose/)
- [七牛云 Kodo 定价](https://www.qiniu.com/prices/kodo)
- [腾讯云 COS 定价](https://buy.cloud.tencent.com/price/cos)
- [又拍云价格计算器](https://www.upyun.com/pricing)
- [腾讯云 PostgreSQL 定价](https://buy.cloud.tencent.com/price/pgsql)
- [微信支付商家转账产品介绍](https://pay.weixin.qq.com/doc/v3/merchant/4012711988)
- [微信支付商家转账申请条件](https://pay.weixin.qq.com/doc/v3/merchant/4013740645)
- [微信支付平台收付通接入准备](https://pay.weixin.qq.com/doc/v3/partner/4012086921)
- [微信支付合作伙伴申请条件](https://kf.qq.com/faq/161220iqeAfA1612202yeURB.html)
- [非银行支付机构监督管理条例](https://www.gov.cn/zhengce/content/202312/content_6920724.htm)
