# 业务进度管理

> 本文件用于跟踪 Sport Era 项目所有功能模块的开发状态、待办事项与避坑记录。每完成一个功能或发现一个坑，及时在对应章节追加。

## 目录

- [一、已完成事项](#一已完成事项)
- [二、进行中事项](#二进行中事项)
- [三、待办事项](#三待办事项)
- [四、避坑记录](#四避坑记录)

---

## 一、已完成事项

### 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`
- `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`
- `uniapp/src/packages_match/pages/worldcup.vue`
- `uniapp/src/pages.json`

### 8. 赛事中心顶部世界杯专题入口优化

- 状态：已完成
- 时间：2026-05-20

完成内容：

- 参考世界杯专题设计稿，将用户端 `pages/match/match` 的世界杯入口从赛事列表区上移到页面头部，放在标题与运动分类之间。
- 新入口改为蓝色专题卡样式，展示 `2026年国际足联世界杯` 与赛事时间区间，点击继续跳转现有世界杯专属页。
- 移除原先仅在“足球 > 世界杯”分类下显示的列表内入口，避免同页重复出现两个世界杯入口。
- 调整赛事页列表高度计算逻辑，改为按实际头部高度回算，避免新增专题卡后遮挡分类条或压缩列表区域。
- 已完成 `npm run build:h5` 构建，并通过浏览器在本地 H5 验证专题入口已出现在赛事页顶部。

涉及模块：

- `uniapp/src/pages/match/match.vue`
- `业务进度管理.md`
- `设计稿映射.md`

### 9. 世界杯专题页排名导航组件化

- 状态：已完成
- 时间：2026-05-20

完成内容：

- 参考世界杯专题页“排名”设计稿，将排名区从 `worldcup.vue` 页面内联结构拆分为独立组件。
- 新增排名导航组件 `RankingNav.vue`，统一承载 `积分榜 / 射手榜 / 助攻榜` 切换。
- 新增积分榜组件 `StandingsPanel.vue`，单独负责分组标题、表头与球队积分表格渲染。
- 新增球员榜组件 `PlayerRankingPanel.vue`，单独负责射手榜与助攻榜列表渲染。
- 积分榜布局按专题设计稿细化为“球队固定在左、场次/胜平负/进失/积分集中在右”的双区块表格结构，移动端表头与数据列保持对齐。
- `worldcup.vue` 只保留专题主导航、数据加载与 ranking 组件调度，降低页面耦合，便于后续继续按设计稿细化榜单样式。
- 已执行 `npm run build:h5` 并通过本地 H5 校验“排名”页可正常展示组件化后的导航与积分榜内容。

涉及模块：

- `uniapp/src/packages_match/pages/worldcup.vue`
- `uniapp/src/packages_match/pages/worldcup/components/ranking/RankingNav.vue`
- `uniapp/src/packages_match/pages/worldcup/components/ranking/StandingsPanel.vue`
- `uniapp/src/packages_match/pages/worldcup/components/ranking/PlayerRankingPanel.vue`
- `业务进度管理.md`

### 10. 世界杯专题页对阵图按真实球队映射
- 状态：已完成
- 时间：2026-05-20

完成内容：
- 用户端 `packages_match/pages/worldcup` 对阵图页新增基于 `worldCupStandings` 的分组名次索引，将 `A1/A2/.../L4` 直接映射为当前积分榜中的真实球队名称与队徽。
- `1/16决赛` 中的第三名组合占位符（如 `A3/B3/C3/D3/F3`）改为逐项替换后再拼接展示，避免继续显示字母占位符。
- 对仍然是“第X场胜者/败者”的后续轮次占位保持原样，不伪造未产生的晋级结果；对无法确定真实队徽的组合占位不再显示默认占位图。
- 为多球队组合名称增加两行展示样式，避免长文本在专题对阵卡片中被单行截断。
- 已执行 `uniapp` 构建验证：`npm run build:h5` 通过。

涉及模块：
- `uniapp/src/packages_match/pages/worldcup.vue`
- `业务进度管理.md`

### 11. 短信助手同步短信与来电记录入库

- 状态：已完成
- 时间：2026-05-22

完成内容：

- 扩展 `/api/sms/uploadSms`，同时接收手机端上传的 `smsList` 与 `callList`，统一写入 `la_sms_upload`。
- 保持短信验证码链路兼容：短信记录仍沿用 `type=1/2`、`status=0/1`；来电记录使用 `type=11/13/15` 区分“已接/未接/拒接”，并使用 `status=2` 表示“不适用”。
- 登录/绑手机号的短信验证码校验规则调整为：只要 `la_sms_upload` 中存在该手机号的任意上传记录，即视为验证通过，不再要求短信内容与输入验证码完全匹配，也不再限制 7 天内或短信类型。
- 助手端采集范围收紧为：短信只上传收到的短信，来电只上传打进来的号码，过滤自己发出去的短信和主动拨出的通话记录。
- 助手端恢复来电真实上传，不再将来电请求按“短信列表为空”视作跳过，并增加助手端请求/响应打印，便于排查实际上传内容。
- 管理端“系统设置 -> 系统维护 -> 验证码”列表同步支持展示来电记录，新增“记录类型”列，并补充“不适用”状态展示。
- 新增 SQL 脚本 `docs/sql/alter_la_sms_upload_for_call_records.sql`，用于将 `la_sms_upload.status` 注释扩展为 `0=待验证 1=已使用 2=不适用`。

涉及数据库变更：

- `la_sms_upload.status`

涉及模块：

- `server/app/api/controller/SmsController.php`
- `server/app/api/logic/LoginLogic.php`
- `server/app/api/logic/UserLogic.php`
- `server/app/adminapi/lists/setting/SmsUploadLists.php`
- `admin/src/views/setting/system/sms_upload.vue`
- `sport-era-msg/pages/index/index.vue`
- `sport-era-msg/pages/logs/logs.vue`
- `docs/sql/alter_la_sms_upload_for_call_records.sql`
- `业务进度管理.md`

---

### 12. 用户页未设密码提示
- 2026-05-23：`uniapp/src/pages/user/user.vue` 在进入“我的”页面时补充未设置密码提示弹窗；当 `has_password` 为 `0` 时，提示用户尽快修改登录密码，并展示手机号后 6 位作为初始密码说明。
- 2026-05-23：`server/app/api/validate/LoginAccountValidate.php` 支持空密码用户使用手机号后 6 位直接登录，避免初始化账号被误判为“用户不存在”。

### 13. 世界杯页面主导航默认索引
- 2026-05-23：`uniapp/src/packages_match/pages/worldcup.vue` 的主导航默认索引调整为第 0 项，页面进入时默认停留在首个 tab。

### 14. 世界杯专题新闻来源同步首页分类
- 2026-05-23：`uniapp/src/pages/match/match.vue` 跳转世界杯专题页时携带首页解析到的 `世界杯` 分类 `cid`，`uniapp/src/packages_match/pages/worldcup.vue` 优先使用该 `cid` 拉取新闻，保证专题新闻来源与首页世界杯分类一致。

### 15. 新闻资讯 AI 翻译
- 2026-05-23：`server/app/api/controller/ArticleController.php` 新增 `/article/translate` 翻译接口，`server/app/api/logic/ArticleLogic.php` 复用 `AiService` 生成并缓存文章翻译结果到 `ext`。
- 2026-05-23：`uniapp/src/pages/news_detail/news_detail.vue` 在新闻详情页新增 AI 翻译入口、加载态与翻译结果展示区，`uniapp/src/api/news.ts` 补充对应请求封装。

### 16. 世界杯专题新闻列表 AI 翻译
- 2026-05-23：`uniapp/src/components/news-card/news-card.vue` 增加可选 AI 翻译触发入口，世界杯专题新闻列表可在卡片内点按翻译按钮。
- 2026-05-23：`uniapp/src/packages_match/pages/worldcup.vue` 接收翻译事件并以弹窗展示翻译结果，保持其他新闻列表默认不变。
### 17. 社区首页特朗普分类 AI 翻译复用
- 2026-05-23：`uniapp/src/packages_community/pages/index.vue` 继续复用 `post-card` 卡片渲染，社区首页无需单独拆分 AI 入口逻辑。
- 2026-05-23：`uniapp/src/packages_community/components/post-card.vue` 将 `特朗普` 标签纳入 AI 翻译入口判断，沿用帖子翻译弹窗展示方式。
### 18. 资讯 AI 翻译改为积分确认流程
- 2026-05-23：`server/app/api/controller/ArticleController.php` 的 `/article/translate` 改为登录后可用，并支持 `article_id/id + confirm` 的积分确认参数。
- 2026-05-23：`server/app/api/logic/ArticleLogic.php` 为资讯翻译补齐 `needs_payment` 探测、积分扣减、翻译缓存复用与已付费用户缓存读取。
- 2026-05-23：`uniapp/src/api/news.ts`、`uniapp/src/pages/news_detail/news_detail.vue`、`uniapp/src/packages_match/pages/worldcup.vue` 改为与社区翻译一致的 `POST + confirm` 调用方式，翻译前先提示登录并在确认后扣积分。
### 19. 赛事详情新增第三方直播入口
- 2026-05-23：`server/app/api/controller/MatchController.php` 复用 `la_match_data.raw_data` 中的直播源文本，向详情接口补充 `living_tv` 字段，便于前端展示直播来源说明。
- 2026-05-23：`uniapp/src/pages/match_detail/match_detail.vue` 新增“直播”入口卡片，点击后通过现有 `webview` 页面跳转到懂球帝第三方直播详情页。

### 20. 管理端赛事直播链接编辑
- 2026-05-23：`admin/src/views/match/lists/index.vue` 在赛事编辑弹窗中新增 `live_url` 输入项，用于维护第三方直播链接。
- 2026-05-23：`server/app/adminapi/logic/match/MatchLogic.php` 允许赛事编辑写入 `live_url`，`uniapp/src/pages/match_detail/match_detail.vue` 优先读取该字段作为直播入口跳转地址。
- 2026-05-23：新增 `docs/sql/alter_la_match_add_live_url.sql`，用于给 `la_match` 补充 `live_url` 字段。
- 2026-05-23：已同步测试库 `sbnews.la_match.live_url` 字段，确认 `/adminapi/match.match/edit` 可正常落库。

### 21. 赛事详情直播入口仅在有链接时展示
- 2026-05-23：`uniapp/src/pages/match_detail/match_detail.vue` 将直播入口收敛为仅在 `match.live_url` 存在时展示，不再为无链接赛事自动兜底第三方直播地址。

### 22. 世界杯专题比赛卡片跳转详情
- 2026-05-23：`uniapp/src/packages_match/pages/worldcup.vue` 的赛程卡片和对阵图卡片统一支持点击跳转 `pages/match_detail/match_detail`，方便从世界杯专题直接进入比赛详情页。

### 23. 近期踩坑与文档同步
- 2026-05-24：将本次调试过程中确认的坑点同步到 `sport-era-project-dev` 技能文档和各级 `AGENTS.md`，补充 `Validate::only()` 不过滤请求参数、`la_match.live_url` 必须先补库、世界杯专题页入口一致性以及构建产物不要混入提交等注意事项。

## 二、进行中事项

暂无。

---

## 三、待办事项

### 1. 业务模块进度补录

- 优先级：中
- 创建时间：2026-05-07

待确认：

- 根据现有 `01-产品方案文档.md`、`02-实现流程文档.md` 和当前代码状态，补录已完成业务模块。
- 按模块梳理后端接口、管理后台页面、uniapp 页面、PC 页面当前完成度。

### 2. 设计稿映射补录

- 优先级：中
- 创建时间：2026-05-07

待确认：

- 确认当前设计稿平台、项目链接和页面节点名称。
- 将首页、新闻列表、新闻详情、个人中心、AI 分析等页面与实现路径建立映射。

---

## 四、避坑记录

### 1. ThinkPHP 时间字段自动转换

- BaseModel 子类查询后 `create_time` / `update_time` 已按配置转为日期字符串。
- 不要对这些字段再次手动 `date()` 转换，避免字符串强转整数导致显示为 1970-01-01。

### 2. MySQL 保留字

- 原生 SQL 中 `system`、`order`、`group`、`key` 等字段必须使用反引号包裹。

### 3. 逗号分隔输入清理

- 手机号、关键词等逗号分隔输入，提交前必须执行 `split → trim → filter(Boolean) → join`。

### 4. 外站图片防盗链

- 新闻详情等富文本中的外站图片如出现 403，优先在前端渲染层设置 `referrerpolicy="no-referrer"`。
- 不擅自清洗图片 URL 参数或改写原始路径。

### 5. 测试服务器代码同步

- 不通过 WSL `sshpass` / `scp` 上传业务代码。
- 项目代码更新由用户通过 SFTP 等方式处理。

### 6. 新增字段与联动入口排查

- `Validate::only()` 只限制校验字段，不会过滤请求参数；新增字段必须同时核对 validate、logic、model、保存白名单和数据库列。
- `adminapi/match.match/edit` 写入失败先看表结构，不要把测试库缺列误判成业务逻辑错误。
- 世界杯专题页、比赛详情页的入口和显示规则要一起改，直播入口只在 `match.live_url` 有值时展示。
- 构建产物如 `server/public/admin`、`server/public/mobile` 不要混进提交，提交前先清理临时截图和生成文件。

---

## 文档维护规范

1. **每完成一个 issue / 功能点 → 立即追加到「已完成事项」**。
2. **每发现一个坑 → 立即追加到「避坑记录」**。
3. **每周清理一次「进行中」与「待办」状态**。
4. **章节序号连续递增，不重排**，保留历史可追溯。
5. **涉及数据库变更必须列出表名和字段**。

### 24. 世界杯专题新闻自动翻译展示
- 2026-05-28：`uniapp/src/packages_match/pages/worldcup.vue` 的新闻区改为自动请求 `/article/translate` 并直接展示中文翻译，专题页不再展示显式 AI 翻译入口，仅保留翻译结果展示。

### 25. 文章列表接口自动翻译回传
- 2026-05-28：`/api/article/lists` 在 `cid=22` 时会自动读取或生成文章译文并写入 `ext.translated_content`，接口直接回传中文翻译；`packages_match/pages/worldcup` 取消前端二次翻译请求，只消费后端返回结果。
