no message
This commit is contained in:
@@ -13,6 +13,469 @@
|
||||
|
||||
## 一、已完成事项
|
||||
|
||||
### 65. Docker AI评论调度接入帖子与资讯
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-12
|
||||
|
||||
完成内容:
|
||||
- 在 `server/public/dongqiudi-crawler` 新增 `ai_comment_dispatch.py`,由 Docker crawler 直接执行 AI 评论调度,不再复用旧的 PHP `article_ai_comment` 运行链。
|
||||
- 评论任务新增统一任务表方案 `la_ai_comment_task`,记录 `target_type/target_id/virtual_user_id/persona_key/selection_sources/comment_content/status/error_msg`,并补充幂等 SQL `docs/sql/create_ai_comment_task.sql`。
|
||||
- 新增幂等 SQL `docs/sql/insert_ai_comment_config.sql`,初始化 `auto_comment_enabled`、`auto_comment_user_pool_size`、`auto_comment_per_run`、`auto_comment_daily_cap`、`auto_comment_concurrency`、`auto_comment_request_timeout`、`auto_comment_article_prompt`、`auto_comment_post_prompt` 等配置;Python 侧直接复用 `la_ai_config` 中的 `openai_* / max_tokens / temperature`。
|
||||
- AI 评论调度会自动把 `ai_comment_` 虚拟账号池补足到 100 个,并按稳定 persona 映射分配昵称与发言角色。
|
||||
- 资讯候选池按现有前台口径实现:每个可见分类最新 100 条、`is_recommend=1` 视为置顶 10 条、今天创建且当前总浏览最高 20 条;帖子候选池按现有 `community_tag` 口径实现:每个标签最新 100 条、`is_top=1` 置顶 10 条、今天创建且 `view_count` 最高 20 条。
|
||||
- 各候选池会先按内容 ID 去重并合并来源标签,再过滤已存在机器人成功评论或已有待执行任务的内容;单轮默认按 25 条资讯 + 25 条帖子配额取数,某一侧不足时由另一侧补满。
|
||||
- 评论生成支持多 persona 的角色、语气、场景和关注点,并在模型失败时回退到兜底短评;成功后直接写入 `la_article_comment` / `la_community_comment` 并同步递增文章或帖子评论数。
|
||||
- `main.py` 新增 `ai_comment_dispatch` 动作注册与 1800 秒超时,`config/crawler_tasks.yaml` 新增 `*/10 * * * *` 的 Docker 定时任务;另补充 `docs/sql/disable_article_ai_comment_crontab.sql` 用于停用旧 `article_ai_comment` 定时任务。
|
||||
|
||||
涉及模块:
|
||||
- `server/public/dongqiudi-crawler/ai_comment_dispatch.py`
|
||||
- `server/public/dongqiudi-crawler/main.py`
|
||||
- `server/public/dongqiudi-crawler/config/crawler_tasks.yaml`
|
||||
- `server/public/dongqiudi-crawler/tests/test_ai_comment_dispatch.py`
|
||||
- `qa/backend/test_ai_comment_dispatch_static.py`
|
||||
- `docs/sql/create_ai_comment_task.sql`
|
||||
- `docs/sql/insert_ai_comment_config.sql`
|
||||
- `docs/sql/disable_article_ai_comment_crontab.sql`
|
||||
|
||||
验证记录:
|
||||
- 已先新增并执行 `python -m unittest server/public/dongqiudi-crawler/tests/test_ai_comment_dispatch.py`,在实现前因缺少 `ai_comment_dispatch` 模块失败。
|
||||
- 修改后已执行 `C:\Python311\python.exe -m unittest server/public/dongqiudi-crawler/tests/test_ai_comment_dispatch.py server/public/dongqiudi-crawler/tests/test_docker_task_runner.py server/public/dongqiudi-crawler/tests/test_runtime_guard.py`,15 个测试全部通过。
|
||||
- 已执行 `C:\Python311\python.exe qa/backend/test_ai_comment_dispatch_static.py`,静态检查通过。
|
||||
- 已执行 `C:\Python311\python.exe -m py_compile server/public/dongqiudi-crawler/ai_comment_dispatch.py server/public/dongqiudi-crawler/main.py server/public/dongqiudi-crawler/scripts/docker_task_runner.py qa/backend/test_ai_comment_dispatch_static.py`,Python 语法检查通过。
|
||||
- 已在测试库执行 `docs/sql/create_ai_comment_task.sql`、`docs/sql/insert_ai_comment_config.sql`、`docs/sql/disable_article_ai_comment_crontab.sql`,确认 `la_ai_comment_task` 建表成功、`auto_comment_*` 配置写入成功,旧 `article_ai_comment` 定时任务已停用。
|
||||
- 已用远端测试库配置手动执行一轮 `ai_comment_dispatch` 最小联调,临时将单轮条数压到 2,实际成功创建 2 条任务:`article_id=2044144`、`post_id=5924`,均已写入对应评论表并将文章/帖子 `comment_count` 回写为 `1`。
|
||||
|
||||
### 64. AI助手资讯类联网检索接入
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-12
|
||||
|
||||
完成内容:
|
||||
- 在 AI 助手固定四阶段编排链的 `Retriever` 阶段新增 `AiAssistantWebNewsRetriever`,对资讯/新闻/消息/转会类问题触发 OpenAI `responses` 的 `web_search` 工具,补充外网最新资讯,不再只依赖站内向量库和知识库。
|
||||
- `DeepSeekClient` 的 `responses` payload 新增 `tools`、`tool_choice`、`include` 透传能力,支持联网检索器强制执行 `web_search` 并请求返回官方 sources 元信息。
|
||||
- `AiAssistantContextService::composePayload()` 新增 `web_news_context`,回答阶段会同时看到“站内资料、联网资讯与实时上下文”;外网资讯来源统一归一为 `web_news`,并跳转到 `/pages/webview/webview?url=...`。
|
||||
- 修正 `AiAssistantPlanner` fallback 意图判断顺序,像“今天NBA有什么最新消息?”这类问题优先识别为 `news_search`,避免被“今天”误判成赛程类。
|
||||
- AI 助手前端来源类型映射新增 `web_news => 外网资讯`,方便用户识别联网结果来源。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/service/ai/AiAssistantWebNewsRetriever.php`
|
||||
- `server/app/common/service/ai/AiAssistantRetriever.php`
|
||||
- `server/app/common/service/ai/AiAssistantContextService.php`
|
||||
- `server/app/common/service/ai/AiAssistantResponder.php`
|
||||
- `server/app/common/service/ai/DeepSeekClient.php`
|
||||
- `server/app/common/service/ai/AiAssistantPlanner.php`
|
||||
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
|
||||
- `qa/backend/test_ai_assistant_web_news_static.php`
|
||||
- `qa/backend/test_ai_assistant_web_news_source_behavior.php`
|
||||
|
||||
验证记录:
|
||||
- 已先执行 `php qa/backend/test_ai_assistant_web_news_static.php`、`php qa/backend/test_ai_assistant_web_news_source_behavior.php`,修改前失败。
|
||||
- 修改后已执行 `php qa/backend/test_ai_assistant_planner_behavior.php`、`php qa/backend/test_ai_assistant_web_news_static.php`、`php qa/backend/test_ai_assistant_web_news_source_behavior.php`、`php qa/backend/test_ai_assistant_orchestrator_static.php`,均通过。
|
||||
- 已执行 `php -l` 检查 `AiAssistantWebNewsRetriever.php`、`AiAssistantRetriever.php`、`AiAssistantContextService.php`、`AiAssistantResponder.php`、`DeepSeekClient.php`、`AiAssistantPlanner.php`,语法检查通过。
|
||||
- 已执行 `npm run build:h5`,H5 构建通过并复制到 `server/public/mobile`。
|
||||
- 已直接使用测试服 `.env` 中的 `OPENAI_API_KEY` 对 `https://lingsuan.top/v1/responses` 发起 `web_search` 请求,确认可返回结构化联网资讯 JSON。
|
||||
- 截至当前一次 `POST /api/assistant/chat` 复测,“今天NBA有什么最新消息?” 仍主要返回站内文章来源,尚未观察到 `web_news` 来源出现在测试服助手接口响应中;当前未执行测试服后端发布脚本,因为项目内 `scripts/deploy-server.ps1` 会自动提交工作区,不符合当前未请求提交的协作约束。
|
||||
|
||||
### 63. AI助手升级为多阶段编排链
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-12
|
||||
|
||||
完成内容:
|
||||
- 将 AI 助手主链路从“直接拼上下文后回答”升级为固定四阶段编排:`Planner -> Retriever -> Ranker -> Responder`,由新增 `AiAssistantOrchestrator` 串联,`AiAssistantService` 保留会话、限流、消息落库和返回格式职责。
|
||||
- 新增 `AiAssistantPlanner`,通过 LLM 先输出结构化查询规划 JSON,包含 `intent`、`rewritten_query`、`alternate_queries`、`domains`、`preferred_domain`、`entities`、`date_range`、`needs_realtime`、`answer_format`、`confidence`;当规划失败时自动回退到规则 fallback,保证助手不中断。
|
||||
- `AiAssistantContextService` 升级为按规划结果驱动检索:知识库检索优先使用 `rewritten_query + alternate_queries` 多路召回并合并去重;赛事和加密实时上下文根据规划结果决定是否检索、提取哪些实体、是否带日期范围。
|
||||
- 新增 `AiAssistantRanker` 对知识库命中做领域偏好重排,并统一拼装 `query_plan + knowledge_hits + match_context + crypto_realtime` 的回答上下文;新增 `AiAssistantResponder` 基于规划结果和证据上下文生成最终 markdown 回复。
|
||||
- 新增 `AiAssistantTrace` 作为本次请求内的轻量 DTO,贯穿四阶段,先不加数据库新表,避免扩大改动面。
|
||||
- 新增 QA 回归覆盖:AI 助手服务必须委托 `AiAssistantOrchestrator`,编排链必须包含 `Planner/Retriever/Ranker/Responder` 四阶段;`Planner` 的归一化输出必须稳定保留 query、domain、date_range 和 markdown 默认格式。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/service/ai/AiAssistantService.php`
|
||||
- `server/app/common/service/ai/AiAssistantOrchestrator.php`
|
||||
- `server/app/common/service/ai/AiAssistantTrace.php`
|
||||
- `server/app/common/service/ai/AiAssistantPlanner.php`
|
||||
- `server/app/common/service/ai/AiAssistantRetriever.php`
|
||||
- `server/app/common/service/ai/AiAssistantRanker.php`
|
||||
- `server/app/common/service/ai/AiAssistantResponder.php`
|
||||
- `server/app/common/service/ai/AiAssistantContextService.php`
|
||||
- `qa/backend/test_ai_assistant_orchestrator_static.php`
|
||||
- `qa/backend/test_ai_assistant_planner_behavior.php`
|
||||
|
||||
验证记录:
|
||||
- 已先执行 `php qa/backend/test_ai_assistant_orchestrator_static.php`、`php qa/backend/test_ai_assistant_planner_behavior.php`,修改前均失败。
|
||||
- 修改后已执行 `php qa/backend/test_ai_assistant_orchestrator_static.php`、`php qa/backend/test_ai_assistant_planner_behavior.php`、`php qa/backend/test_ai_assistant_frontend_error_static.php`、`php qa/backend/test_ai_assistant_markdown_static.php`、`php qa/backend/test_ai_assistant_markdown_table_static.php`、`php qa/backend/test_ai_assistant_match_context_static.php`、`php qa/backend/test_ai_assistant_retry_options.php`、`php qa/backend/test_ai_assistant_worldcup_schedule_static.php`,均通过。
|
||||
- 已执行 `php -l` 检查新增/修改的 `AiAssistant*` 服务类与相关 QA 脚本,语法检查通过。
|
||||
- 已复测测试服 `POST /api/assistant/chat`:
|
||||
- 提问“今天的世界杯赛程”可返回 2026-06-12 的两场世界杯并附带表格;
|
||||
- 提问“BTC 今天行情怎么样?”可返回实时行情摘要并附带 `BTC/USDT` 行情来源。
|
||||
|
||||
### 62. AI助手世界杯今日赛程与表格渲染修复
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-12
|
||||
|
||||
完成内容:
|
||||
- 复测 `POST /api/assistant/chat` 提问“今天的世界杯赛程”,确认修复前助手会把 2026-07-15/18/19 的未来淘汰赛占位对阵误当成“今天赛程”,根因是赛事检索只按球队/联赛模糊匹配并默认按 `match_time desc` 取最新,不区分“今天/明天/昨天”这类日期问法。
|
||||
- `AiAssistantContextService` 新增日期范围识别逻辑,对“今天/今日/明天/昨天/昨日”的赛程类问题按本地自然日过滤 `match_time`,并让赛程类问法按时间正序取当天比赛;结果类问法继续优先已完场赛事。
|
||||
- 复测同一接口发现模型会用 markdown 表格输出赛程,而 `uniapp/src/utils/assistant-markdown.ts` 原先未支持表格,容易导致 AI 助手正文显示异常;现已补齐 markdown table 转 HTML table 逻辑,并在 AI 助手消息样式中补充表格排版。
|
||||
- 同步更新 QA 静态回归:覆盖“世界杯今日赛程”日期筛选,以及 markdown 表格识别与转换。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/service/ai/AiAssistantContextService.php`
|
||||
- `uniapp/src/utils/assistant-markdown.ts`
|
||||
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
|
||||
- `qa/backend/test_ai_assistant_worldcup_schedule_static.php`
|
||||
- `qa/backend/test_ai_assistant_markdown_table_static.php`
|
||||
- `qa/backend/test_ai_assistant_match_context_static.php`
|
||||
|
||||
验证记录:
|
||||
- 已先执行 `php qa/backend/test_ai_assistant_worldcup_schedule_static.php`、`php qa/backend/test_ai_assistant_markdown_table_static.php`,修改前均失败。
|
||||
- 修改后已执行 `php qa/backend/test_ai_assistant_markdown_static.php`、`php qa/backend/test_ai_assistant_frontend_error_static.php`、`php qa/backend/test_ai_assistant_match_context_static.php`、`php qa/backend/test_ai_assistant_markdown_table_static.php`、`php qa/backend/test_ai_assistant_worldcup_schedule_static.php`,均通过。
|
||||
- 已执行 `php -l server/app/common/service/ai/AiAssistantContextService.php`、`php -l qa/backend/test_ai_assistant_match_context_static.php`、`php -l qa/backend/test_ai_assistant_markdown_table_static.php`、`php -l qa/backend/test_ai_assistant_worldcup_schedule_static.php`,语法检查通过。
|
||||
- 已执行 `npm run build:h5`,H5 构建通过并复制到 `server/public/mobile`。
|
||||
- 已复测测试服 `POST /api/assistant/chat` 提问“今天的世界杯赛程”,回复改为列出 2026-06-12 的两场世界杯:`韩国 vs 捷克`、`加拿大 vs 波黑`,并返回 markdown 表格正文与对应赛事来源。
|
||||
|
||||
### 61. AI助手回复 markdown 渲染适配
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-12
|
||||
|
||||
完成内容:
|
||||
- 排查 `uniapp/src/pages/ai_assistant/ai_assistant.vue`,确认当前助手消息直接通过纯文本节点输出,导致 `##`、`**`、列表等 markdown 语法原样展示。
|
||||
- 复用项目已全局注册的 `u-parse` 组件,新增 `uniapp/src/utils/assistant-markdown.ts`,将助手回复中的标题、加粗、列表、引用、分割线、代码块和链接转换为安全 HTML 后渲染。
|
||||
- AI 助手消息区分用户文本与助手回复:用户消息继续走纯文本展示,助手消息走 markdown 渲染链路,并补充对应的排版样式。
|
||||
- 新增 QA 静态回归脚本,检查 AI 助手页面存在 markdown 转换逻辑并通过 `u-parse` 渲染助手回复。
|
||||
|
||||
涉及模块:
|
||||
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
|
||||
- `uniapp/src/utils/assistant-markdown.ts`
|
||||
- `qa/backend/test_ai_assistant_markdown_static.php`
|
||||
|
||||
验证记录:
|
||||
- 已先执行 `php qa/backend/test_ai_assistant_markdown_static.php`,修改前失败,提示缺少 markdown 转换逻辑。
|
||||
- 修改后已执行 `php qa/backend/test_ai_assistant_markdown_static.php`,通过。
|
||||
- 已执行 `php -l qa/backend/test_ai_assistant_markdown_static.php`,语法检查通过。
|
||||
- 已执行 `php qa/backend/test_ai_assistant_frontend_error_static.php`,通过。
|
||||
- 已执行 `npm run build:h5`,H5 构建通过并复制到 `server/public/mobile`。
|
||||
- 已确认本地页面 `http://localhost:8991/pages/ai_assistant/ai_assistant` 可返回 HTTP 200;当前线程未提供可用浏览器/Playwright 依赖,未做自动化截图验收。
|
||||
|
||||
### 60. AI助手马刺最新赛果上下文修复
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-12
|
||||
|
||||
完成内容:
|
||||
- 核查 `pages/match_detail/match_detail?id=3567442` 对应赛事,确认测试库 `la_match.id=3567442` 为 NBA 纽约尼克斯 vs 圣安东尼奥马刺,比分 107-106,已完场。
|
||||
- 确认该赛事已进入 AI 知识库:`la_ai_kb_document.id=948`,`domain=match`、`subtype=event`、`source_id=3567442`,6 个 chunk 均已有 1024 维 embedding,最近同步任务 `la_ai_kb_sync_job.id=25444` 成功。
|
||||
- 定位 AI 助手未优先回答该场的原因:`马刺最新比赛结果` 这类中文连写问题没有从 `queryTerms()` 中拆出“马刺”,而知识库向量召回本身没有时间排序语义;同时实时赛事兜底原先按 `match_time desc` 优先拿未来 0-0 赛程。
|
||||
- `AiAssistantContextService` 已补充赛事查询词停用词剥离,将“马刺最新比赛结果”归一出“马刺”;对“最新/最近/结果/比分/赛果/成绩/战绩”等问法优先查询已完场比赛,再补充其他赛程。
|
||||
- 新增 QA 静态回归脚本,防止中文连写球队词无法提取、最新赛果不优先完场赛事的问题回退。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/service/ai/AiAssistantContextService.php`
|
||||
- `qa/backend/test_ai_assistant_match_context_static.php`
|
||||
- `la_match`
|
||||
- `la_ai_kb_document`
|
||||
- `la_ai_kb_chunk`
|
||||
- `la_ai_kb_sync_job`
|
||||
|
||||
验证记录:
|
||||
- 已查询测试库,确认 `source_id=3567442` 的 match/event 知识库文档存在且有 6 个有效向量 chunk。
|
||||
- 已查询 `la_ai_kb_query_log`,确认修复前 `马刺最新比赛结果` 的 hit docs 不包含 `3567442`。
|
||||
- 已执行 `php qa/backend/test_ai_assistant_match_context_static.php`,修改前失败、修改后通过。
|
||||
- 已执行 `php -l server/app/common/service/ai/AiAssistantContextService.php`、`php -l qa/backend/test_ai_assistant_match_context_static.php`,语法检查通过。
|
||||
- 已请求测试服 `POST /api/assistant/chat` 提问“马刺最新比赛结果”,返回答案包含“圣安东尼奥马刺客场 106-107 不敌纽约尼克斯”,sources 包含 `/pages/match_detail/match_detail?id=3567442`。
|
||||
|
||||
### 59. 赛事时间按当前时区显示
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-12
|
||||
|
||||
完成内容:
|
||||
- 排查赛事时间展示链路,确认普通赛事卡和详情主时间已基本使用本地 `Date`,偏差集中在世界杯专题页固定叠加北京时间、以及比赛详情文字直播时间固定转北京时间。
|
||||
- 新增 `uniapp/src/utils/match-time.ts`,统一将赛事 Unix 秒转换为设备当前时区的 `Date`;世界杯源字段按 UTC 时间保存但历史入库为服务器本地 Unix 秒,先在工具层归一到真实时间点再本地化展示。
|
||||
- `match-card`、`match_detail`、`WorldCupPanel` 已统一接入 `getLocalMatchDate`,世界杯赛程分组、赛程卡时间、对阵图日期/时间和比赛详情主时间不再固定显示北京时间。
|
||||
- 比赛详情文字直播时间移除 `+8 * 3600` 与 `getUTC*`,数字时间戳直接按设备当前时区显示。
|
||||
- 新增 QA 静态回归脚本,检查赛事时间展示必须走统一本地时区工具,并阻止世界杯面板/详情页再次写入北京时间硬编码。
|
||||
|
||||
涉及模块:
|
||||
- `uniapp/src/utils/match-time.ts`
|
||||
- `uniapp/src/components/match-card/match-card.vue`
|
||||
- `uniapp/src/pages/match_detail/match_detail.vue`
|
||||
- `uniapp/src/packages_match/components/WorldCupPanel.vue`
|
||||
- `qa/backend/test_match_timezone_display_static.php`
|
||||
|
||||
验证记录:
|
||||
- 已先执行 `php qa/backend/test_match_timezone_display_static.php`,修改前因缺少统一赛事时间工具失败。
|
||||
- 修改后已执行 `php qa/backend/test_match_timezone_display_static.php`,通过。
|
||||
- 已执行 `php -l qa/backend/test_match_timezone_display_static.php`,语法检查通过。
|
||||
- 已执行 `npm run build:h5`,H5 构建通过并复制到 `server/public/mobile`。
|
||||
|
||||
### 58. AI助手知识库检索 fallback 修复
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-12
|
||||
|
||||
完成内容:
|
||||
- 排查 `/api/assistant/chat` 提问“旧澳六合最近有什么分析线索?”返回 `sources=[]`,确认测试库向量库已有彩票内容:`lottery/draw_result` 4698 条文档、`post/post` 中 `旧澳六合` 相关文档 207+ 条,问题不在向量入库。
|
||||
- 查询 `la_ai_kb_query_log`,确认当前 59+ 条知识库检索日志均为 `status=2`、`hit_docs_json=[]`,AI 助手在知识库检索异常后静默退化为“站内资料不足”。
|
||||
- 定位根因:`KbService::loadCandidates()` fallback 使用了 ThinkPHP 不支持的 `whereOrLike()` 魔术方法,会被解析成字段名 `like` 并导致 SQL 异常;同时中文长句只保留整句作为 LIKE 词,无法拆出“旧澳六合”等核心召回词。
|
||||
- 修复 fallback:改为显式 `whereOr('字段', 'like', $like)`,多关键词按 OR 召回;补充“旧澳六合 -> 老澳门六合彩”“新澳六合 -> 新澳门六合彩”别名,避免依赖 MySQL 中文全文分词。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/service/ai/KbService.php`
|
||||
- `qa/backend/test_kb_retrieve_fallback_static.php`
|
||||
|
||||
验证记录:
|
||||
- 已执行 `php qa/backend/test_kb_retrieve_fallback_static.php`,通过。
|
||||
- 已执行 `php -l server/app/common/service/ai/KbService.php`、`php -l qa/backend/test_kb_retrieve_fallback_static.php`,语法检查通过。
|
||||
- 已执行 `php qa/backend/test_kb_sync_pipeline_static.php`、`php qa/backend/test_kb_redis_enqueue_static.php`,通过。
|
||||
- 已用测试库 SQL 复刻修复后的 fallback 条件,确认“旧澳六合最近有什么分析线索?”可召回 `post/post` 211 条和 `lottery/draw_result` 2 条,样本包含“老澳门六合彩 第2026162期开奖”。
|
||||
- 已通过 `scripts/deploy-server.ps1 -AutoIncremental` 发布 server 修复到测试服,并执行 `php think clear` 清理缓存;复测 `/api/assistant/chat` 提问“旧澳六合最近有什么分析线索?”返回 `sources` 6 条,`la_ai_kb_query_log` session 29 记录 `status=1`、`hit_len=6`。
|
||||
|
||||
### 57. AI助手前端网络失败兜底增强
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 排查用户端仍展示“AI助手请求失败,请检查网络后重试。”,确认该文案来自前端 `request:fail/network/网络` 分支;测试库最近 30 分钟无新的助手失败记录,说明该类报错多发生在前端未拿到后端响应时。
|
||||
- AI 助手发送失败时新增历史恢复逻辑:若请求已到后端并生成会话/回复,但前端网络层未收到响应,则通过 `client_id + last_message` 拉取最新会话消息并回填当前对话。
|
||||
- 网络失败提示保留原始 `errMsg/message`,展示为“错误详情:xxx”,避免继续只显示泛化网络文案。
|
||||
- 已重新执行 `npm run build:h5` 并使用 `-IncludePublicBuilds` 发布到测试服,确认远端 `public/mobile` 新产物包含恢复逻辑与“错误详情”文案。
|
||||
|
||||
涉及模块:
|
||||
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
|
||||
- `qa/backend/test_ai_assistant_frontend_error_static.php`
|
||||
- `server/public/mobile`
|
||||
|
||||
验证记录:
|
||||
- 已执行 `php qa/backend/test_ai_assistant_frontend_error_static.php`,通过。
|
||||
- 已执行 `npm run build:h5`,H5 构建通过并复制到 `server/public/mobile`。
|
||||
- 已请求测试服 `/api/assistant/chat`,`马刺最近比赛` 返回 `code=1`。
|
||||
- 已发布测试服并执行 `php think clear`;远端构建产物可检索到“错误详情”和恢复逻辑。
|
||||
|
||||
### 56. AI助手上游502重试增强
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 排查用户端返回 `OpenAI: OpenAI 返回异常: 响应不是有效JSON(HTTP 502),已重试1次`,确认配置与 API Key 正常,`https://lingsuan.top/v1/responses` 最小请求可返回 200。
|
||||
- 查询测试库 `la_ai_chat_message`,确认失败集中在 `马刺最近比赛` 等完整助手请求,模型为 `gpt-5.5`,错误为上游中转偶发 `HTTP 502 + 非 JSON`。
|
||||
- AI 助手模型调用单独提高瞬时故障重试能力:`retry_times=3`、`retry_sleep_ms=1200`,不影响其他 AI 分析链路的默认重试配置。
|
||||
- 新增 QA 脚本检查 AI 助手默认重试参数,避免后续退回到只重试 1 次。
|
||||
- 已发布 server 到测试服并执行 `php think clear`;复测 `马刺最近比赛`、`马刺 最近比赛`、`马刺最新的比赛` 均返回 `code=1`。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/service/ai/AiAssistantService.php`
|
||||
- `qa/backend/test_ai_assistant_retry_options.php`
|
||||
- `la_ai_chat_message`
|
||||
|
||||
验证记录:
|
||||
- 已执行 `php qa/backend/test_ai_assistant_retry_options.php`,通过。
|
||||
- 已执行 `php qa/backend/test_deepseek_client_transient_retry.php`,通过。
|
||||
- 已执行 `php -l server/app/common/service/ai/AiAssistantService.php`、`php -l server/app/common/service/ai/DeepSeekClient.php`、`php -l qa/backend/test_ai_assistant_retry_options.php`,语法检查通过。
|
||||
|
||||
### 55. 世界杯专题页赛程时间校正
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 修复 `/packages_match/pages/worldcup` 世界杯赛程时间显示偏差:源赛程时间戳比预期北京时间少 8 小时,页面增加世界杯专用时间规范化后再按北京时间展示。
|
||||
- 统一修正赛程日期分组、赛程卡中间时间、对阵图时间和对阵图日期,避免出现 `19:00` 应为次日 `03:00` 的情况。
|
||||
|
||||
验证记录:
|
||||
- 已用 `match_time=1781175600` 静态验证,页面新逻辑输出 `2026-06-12 03:00`。
|
||||
- 已执行 `npm run build:h5`,H5 构建通过并复制到 `server/public/mobile`。
|
||||
|
||||
### 54. AI知识库Redis队列测试服启用与消费修复
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 在测试库执行并确认 `kb:enqueue-recent` 每分钟定时任务注册成功,补齐近期扫描索引:`idx_kb_recent_article`、`idx_kb_recent_match`、`idx_kb_recent_post`、`idx_kb_recent_draw`、`idx_kb_recent_ai_history`。
|
||||
- 发布 server 代码到测试服并执行 `php think clear`,解决测试服 `Command "kb:enqueue-recent" is not defined` 导致定时任务失败的问题。
|
||||
- 同步远端 `docker/docker-compose.crawler.yml`,补充并启动 `sport-era-kb-worker` 服务;从应用 `.env` 安全同步 embedding key 到 `docker/.env.docker`。
|
||||
- 修复 PHP `KbService` 中 `source_updated_at/source_created_at` 直接 `(int)` 转换日期字符串导致写成 `2026` 的问题,统一解析为 Unix 时间戳。
|
||||
- 修复 Python worker 对 DashScope embedding 单次批量超过 10 条时报错的问题,改为按 `EMBEDDING_BATCH_SIZE` 分批请求;`vector_norm` 写库前保留 8 位小数,减少 MySQL decimal 截断告警。
|
||||
- 清理 Redis consumer group 中旧 worker 遗留 pending 消息,重新写回 Stream 后由新 worker 消费。
|
||||
- 追加 worker Redis 读取超时保护,设置连接/读取超时与健康检查;遇到临时 `TimeoutError/ConnectionError` 时记录 warning 并继续轮询,避免容器因 Redis 短暂抖动重启。
|
||||
|
||||
验证记录:
|
||||
- 已执行测试服 `php think kb:enqueue-recent --limit=10 --minutes=30`,成功写入 Redis Stream。
|
||||
- Redis DB4 `ai:kb:sync:stream` 已存在,consumer group `ai_kb_workers` 已创建,`ai:kb:sync:dead` 死信长度为 0。
|
||||
- `sport-era-kb-worker` 已启动并持续输出 `kb upsert ok` 日志,`la_ai_kb_document` 与 `la_ai_kb_chunk` 持续增量更新。
|
||||
- 截至 2026-06-11 13:10 左右,Redis lag 已从 648 降至 398,今日赛事过期文档数从 27 降至 20,队列仍在继续追赶。
|
||||
- 截至 2026-06-11 13:51 左右,Redis `pending=0`、`lag=0`、死信长度为 0,worker 持续消费并写入知识库。
|
||||
|
||||
### 53. AI知识库Redis队列与Python异步向量Worker
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 新增 `kb:enqueue-recent` 后端命令,每分钟扫描最近 30 分钟更新的资讯、加密资讯、彩票开奖结果、彩票 AI 历史、赛事和社区帖子,并写入 Redis Stream `ai:kb:sync:stream`。
|
||||
- 新增 `KbRedisQueueService`,按源表更新时间筛选缺失、失效或过期的知识库文档,入队前使用 `ai:kb:sync:dedupe:{domain}:{subtype}:{source_id}` 做 30 分钟去重。
|
||||
- 新增 Python 常驻 worker `scripts/kb_worker.py`,通过 Redis consumer group `ai_kb_workers` 消费队列,直接写入 `la_ai_kb_document` 与 `la_ai_kb_chunk`;成功 `XACK`,失败重试,超过阈值写入 `ai:kb:sync:dead` 死信队列。
|
||||
- `docker/docker-compose.crawler.yml` 新增 `kb-worker` 服务,复用 crawler 镜像并支持 `EMBEDDING_API_KEY/BASE_URL/MODEL/DIM` 环境变量;crawler entrypoint 支持传入命令时直接执行,避免 worker 被固定 cron entrypoint 拦截。
|
||||
- 新增幂等 SQL 注册每分钟 `kb:enqueue-recent` 定时任务,并为近实时扫描补充 `update_time` 相关索引 SQL。
|
||||
- 新增 QA 静态检查和 Python worker 队列行为单测,覆盖 Redis Stream 名称、去重、五类扫描、consumer group、ack、死信和 Docker worker 配置。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/command/KbEnqueueRecent.php`
|
||||
- `server/app/common/service/ai/KbRedisQueueService.php`
|
||||
- `server/public/dongqiudi-crawler/scripts/kb_worker.py`
|
||||
- `server/public/dongqiudi-crawler/docker/entrypoint.sh`
|
||||
- `docker/docker-compose.crawler.yml`
|
||||
- `docker/.env.docker.example`
|
||||
- `docs/sql/insert_ai_kb_enqueue_recent_crontab.sql`
|
||||
- `docs/sql/add_ai_kb_recent_source_indexes.sql`
|
||||
- `qa/backend/test_kb_redis_enqueue_static.php`
|
||||
- `qa/backend/test_kb_worker_static.py`
|
||||
- `server/public/dongqiudi-crawler/tests/test_kb_worker.py`
|
||||
- `la_ai_kb_document`
|
||||
- `la_ai_kb_chunk`
|
||||
- Redis Stream `ai:kb:sync:stream`
|
||||
|
||||
验证记录:
|
||||
- 已执行 `php qa/backend/test_kb_redis_enqueue_static.php`,静态检查通过。
|
||||
- 已执行 `C:\Python311\python.exe qa/backend/test_kb_worker_static.py`,静态检查通过。
|
||||
- 已执行 `C:\Python311\python.exe -m unittest discover -s server/public/dongqiudi-crawler/tests -p test_kb_worker.py`,worker 队列行为单测通过。
|
||||
- 已执行 `C:\Python311\python.exe -m py_compile server/public/dongqiudi-crawler/scripts/kb_worker.py server/public/dongqiudi-crawler/tests/test_kb_worker.py qa/backend/test_kb_worker_static.py`,Python 语法检查通过。
|
||||
- 已执行 `php -l server/app/common/service/ai/KbRedisQueueService.php`、`php -l server/app/common/command/KbEnqueueRecent.php`、`php -l qa/backend/test_kb_redis_enqueue_static.php`,PHP 语法检查通过。
|
||||
- 本机未安装 Docker CLI,无法执行 `docker compose config`;本机 PHP CLI 仍因 Redis 驱动缺失报 `not support: redis`,需在测试服执行 SQL、启动 `kb-worker` 并观察 Redis Stream 与知识库表增量。
|
||||
|
||||
### 52. AI知识库资讯与赛事向量同步链路修复
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 核查测试库 AI 知识库状态,确认 `la_ai_kb_document` 与 `la_ai_kb_chunk` 当前无有效记录;`la_article` 可见资讯 38121 条全部缺少 article 向量文档,最近 24 小时可见资讯 999 条全部缺少向量文档;2026-06-11 当天赛事 36 场全部缺少 match/event 向量文档。
|
||||
- 确认测试库 `la_dev_crontab` 原本没有 `kb:consume` 定时任务,`la_ai_kb_sync_job` 只有 article/post 待处理任务且长期未消费;爬虫直接写入 `la_article` 和 `la_match`,不会主动调用 PHP `KbSyncService::enqueue()`。
|
||||
- `KbSyncService` 新增资讯回填,并将回填逻辑从“只补缺失文档”升级为“补缺失或源数据更新时间晚于向量文档”的未同步数据;赛事回填优先级调高,避免今天赛事被历史资讯 backlog 压住。
|
||||
- `kb:consume` 每次运行前自动补标赛事、资讯和彩票缺失/过期向量任务;`kb:rebuild` 后按重建域补标残留缺失/过期任务。
|
||||
- 管理端知识库重建域校验补充 `match`,使后台可触发赛事知识库重建。
|
||||
- 新增幂等 SQL `docs/sql/insert_ai_kb_consume_crontab.sql`,已在测试库执行并确认只生成 1 条启用的 `kb:consume` 定时任务,表达式为 `*/5 * * * *`,参数为 `--batch=100`。
|
||||
- 新增 QA 静态回归脚本,检查资讯/赛事未同步回填、消费命令补标、重建补标、管理端 match 域校验和定时任务 SQL。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/service/ai/KbSyncService.php`
|
||||
- `server/app/common/command/KbConsume.php`
|
||||
- `server/app/common/command/KbRebuild.php`
|
||||
- `server/app/adminapi/validate/ai/KbSyncJobValidate.php`
|
||||
- `docs/sql/insert_ai_kb_consume_crontab.sql`
|
||||
- `qa/backend/test_kb_sync_pipeline_static.php`
|
||||
- `la_ai_kb_document`
|
||||
- `la_ai_kb_chunk`
|
||||
- `la_ai_kb_sync_job`
|
||||
- `la_dev_crontab`
|
||||
|
||||
验证记录:
|
||||
- 已用 MySQL 查询测试库,确认修复前 article/match 向量覆盖率均为 0,且无 `kb:consume` 定时任务。
|
||||
- 已执行 `docs/sql/insert_ai_kb_consume_crontab.sql`,重复执行后确认 `kb:consume` 仍只有 1 条启用记录,SQL 幂等。
|
||||
- 已执行 `php qa/backend/test_kb_sync_pipeline_static.php`,回归检查通过。
|
||||
- 已执行修改过的 PHP 文件语法检查,均通过。
|
||||
- 本地 Windows CLI 执行 `php think kb:consume --batch=5` 时被当前 PHP 环境 Redis 驱动拦截,报 `not support: redis`,未进入业务消费逻辑;需由测试服 PHP 环境实际定时消费后再观察 `la_ai_kb_document` 增量。
|
||||
|
||||
### 51. 资讯卡片底部信息布局优化
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 调整 `feed-card__footer` 布局,将作者信息固定在左侧,阅读量和发布时间组合固定在右侧展示。
|
||||
- 右侧阅读量与时间改为独立信息组,避免与作者等分宽度导致视觉分散;作者名称超长时在左侧省略,不挤压右侧信息。
|
||||
|
||||
涉及模块:
|
||||
- `uniapp/src/components/feed-card/feed-card.vue`
|
||||
|
||||
验证记录:
|
||||
- 已执行 `npm run build:h5`,H5 构建通过。
|
||||
|
||||
### 50. AI 助手快捷问题单行省略
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 修复 `/pages/ai_assistant/ai_assistant` 中 `.quick-list__item` 快捷问题过长时会分行显示的问题。
|
||||
- 快捷问题文本增加独立 `.quick-list__text` 包裹,容器与文本均设置单行、省略号和溢出隐藏,移除导致强制换行的 `word-break: break-all`。
|
||||
|
||||
涉及模块:
|
||||
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
|
||||
|
||||
验证记录:
|
||||
- 已先执行静态检查,修改前确认缺少单行省略样式会失败。
|
||||
- 修改后静态检查通过,确认存在 `quick-list__text`、`white-space: nowrap`、`text-overflow: ellipsis`。
|
||||
- 已执行 `npm run build:h5`,H5 构建通过并复制到 `server/public/mobile`。
|
||||
|
||||
### 49. 部署脚本发布前自动提交 server 变更
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- `scripts/deploy-server.ps1` 新增发布前 `server` 工作区检查,在打包和上传前执行 `git status --porcelain -- server`。
|
||||
- 发现 `server` 下存在未提交、删除或未跟踪文件时,脚本会先 `git add -A -- server` 并自动提交,然后再继续计算增量范围。
|
||||
- 新增 `-AutoCommitMessage` 参数,可自定义自动提交说明;默认提交说明为 `deploy: auto commit server changes <时间>`。
|
||||
- 若 `server` 下存在合并冲突,脚本会提示先手动解决后再发布。
|
||||
- README 已补充说明:包含 `-DryRun` 在内,发布脚本都会先自动提交 `server` 变更。
|
||||
|
||||
涉及模块:
|
||||
- `scripts/deploy-server.ps1`
|
||||
- `README.md`
|
||||
|
||||
验证记录:
|
||||
- 已使用临时 Git 仓库验证:`server` 下修改和新增文件会被自动提交,随后继续自动增量 dry-run;仓库中 README/admin 的未提交变更不会被自动提交。
|
||||
- 已使用临时 Git 仓库验证:`server` 下删除文件会被自动提交,随后进入增量删除清单。
|
||||
- 已执行 PowerShell Parser 检查,`scripts/deploy-server.ps1` 语法解析通过。
|
||||
- 已执行 `git diff --check -- scripts/deploy-server.ps1`,未发现空白错误。
|
||||
|
||||
### 48. AI 助手对话页跨端样式优化
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 优化 `/pages/ai_assistant/ai_assistant` 移动端聊天视觉:导航、欢迎卡片、快捷问题、AI/用户消息气泡、资料来源卡片和底部输入栏统一为更清爽的对话界面。
|
||||
- AI 消息补充头像标识与加载状态脉冲条,长文本气泡提升行高和换行稳定性,来源卡片增加左侧强调线与绿色来源标签,便于阅读和点击。
|
||||
- 底部输入区拆分为 `input-panel + input-bar`,补充 iOS/Android/H5 安全区、`disable-default-padding`、`cursor-spacing` 和隐藏 iOS confirm bar,避免输入栏贴边、默认内边距和键盘遮挡问题。
|
||||
- 输入框固定为与发送按钮同高,去除 `auto-height`,输入内容增减时不再撑开底部输入栏,多行内容在输入框内部滚动。
|
||||
- 修复 H5 下 `constant(safe-area-inset-bottom)` 写在 `padding` 简写中导致整条 padding 失效的问题,改为独立声明 top/left/right/bottom。
|
||||
|
||||
涉及模块:
|
||||
- `uniapp/src/pages/ai_assistant/ai_assistant.vue`
|
||||
|
||||
验证记录:
|
||||
- 已执行 UI 特征检查,确认安全高度、textarea 跨端属性、AI 头像、输入安全区容器和来源强调线均存在。
|
||||
- 已执行 `npm run build:h5`,H5 构建通过并复制到 `server/public/mobile`。
|
||||
- 已通过 Edge Headless DevTools 以 430×932 移动视口检查目标页,确认路由加载为 `pages/ai_assistant/ai_assistant`、页面宽度 430、无横向溢出,输入栏左右 padding 与底部安全区生效。
|
||||
|
||||
### 47. AI 助手 OpenAI 502 瞬时错误重试
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- 排查 `/api/assistant/chat` 请求 `NBA 最近比赛近况` 返回 `OpenAI: OpenAI 返回异常: 响应不是有效JSON(HTTP 502)`,确认根因是上游 OpenAI 中转偶发返回 502 且响应体不是 JSON,`DeepSeekClient` 原逻辑会立即失败并透传错误。
|
||||
- `DeepSeekClient` 新增可覆盖的 HTTP 发送方法,并对 cURL 错误、HTTP 429、HTTP 5xx 做有限重试,默认重试 1 次,可通过 `ai_request_retry_times` 和 `ai_request_retry_sleep_ms` 配置调整。
|
||||
- 失败结果补充“已重试N次”提示,便于后续从 AI 助手错误消息和日志判断是否为持续性上游故障。
|
||||
- 新增 QA 回归脚本,模拟第一次 `HTTP 502 + 非 JSON`、第二次正常 Responses JSON,确认瞬时故障可自动恢复。
|
||||
|
||||
涉及模块:
|
||||
- `server/app/common/service/ai/DeepSeekClient.php`
|
||||
- `qa/backend/test_deepseek_client_transient_retry.php`
|
||||
|
||||
验证记录:
|
||||
- 已执行 `php qa/backend/test_deepseek_client_transient_retry.php`,回归测试通过。
|
||||
- 已执行 `php qa/backend/test_deepseek_client_invalid_response.php`,原有非 JSON/null 防护测试通过。
|
||||
- 已执行 `php -l server/app/common/service/ai/DeepSeekClient.php` 与 `php -l qa/backend/test_deepseek_client_transient_retry.php`,语法检查通过。
|
||||
|
||||
### 46. 部署脚本自动增量支持自定义提交数
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
完成内容:
|
||||
- `scripts/deploy-server.ps1` 新增 `-AutoIncrementalCommits <n>` 参数,配合 `-AutoIncremental` 使用时可自动对比 `HEAD~n` 到 `HEAD`,默认仍为最近 1 个提交。
|
||||
- 自动增量日志补充 `auto incremental commits` 输出,部署元信息补充 `auto_incremental_commits`,便于 dry-run 和真实发布时确认范围。
|
||||
- README 自动增量发布说明已同步新增最近 N 个提交的发布示例。
|
||||
|
||||
涉及模块:
|
||||
- `scripts/deploy-server.ps1`
|
||||
- `README.md`
|
||||
|
||||
验证记录:
|
||||
- 已先执行 `powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\deploy-server.ps1 -AutoIncremental -AutoIncrementalCommits 2 -RemoteDir /www/wwwroot/test-server.sbnews.net -DryRun`,修改前因参数不存在失败,确认覆盖新行为。
|
||||
- 修改后已执行自定义 2 个提交 dry-run,日志显示 `auto incremental commits: 2`,只打包不上传。
|
||||
- 修改后已执行默认自动增量 dry-run,日志显示 `auto incremental commits: 1`,原命令兼容。
|
||||
- 已验证单独传 `-AutoIncrementalCommits` 且不带 `-AutoIncremental` 会报错阻止误用。
|
||||
|
||||
### 45. AI助手请求失败提示补充真实错误
|
||||
|
||||
- 状态:已完成 - 时间:2026-06-11
|
||||
|
||||
Reference in New Issue
Block a user