Files
sbnews/业务进度管理.md
T
2026-06-11 17:13:55 +08:00

850 lines
58 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 业务进度管理
> 本文档用于跟踪 Sport Era 项目所有功能模块的开发状态、待办事项与避坑记录。每完成一个功能或发现一个坑,及时在对应章节追加。
## 目录
- [一、已完成事项](#一已完成事项)
- [二、进行中事项](#二进行中事项)
- [三、待办事项](#三待办事项)
- [四、避坑记录](#四避坑记录)
---
## 一、已完成事项
### 45. AI助手请求失败提示补充真实错误
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 排查用户端显示“AI助手请求失败,请稍后重试。”,确认该文案来自 `ai_assistant.vue` 的前端 catch 兜底;测试服 `/api/assistant/chat` 直接请求当前可返回 `code=1`
- 补充 AI 助手前端错误解析,优先展示后端 `msg`、请求 `errMsg`、异常 `message`,并针对 timeout、abort、network/request:fail 给出更明确提示。
- catch 中增加 `[ai_assistant] chat failed` 控制台日志,便于后续复现时直接定位是网络层、请求取消、超时还是后端返回失败。
- 已复测测试服 AI 助手接口,最新消息入库模型为 `gpt-5.5`,确认当前服务端已走 OpenAI Responses 配置,不再走旧 `qwen3.7-plus` 链路。
- 已在测试服执行 `php think clear` 清理 runtime 缓存;当前 ThinkPHP 8.0.3 项目没有 `optimize:clear` 命令,后续清缓存使用 `clear`
- 继续排查 `{"code":0,"msg":"AI助手暂时不可用,请稍后再试"}`,确认原始失败原因是 `OpenAI: OpenAI 返回异常: Upstream rate limit exceeded, please retry later`,即上游中转限流。
- 后端失败返回改为输出脱敏后的模型原始错误,不再固定覆盖成“AI助手暂时不可用”;已同步测试服并复测失败路径,接口 `msg` 可直接返回上游限流原因。
- 已执行 `npm run build:h5`H5 构建通过并复制到 `server/public/mobile`
涉及模块:
- `server/app/common/service/ai/AiAssistantService.php`
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
- `server/public/mobile`
### 44. uniapp 启动缺失 sourcemap 修复
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 排查 H5 启动时报 `Failed to load source map ... index.js.map`,确认根因是 `vk-uview-ui` 内置 `async-validator.js` 尾部保留了 `//# sourceMappingURL=index.js.map`,但同目录没有对应 map 文件。
- 移除该第三方 vendored 文件的无效 sourcemap 注释,避免 Vite 启动或构建时继续读取不存在的 `index.js.map`
涉及模块:
- `uniapp/src/uni_modules/vk-uview-ui/libs/util/async-validator.js`
验证记录:
- 已执行 `npm run build:h5`H5 构建通过,日志中不再出现 `index.js.map` 缺失报错。
### 43. 项目 AI 统一切换 OpenAI Responses 配置
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 后端生成类 AI 统一改为通过 `DeepSeekClient::defaultModelOptions()` 读取项目 OpenAI 配置,默认模型 `gpt-5.5`、Base URL `https://lingsuan.top`、协议 `responses`
- `DeepSeekClient` 支持从 `server/.env``OPENAI_API_KEY / OPENAI_BASE_URL / OPENAI_MODEL / OPENAI_WIRE_API` 以及 `la_ai_config.openai_%` 读取配置,并默认关闭 Responses 存储。
- 帖子图片识别、彩票/赛事/资讯 RAG 分析和 AI 助手统一复用 OpenAI Responses 配置;AI 助手不再优先走 `qwen_%` 配置。
- 已向测试库 `la_ai_config` 写入 `openai_api_key``openai_base_url``openai_model``openai_wire_api``openai_provider_label``openai_reasoning_effort``openai_disable_response_storage` 配置项。
- 新增幂等 SQL `docs/sql/insert_openai_ai_config.sql`,用于初始化非密钥 OpenAI 配置;API Key 建议继续通过 `.env` 或后台配置维护。
涉及模块:
- `server/app/common/service/ai/DeepSeekClient.php`
- `server/app/common/service/ai/AiService.php`
- `server/app/common/service/ai/KbRagService.php`
- `server/app/common/service/ai/AiAssistantService.php`
- `docs/sql/insert_openai_ai_config.sql`
- `la_ai_config`
验证记录:
- 已执行 PHP 语法检查,相关 AI 服务文件均通过。
- 已查询测试库 `la_ai_config`,确认 `openai_%` 配置已写入且密钥只做脱敏检查。
### 42. 私聊语音输入与 Docker Whisper 转文字
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 私聊聊天室底部新增语音输入入口,App 端点击麦克风后可按住录音、松开发起识别;识别结果只填入文字输入框,由用户确认后再发送为普通文字消息。
- H5 端保留麦克风入口并降级提示“请在App中使用语音输入”,不尝试调用浏览器录音能力。
- 新增前台登录接口 `/api/chat/voiceToText`,接收单个音频文件并转发到本地 Docker Whisper ASR 服务,返回 `text``duration_ms`;支持开关、超时、Token、大小限制等 `whisper_asr_%` 配置。
- 新增 Docker Whisper ASR 服务目录,基于 FastAPI + `faster-whisper` 提供 `/health``/v1/transcribe`,默认仅绑定 `127.0.0.1:8791`,模型缓存使用 Docker volume。
- 关系文案统一优化为“对方还未添加你为好友”,并同步前端兜底展示。
- App 打包配置补充 Android 麦克风权限与 iOS 麦克风用途说明。
- 私聊聊天室底部输入栏补充对齐优化,麦克风、图片、输入框和发送按钮统一按同一中线排布,避免固定底栏控件高低错位。
- 私聊聊天室输入框改为固定高度,长文本在输入框内部滚动,避免内容继续撑开底部固定输入区。
- 私聊聊天室消息区补充头像和昵称展示:非本人消息左侧展示对方头像并在气泡上方展示对方昵称;本人消息右侧展示我的头像,不显示昵称。
- 私聊聊天室关系提示在当前用户未关注对方时追加蓝色下划线“添加好友”操作,点击后复用社区关注接口并更新本地关系状态。
- 私聊聊天室顶部仅显示对方头像和昵称,不再显示关系副标题;互关时聊天区不展示关系提示,单向关注时分别展示“对方未添加互关”或“对方已关注 + 添加互关”。
涉及模块:
- `server/app/api/controller/ChatController.php`
- `server/app/common/service/chat/WhisperAsrService.php`
- `server/app/common/service/chat/PrivateChatService.php`
- `server/app/adminapi/lists/ai/KbConfigLists.php`
- `server/extend/whisper-asr`
- `uniapp/src/api/chat.ts`
- `uniapp/src/pages/private_chat/room.vue`
- `uniapp/src/pages/private_chat/list.vue`
- `uniapp/src/manifest.json`
- `docs/sql/insert_whisper_asr_config.sql`
- `qa/backend/test_whisper_asr_service.php`
验证记录:
- 已执行 `php -l server/app/api/controller/ChatController.php`,语法检查通过。
- 已执行 `php -l server/app/common/service/chat/PrivateChatService.php`,语法检查通过。
- 已执行 `php -l server/app/common/service/chat/WhisperAsrService.php`,语法检查通过。
- 已执行 `php -l server/app/adminapi/lists/ai/KbConfigLists.php`,语法检查通过。
- 已执行 `php -l qa/backend/test_whisper_asr_service.php`,语法检查通过。
- 已执行 `php qa/backend/test_whisper_asr_service.php`,回归测试通过。
- 已执行 `C:\Python311\python.exe -m py_compile server/extend/whisper-asr/main.py`Python 语法检查通过。
- 已在 `server/.env` 指向的 `sbnews` 库重复执行 `docs/sql/insert_whisper_asr_config.sql`,确认 `whisper_asr_%` 5 个配置项均已写入且 SQL 可重复执行。
- 已执行 `npm run build:h5`H5 构建通过并复制到 `server/public/mobile`
- 当前本机未安装 Docker CLI`docker --version``docker compose config` 无法执行;需在服务器 Docker 环境执行 `server/extend/whisper-asr` 下的 `docker compose up -d --build` 后再验证 `/health``/v1/transcribe`
### 41. Docker 化爬虫调度与任务日志管理
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 新增懂球帝爬虫 Docker 运行方案,`docker/docker-compose.crawler.yml` 构建并启动独立 `sport-era-crawler` 容器,容器内通过 cron 调度 Python crawler。
- 新增 `server/public/dongqiudi-crawler/config/crawler_tasks.yaml`,迁移当前启用的 crawler 任务清单,包括赛程、实时详情、比赛收尾、资讯、文章补全、彩票开奖、世界杯和错误报告等动作。
- 新增 `scripts/docker_task_runner.py`,负责动作级文件锁、执行超时、子进程输出采集、运行中/成功/失败/跳过状态写入 `la_crawler_task_log`
- `src/core/config.py` 支持 `DQD_DB_*``DQD_REDIS_*``DQD_LOG_*` 环境变量覆盖,Docker 镜像不需要写死数据库和 Redis 密钥。
- 新增管理端只读菜单“爬虫任务日志”,接口为 `/adminapi/crawler.taskLog/lists``/adminapi/crawler.taskLog/detail`,支持按任务、动作、状态、来源筛选并查看输出详情。
- 旧 PHP `crontab` 与手动执行入口对 `crawler``truth_social``fifa_worldcup_news` 这类 Python crawler 命令不再启动本机 Python,统一提示已迁移到 Docker 容器调度,避免 Docker 与 PHP 双跑。
- 新增幂等 SQL `docs/sql/create_crawler_task_log.sql`:创建 `la_crawler_task_log`、注册菜单权限,并在 Docker 验证上线后停用旧 `la_dev_crontab` 中的 Python crawler 任务。
涉及模块:
- `server/public/dongqiudi-crawler`
- `server/app/adminapi/controller/crawler/TaskLogController.php`
- `server/app/adminapi/lists/crawler/TaskLogLists.php`
- `server/app/common/model/CrawlerTaskLog.php`
- `admin/src/views/crawler/task_log/index.vue`
- `docs/sql/create_crawler_task_log.sql`
验证记录:
- 已新增 Python 单元测试覆盖配置环境变量覆盖、cron 渲染、成功/失败/超时/重复任务跳过。
- 已在测试服执行 `docs/sql/create_crawler_task_log.sql`,确认 `la_crawler_task_log`、菜单权限写入成功,并将旧 `la_dev_crontab` 中 active Python crawler 任务停用。
- 已在测试服安装 Docker Compose v2,并通过单服务 `crawler` 启动 `sport-era-crawler`;容器只运行 Python crawler 与 cronMySQL、Redis、Nginx 均继续使用宿主机服务。
- 已确认 `DQD_DB_HOST/DQD_REDIS_HOST` 指向 `host.docker.internal`,容器内 `scrapling``browserforge` 依赖可正常导入。
- 已确认 `nba_match``live_detail``match_finish``article_content_fetch` 等任务持续写入 `la_crawler_task_log` 成功日志,旧 `la_dev_crontab_log` 不再新增 Python crawler 日志。
- 已复测 `/api/match/detail?id=3567442`,返回纽约尼克斯 107-106 圣安东尼奥马刺,状态为已结束。
### 40. 后端部署脚本目录权限兼容修复
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 排查 `scripts/deploy-server.ps1` 全量部署测试服时报 `tar: Cannot change mode ... Operation not permitted`,确认 SSH 用户 `ubuntu` 仅通过 `www` 组拥有目标目录写权限,并不是目录 owner,GNU tar 覆盖解包目录项时会尝试 `chmod` 已有目录导致失败。
- 远端安装 payload 改为优先使用 `rsync -r --links --no-perms --no-owner --no-group`,不保留 owner/group/perms;远端无 rsync 时回退为 `find + mkdir/cp/ln` 逐文件复制,避免对已有目录执行 chmod。
- 修复通过 `ssh bash -s` 下发远端 Bash 文本时可能写入 UTF-8 BOM 的问题,改为用 `UTF8 No BOM` 字节流写入 stdin,避免 `set -euo pipefail` 失效导致部署“假成功”。
- 保留当前全量部署包含整个 `public` 目录的变更,解决包含更多已有目录后触发的部署失败。
涉及模块:
- `scripts/deploy-server.ps1`
### 39. AI 分析 Responses 非 JSON 返回防护
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 修复 `/api/community/aiAnalysis` 在 GPT 中转 Responses API 返回空响应、HTML 或其他非 JSON 内容时,`DeepSeekClient::extractResponsesContent()` 因收到 `null` 触发 TypeError,导致前台显示“AI分析异常”的问题。
- `DeepSeekClient` 现在会先校验 `json_decode()` 结果是否为数组;非数组响应统一返回 `OpenAI(GPT中转) 返回异常: 响应不是有效JSON/响应JSON结构异常`,不再抛出 PHP fatal。
- `extractResponsesContent()` 增加 `null` 兜底,避免后续调用方再次把异常响应升级成类型错误。
- 新增 QA 回归脚本,覆盖 Responses 返回体解析遇到 `null` 的场景。
涉及模块:
- `server/app/common/service/ai/DeepSeekClient.php`
- `qa/backend/test_deepseek_client_invalid_response.php`
验证记录:
- 已执行 `php -l server/app/common/service/ai/DeepSeekClient.php`,语法检查通过。
- 已执行 `php -l qa/backend/test_deepseek_client_invalid_response.php`,语法检查通过。
- 已执行 `php qa/backend/test_deepseek_client_invalid_response.php`,回归测试通过。
- 使用测试账号请求测试服 `/api/community/aiAnalysis?post_id=5374&force=1` 时,测试服仍返回旧版 `extractResponsesContent(array $data)` 堆栈,说明测试服运行文件尚未同步或 OPcache 尚未刷新;待服务器同步最新 `DeepSeekClient.php` 后需复测。
### 38. NBA 实时比分爬虫与定时任务恢复
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 排查 `/pages/match_detail/match_detail?id=3567442` NBA 比赛比分不更新,确认前端详情页直接读取 `/api/match/detail``la_match` 数据,根因在测试服爬虫定时任务未持续写入实时比分。
- 修复懂球帝爬虫运行保护:`main.py` 新增动作级超时配置、跨进程动作锁、`writer.connect()` 连接超时、执行超时失败落日志,并将告警管理改为懒加载,避免导入阶段异常导致日志长期停留 `status=0`
- 修复 ThinkPHP 定时调度保护:`Crontab` 启动 crawler 前会按动作超时标记陈旧运行日志,并跳过超时时间内的重复 crawler 启动,避免 `nba_match` / `live_detail` / `match_finish` 堆积。
- 补齐 `crawler` 命令白名单,允许 `match_finish``live_detail` 通过统一 `php think crontab` 调度入口执行。
- 测试服重建并切换 `public/dongqiudi-crawler/venv`,旧环境备份为 `venv.bak-20260611041713`,修复 `aiohttp.http_writer.HttpVersion``pip._vendor.rich.protocol.is_renderable` 导入异常。
- 已修复目标比赛 `id=3567442 / match_id=54467991` 数据,接口返回纽约尼克斯 107-106 圣安东尼奥马刺,状态为已结束。
涉及模块:
- `server/public/dongqiudi-crawler/main.py`
- `server/public/dongqiudi-crawler/tests/test_runtime_guard.py`
- `server/app/common/command/Crontab.php`
- `server/app/common/command/CrawlerCommand.php`
- `la_match`
- `la_dev_crontab_log`
验证记录:
- 本地已覆盖爬虫动作锁与超时配置单元测试。
- 测试服 `main.py test``main.py nba_match``main.py live_detail` 均可正常完成。
- 测试服最近 `match_finish``nba_match``live_detail` 定时日志已恢复成功状态,相关任务当前无 `status=0` 遗留运行日志。
- `/api/match/detail?id=3567442` 已返回 `status=2``home_score=107``away_score=106`
### 37. 社区列表取消请求误报修复
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 复测测试服 `/api/community/postLists?page_no=1&page_size=15`,接口当前返回 `code=1`、本页 15 条、总数 5058,不是后端空响应。
- 排查社区列表页首屏生命周期与请求取消器交互:页面初始 `needRefresh=true` 时可能触发重复 `/community/postLists`,前一个请求被 `abort` 后网络面板显示无响应,页面 catch 又统一提示“加载失败,请重试”。
- `/packages_community/pages/index``/pages/empty` 初始刷新标记改为 `false`,首屏仅由 `onMounted` 拉取;新增请求序号保护,旧请求返回或取消时不覆盖最新列表状态。
- 两个页面对 `request:fail abort` 不再展示加载失败 toast,避免用户把主动取消的旧请求误判为接口失败。
- 同步补齐 `/packages_community/pages/index` 模板引用的分享弹窗状态与 `handleShare`,避免运行期未定义变量告警。
涉及模块:
- `uniapp/src/packages_community/pages/index.vue`
- `uniapp/src/pages/empty/empty.vue`
验证记录:
- 已执行 `npm run build:h5`H5 构建通过并复制到 `server/public/mobile`
- 已复测测试服 `/api/community/postLists?page_no=1&page_size=15` 返回 `code=1``lists=15``count=5058`
### 36. 用户主页底部间隔优化
- 状态:已完成 - 时间:2026-06-11
完成内容:
- `/packages_community/pages/user_profile` 移除 `scroll-view` 基于 `windowHeight` 的 JS 高度计算,改为页面根容器纵向 flex 布局。
- 内容区使用 `flex: 1; height: 0; min-height: 0` 自适应剩余空间,并补充底部安全区 padding,避免 Android/iOS 端底部出现灰色间隔。
- H5 移动视口截图抽样确认底部为白色;`npm run build:h5``npm run build:app` 均已通过。
涉及模块:
- `uniapp/src/packages_community/pages/user_profile.vue`
### 35. 帖子加好友与私聊 v1
- 状态:已完成 - 时间:2026-06-11
完成内容:
- “好友”复用社区关注关系 `la_community_follow`,帖子作者区、他人主页、我的关注/粉丝列表均新增“加好友/已好友”和“私聊”入口,不新增好友申请/同意流程。
- 新增前台私聊接口 `/api/chat/sessions``/api/chat/open``/api/chat/messages``/api/chat/send`,登录后可查看会话、打开会话、轮询消息和发送文字/图片消息。
- 新增私聊数据表初始化 SQL`docs/sql/create_private_chat_tables.sql`,包含 `la_private_chat_session``la_private_chat_message`SQL 使用 `CREATE TABLE IF NOT EXISTS` 保持幂等。
- 私聊会话和消息返回关系状态 `is_followed_by_me``is_following_me``is_mutual``relationship_text`;未互关时聊天页顶部和首屏提示展示“对方还未添加你为好友”。
- uni-app 新增 `src/api/chat.ts``/pages/private_chat/list` 会话列表、`/pages/private_chat/room` 聊天室,聊天室每 3 秒通过 `after_id` 轮询新消息,页面隐藏/卸载时停止轮询。
- 个人中心新增“私聊消息”入口,并展示 `chat_unread_count` 未读数;`/api/community/userStats` 同步返回私聊未读总数。
涉及模块:
- `server/app/api/controller/ChatController.php`
- `server/app/api/controller/CommunityController.php`
- `server/app/common/model/chat/PrivateChatSession.php`
- `server/app/common/model/chat/PrivateChatMessage.php`
- `server/app/common/service/chat/PrivateChatService.php`
- `uniapp/src/api/chat.ts`
- `uniapp/src/pages/private_chat/list.vue`
- `uniapp/src/pages/private_chat/room.vue`
- `uniapp/src/packages_community/pages/post_detail.vue`
- `uniapp/src/packages_community/pages/user_profile.vue`
- `uniapp/src/pages/my_follow/my_follow.vue`
- `uniapp/src/pages/user/user.vue`
- `docs/sql/create_private_chat_tables.sql`
- `qa/backend/test_private_chat_api.py`
验证记录:
- 已执行新增/修改 PHP 文件 `php -l`,语法检查通过。
- 已执行 `uniapp``npm run build:h5`H5 构建通过并复制到 `server/public/mobile`
- 已在 `server/.env` 指向的 `sbnews` 库重复执行 `docs/sql/create_private_chat_tables.sql`,确认 `la_private_chat_session``la_private_chat_message` 均已存在且 SQL 可重复执行。
- `qa/backend/test_private_chat_api.py` 已确认可由 `C:\Python311\python.exe` 启动;当前环境缺少 `PRIVATE_CHAT_TOKEN_A``PRIVATE_CHAT_TOKEN_B``PRIVATE_CHAT_TARGET_USER_ID`,未进入真实接口请求阶段。
### 34. AI 助手等待回复读秒
- 状态:已完成 - 时间:2026-06-11
完成内容:
- `/pages/ai_assistant/ai_assistant` 在助手 pending 气泡中新增“分析用时”读秒展示,发送消息后从 `0m0s` 开始逐秒更新。
- 接口成功或失败后停止计时并替换为正式回答或失败提示;完成后的历史消息不持久化本地计时字段。
- 页面卸载时清理计时器,避免切页后 interval 继续运行。
涉及模块:
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
### 33. AI 助手测试服接口 500/403 修复
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 测试服补执行 `docs/sql/create_ai_assistant_tables.sql`,创建 `la_ai_chat_session``la_ai_chat_message` 并写入 `assistant_%` 配置,修复 `/api/assistant/sessions` 因缺表导致的 500。
- `AiAssistantService` 的助手模型调用改为优先读取 `qwen_api_key` / `qwen_base_url` / `qwen_model`,并回退 `server/.env``DASHSCOPE_API_KEY`;未配置 Qwen 时才使用现有默认客户端。
- 前台助手失败时返回通用“暂时不可用”文案,真实下游错误继续写入 `la_ai_chat_message.error_msg`,便于后台排查。
涉及模块:
- `server/app/common/service/ai/AiAssistantService.php`
- `docs/sql/create_ai_assistant_tables.sql`
### 32. 世博头条 AI 助手 v1
- 状态:已完成 - 时间:2026-06-11
完成内容:
- 新增前台 `/api/assistant/chat``/api/assistant/sessions``/api/assistant/messages``/api/assistant/clear`,支持匿名 `client_id` 与登录用户两类会话隔离。
- 新增 AI 助手会话表与消息表初始化 SQL:`docs/sql/create_ai_assistant_tables.sql`,并追加 `assistant_%` 配置项。
- 新增 `AiAssistantService``AiAssistantContextService`,复用 GPT 中转客户端、`KbService::retrieve()`、AI 调用日志和 Redis 频控。
- 知识库召回覆盖资讯、社区、彩票,并扩展 `match:event` 赛事知识库文档生成;加密行情按币种实时查询 Binance ticker 后注入上下文。
- uni-app 新增 `/pages/ai_assistant/ai_assistant` 页面、`src/api/assistant.ts`、首页入口和个人中心入口,支持快捷问题、历史会话、引用来源跳转和匿名对话。
涉及模块:
- `server/app/api/controller/AssistantController.php`
- `server/app/common/service/ai/AiAssistantService.php`
- `server/app/common/service/ai/AiAssistantContextService.php`
- `server/app/common/service/ai/KbService.php`
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
- `uniapp/src/api/assistant.ts`
- `docs/sql/create_ai_assistant_tables.sql`
### 31. AI 生成与图片识别切换到 GPT 中转
- 状态:已完成 - 时间:2026-06-10
完成内容:
- `DeepSeekClient` 保留历史类名以兼容既有引用,但默认提供商已硬编码切换为 GPT 中转,base url 为 `https://sub2.congmingai.com`,默认模型 `gpt-5.5`
- 客户端新增 OpenAI Responses API wire 支持,请求路径自动拼接 `/v1/responses`,并兼容 `output_text``output[].content[].text` 两类返回结构。
- 社区帖子 RAG 最终生成从 Qwen 固定配置改为 GPT 中转,并显式传入 `wire_api=responses`
- 旧澳/新澳六合彩图片识别链路从 DashScope Qwen 改为 GPT 中转,图片仍会先转为 data URL 后提交,降低第三方图片 URL 被模型侧拒绝的概率。
- AI 日志模型 fallback 改为 `gpt-5.5`;知识库 Embedding 暂保留原有 embedding 配置,避免用生成模型替代向量模型导致召回不可用。
涉及模块:
- `server/app/common/service/ai/DeepSeekClient.php`
- `server/app/common/service/ai/KbRagService.php`
- `server/app/common/service/ai/AiService.php`
### 30. 帖子 AI 分析页展示原图并改为看图自由分析
- 状态:已完成 - 时间:2026-06-10
完成内容:
- `/pages/ai_analysis/ai_analysis` 在帖子 AI 分析场景新增原帖图片展示,读取 `/api/community/postDetail` 返回的 `images`,支持点击预览。
- 帖子分析结果新增 `图片解读``诗句字谜` 展示区,对应后端返回的 `image_interpretation``poem_analysis` 字段。
- 旧澳/新澳六合彩帖子分析改为只依据当前帖子文案与图片识别内容自由解读,不再要求依赖知识库证据,也不会把“知识库证据不足”作为主结论。
- 后端归一化阶段新增兜底过滤:新澳六合、旧澳六合帖子如果模型仍返回“知识库”相关表述,会替换为“仅依据当前图片和帖子文案解读”的口径。
- 后端新增 `analysis_source=image_free_v1` 缓存版本标记,并要求六合彩帖子缓存命中该标记,避免继续复用旧的知识库不足缓存。
- 图片内容识别仍保留理性风险提示,但允许围绕诗句、字谜、藏宝图、生肖、波色、尾数、胆码、旺弱号码等当前图片内容进行自由分析。
- 前端补充 AI 响应安全解包,避免请求异常或旧路由返回空数据时出现 `Cannot read properties of undefined (reading 'analysis')`
- `/api/community/aiAnalysis` 新增 `force=1` 支持;前端发现旧版缓存缺少 `analysis_source=image_free_v1` 时,会自动强制刷新并重新生成看图分析。
涉及模块:
- `server/app/common/service/ai/KbRagService.php`
- `server/app/common/service/ai/AiService.php`
- `server/app/api/controller/CommunityController.php`
- `uniapp/src/api/community.ts`
- `uniapp/src/pages/ai_analysis/ai_analysis.vue`
### 29. AI 分析长请求断线后轮询结果
- 状态:已完成 - 时间:2026-06-10
完成内容:
- 社区帖子 AI 分析新增 `/api/community/aiAnalysisResult` 只读结果接口,只查询 `la_ai_analysis` 成功缓存,不触发图片识别、知识库召回或 LLM 生成。
- `/pages/ai_analysis/ai_analysis` 帖子分析主请求如果遇到 `timeout / request:fail / abort`,不再立即退出失败态,而是继续 loading 并轮询缓存结果,最多等待约 `120` 秒。
- 轮询期间如果测试服尚未同步新接口或返回异常,会低频回退查询原 `/community/aiAnalysis`,优先命中已生成缓存,避免页面直接报“网络失败”。
- AI 请求前端超时从 `3` 分钟放宽到 `5` 分钟;`docs/sql/insert_qwen_ai_config.sql``ai_request_timeout` 默认值和更新语句同步改为 `300` 秒。
- 本地尝试直连测试库更新 `la_ai_config.ai_request_timeout=300` 时被 MySQL 拒绝访问,需在有数据库权限的环境执行对应 SQL 后才算线上配置完全生效。
涉及模块:
- `server/app/api/controller/CommunityController.php`
- `uniapp/src/api/aiRequest.ts`
- `uniapp/src/api/community.ts`
- `uniapp/src/pages/ai_analysis/ai_analysis.vue`
- `docs/sql/insert_qwen_ai_config.sql`
### 28. 社区帖子 AI 分析 request:fail 稳定性优化
- 状态:已完成 - 时间:2026-06-10
完成内容:
- 复测 `/api/community/aiAnalysis?post_id=5310`,测试服当前已稳定返回 `code=1` JSON,并命中帖子 AI 分析缓存,不再返回 ThinkPHP 500 HTML。
- 针对 uni-app 端长耗时 AI 请求补充 `ignoreCancel=true`,避免 `/community/aiAnalysis` 这类相同 URL 的长请求被全局请求取消器误 abort,前端表现为 `request:fail`
- AI 分析页补充 `abort` 与通用 `request:fail` 错误文案,用户侧不再直接暴露底层错误字符串。
- 已执行 `npm run build:h5` 验证通过;构建产物复制到 `server/public/mobile`
涉及模块:
- `uniapp/src/api/aiRequest.ts`
- `uniapp/src/pages/ai_analysis/ai_analysis.vue`
### 27. 全站 AI 默认提供商切换为 DashScope Qwen
- 状态:已完成 - 时间:2026-06-10
完成内容:
- OpenAI-compatible 聊天客户端默认提供商已从 `deepseek_*` 配置切换为 DashScope Qwen,默认模型 `qwen3.7-plus`,默认 base url 为 `https://dashscope.aliyuncs.com/compatible-mode`
- `DeepSeekClient` 保留历史类名以兼容服务器同步和既有引用,但内部默认提供商已改为 DashScope Qwen。
- `DASHSCOPE_API_KEY` 作为默认密钥来源;后台 `qwen_api_key` 留空时自动回退到 `.env`,避免密钥硬编码。
- 赛事分析、资讯分析、彩票分析、帖子分析、用户可信度分析、文章评论生成等所有默认 LLM 生成链路现在统一走 Qwen;帖子图片识别原本已走 Qwen,保持一致。
- 知识库 Embedding 默认也切换为 DashScope compatible 接口,默认模型 `text-embedding-v4`、默认维度 `1024`,避免向量召回因 `embedding_*` 未配置而退化。
- 后台知识库配置列表已放开 `qwen_%` 配置项,并新增幂等 SQL `docs/sql/insert_qwen_ai_config.sql`;当前测试库已执行该 SQL。
涉及模块:
- `server/app/common/service/ai/DeepSeekClient.php`
- `server/app/common/service/ai/EmbeddingClient.php`
- `server/app/common/service/ai/AiService.php`
- `server/app/adminapi/lists/ai/KbConfigLists.php`
- `docs/sql/insert_qwen_ai_config.sql`
### 26. AI 分析页长耗时请求超时优化
- 状态:已完成 - 时间:2026-06-10
完成内容:
- `/pages/ai_analysis/ai_analysis` 使用的赛事分段分析、资讯分析和帖子分析请求已改为 AI 专属 3 分钟超时,不再受全局普通接口 `60s` 超时限制。
- 长耗时 AI GET 请求已禁用自动超时重试,避免一次模型分析尚未返回时又重复触发新的 LLM/RAG 请求。
- 请求封装已修复“禁用重试后 timeout 错误丢失”的问题,超时会继续把原始错误交给页面处理。
- AI 分析页补充字符串错误和 `errMsg` 兼容,超时时显示更明确的“耗时较长/稍后重试”提示;加载超过 60 秒时会提示正在结合知识库与模型继续推理。
- 同步给彩票 AI 分析类接口套用相同长超时策略,减少后续彩票模块 AI 请求被前端提前截断。
- 后端 OpenAI-compatible 模型客户端的固定 `60s` cURL 超时已改为可配置 `ai_request_timeout`,默认 `180s`,并增加连接超时,避免前端已延长但后端先断开。
涉及模块:
- `server/app/common/service/ai/DeepSeekClient.php`
- `uniapp/src/api/aiRequest.ts`
- `uniapp/src/api/ai.ts`
- `uniapp/src/api/community.ts`
- `uniapp/src/api/lottery.ts`
- `uniapp/src/pages/ai_analysis/ai_analysis.vue`
- `uniapp/src/utils/request/http.ts`
### 25. 社区帖子 RAG 生成模型切换到 Qwen3.7
- 状态:已完成 - 时间:2026-06-10
完成内容:
- 排查 `/api/community/aiAnalysis` 仍返回 `DeepSeek 返回异常: Insufficient Balance` 的原因,确认图片识别已走 DashScope Qwen,但帖子 RAG 最终 JSON 生成仍复用默认 DeepSeek 配置。
- 已将 `KbRagService::analyzePost()` 的最终生成阶段改为 DashScope OpenAI 兼容接口,模型固定为 `qwen3.7-plus`,使用 `server/.env``DASHSCOPE_API_KEY`
- `DeepSeekClient` 作为 OpenAI 兼容 HTTP 客户端保留,但现在会按调用方传入的 `provider_label` 返回错误提示;帖子分析失败时将显示 `DashScope(Qwen)`,不再误导为 DeepSeek。
- `AiService::saveResult()` 已改为记录下游返回的真实模型名,帖子 AI 日志会写入 `qwen3.7-plus`
涉及模块:
- `server/app/common/service/ai/KbRagService.php`
- `server/app/common/service/ai/DeepSeekClient.php`
- `server/app/common/service/ai/AiService.php`
### 24. 社区帖子 AI 分析改为统一分析页并显示分析计时
- 状态:已完成 - 时间:2026-06-10
完成内容:
- 社区列表页与首页社区流中的六合彩帖子 `AI分析` 入口已改为直接跳转统一分析页 `/pages/ai_analysis/ai_analysis?type=post&id=...`,不再先进帖子详情页再等待页内分析。
- 帖子详情页中的 `AI分析` 按钮也已切换为直接跳统一分析页;旧的 `show_ai=1` 链路改为兼容重定向,避免历史入口失效。
- 统一分析页已新增 `post` 类型支持,接入 `/api/community/aiAnalysis`,并展示帖子卡片、综合结论、下期预测、可信线索、风险提示、相似历史和知识库证据。
- AI 分析加载阶段新增“分析用时 `0m1s`”计时显示;赛事分段分析的后续阶段 loading 也会继续显示累计分析时长,避免长耗时场景下用户无感等待。
涉及模块:
- `uniapp/src/pages/ai_analysis/ai_analysis.vue`
- `uniapp/src/packages_community/pages/post_detail.vue`
- `uniapp/src/packages_community/pages/index.vue`
- `uniapp/src/pages/empty/empty.vue`
### 23. 六合图片分析升级到 Qwen3.7 并移除代码内密钥
- 状态:已完成 - 时间:2026-06-10
完成内容:
- `AiService::analyzeLotteryPostImages()` 已将 DashScope 视觉模型从旧版 `qwen-vl-max-latest` 切换为新版统一多模态模型 `qwen3.7-plus`,继续沿用 OpenAI 兼容接口 `https://dashscope.aliyuncs.com/compatible-mode`
- 移除了 `AiService` 中硬编码的 DashScope API Key,改为统一从 `server/.env``DASHSCOPE_API_KEY` 读取,避免密钥继续直接写入代码文件。
- 同步补充 `server/.example.env` 的 DashScope Key 占位配置,便于后续环境初始化和部署时对齐。
涉及模块:
- `server/app/common/service/ai/AiService.php`
- `server/.env`
- `server/.example.env`
### 22. 六合图片分析 404 链路修复
- 状态:已完成 - 时间:2026-06-09
完成内容:
- 排查 `/api/community/translatePost``旧澳六合/新澳六合` 图片分析分支返回 `HTTP 404` 的问题,确认不是帖子不存在,而是 Qwen 视觉模型请求地址被拼成了 `.../v1/v1/chat/completions`
- 已将 `AiService` 中 DashScope 兼容接口基地址收敛为 `https://dashscope.aliyuncs.com/compatible-mode`,并在 `DeepSeekClient` 中补充聊天接口地址规范化,兼容 `base_url` 传入根地址、`/v1` 地址或完整 `/chat/completions` 地址,避免后续再次重复拼接。
- 同步把多模型错误提示统一改为带 provider 名称返回,后续如果 DashScope/Qwen 鉴权或模型权限异常,接口会更容易直接看出来自哪个下游。
涉及模块:
- `server/app/common/service/ai/AiService.php`
- `server/app/common/service/ai/DeepSeekClient.php`
### 21. 六合图片分析切换到 DashScope Qwen 视觉模型
- 状态:已完成 - 时间:2026-06-09
完成内容:
- `AiService::analyzeLotteryPostImages()` 已按当前需求固定改为调用阿里云 DashScope OpenAI 兼容接口,不再读取后台 `lottery_image_analysis_*``deepseek_vision_model` 配置。
- 当前六合彩图片分析分支硬编码使用 `Qwen` 视觉模型 `qwen-vl-max-latest`,兼容接口基地址统一为 `https://dashscope.aliyuncs.com/compatible-mode`,由客户端自动补齐聊天接口路径,并使用指定的 DashScope API Key。
- 错误提示中的 provider 标识已改为 `DashScope(Qwen)`,方便后续定位图片分析失败是否来自 Qwen 视觉链路。
- 同步收紧图片分析提示词,新增“先过滤噪音再逐项分析”的规则,只保留当期号码、图表结论、推荐组合等有效信息,忽略水印、口号、装饰边框、重复标题和低置信度杂讯。
涉及模块:
- `server/app/common/service/ai/AiService.php`
### 20. 六合帖子 `translatePost` 收紧为纯图片分析
- 状态:已完成 - 时间:2026-06-09
完成内容:
- `/api/community/translatePost``新澳六合 / 旧澳六合` 已改为只走当前帖子图片分析,不再接受旧版六合彩分析缓存直接命中。
- 新增 `lottery_analysis_source=image_only``lottery_analysis_images_hash` 标记,只有明确由当前帖子图片生成的分析结果才会复用;旧缓存或图片已变更时会重新按图片分析。
- 移除了六合彩图片分析失败时写入“虚拟历史分析文案”的兜底逻辑,当前图片无法识别时接口会直接返回失败,避免返回看似真实、实则并非基于当前图片的内容。
- 同步收紧图片分析提示词,明确禁止引用往期内容、历史期数、知识库信息或模型记忆;社区列表侧也只展示 `image_only` 来源的六合彩分析结果。
涉及模块:
- `server/app/api/controller/CommunityController.php`
- `server/app/api/lists/community/CommunityPostLists.php`
- `server/app/common/service/ai/AiService.php`
### 19. 社区帖子分支链路收紧为“普通/特朗普/六合”三类
- 状态:已完成 - 时间:2026-06-09
完成内容:
- 重新梳理社区帖子链路后,已将普通帖子、特朗普帖子、`新澳六合/旧澳六合` 帖子的入口分支彻底拆开:普通帖子不再显示或触发 AI 分析;特朗普帖子只保留本地 `MTranServer` 翻译链路;六合帖子才显示 AI 入口。
- `post-card``/pages/empty/empty`、社区分包列表页、帖子详情页已统一按 `旧澳六合/新澳六合` 标签控制 `AI` 按钮和 `show_ai=1` 跳转,避免普通帖误入 `/api/community/aiAnalysis`
- 后端 `CommunityController::aiAnalysis()` 已改为只接受六合帖,并在进入知识库分析前先确保 `lottery_analysis_content` 已由视觉模型完成图片识别;`translatePost()` 的彩票图片分析分支也同步从泛 `彩票` 收紧为 `a6/xa6`
- `KbRagService::analyzePost()``AiService::analyzePost()` 已补强:当前帖子本身只要识别为 `a6/xa6` 就稳定输出 `next_prediction`,并跳过缺少预测字段的旧缓存,避免仍回落到历史错误结果。
涉及模块:
- `uniapp/src/pages/empty/empty.vue`
- `uniapp/src/packages_community/pages/index.vue`
- `uniapp/src/packages_community/components/post-card.vue`
- `uniapp/src/packages_community/pages/post_detail.vue`
- `server/app/api/controller/CommunityController.php`
- `server/app/api/lists/community/CommunityPostLists.php`
- `server/app/common/service/ai/AiService.php`
- `server/app/common/service/ai/KbRagService.php`
### 18. 世界杯资讯与特朗普帖子翻译切换 GPT-4o
- 状态:已完成 - 时间:2026-06-09
完成内容:
- 世界杯资讯翻译链路已改为按文章分类识别:当资讯属于“世界杯”分类时,`ArticleLogic::translate()``autoTranslateArticle()` 会优先走 `GPT-4o` 翻译,不影响其他资讯仍沿用原有翻译模型。
- 特朗普帖子翻译链路已改为按帖子标签识别:社区列表自动预热、帖子详情自动补翻译、`/api/community/translatePost` 手动翻译这 3 条路径,命中“特朗普”标签时统一走 `GPT-4o`
- 在 AI 配置层新增 `openai_api_key / openai_base_url / openai_translation_model` 约定,并补充幂等 SQL `docs/sql/insert_ai_translation_gpt4o_config.sql`;后台知识库配置列表已放开 `openai_%` 配置项,便于直接维护 `GPT-4o` 翻译参数。
- 同步把 OpenAI 兼容翻译调用的错误文案改成按 provider 显示,避免 `GPT-4o` 未配置时仍提示成 `DeepSeek API Key未配置`
涉及模块:
- `server/app/common/service/ai/DeepSeekClient.php`
- `server/app/common/service/ai/AiService.php`
- `server/app/api/logic/ArticleLogic.php`
- `server/app/api/controller/CommunityController.php`
- `server/app/api/lists/community/CommunityPostLists.php`
- `server/app/adminapi/lists/ai/KbConfigLists.php`
- `docs/sql/insert_ai_translation_gpt4o_config.sql`
### 17. 定时任务企业微信告警接入
- 状态:已完成 - 时间:2026-06-08
完成内容:
- 为 crawler 本地配置增加 `alert.dispatch_enabled / alert.wecom_webhook / alert.cooldown_seconds`,企业微信告警改走固定群机器人 Webhook,本地维护,不做后台配置页。
- 新增统一告警表 `la_crontab_alert`,并在 Python `Database` 与 PHP `CrontabAlertService` 中同时补上建表与读写逻辑,支持告警创建、30 分钟冷却、成功恢复后自动关闭。
- `main.py` 已增加 `TASK_ALERT_POLICY` 与标准化运行摘要;已启用的 `crawler` 任务按“采集型 saved_required / 维护型 saved_if_candidates / error_report 跳过自告警”规则统一落库告警。
- `ErrorCollector` 已扩展为记录单次运行的 `404 / 5xx / 网络异常` 统计;`error_report` 任务已改为读取 `la_crontab_alert` 并尝试分发企业微信消息。
-`crawler` 的 PHP 定时任务(如 `sms_verify``worldcup_article_translate`)已通过 `Crontab.php` 接入同一张告警表,仅在执行异常时产生 `command_exception` 告警。
- 已新增幂等 SQL `server/public/dongqiudi-crawler/update_crontab_error_report.sql`,并已把测试服现有 `error_report` 任务频率从 `*/5 * * * *` 调整为 `*/1 * * * *`
涉及模块:
- `server/public/dongqiudi-crawler/config/settings.yaml`
- `server/public/dongqiudi-crawler/main.py`
- `server/public/dongqiudi-crawler/src/core/error_collector.py`
- `server/public/dongqiudi-crawler/src/core/alert_manager.py`
- `server/public/dongqiudi-crawler/src/storage/database.py`
- `server/public/dongqiudi-crawler/src/scheduler/task_runner.py`
- `server/app/common/command/Crontab.php`
- `server/app/common/service/crontab/CrontabAlertService.php`
- `server/public/dongqiudi-crawler/update_crontab_error_report.sql`
### 16. 资讯无正文默认稿子并禁止发布
- 状态:已完成 - 时间:2026-06-07
完成内容:
- 为爬虫侧新增 `article_publish_helper.py`,统一判断资讯正文是否达到可发布标准;没有拉到正文、只有 RSS 摘要或占位文本的文章,采集入库时默认写成稿子状态(`is_show=0`)。
- `article_fetcher.py` 已调整为优先处理稿子状态或正文明显不足的资讯;抓到真实正文后会自动写回 `content`,同时将文章切回发布状态并重置 `content_retry`
- `nba_news.py``cba_news.py``crypto_news.py``lottery_news.py``hkjc_lottery_news.py``taiwan_lottery_news.py``fifa_worldcup_news.py` 已统一接入该规则,避免后续新采文章在正文未完成时直接暴露到前台。
- 后台 `ArticleLogic` / `ArticleController` 已增加发布拦截:手动新增、编辑或切换状态时,如果正文未达到发布标准,会直接返回“暂不能发布,请先保存为稿子”。
- 已在测试服先行回退当前可见的 NBA / CBA 占位稿:示例 `1903906``1915226` 的公开详情现已返回空数据,不再继续对前台暴露无正文资讯。
涉及模块:
- `server/public/dongqiudi-crawler/article_publish_helper.py`
- `server/public/dongqiudi-crawler/article_fetcher.py`
- `server/public/dongqiudi-crawler/nba_news.py`
- `server/public/dongqiudi-crawler/cba_news.py`
- `server/public/dongqiudi-crawler/crypto_news.py`
- `server/public/dongqiudi-crawler/lottery_news.py`
- `server/public/dongqiudi-crawler/hkjc_lottery_news.py`
- `server/public/dongqiudi-crawler/taiwan_lottery_news.py`
- `server/public/dongqiudi-crawler/fifa_worldcup_news.py`
- `server/app/common/model/article/Article.php`
- `server/app/adminapi/logic/article/ArticleLogic.php`
- `server/app/adminapi/controller/article/ArticleController.php`
### 15. NBA / CBA 资讯正文抓取补回退链路
- 状态:已完成 - 时间:2026-06-07
完成内容:
- 继续排查发现,NBA / CBA 资讯列表入库后,详情正文并不是完全没跑,而是由 `article_content_fetch` 每轮按分类各抓 `3` 条慢慢补;因此刚采集完的一大批文章会先以 RSS 摘要占位,随后逐轮补正文。
- 测试服执行日志确认 `article_content_fetch` 一直在跑,但部分 Google News 解码后的真实地址(如 `m.sohu.com``sports.sina.cn``sports.cctv.com`)在 `scrapling Fetcher` 路径下会返回 `HTTP 403`,导致正文抓取失败并累计 `content_retry`
- 已为 `server/public/dongqiudi-crawler/article_fetcher.py` 增加 `requests + BeautifulSoup` 回退抓取链路:当 `scrapling` 返回 `403` 或抛异常时,改用普通请求抓页面并复用同一套正文抽取规则,降低这类站点的正文缺失率。
- 同步补充 `server/public/dongqiudi-crawler/requirements.txt``beautifulsoup4` 依赖声明,避免后续环境重装时漏掉回退解析库。
涉及模块:
- `server/public/dongqiudi-crawler/article_fetcher.py`
- `server/public/dongqiudi-crawler/requirements.txt`
### 14. NBA / CBA 资讯定时任务补注册与恢复拉取
- 状态:已完成 - 时间:2026-06-07
完成内容:
- 排查发现 `server/public/dongqiudi-crawler/main.py``nba_news.py``cba_news.py` 代码入口都已存在,`article_content_fetch` 也已覆盖 `cid=17/18` 的正文补全,但测试服 `la_dev_crontab` 中缺少 `nba_news``cba_news` 两个定时任务,所以后台从未自动触发 NBA / CBA 资讯采集。
- 已补充幂等 SQL `insert_crontab_nba_news.sql``insert_crontab_cba_news.sql`,分别注册 `crawler nba_news``crawler cba_news`
- 已在测试服后台实际创建两条任务,当前执行规则分别为 `10 * * * *`NBA)和 `20 * * * *`CBA),状态均为“运行”。
- 已手动验证一次:NBA 任务成功抓取 100 条,新增 99 条;CBA 任务成功抓取 169 条,新增 152 条。
- 已继续验证正文抓取链路:`article_content_fetch` 在 2026-06-07 00:50 自动处理了新入库的 NBA / CBA 文章,成功补全 4 篇正文;另有 2 篇源站返回 HTTP 403,已按现有 `content_retry` 机制记录重试。
涉及模块:
- `server/public/dongqiudi-crawler/main.py`
- `server/public/dongqiudi-crawler/nba_news.py`
- `server/public/dongqiudi-crawler/cba_news.py`
- `server/public/dongqiudi-crawler/article_fetcher.py`
- `server/public/dongqiudi-crawler/insert_crontab_nba_news.sql`
- `server/public/dongqiudi-crawler/insert_crontab_cba_news.sql`
### 13. 赛事 AI 分段分析接入知识库召回
- 状态:已完成 - 时间:2026-06-06
完成内容:
- 排查发现 `/api/ai/matchPredictSection` 原链路只会组装 `match_info / head_to_head / home_recent / away_recent` 后直接调用 `DeepSeekClient::chatJson()`,并不会进入知识库检索层。
- 现已为赛事分析补充 `KbRagService::analyzeMatch()``analyzeMatchSection()`,先根据主队、客队、联赛名到知识库中召回相关资讯/帖子,再把召回证据与结构化交手记录、近期战绩、赔率一起交给 LLM。
- `AiService::predictMatch()``predictMatchSection()` 已切换到赛事专用 RAG 链路,返回结果增加 `evidence_list / similar_history / from_kb / retrieval_meta` 等知识库增强字段。
- 为避免旧的赛事分段缓存继续短路新链路,当前逻辑只接受带知识库字段痕迹的新缓存;老缓存会自动跳过并重新走 RAG 生成。
- 当前赛事 RAG 仍未把 `match_event / match_history / match_recent` 建成独立知识库 domain,交手记录和近期战绩继续直接从业务表读取;知识库侧主要召回相关资讯与帖子。
涉及模块:
- `server/app/common/service/ai/AiService.php`
- `server/app/common/service/ai/KbRagService.php`
- `server/app/common/service/ai/KbService.php`
- `server/app/api/controller/AiController.php`
### 12. 全站 AI 知识库与 RAG 分析底座
- 状态:已完成 - 时间:2026-06-06
完成内容:
- 新增 AI 知识库底座表设计与 SQL:`la_ai_kb_document``la_ai_kb_chunk``la_ai_kb_sync_job``la_ai_kb_query_log`,并补充知识库菜单与 Embedding / KB 配置初始化 SQL。
- 后端新增 `KbService / KbSyncService / EmbeddingClient / KbRagService`,支持资讯、帖子、彩票历史内容统一建档、切片、Embedding、全文候选、向量重排、规则混排和查询日志记录。
- 新增控制台命令 `php think kb:rebuild``php think kb:consume`,支持全量回填与增量消费;文章新增/编辑/上下架、帖子发布/删除/翻译缓存更新已接入同步任务队列,彩票历史通过消费命令补录扫描。
- 现有 `AiService` 已接入知识库增强分析:资讯分析、彩票总分析、彩票分模块分析统一增加 `from_kb / evidence_list / similar_history / retrieval_meta`;新增帖子专属接口 `GET /api/community/aiAnalysis?post_id={id}`
- 管理后台新增知识库配置、知识文档、同步任务、查询日志页面与对应 API,且扩展了 AI 分析记录 / AI 日志类型展示。
- 新增 `qa/backend/test_kb_article_analysis.py``qa/backend/test_kb_post_analysis.py` 作为知识库增强接口的最小冒烟脚本。
涉及模块:
- `server/app/common/model/ai/*`
- `server/app/common/service/ai/*`
- `server/app/common/command/KbRebuild.php`
- `server/app/common/command/KbConsume.php`
- `server/app/api/controller/CommunityController.php`
- `server/app/common/service/ai/AiService.php`
- `server/app/adminapi/controller/ai/*`
- `admin/src/views/ai/*`
- `docs/sql/create_ai_kb_tables.sql`
- `docs/sql/insert_ai_kb_config.sql`
- `docs/sql/insert_menu_ai_kb.sql`
- `qa/backend/test_kb_article_analysis.py`
- `qa/backend/test_kb_post_analysis.py`
### 11. 彩票资讯远程图片代理中转
- 状态:已完成 - 时间:2026-06-03
完成内容:
- 为前台资讯接口补充 `ArticleImageProxyService`,对白名单内的香港赛马会与台湾彩券远程图片生成站内代理地址。
- 新增公开接口 `/api/article/imageProxy`,由服务器代拉 `res.hkjc.com``cdn.taiwanlottery.com.tw` 等远程图片并回传,规避国内客户端无法直连的问题。
- `ArticleLogic::detail()``ArticleLists::lists()` 已统一接入代理改写,老文章无需重采即可让详情正文图片和列表封面图走服务器中转。
- 代理按 `ext.source` 白名单控制,仅对 `hkjc_racingnews``taiwan_lottery` 两类彩票资讯生效,降低 SSRF 风险。
涉及模块:
- `server/app/common/service/article/ArticleImageProxyService.php`
- `server/app/api/controller/ArticleController.php`
- `server/app/api/logic/ArticleLogic.php`
- `server/app/api/lists/article/ArticleLists.php`
### 1. 项目基础文档与协作协议
- 状态:已完成 - 时间:2026-05-07
完成内容:
- 创建根目录 `AGENTS.md`,记录项目技术栈、子模块分工、数据库基准与协作规范。
- 创建 `server/AGENTS.md``admin/AGENTS.md``uniapp/AGENTS.md``pc/AGENTS.md``qa/AGENTS.md`
- 创建 `业务进度管理.md``设计稿映射.md`,作为后续进度与设计稿映射维护入口。
涉及模块:
- `AGENTS.md`
- `server/AGENTS.md`
- `admin/AGENTS.md`
- `uniapp/AGENTS.md`
- `pc/AGENTS.md`
- `qa/AGENTS.md`
- `业务进度管理.md`
- `设计稿映射.md`
### 2. 新闻爬虫文章入库去重
- 状态:已完成 - 时间:2026-05-09
完成内容:
- 在懂球帝爬虫公共入库方法 `upsert_articles` 中增加同分类标题去重,阻止不同 `article_id` 的同标题文章重复写入。
- 新闻和视频采集任务按已知频道传入对应文章分类 `cid`,减少新增 `cid=0` 数据。
- 对已存在 `article_id` 且旧分类为 `cid=0` 的数据,后续带正确分类再次入库时可迁移到正确分类。
涉及模块:
- `server/public/dongqiudi-crawler/src/storage/database.py`
- `server/public/dongqiudi-crawler/src/scheduler/task_runner.py`
### 3. Truth Social 定时任务入口整理
- 状态:已完成 - 时间:2026-05-09
完成内容:
- 后台定时任务 `truth_social` 改为执行 `public/dongqiudi-crawler/main.py truth_social`
- 移除旧的 `server/public/truth-social` 独立采集目录,避免继续维护两套特朗普消息采集代码。
涉及模块:
- `server/app/adminapi/logic/crontab/CrontabLogic.php`
- `server/public/dongqiudi-crawler/truth_social.py`
### 4. 49宝典彩票社区爬虫接入
- 状态:已完成 - 时间:2026-05-11
完成内容:
- 新增 `lottery_community` 爬虫入口,拉取 49宝典首页 Astro props 数据并解析开奖与图库资料。
- 自动创建或复用社区标签 `彩票`,自动创建或复用发布用户 `lottery_publisher`
-`origin_id` 对彩票社区帖子做幂等新增/更新,并同步帖子图片和标签关联。
- 接入 ThinkPHP `crawler` 命令白名单和 Python 主入口命令映射。
- 提供幂等 SQL 注册定时任务 `crawler lottery_community`
- 修复 49宝典响应中文解码和图库图片域名规则,`prod/` 图片资源改用可直接访问的 `tk2cdn-ali.tprswe.com`
涉及模块:
- `server/public/dongqiudi-crawler/lottery_community.py`
### 10. 彩票 AI 趋势分析坏缓存容错
- 状态:已完成 - 时间:2026-06-03
完成内容:
- 排查 `/api/lottery/aiTrend?code=XOMLHC` 时发现,当前问题不是彩种不存在,也不是当前 DeepSeek key 鉴权失败,而是命中了 `la_ai_analysis` 中一条 `type=4` 的成功缓存,但该缓存 `result` 实际是 JSON 字符串 `\"\"``json_decode(..., true)` 后得到的是字符串而不是数组。
- `server/app/common/service/ai/AiService.php``analyzeLotteryModule()` 已补充防守:彩票 AI 模块缓存只有在解码后为非空数组时才视为有效;若模型返回的 `parsed` 不是数组或为空,也不再写入“成功缓存”,而是按格式异常处理。
- 这样可以避免旧的坏缓存继续让 `LotteryController::aiTrend()``aiHotCold()``aiStats()``aiColorZodiac()` 走到 `$this->data(string)` 并触发类型错误。
涉及模块:
- `server/app/common/service/ai/AiService.php`
### 9. 世界杯资讯翻译预热限制为列表前 50 条
- 状态:已完成 - 时间:2026-06-03
完成内容:
- 调整 `server/app/common/command/WorldcupArticleTranslate.php`,世界杯英文资讯翻译预热不再全量扫描全部文章。
- 预热范围改为按前台资讯列表同口径排序:`published_at desc, id desc`,仅处理用户当前最先看到的前 50 条世界杯资讯。
- 这样可以在 AI key 恢复后优先补齐前台首屏和专题页最靠前文章的翻译缓存,避免一次性处理历史文章拖慢恢复。
涉及模块:
- `server/app/common/command/WorldcupArticleTranslate.php`
### 9. 世界杯比赛详情接口默认直播链接
- 状态:已完成 - 时间:2026-06-03
完成内容:
- `server/app/api/controller/MatchController.php` 在前台 `/api/match/detail` 接口中为世界杯比赛补充默认直播链接。
- 当赛事 `league_name=世界杯``competition_id=61` 且数据库 `live_url` 为空时,接口响应中的 `live_url` 默认返回 `https://sports.cctv.com/?spm=C28340.P9mj1V5B06xk.E2XVQsMhlk44.7`
- 默认值仅在接口响应层兜底,不写回数据库;后台已维护的 `live_url` 仍优先返回,用户端继续只消费接口返回字段。
涉及模块:
- `server/app/api/controller/MatchController.php`
- `admin/src/views/match/lists/index.vue`
- `uniapp/src/pages/match_detail/match_detail.vue`
- `server/public/dongqiudi-crawler/main.py`
- `server/app/common/command/CrawlerCommand.php`
- `server/public/dongqiudi-crawler/insert_crontab_lottery_community.sql`
### 5. 项目级文档归档到根目录
- 状态:已完成 - 时间:2026-05-14
完成内容:
- 将项目级文档 `01-产品方案文档.md``02-实现流程文档.md``爬虫任务脚本文档.md``docs/` 目录移动到项目根目录统一维护。
- 在根目录 `AGENTS.md` 中补充项目级文档存放规则,明确协作类与业务类总文档默认放根目录。
- 同步修正文档引用路径,避免后续继续引用旧的 `docs/` 路径。
涉及模块:
- `AGENTS.md`
- `业务进度管理.md`
- `01-产品方案文档.md`
- `02-实现流程文档.md`
- `爬虫任务脚本文档.md`
### 6. FIFA 世界杯资讯定时采集接入
- 状态:已完成 - 时间:2026-05-15
完成内容:
- 新增 FIFA 世界杯资讯爬虫入口 `fifa_worldcup_news`,通过 FIFA CXM API 拉取世界杯页面新闻区块数据。
- 增加世界杯文章分类幂等创建/复用逻辑,默认分类名为 `世界杯`,并自动启用显示。
- 新增定时任务注册 SQL `insert_crontab_fifa_worldcup_news.sql`,采用 `crawler fifa_worldcup_news` 动作并按 10 分钟执行。
- 将后端定时任务调度链路扩展到 `fifa_worldcup_news`,沿用现有 crawler 异步执行模式。
- 已验证 FIFA API 可返回 20 条世界杯资讯;本地完整写库验证因 crawler 当前数据库配置指向 `127.0.0.1` 而 MySQL 拒绝连接,需在服务器/可用数据库环境执行。
涉及模块:
- `server/public/dongqiudi-crawler/fifa_worldcup_news.py`
- `server/public/dongqiudi-crawler/main.py`
- `server/public/dongqiudi-crawler/insert_crontab_fifa_worldcup_news.sql`
- `server/app/common/command/CrawlerCommand.php`
- `server/app/adminapi/logic/crontab/CrontabLogic.php`
### 7. 懂球帝世界杯专属采集与用户端世界杯中心
- 状态:已完成 - 时间:2026-05-15
完成内容:
- 新增 `dqd_worldcup` 专属采集任务,固定抓取懂球帝 2026 世界杯 `standing / schedule / person_ranking(goals|assists)`
- 世界杯赛程写入 `la_match`,统一使用 `league_name=世界杯``competition_id=61``sport_type=1`,并保留 `round_name``stage`
- 新增世界杯缓存表 `la_worldcup_standing``la_worldcup_person_ranking`,保留小组积分榜和球员榜结构。
- 新增幂等 SQL `insert_crontab_dqd_worldcup.sql`,自动创建并启用足球二级分类"世界杯",同时注册 `crawler dqd_worldcup` 定时任务。
- `MatchController` 新增 `worldCupStandings``worldCupRankings``worldCupSchedule` 3 个前台接口,供用户端世界杯中心使用。
- 用户端 `pages/match/match` 在"足球 > 世界杯"分类下新增"赛程对阵图"顶部入口卡,并新增 `packages_match/pages/worldcup` 世界杯专属页,提供"对阵图 / 积分榜 / 射手榜 / 助攻榜 / 赛程" 5 个 tab。
- 已在测试库执行 SQL 并手动跑通一次采集,当前写入结果为:`la_match` 104 场、`la_worldcup_standing` 48 条、`la_worldcup_person_ranking``goals/assists` 暂为空。
- 已验证测试服 `/api/match/leagues``/api/match/lists?league_name=世界杯` 可返回世界杯分类与赛程;`worldCupStandings / worldCupRankings / worldCupSchedule` 仍需等待后端自动同步到测试服后再做最终联调。
涉及模块:
- `server/public/dongqiudi-crawler/dqd_worldcup.py`
- `server/public/dongqiudi-crawler/main.py`
- `server/public/dongqiudi-crawler/insert_crontab_dqd_worldcup.sql`
- `server/app/common/command/CrawlerCommand.php`
- `server/app/common/model/match/WorldCupStanding.php`
- `server/app/common/model/match/WorldCupPersonRanking.php`
- `server/app/api/controller/MatchController.php`
- `uniapp/src/api/match.ts`
- `uniapp/src/pages/match/match.vue`
### 8. 49宝典新澳六合/旧奥六合爬取 API 格式适配修复
- 状态:已完成 - 时间:2026-06-01
完成内容:
- 发现新澳六合(xa6)和旧奥六合(a6)的 draw 类型帖子自 2026-05-29 起停止更新,根源为第三方 API 变更响应格式。
- 字段变更:开奖号码数组从 `openCode` 迁移到 `currentResult`,期号从 `issue` 迁移到 `currentCompleteIssue`/`currentIssue`
- 字段编码:五行由中文(金木水火土)变为字母编码(j/m/s/h/t),单双由中文(单双)变为字母编码(o/e),大小由中文(大小)变为字母编码(b/s),颜色新增 R/G/B 编码。
- 时间格式:开奖时间从时间戳变为 `"Y-m-d H:i:s"` 字符串格式。
- 修复 `lottery_community.py``build_draw_post` 函数,添加 `WUXING_MAP``ODD_EVEN_MAP``SIZE_MAP` 等映射表,增强 `color_text` 函数支持 R/G/B 编码,增强 `format_time` 函数支持字符串时间格式。
- 修复后的代码在 2026-05-31 18:10 的执行中成功同步:xa6 新增 92 条(含 1 条 draw + 91 条 gallery),a6 更新 101 条。
- 数据库验证:xa6 和 a6 的 draw 类型均已同步到最新 2026151 期,gallery 类型同步到最新数据。
- 注意:2026149-2026150 期因 API 格式变更期间不可回溯(API 只返回当前期),已无法补回。
涉及模块:
- `server/public/dongqiudi-crawler/lottery_community.py`