Files

328 lines
17 KiB
Markdown
Raw Permalink Normal View History

# 常见问题排查
2026-07-07 14:21:30 +08:00
> 本文只记录可复用的本地排障步骤。T-538 后用户数据默认位于 `data/`,涉及 `data/config.json`、`data/config/ai_models.json`、`data/config/cmhub.json`、`data/cmshopee.db`、`data/chrome_user_data_dir/`、`data/images/` 时,默认它们是本机敏感或业务数据,必须保持 gitignore,不把真实密码、API Key、Cookie、token 写入文档、日志或提交。
2026-07-10 16:19:01 +08:00
## ④启动登录提示 Chrome 路径无效或找不到 Chrome
### 推荐修复
打开⑤“设置”,在“Chrome路径”右侧先点“自动检测”。检测到后会填入完整路径并提示结果,随后点“保存设置”。
如果没有检测到,不会清空当前输入内容。请点“选择...”手动选择本机的 `chrome.exe`;便携版、任意目录解压版或没有注册表记录的 Chrome 都需要这一步。不要选择 Edge、Chromium 或文件夹路径,本软件只使用 Google Chrome 保持各账号独立登录态。
### 检查顺序
1. 确认本机已安装 Google Chrome,并能手动打开。
2. 在⑤先点“自动检测”,再保存设置。
3. 仍失败时,点“选择...”定位 `chrome.exe`,再回④点击“启动登录”。
程序首次启动只会在当前路径为空或已失效时自动定位 Chrome;已经保存且有效的自定义路径不会被自动覆盖。
## 启动时报 “AI 模型 category 必须是 text 或 image”
### 现象
运行 `python main.py` / `python -m app` 启动 GUI 时,弹出或输出:
```text
AI 模型 category 必须是 text 或 image
```
### 原因
2026-07-07 14:21:30 +08:00
`data/config/ai_models.json` 是本地 AI 模型清单,里面每个模型都必须有合法的 `category`:
- `text`:标题生成模型,会出现在“标题大模型”下拉。
- `image`:封面生成模型,会出现在“图片大模型”下拉。
2026-07-07 14:21:30 +08:00
早期或手工维护过的 `data/config/ai_models.json` 可能缺少 `category`,或者填了中文、空值、旧字段,导致 `appconfig.load_ai_models_config()` 严格校验失败,GUI 启动被阻断。
### 不要这样做
2026-07-07 14:21:30 +08:00
- 不要删除 `data/config/ai_models.json` 来“重置”,否则会丢失本地明文 API Key 和模型配置。
- 不要把 `data/config/ai_models.json` 提交到 git。
- 不要把完整文件内容贴到聊天、文档或日志里;该文件含本地明文 API Key。
### 推荐修复
先只查看非敏感字段,确认哪些模型缺少 `category`:
```powershell
python -c "import json; p='data/config/ai_models.json'; data=json.load(open(p,encoding='utf-8')); [print({'index': i+1, 'name': m.get('name'), 'category': m.get('category'), 'api_type': m.get('api_type'), 'enabled': m.get('enabled'), 'has_api_key': bool(m.get('api_key'))}) for i,m in enumerate(data.get('models', []))]"
```
2026-07-07 14:21:30 +08:00
然后手工编辑 `data/config/ai_models.json`,只补这些字段:
```json
{
"name": "示例文本模型",
"category": "text",
"enabled": true
}
```
```json
{
"name": "示例图片模型",
"category": "image",
"enabled": true
}
```
如果要用脚本批量修复,只按模型名或 `api_type` 推断 `category`,并保留原有 `url`、`model`、`api_key`、`extra_body` 等字段。示例:
```powershell
python -c "import json; p='data/config/ai_models.json'; data=json.load(open(p,encoding='utf-8')); mapping={'你的文本模型名':'text','你的图片模型名':'image'}; changed=False
for m in data.get('models', []):
name=m.get('name')
if not m.get('category') and name in mapping:
m['category']=mapping[name]; changed=True
if m.get('enabled') is None:
m['enabled']=True; changed=True
open(p,'w',encoding='utf-8').write(json.dumps(data,ensure_ascii=False,indent=2)+'\n')
print('updated' if changed else 'unchanged')"
```
### 验证
验证时只输出模型名、类别、是否启用、是否存在 Key,不输出 Key 本身:
```powershell
python -c "import os,sys; sys.path.insert(0, os.getcwd()); from app import appconfig; print([(m['name'], m['category'], m['enabled'], m['api_key_set']) for m in appconfig.list_ai_models()])"
```
2026-07-07 14:21:30 +08:00
确认 `data/config/ai_models.json` 仍被忽略:
```powershell
git status --short --ignored data/config/ai_models.json
```
正常输出应包含:
```text
!! data/config/ai_models.json
```
最后重新启动:
```powershell
python main.py
```
## ⑤ 设置里测试连接提示 “HTTP 404”
### 现象
在⑤设置里填写文本大模型信息后,点击「测试连接」,结果显示:
```text
HTTP 404
```
### 原因
HTTP 404 表示服务端已响应,但当前请求 URL 路径不存在。旧代码会把「网址」字段原样作为 POST 地址;如果只填 OpenAI-compatible base URL,例如:
```text
https://api.vectorengine.ai/v1
```
程序会直接 POST 到 `/v1`,部分服务商会返回 404。当前代码已兼容 base URL:
- `api_type=chat` 或 `auto`:`/v1`、`/api/v1` 会自动补成 `/chat/completions`。
- `api_type=images_edits`:`/v1`、`/api/v1` 会自动补成 `/images/edits`。
- 已经填写完整 endpoint(如 `/v1/chat/completions`)时保持不变。
### 推荐修复
更新到包含该修复的代码后,保留当前配置即可;也可以手工把「网址」改成完整 endpoint:
```text
https://api.vectorengine.ai/v1/chat/completions
```
2026-07-07 14:21:30 +08:00
如果仍然 404,优先检查服务商文档要求的 endpoint 路径和 `api_type`,不要把 `data/config/ai_models.json` 或 API Key 贴到日志、文档或聊天里。
### 非敏感检查
只输出非密钥字段确认 URL 形态:
```powershell
python -c "import json; from urllib.parse import urlsplit,urlunsplit; p='data/config/ai_models.json'; data=json.load(open(p,encoding='utf-8')); [print({'name':m.get('name'),'category':m.get('category'),'api_type':m.get('api_type'),'url_without_query':urlunsplit((urlsplit(m.get('url','')).scheme,urlsplit(m.get('url','')).netloc,urlsplit(m.get('url','')).path,'','')),'has_api_key':bool(m.get('api_key'))}) for m in data.get('models', [])]"
```
## ⑤ cmhub「刷新别名 / 测试连接」提示 notfound / 404
### 现象
在⑤设置切到 cmhub 后端,手动填入 Base URL、API Key,点「刷新别名」或「测试连接」,提示 `notfound`(即 HTTP 404)。
### 原因
先明确:**cmshopee 的请求本身是达标的**——`GET {Base URL}/api/v1/models`,头 `Authorization: Bearer <key>`,与对接文档《cmhub-接口对接文档-桌面端生文生图》§4.4 和 cmhub 服务端路由 `path("v1/models", ModelsView)` 完全一致。404 表示服务端已响应但该路径不存在,原因在请求之外,通常是两类:
1. **Base URL 填了多余路径(手动填入最常见)**:Base URL 只能填**网关根**,例如 `https://cmhub.example.com`。T-530 后程序会在保存和请求前规整 Base URL,填成 `https://host/api/v1` 也会按 `https://host` 拼出 `https://host/api/v1/models`;仍建议只填网关根,便于人工排查。
2. **连的那台 cmhub 实例没有该路由**:`ModelsView` 在 cmhub 仓库代码里有,但**运行中的实例**若未重新部署/重启,`/api/v1/models`(较新接口)会 404,而 `/api/v1/balance`(较老接口)可能正常。
### 隔离方法(一条 curl 定位)
```bash
curl -i "https://<你的BaseURL>/api/v1/models" -H "Authorization: Bearer sk_cmhub_xxx"
curl -i "https://<你的BaseURL>/api/v1/balance" -H "Authorization: Bearer sk_cmhub_xxx"
```
- 两个都 404 → **Base URL 填错**,改成网关根(不带 `/api`、`/api/v1`)。
- balance 通、models 404 → **cmhub 实例未更新**,让部署方重启/重部署带上 `ModelsView`。
- models 通 → cmshopee 侧别的问题,回代码排查。
> 不要把 API Key 贴进日志、文档或聊天;curl 里的 `sk_cmhub_xxx` 是占位。
### 当前处理(T-530 后)
T-530 已实现:保存和请求前都会把 Base URL 规整为网关根,去掉多余路径、查询串和片段;HTTP 404 会映射为 `not_found`,显示“cmhub 接口不存在,请检查 Base URL 或该实例是否已部署 /api/v1/models”,不再透传 `notfound` 这类生涩原文。
## ②AI生成提示“当前筛选结果没有可生成任务”
### 现象
在②AI生成模块选中某个批次,列表里看到多条“失败”记录,点击「开始生成」后,状态栏提示:
```text
当前筛选结果没有待生成或生成失败可重试任务;请先在①导入采集完成旧数据采集
```
旧版本可能提示:
```text
当前筛选结果没有可生成任务
```
### 原因
②AI生成只能处理两类任务:
- 已完成①采集的待生成任务:底层通常是 `stage=collected`。
- AI 生成阶段失败、可以重试的任务:例如生成标题或生成封面失败。
如果列表里的“失败”其实是①采集失败,任务还停在 `stage=imported/status=failed`,没有旧标题和旧封面,②无法直接生成。2026-07-06 的实测问题就是这种情况:本地最新批次 5 条任务都是 `stage=imported/status=failed/collect_attempts>0/generate_attempts=0`,属于采集失败,不是 AI 生成失败。
如果失败来自③更新shopee,任务通常已有新标题/新封面,但这是更新阶段失败,也不应回到②自动重新生成。
### 当前处理
当前代码已把②AI生成列表的失败状态细分为:
- `采集失败`:需要先回①重新采集旧标题/旧封面。
- `生成失败`:可以在②当前筛选范围内再次点击「开始生成」重试。
- `更新失败`:应去③更新shopee重试或重置更新状态,不会被②误当成生成任务。
②「开始生成」使用统一的 `ai.is_generatable_task()` 判断可生成范围,GUI、Worker 和底层 `generate_batch()` 口径一致。
### 推荐处理
1. 如果②状态列显示“采集失败”:回到①导入采集,确认对应账号 Chrome 已启动且已登录,再重新采集旧标题/旧封面。
2. 如果②状态列显示“生成失败”:留在②,确认 cmhub Base URL、API Key、别名和点数正常后,直接点击「开始生成」重试当前筛选结果。
3. 如果②状态列显示“更新失败”:到③更新shopee处理;需要重复更新时使用③的重置更新状态入口,不要在②重新生成。
2026-07-07 14:21:30 +08:00
排查时不要把 `data/cmshopee.db`、`data/config/cmhub.json`、`data/config/ai_models.json` 或任何 API Key、密码、Cookie 发到聊天、文档或提交里。
## AI生成:标题成功但图片生成失败,且看不到原因
当前代码会为 ② AI生成写两层日志:
- 页面右下「AI生成运行日志」显示最近一次 `run_type=generate` 的逐条事件,例如 `phase=cover step=cover_request result=failed detail=...`。
- 本地 `data/logs/cmshopee.log` 保存脱敏后的 traceback、任务 id、alias、item_id、phase 和 step,用于判断卡在模型配置、封面请求、图片解析、保存文件还是写库。
2026-07-07 14:21:30 +08:00
排查顺序:先看 ② 页面运行日志里的 `phase` / `step` / `detail`;如果只看到简短错误,再查看本地 `data/logs/cmshopee.log`。不要把 `data/config/ai_models.json` 或 API Key 发到聊天、文档或提交里。
2026-07-06 15:01:50 +08:00
## ④启动登录重复打开 Chrome
现象:在④账号管理中选中同一个账号,第一次点击「启动登录」会打开该账号 Chrome;不关闭该 Chrome 的情况下再次点击「启动登录」,旧版本会再打开一个 Chrome 窗口,而不是复用已打开的账号窗口创建/激活 tab。
旧原因:原代码路径是 `AccountsTab.launch_login()` → `accounts.launch_for_login()` → `chrome.launch_chrome()` → `subprocess.Popen()`,每次点击都会直接启动进程;已有的 `chrome.is_running(debug_port)` 没有接入启动入口,`login_statuses[alias]="已启动"` 也只是界面状态,不会阻止下一次点击。
已修复:T-105b 已把④「启动登录」改成幂等流程。先检查该账号 `debug_port` 是否已有 CDP 响应;已响应时不再 `Popen`,而是复用现有 Chrome/CDP 并打开或激活 `https://<region_host>/portal/` 登录/卖家中心 tab;未响应时才新启动 Chrome。该修复不自动登录、不填密码、不绕过验证码,也不改变①/③预检“不自动启动 Chrome”的规则。
验证方式:同一账号第一次点击「启动登录」应显示“Chrome 已启动,请人工登录”;保持该账号 Chrome 不关闭,再点一次应显示“该账号 Chrome 已打开,已复用现有窗口”,且不会新增 Chrome 进程。
## 打包版窗口左上角显示不全,标题栏不可拖动
### 现象
2026-07-08 14:21:31 +08:00
在 Windows 10 虚拟机或小分辨率环境运行打包后的 `dist/cmshopee/cmshopee.exe` / `release/蝦皮圈優化助手<版本>.zip` 后,主窗口出现在屏幕左上角,左边和标题栏显示不全,看不到「蝦皮圈優化助手 v<版本>」标题,导致无法用鼠标拖动窗口到中间。
### 原因
2026-07-07 14:21:30 +08:00
修复前旧逻辑只设置了固定窗口大小:
```python
self.resize(1180, 760)
```
2026-07-07 14:21:30 +08:00
没有按当前屏幕可用区域做以下处理:
- 限制初始尺寸不超过屏幕可用区域。
- 居中显示。
- 保证窗口 frame/title bar 完整落在屏幕内。
因此在虚拟机、小分辨率、高 DPI、任务栏占用较多或多显示器切换环境下,Qt/Windows 默认放置窗口时可能让标题栏或左边缘落到屏幕外。PyInstaller 打包不是根因,只是打包版更常在目标虚拟机里暴露该问题。
### 临时处理
如果已经遇到窗口无法拖动:
1. 按 `Alt + Space`。
2. 按 `M` 选择移动。
3. 用方向键把窗口移回屏幕中间,再按回车。
也可以尝试 `Win + 方向键` 贴靠/恢复窗口,或先调高虚拟机分辨率。
### 当前修复(T-541 后)
T-541 已在主窗口启动时读取 `QApplication.primaryScreen().availableGeometry()`:
- 大屏保持接近 `1180x760`。
- 小屏自动缩小到可用区域内。
- `resize()` 后按可用区域居中 `move()`。
2026-07-07 14:21:30 +08:00
- 确保窗口 frame 左上角不小于可用区域左上角,标题栏完整可见、可拖动。
- 不保存坏的历史窗口坐标,避免下次继续打开到屏幕外。
修复后需要在普通桌面和 Windows 10 虚拟机/小分辨率环境各启动一次打包版,确认标题栏完整可见。
## ② cmhub 图片下载很慢(几十秒~几分钟),而 curl 只需几秒
### 现象
② 生图时,日志显示 `cmhub 已返回 image_url` 后,本地「下载完成」耗时几十秒甚至上百秒;用 curl 下载同一个 `image_url`(如 `http://<ip>:8080/generated/images/...png`)只需几秒。
### 原因
图片是从 cmhub 的**媒体服务**(常见形如 `http://<公网IP>:8080/...`,明文 HTTP、非标准端口)下载,与生成 API(HTTPS 域名)是不同端点。慢的常见根因两类:
1. **系统代理**(最常见):`requests` 默认读 `HTTP(S)_PROXY`/`ALL_PROXY` 环境变量,会把明文 HTTP 到 `:8080` 的下载塞进代理;慢/不支持非标端口的代理转发会让下载卡顿,而干净窗口的 curl 直连很快。
2. **并发争抢**:多图并发时,同步生成的长连接 + 并发下载挤同一主机,单条下载被拖慢(T-545 已限制生图/下载并发上限 5;T-546 已加共享连接池缓解)。
### 定位(一条命令区分代理 vs 并发)
```powershell
# curl 直连基准
curl -o NUL -w "curl %{time_total}s`n" "<image_url>"
# python 关掉代理直连
py -3.10 -c "import requests,time; s=requests.Session(); s.trust_env=False; t=time.time(); r=s.get('<image_url>'); print('no-proxy', len(r.content), round(time.time()-t,1),'s')"
```
若 `no-proxy` 明显变快 → 就是代理。
### 修复(T-546 后)
cmshopee 的 cmhub 请求默认**绕过系统代理**(`ai.cmhub.use_system_proxy` 默认 `false`),并用共享 `requests.Session` + 连接池减少握手/连接饥饿。
- 若你的机器**必须走代理**才能上网,编辑 `data/config.json` 把 `ai.cmhub.use_system_proxy` 改为 `true`(注意:慢代理仍可能拖累图片下载)。
- 若下载仍慢且 curl 也慢,则是 cmhub **媒体服务器本身慢**(如 Django 直接服媒体、单线程),属服务端问题,需在 cmhub 侧用 nginx/对象存储服 `/generated/images/`。
- 调试期可临时把 ⑤「图片并发数」设 1 复测单张,排除并发因素。
## 自动升级排障
- 强制升级窗口显示“该版本自动升级曾失败”:本机已经自动回滚过相同版本和zip hash,为避免循环不会再次自动安装。等待管理员发布修复包/更高版本,或退出后人工覆盖可信发布包;不要删除 `data/`。
- 升级后提示数据迁移冲突、数据目录不可写或Chrome配置错误:这是本地环境阻断,新版不会自动回滚。按原提示修复目录或Chrome配置后重新启动。
- 自动升级失败的本地记录位于安装目录 `.cmshopee-update/logs/`、`transactions/` 和 `failed-versions.json`。提供排障材料前先检查并脱敏;程序不会自动上传日志。
- 人工恢复时只覆盖 `cmshopee.exe`、`_internal/`、版本/说明/manifest和更新器,必须保留 `data/`。不要把 `.cmshopee-update/backup/` 当业务数据目录。