docs: 为 category-api 和 apikey-article-api 添加项目笔记文件

- 添加 category-api 的 problems、decisions、learnings、issues 文档
- 添加 apikey-article-api 的 issues、decisions、learnings 文档
- 包含架构决策、问题记录和学习总结
This commit is contained in:
augushong
2026-04-28 21:03:15 +08:00
parent bb08dee91d
commit 0e8944bc7f
13 changed files with 1830 additions and 1 deletions

View File

@@ -0,0 +1,65 @@
# 修复 `date(): Argument #2 ($timestamp) must be of type ?int, string given` 计划
## 一、Summary
- 目标:修复后台 `ApiKey->index()` 页面在格式化创建时间时触发的 `TypeError`,恢复页面可访问与数据展示。
- 成功标准:
- `admin/ApiKey/index` 页面不再抛出 `date()` 参数类型错误。
- “创建时间”正常显示(优先显示 `Y-m-d H:i:s`)。
- 对历史数据(整型时间戳/数字字符串/日期字符串)具备兼容处理能力。
## 二、Current State Analysis
- 报错位置:`app/admin/controller/ApiKey.php``index()` 中:
- 当前代码:`date('Y-m-d H:i:s', $api_key->create_time);`
- 现状分析:
- 项目在 `config/database.php` 中启用了:
- `'auto_timestamp' => true`
- `'datetime_format' => 'Y-m-d H:i:s'`
- 在该配置下,模型时间字段可能被框架格式化为字符串返回。
- PHP 8+ 中 `date()` 第二参数要求 `?int`,传入字符串会抛出当前 `TypeError`
- 影响范围:
- 当前直接影响 API Key 管理页渲染。
- 同类写法若存在于其他控制器,也存在潜在风险(本次检索到该处为唯一直接命中)。
## 三、Proposed Changes
- 修改文件:`app/admin/controller/ApiKey.php`
- 修改点:`index()` 中创建时间格式化逻辑
- 具体方案(确定采用):
- 不直接将 `$api_key->create_time` 传给 `date()`
- 先取原始值并做类型归一化:
- 若是纯数字int/数字字符串):转为 `(int)``date()`
- 若是日期字符串:先 `strtotime()`,成功后再 `date()`
- 若为空或无法解析:兜底为 `'-'`(避免页面报错)。
- 方案原因:
- 与现有时间字段配置兼容,不依赖单一数据库驱动返回类型。
- 风险低,仅影响展示层,不改动数据库结构与业务写入逻辑。
## 四、Assumptions & Decisions
- 关键决策:
- 在控制器层做兼容转换,先快速止血,保证页面稳定。
- 关键假设:
- `create_time` 可能出现三种形态:`int`、数字字符串、格式化日期字符串。
- 页面允许在异常值下显示 `'-'`,优先保证可用性。
- 不在本次范围(明确 out of scope
- 不调整全局 `database.php` 的时间格式策略。
- 不改动迁移字段类型(仍保持 int 时间戳)。
## 五、Verification Steps
- 功能验证:
- 打开 `admin/ApiKey/index`,确认页面可正常渲染,无 `TypeError`
- 检查“创建时间”显示格式是否为 `Y-m-d H:i:s` 或兜底 `-`
- 兼容验证:
- 使用已有记录验证(正常数据)。
- 人工构造/模拟:
- `create_time` 为数字字符串;
- `create_time``Y-m-d H:i:s` 字符串;
- `create_time` 为空/非法字符串。
- 回归验证:
- 验证“生成 Key / 重新生成 / 启用禁用 / 权限切换”流程不受影响。
## 六、可选架构优化建议(执行阶段仅建议,不默认实现)
- 更优做法 A`app/model/ApiKey.php` 增加统一访问器(如 `getCreateTimeTextAttr`),将格式化逻辑从控制器下沉到模型,减少重复与类型风险。
- 更优做法 B统一项目时间字段读取规范
- 业务计算统一使用原始值(如 `getData('create_time')`
- 展示统一走访问器或单一格式化方法。
- 更优做法 C补充一条针对时间格式化的回归测试若项目后续引入可执行测试基线