docs(design): site center spec (sites page as single entry, credentials, user data, dashboard)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
1 parent
911a810da5
commit
8cad83e8f5
1 file changed
+222
@@ -0,0 +1,222 @@
|
||||
# 站点中心与仪表盘调整(v0.2.1)
|
||||
|
||||
> 依据:`docs/plan/00-first-version-plan.md` §8(用户 2026-09-28 上午)。状态:待审阅。只读调研 + 规格,不含代码改动。
|
||||
> 参考:MoviePilot v3(`/opt/moviepilot-plus/upstream`)、MovieClaw v0.27.0(`spikes/movieclaw-src/repo`)。
|
||||
|
||||
## 1. 用户要求(原文要点)
|
||||
|
||||
- 资源 → 站点页 = 添加站点 + 凭证管理(账密 / Cookie / API Key,馒头 API Key)+ 卡片/列表(上次登录时间、上传/下载、分享率、用户等级、VIP、账号状态,数据来自 `sites/user-parsers` 的 `refreshSiteUserData`)+ 手动"检测健康"与"用凭证刷新登录状态"。
|
||||
- 账密登录走 NexusPHP takelogin;验证码 / 二次验证失败 → 待处理,提示改用 Cookie。
|
||||
- 设置里只留全局默认(限流、快照周期)。
|
||||
- 仪表盘保留 REQ 六区块,补 MP 有价值的区块(媒体库统计、存储用量、下载器实时状态、最近入库、定时任务状态),砍重复。
|
||||
|
||||
## 2. 参考实现
|
||||
|
||||
### 2.1 MoviePilot v3
|
||||
|
||||
| 方面 | 做法 | 位置 |
|
||||
| --- | --- | --- |
|
||||
| 卡片 | 名称、URL、左侧状态色条(`sitestatistic.lst_state` 成功/失败 + `seconds` 耗时,≥5s 黄)、徽标(限流 / 代理 / 浏览器仿真 / 过滤)、上传 / 下载量;按钮:测试连通、用户数据、更新 Cookie;菜单:编辑、删除;可拖拽排序(优先级) | `components/cards/SiteCard.vue`、`views/site/SiteCardListView.vue` |
|
||||
| 添加 / 编辑 | 名称、URL、优先级 pri、RSS 地址、Cookie、API Key、Token、UA、代理开关、浏览器仿真、超时、限流(`limit_interval` 秒内 `limit_count` 次、`limit_seconds` 间隔)、下载器、启用 | `dialog/SiteAddEditDialog.vue`、`db/models/site.py` |
|
||||
| 更新 Cookie | 对话框填用户名 / 密码 / 二步验证码(或 TOTP 密钥)→ `POST site/cookie/{id}`;后端 `CookieHelper` 用 Playwright 浏览器打开登录页、OCR 识别验证码、按 `two_step_code/otp` 输入框填 TOTP,拿到 Cookie + UA 写回站点。**密码不保存** | `chain/site.py update_cookie`、`application/security/cookie.py` |
|
||||
| 测试连通 | GET 首页,`SiteUtils.is_logged_in` 判登录;Cloudflare 挑战单独提示;结果与耗时写 `sitestatistic`(success/fail/seconds/lst_state/lst_mod_date) | `chain/site.py test/__test` |
|
||||
| 用户数据 | `siteuserdata` 按天一行:username、userid、user_level、join_at、bonus、upload、download、ratio、seeding、leeching、seeding_size、leeching_size、seeding_info、message_unread(+内容)、err_msg、updated_day/time;对话框看历史曲线 | `db/models/siteuserdata.py`、`dialog/SiteUserDataDialog.vue` |
|
||||
| 定时 | `sitedata_refresh`「站点数据刷新」,间隔 `sitedata_refresh_interval` | `scheduler/catalog.py` |
|
||||
| Cookie 来源 | 手填、账密换取、CookieCloud 同步(设定 → 站点:地址 / 密钥 / 间隔 / 黑名单) | `chain/site.py sync_cookies` |
|
||||
|
||||
### 2.2 MovieClaw v0.27.0
|
||||
|
||||
- 认证方式三种:`cookie` / `apikey` / `credential`(用户名 + 密码,程序模拟登录并保存)。`CredentialAuthProvider`:GET `login.php` → 正则找 `imagecode.php?...` 验证码(无识别器 → `NEEDS_CAPTCHA` 返回图片地址)→ 带隐藏字段、`imagehash`、`extra_form_data` POST 表单 → `success_css`(`a[href*='logout']`)判成功,`error_css`(`td.text`)取失败原因,验证码错最多重试。
|
||||
- 账号状态 `pending / verifying / active / failed`,附 `last_verified_at`、`last_checked_at`、`last_error`(归类后的中文);启动时把卡在 verifying 的复位。保存凭证即"保存并验证",卡片有"重新验证"。
|
||||
- 验证成功时顺手抓 `profile`:用户名、等级、`vip_group`(定义里 `vip_css` 命中即 VIP)、上传 / 下载字节、分享率(null 与 0 区分)、魔力(无则不显)、做种 / 下载数、`fetched_at`。
|
||||
- 卡片另有同步统计(资源数、上次同步 / 成功、下次同步、连续失败、上次错误)和保护 / 刷流开关(不在本期范围)。
|
||||
|
||||
## 3. 现状与缺口
|
||||
|
||||
| 项 | 现状 | 缺口 |
|
||||
| --- | --- | --- |
|
||||
| 入口 | 站点工作台卡片(启停、健康、账号摘要、快照);详情"账号"页签;设置 `#sites` 另有站点列表 + 登记抽屉 + 凭证表单(`components/settings/sites.tsx`,625 行) | 仍是两处可增删改,违背 IA"一个对象一个家" |
|
||||
| 凭证 | `PUT /sites/{id}/credentials`(cookie/passkey/api_key/password + username)与 `/site-accounts` CRUD 并存;密码只存不用 | 无账密登录实现;无 UA 字段;无 TOTP |
|
||||
| 用户数据 | `refreshSiteUserData` 与 20 个解析器已移植,**服务端没有调用点**;`site_account.user_info` 只存 username | 无数据、无历史、无 VIP 字段 |
|
||||
| 健康 | adapter 有 `healthCheck()`(首页 + `loginSuccess`),**无路由**;健康只在快照 / Feed 出错时被动更新 | 无手动检测、无检测时间与耗时 |
|
||||
| 登录态 | `site_account.status` = unknown/active/invalid/expired,`last_verified_at` 只在失败时写 | 没有"需验证"态、没有上次登录时间 |
|
||||
| 删除 | 无删除站点 / 账号接口 | 需要 |
|
||||
| 全局默认 | settings 无站点默认项;`snapshotIntervalSec=null` 时不做定时快照 | 需要 `sites.*` 默认 |
|
||||
|
||||
站点定义:23 个里 22 个有 `umt.login`(`path/usernameField/passwordField/errorCss/extraFormData/selectDefaults`),馒头只支持 `apikey`;`chdbits`、`ssd` 的 `umt.profile.vip_css` 已有。
|
||||
|
||||
## 4. 站点页规格(`/console/sites`,唯一入口)
|
||||
|
||||
### 4.1 页面
|
||||
|
||||
- 页头:标题"站点"、视图切换(卡片 / 列表,写 URL `?view=`)、刷新、"添加站点"。筛选:全部 / 已启用 / 需处理(账号非正常或健康 failing)。
|
||||
- 卡片与列表同字段,列表可按分享率、上传、上次登录排序。点名称进详情(整理视图 / 原站视图 / 快照与 Feed / 账号 4 页签不变,"账号"页签改为本页抽屉的完整版,含用户数据历史)。
|
||||
|
||||
### 4.2 卡片字段
|
||||
|
||||
| 字段 | 来源 | 显示规则 |
|
||||
| --- | --- | --- |
|
||||
| 名称、域名 | `site.name`、`site.base_url` 主机名 | 域名可点,新窗口开原站 |
|
||||
| 启用 | `site.enabled` | 开关 |
|
||||
| 账号状态 | `site_account.status` | 正常(active)/ 已失效(expired、invalid)/ 需验证(challenge)/ 未验证(unknown)/ 未配置(无账号);多账号取最差 |
|
||||
| 凭证类型 | `auth_kind` | Cookie / API Key / 账号密码;另有 passkey 时加"Passkey"小标 |
|
||||
| 上次登录 | `last_login_at` | 相对时间;从未成功显示"—" |
|
||||
| 上传 / 下载 / 分享率 | `user_data.upload/download/ratio` | 字节格式化;分享率 null 显示"—",download=0 显示"∞" |
|
||||
| 等级、VIP | `user_data.userLevel`、`user_data.vip` | VIP 为 true 才显徽标 |
|
||||
| 做种数(体积) | `seeding`、`seedingSize` | |
|
||||
| 魔力 | `bonus` | 0 且站点不提供时不显 |
|
||||
| 未读消息 | `messageUnread` | >0 才显 |
|
||||
| 健康检测 | `site.last_health` + `last_health_at` | "正常 · 320 ms · 5 分钟前" / 失败原因一句 |
|
||||
| 快照 | `last_snapshot_at`、周期 | 过期标黄(沿用 `snapshotStale`) |
|
||||
| 限流 | `site.rate_limit`,空则"默认" | 例:"20 次/分" |
|
||||
|
||||
用户数据时间戳(`user_data_at`)显示在数据区角落:"数据 2 小时前"。
|
||||
|
||||
### 4.3 操作
|
||||
|
||||
卡片主按钮:检测健康、刷新登录;"更多"菜单:更新 Cookie / 更新 API Key / 更新密码(按凭证类型显示一项)、编辑、快照、停用 / 启用、删除。
|
||||
|
||||
| 操作 | 行为 | 端点 |
|
||||
| --- | --- | --- |
|
||||
| 添加站点 | 三步对话框:① 选定义(搜索框 + 列表,已登记的置灰;"未适配站点"只能 generic_rss)② 域名覆盖(默认定义域名)+ 凭证(按定义 `authSupported` 列出可选类型)+ 可选 UA ③ "测试"=保存后立即刷新登录,显示结果(成功带用户名 / 等级),失败可返回修改;"保存"关闭 | `POST /sites` → `PUT /sites/{id}/credentials` → `POST /sites/{id}/refresh-login` |
|
||||
| 编辑 | 抽屉:名称、域名、限流(空 = 全局默认)、定时快照开关与周期、UA、使用代理 | `PATCH /sites/{id}` |
|
||||
| 检测健康 | 首页连通 + 登录态,同步返回(≤20 s,走站点限流) | `POST /sites/{id}/health-check` |
|
||||
| 刷新登录 | 账密:重新登录拿 Cookie;Cookie / API Key:校验;成功后拉用户数据。异步任务,返回 taskId,卡片转圈直到任务结束 | `POST /sites/{id}/refresh-login` |
|
||||
| 更新凭证 | 小对话框,只写,不回显;保存即触发刷新登录 | `PUT /sites/{id}/credentials` |
|
||||
| 删除 | 确认框写明后果:"删除站点、账号和凭证;已抓到的资源和下载任务保留。不可恢复" | `DELETE /sites/{id}` |
|
||||
|
||||
### 4.4 账密登录(NexusPHP takelogin)
|
||||
|
||||
适配器新增 `packages/adapters/src/sites/login/nexusphp.ts`,输入定义的 `umt.login` + 用户名 / 密码 / 可选 TOTP 密钥,输出 `{ ok, cookie, userAgent }` 或 `SiteLoginError{ reason }`。流程对齐 MovieClaw `CredentialAuthProvider`:
|
||||
|
||||
1. 用固定 UA 清空 Cookie GET `login.php`(`umt.login.path`),记下 Set-Cookie。
|
||||
2. 页面匹配 `imagecode.php?…` → 验证码。本期不做 OCR:直接失败,`reason=captcha`。
|
||||
3. 取登录表单(`form[action*=takelogin]`,缺省 `takelogin.php`)的隐藏字段,填 `usernameField` / `passwordField`、`selectDefaults`、`extraFormData`;有 TOTP 密钥且表单有 `two_step_code`/`otp` 字段时填当前 6 位码。
|
||||
4. POST(不跟随 3xx),再 GET `index.php`;`loginSuccess` 命中 → 成功,拼 Cookie。
|
||||
5. 失败分支:`errorCss` 文本归类 —— 账号或密码错(`bad_credentials`)、需要二次验证而无 TOTP(`two_factor`)、验证码(`captcha`)、账号封禁 / 未确认(`account_blocked`)、Cloudflare 挑战(`challenge`)、其它(`unknown`,原文截 200 字)。
|
||||
|
||||
服务端处理:
|
||||
|
||||
- 成功:派生 Cookie 存入 `session_secret_ref`(purpose `site_cookie`,label `site_account:<label>:session`),`status=active`,`last_login_at=now`;之后请求优先用会话 Cookie,遇 `auth_expired` 自动重登一次(同账号 10 分钟内最多一次),仍失败再走现有 `onAuthError`。
|
||||
- `captcha / two_factor / challenge`:`status=challenge`,开待处理(kind 复用 `source_unreachable`,`dedupeKey=site-login:<accountId>`),标题"站点「X」登录需要人工验证",摘要"登录页要求验证码 / 二次验证,无法自动登录。改用 Cookie 登录,或填写 TOTP 密钥后重试",选项:改用 Cookie(深链站点页并打开凭证对话框)、重试登录、忽略。
|
||||
- `bad_credentials / account_blocked`:`status=invalid`,同一待处理,选项去掉"重试登录"。
|
||||
- 表单里提供"只换 Cookie,不保存密码"(MP 做法):登录成功后凭证类型直接落为 Cookie,密码丢弃。
|
||||
- 馒头及 `authSupported` 不含 password 的站点,对话框不显示账号密码。
|
||||
|
||||
### 4.5 用户数据
|
||||
|
||||
- 调用 `refreshSiteUserData({ name, url, schema, cookie|apikey, limiter, fetchMessages:false })`,做种分页上限由全局 `sites.userDataMaxSeedingPages`(缺省 10;MP 为 50)控制,请求全部过站点令牌桶。
|
||||
- VIP:`SiteUserInfo` 增加 `vip: boolean | null`;定义有 `umt.profile.vip_css` 时在首页 / 详情页判定,否则按新可选字段 `umt.vipLevels`(等级名列表)匹配,都没有为 null(不显示)。
|
||||
- `errMsg` 非空或 `userId` 为空:视为登录态失效,走 4.4 失败处理;数据不覆盖上次成功值。
|
||||
- 首页已显示登录态时顺手更新 `last_login_at`(Cookie / API Key 校验成功也算"登录")。
|
||||
|
||||
### 4.6 状态机(`site_account.status`)
|
||||
|
||||
`unknown` →(刷新登录成功)`active` →(请求遇 auth_expired 且重登失败)`expired`;任意态 →(验证码 / 二次验证 / 挑战)`challenge`;→(密码错 / 封禁)`invalid`;更新凭证 → `unknown` 并关闭 `site-auth:*` 与 `site-login:*` 待处理(现有逻辑扩展)。
|
||||
|
||||
## 5. 数据模型(迁移 `0031_site_center.ts`)
|
||||
|
||||
`site_account`(沿用 `auth_kind` 作为凭证类型,不改名;`status` 即登录状态):
|
||||
|
||||
| 列 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `status` | 检查约束加 `challenge` | contracts `SiteAccountStatus` 同步 |
|
||||
| `login_name` | text null | 账密登录名;从 `user_info.username` 迁出 |
|
||||
| `totp_secret_ref` | uuid null | 可选 TOTP 密钥(purpose 新增 `site_totp`) |
|
||||
| `session_secret_ref` | uuid null | 账密登录得到的会话 Cookie |
|
||||
| `user_agent` | text null | 空 = 全局默认 UA;Cookie 与 UA 需成对时填 |
|
||||
| `last_login_at` | timestamptz null | 最近一次登录 / 校验成功 |
|
||||
| `last_error` | jsonb null | `{reason, message, at}` |
|
||||
| `user_data` | jsonb not null default `{}` | 最近一次成功的 `SiteUserInfo` 去掉 `raw`、`messageUnreadContents`、`seedingInfo` |
|
||||
| `user_data_at` | timestamptz null | |
|
||||
|
||||
`user_info` 保留只读兼容一版,迁移把 `username` 写入 `login_name`。
|
||||
|
||||
新表 `site_user_data`(按天一行,MP `siteuserdata` 对应):`id, site_account_id → site_account on delete cascade, day date, upload bigint, download bigint, ratio numeric null, bonus numeric null, seeding int, seeding_size bigint, leeching int, user_level text null, vip boolean null, captured_at timestamptz`,唯一 `(site_account_id, day)`,同日 upsert 取最新;保留 400 天(并入现有日志保留清理)。
|
||||
|
||||
`site`:加 `last_health jsonb null`(`{ok, status, latencyMs, message}`)、`last_health_at timestamptz null`、`proxy boolean not null default false`。
|
||||
|
||||
contracts:`SiteAccount` 增加上表字段(secret ref 不外露,只给 `hasTotp`、`hasSession` 布尔);`Site` 增加 `lastHealth`、`lastHealthAt`、`proxy`;新增 `SiteUserData`、`SiteHealthResult`、`SiteCredentialsPut` 改为按 kind 的判别联合。
|
||||
|
||||
## 6. 后端端点
|
||||
|
||||
| 方法 路径 | scope | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `GET /sites?include=accounts` | read | 列表附带账号摘要(状态、凭证类型、`last_login_at`、`user_data`),站点页一次请求 |
|
||||
| `POST /sites` / `PATCH /sites/{id}` | admin | 现有;PATCH 加 `proxy` |
|
||||
| `DELETE /sites/{id}` | admin | 删站点、账号、secret;`source_release` 保留(外键改 set null 或保留 site_id 只读,实现时确认) |
|
||||
| `POST /sites/{id}/health-check` | admin | 同步,返回 `SiteHealthResult` 并写 `site.last_health*`、`health_status` |
|
||||
| `POST /sites/{id}/refresh-login` | admin | body `{accountId?}`;入队引擎任务 `refreshSiteAccount`,返回 `{taskId}`;幂等键按 10 s 取整 |
|
||||
| `GET /sites/{id}/user-data` | read | `?accountId&days=30`,返回 `site_user_data` 序列 |
|
||||
| `PUT /sites/{id}/credentials` | admin | body 判别联合:`{kind:"password", label, username, password, totpSecret?, saveCookieOnly?}` / `{kind:"cookie", label, cookie, userAgent?}` / `{kind:"api_key", label, apiKey}`;passkey 仍用 `{kind:"passkey", passkey}` 附加到同账号(RSS / 下载用,不参与登录) |
|
||||
| `DELETE /site-accounts/{id}` | admin | 删账号与其 secret |
|
||||
|
||||
`/site-accounts` 的 POST / PATCH(凭证部分)标弃用,前端全部改走 `PUT /sites/{id}/credentials`;Agent 能力表(`capabilities.ts`)登记 `sites.healthCheck`、`sites.refreshLogin` 两个只读风险低的能力。
|
||||
|
||||
## 7. 定时任务
|
||||
|
||||
在 `sources-identity/index.ts` 用现有 `job()` 登记:
|
||||
|
||||
| key | 名称 | 分组 | 默认 | 行为 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `sites.userData` | 站点数据刷新 | collect | 每 6 小时,`firstRun: after_interval` | 对启用站点的启用账号依次入队 `refreshSiteAccount`(不重登,只有遇失效才重登);跳过 `challenge/invalid` 账号;只读对账模式跳过 |
|
||||
|
||||
另:`sites.snapshot` 对 `snapshotIntervalSec=null` 的站点改用全局默认周期。
|
||||
|
||||
## 8. 设置页"站点与账号"改为"站点默认"
|
||||
|
||||
- `SETTINGS_SECTIONS.sites`:label 改"站点默认",description"新站点的限流、快照周期、UA 和代理;站点和凭证在站点页管理",`resources: []`,`fields` 如下(新存储 key `sites`,contracts `SitesSettings`):
|
||||
|
||||
| 字段 | 缺省 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `sites.defaultRateLimit` | `{requestsPerMinute: 20, concurrency: 1}` | 站点 `rate_limit` 为空时使用 |
|
||||
| `sites.defaultSnapshotIntervalSec` | 3600 | 站点未设周期时使用 |
|
||||
| `sites.userAgent` | 固定桌面 Chrome UA | 账号未设 UA 时使用 |
|
||||
| `sites.proxyUrl` | 空 | 站点开"使用代理"时生效 |
|
||||
| `sites.userDataMaxSeedingPages` | 10 | 用户数据做种分页上限 |
|
||||
|
||||
- 删除 `components/settings/sites.tsx` 里的站点列表、登记抽屉、凭证表单、账号列表;节顶部放一行"站点和凭证在「站点」页管理"+ 跳转链接。
|
||||
- 迁移:`legacyTabs` 保留 `site-credentials`,但落点改为 `/console/sites`;`settingsPath("sites", "accounts")` 的调用点全部改为 `consolePath("sites")`;冒烟 `REDIRECT_ROUTES` 补一条。
|
||||
- 数据迁移:无(旧设置里没有站点默认值;现有站点的 `rate_limit` 保留)。
|
||||
- `console-ia.md` §6 设置分区表与 §6.3"站点三处合一"行在实施后更新。
|
||||
|
||||
## 9. 文案(按 glossary)
|
||||
|
||||
- 页名"站点"(侧栏"站点工作台"改名);凭证统称"凭证";不写"PT 源""认证信息"。
|
||||
- 按钮:添加站点、检测健康、刷新登录、更新 Cookie、更新 API Key、更新密码、删除站点。
|
||||
- 空态:"还没有站点。添加站点并填写凭证后,这里显示账号数据和健康状态"。
|
||||
- 错误示例:"登录失败:站点要求验证码。改用 Cookie,或稍后在站点页重试"、"Cookie 已失效。更新 Cookie 后重新刷新登录"。
|
||||
- 账密说明只陈述事实:"密码加密保存,用于 Cookie 失效后自动重新登录。选'只换 Cookie'则不保存密码"。
|
||||
|
||||
## 10. 仪表盘调整
|
||||
|
||||
MP 仪表盘组件与数据源:媒体统计(`dashboard/statistic`:电影 / 剧集 / 集 / 音乐数)、存储(`dashboard/storage`:总 / 已用)、下载速度(`dashboard/downloader`:上下行速度、累计、剩余空间)、后台服务(`dashboard/schedule` + 整理队列)、最近入库(`history/transfer`)、周整理量(`dashboard/transfer`)、媒体服务器最新 / 在播 / 媒体库、CPU / 内存 / 网络 / 进程 / 系统信息、快捷操作。
|
||||
|
||||
| 区块 | 处理 | 数据来源 | 位置 |
|
||||
| --- | --- | --- | --- |
|
||||
| 自动化概览 | 保留;加"媒体库"一行:电影 / 剧集 / 集数(MP 媒体统计并入) | `GET /dashboard` 新增 `library{movies, series, episodes, assets}`(按 `media_entity`、`content_unit`、`media_asset` 计数) | 第一行左 |
|
||||
| 当前工作 | 保留;页头加下载器实时速度 ↓/↑ 与活动数(MP 下载速度并入) | `/dashboard` 新增 `downloaders[]{id, name, dlSpeed, upSpeed, freeBytes}`,来自 qB `transferInfo()`,服务端 5 s 缓存 | 第一行中 |
|
||||
| 待处理 | 保留 | 现有 | 第一行右 |
|
||||
| 缓存水位 → 存储 | 合并:下载缓存卷 + 库根所在卷(MP 存储) | `/dashboard.cache` 保留;新增 `storage[]{rootId, label, totalBytes, usedBytes}`(库根 statfs,按设备去重) | 第二行左 |
|
||||
| 来源健康 | 保留;站点行加账号状态点与分享率,需处理的排前 | `/dashboard.sources.sites` 增加 `accountStatus`、`ratio`、`lastLoginAt` | 第二行中 |
|
||||
| 最近产出(= MP 最近入库) | 保留,加海报缩略图 | 现有 `recentOutput` 加 `posterPath` | 第二行右 |
|
||||
| 定时任务 | 新增小块:失败的任务在前,其余显示下次运行 | 前端直接用 `GET /schedules`(已有) | 第三行,整宽窄条 |
|
||||
|
||||
不做:CPU / 内存 / 网络 / 进程 / 系统信息(与媒体流程无关)、媒体服务器在播与最新(v0.3 再评估)、周整理量图(自动化概览已有今日计数)、快捷操作(侧栏与 Agent 已覆盖)、站点统计单独区块(并入来源健康)。
|
||||
|
||||
## 11. 实施拆分
|
||||
|
||||
| 路 | 范围 | 主要文件 | 估算 |
|
||||
| --- | --- | --- | --- |
|
||||
| 后端 B | 迁移 0031;contracts(`sources.ts`、`instances.ts` 凭证联合、`settings.ts` 的 `SitesSettings` 与分区、`organization.ts` Dashboard 扩展);NexusPHP 登录模块 + fixture 测试(成功 / 密码错 / 验证码 / 二次验证 / TOTP);`SiteUserInfo.vip` 与 `umt.vipLevels` schema;`refreshSiteAccount` 引擎任务、会话 Cookie 优先与自动重登;4.3 / 6 节端点;`sites.userData` 定时任务;默认值接入快照与限流;dashboard 聚合(库计数、qB 速度、库根 statfs);Agent 能力登记;vertical 测试补一条"添加站点 → 刷新登录 → 用户数据入库" | `packages/db/migrations/0031_site_center.ts`、`packages/db/src/types.ts`、`packages/contracts/src/{sources,instances,settings,organization,api}.ts`、`packages/adapters/src/sites/{login/*,user-parsers/types.ts,definitions/schema.ts}`、`apps/server/src/modules/sources-identity/{routes/sources.ts,service/account.ts(新),tasks.ts,index.ts,capabilities.ts}`、`auth-settings/instances-routes.ts`(凭证 PUT)、`acquisition-organize/routes/dashboard.ts` | 3–3.5 天 |
|
||||
| 前端 F | 站点页重写(卡片 / 列表切换、筛选、字段、操作菜单);添加站点三步对话框(替换 `site-register-dialog.tsx`);凭证对话框(三种 kind + 只换 Cookie + TOTP);编辑抽屉;详情"账号"页签加用户数据折线(近 30 天上传 / 分享率);设置分区改"站点默认"并删旧表单;`settingsPath("sites")` 调用点与重定向;首页区块调整;侧栏改名;冒烟与 nav 测试 | `routes/console/sites.tsx`、`sites.$siteId.tsx`、`components/workbench/{site-card.tsx(新),site-list.tsx(新),site-register-dialog.tsx,site-credential-dialog.tsx(新),site-accounts.tsx}`、`components/settings/sites.tsx`、`api/sites.ts`、`api/dashboard.ts`、`routes/console/home.tsx`、`components/console/nav.ts`、`scripts/smoke.mjs` | 2.5–3 天 |
|
||||
|
||||
顺序:B 先交 contracts 与迁移(半天),F 基于 contracts 用 mock 并行;testkit mock 站点补 `login.php/takelogin.php` 与用户详情页,两路共用。
|
||||
|
||||
## 12. 待核验 / 风险
|
||||
|
||||
1. takelogin 表单字段、二次验证字段名、错误文本全部未经真实站点核验(同 README"待真实站点核验")。
|
||||
2. 保存密码是与 MP 不同的取舍(MovieClaw 保存);默认选"保存",可选"只换 Cookie"。
|
||||
3. 用户数据做种分页请求量大,限流默认值需在真实账号上调。
|
||||
4. Cloudflare 站点需要浏览器服务(camofox)登录,本期只识别并转待处理。
|
||||
5. `DELETE /sites/{id}` 对 `source_release.site_id` 外键的处理需实现时确认,不能级联删资源。
|
||||
Reference in new issue
Block a user