# EveryPublish Web-only V1 逻辑图 ## 1. 系统拓扑 ```text ┌───────────────────────┐ REST / Browser WS ┌──────────────────────────────┐ │ 浏览器 │◄────────────────────────────►│ Go server │ │ React + TDesign │ │ Gin API + JWT + GORM │ └───────────┬───────────┘ │ MySQL + Redis │ │ ├──────────────┬───────────────┤ │ │ WebExecutor │ PlatformAdapter│ │ │ mock │ 本机 profile │ │ └──────┬───────┴───────┬───────┘ │ │ │ └────────────────────────────── localhost ─────────┴───────► 目标平台 ``` ## 2. 登录 ```text 输入邮箱/密码 │ ├─ POST /auth/login ──> Argon2 校验 ──> access + refresh │ │ │ └─ 失败:统一错误码、登录限速、审计 └─ GET /auth/me + connectWS ──> 工作台 ``` ## 3. 素材到任务 ```text 拖入文件 │ POST /materials multipart ▼ 流式 SHA-256 ── 同工作区查重 ──┬─ 命中:返回已有素材(dedup) └─ 未命中:写本地存储 + metadata │ ▼ 新建发布向导 │ POST /tasks(draft) │ submit → approve / reject → queued ``` ## 4. 任务执行 ```text queued │ dispatcher poll / immediate trigger ▼ dispatched → running ── WebExecutor/PlatformAdapter ──┬─ success ──> published URL + receipt ├─ challenge ──> Challenge Center / solve / resume ├─ cancel ──> context cancel + cancelled └─ failed ──> error category + retry ``` 排期任务在 `schedule_at` 到期前保持 `queued`;草稿/驳回任务可在排期日历通过 `PUT /tasks/:id` 设置或清除时间,已执行任务只读。 ## 5. 真实平台登录 ```text 网页点击“登录账号” │ ├─ POST /accounts/:id/bind ├─ PlatformAdapter.BeginLogin 生成唯一二维码 token/url ├─ 网页显示 QR;用户使用目标平台手机客户端扫码 ├─ worker 轮询 86101/86090/0 等平台状态 ├─ confirmed 后保存 workspace/account 隔离的加密凭据 └─ account.status = active / expired / suspended ``` ## 6. 凭据导入与检查 ```text 网页粘贴 Cookie │ POST /accounts/:id/credentials ├─ 适配器校验平台必需字段 ├─ AES-256-GCM Store.Save(workspaceID, accountID) └─ 只返回 active;Cookie 不进入响应/日志/WS 点击“检查” │ POST /accounts/:id/check ├─ adapter.CheckCredentials -> 平台 nav/profile 接口 ├─ 有效:active + lastActiveAt └─ 失效:expired + lastError ``` ## 7. 参考系统逻辑图:MediaPublishPlatform ```text Vue 页面 ├─ /uploadSave ───────> Flask 保存 videoFile + SQLite file_records ├─ /getAccounts ──────> SQLite user_info ├─ /login (SSE) ──────> Thread + Queue │ └─ Playwright 可视 Chrome 登录 │ └─ storage_state 写 cookiesFile ├─ /postVideo ────────> SQLite publish_task_records └─ /postVideos... ────> multiFileUploader └─ file → platform → account 串行尝试 └─ BaseFileUploader + platform_configs ``` ## 8. 参考系统逻辑图:social-auto-upload-web-ui ```text Vue/Element Plus ├─ /login (SSE) ──────> Flask blueprint / platform.login ├─ /importAccount ────> cookie parse → temp file → sync profile ├─ /postVideo ────────> task_id → background executor └─ /postVideo/status ─> memory/task status polling Registry └─ platform id → BasePlatform ├─ login ├─ check_cookie ├─ sync_profile └─ publish_video ``` ## 9. 参考逻辑到 EveryPublish 的映射 ```text 参考 SSE Queue -> Challenge 表 + Browser WS + REST 刷新 参考 SQLite task record -> Task + TaskEvent + workspace 条件 参考 storage_state cookie -> 服务器本机受保护 profile/credential store 参考 multi-account fallback -> Task adapter 的账号候选与错误分类 参考 platform_configs -> Go PlatformAdapter registry(每个平台独立测试) ```