# Change Log — 2026-08-24 ## 请求 1. 新增一个「公共模块」,模块下存放 `tools` 功能模块,`tools` 下再分各种子功能。 2. 建立项目上下文记忆体系:记录每次请求与更改,方案对比后落地;要求后续使用其他 CodeBuddy 账号也能无缝衔接。 ## 变更 新增文件: - `common/doc.go` — 公共模块说明(不依赖 internal、可独立抽取) - `common/tools/doc.go` — tools 模块布局清单与封装规则 - `common/tools/md5/md5.go` — MD5 摘要(Md5Hex / Md5Bytes / Md5File) - `common/tools/cryptox/cryptox.go` — AES-128-CBC / DES-ECB 加解密(base64 输出,密钥任意长度自动规范化) - `common/tools/uuid/uuid.go` — 唯一 ID(New 32 位 / Short 短随机码) - `common/tools/random/random.go` — 随机数/随机串(Int / String / Digits / Letters) - `common/tools/timex/timex.go` — 时间工具(Format / Timestamp / StartOfDay / EndOfDay) - `common/tools/convertx/convertx.go` — 类型转换带默认值(ToInt / ToInt64 / ToFloat64 / ToString / ToBool) - `common/tools/strx/strx.go` — 字符串工具(命名转换 SnakeCase/CamelCase + 脱敏 MaskPhone/MaskIDCard/MaskName) - `common/tools/slicex/slicex.go` — 泛型切片工具(Contains / Unique / Chunk / Map / Filter) - `common/tools/ip/ip.go` — IP 工具(IsValid / LocalIP / IsInternal / ToLong / ToString) - `common/tools/filex/filex.go` — 文件工具(Exists / IsDir / ReadString / WriteString) - `AGENTS.md` — 项目智能体说明书(架构、规范、命令、记忆体系索引) - `docs/change-log/2026-08-24.md` — 本文档 修改文件: - `.gitignore` — 追加 `.workbuddy/`(本机记忆不入库) - `PROJECT_STRUCTURE.md` — 目录树补充 `common/` 与 `docs/change-log/`(见后续提交) 验证:`go build ./...` 与 `go vet ./common/...` 全部通过。 ## 决策与理由 - **公共模块放顶层 `common/` 而非 `internal/common/`**:Go 的 internal 包无法被外部模块引用,放顶层便于未来抽取为独立库/被同仓库其他服务复用。 - **tools 一律薄封装 GoFrame 内置组件**:v2.10.2 中 AES/DES 已拆为 `crypto/gaes`、`crypto/gdes`,UUID 为 `util/guid`,无 `gslicer`(用标准库 `slices` 替代);避免重复造轮子,保持与框架一致。 - **记忆体系三层方案**(对比见下): 1. `AGENTS.md`(根目录)— 长期稳定规范,跨工具标准(Claude Code/CodeBuddy/Codex 等均识别),随 git 走; 2. `docs/change-log/YYYY-MM-DD.md` — 每次请求变更的结构化记录,随 git 走,**这是跨账号衔接的关键**; 3. `.workbuddy/memory/` — WorkBuddy 本机增强,不入库。 - 对比过 `CLAUDE.md`(Claude Code 专属、已建议统一为 AGENTS.md)、`.cursor/rules`(Cursor 专属)、`.codebuddy/`(仅 CodeBuddy 读取)——它们都不是最大公约数,故不采用。 ## 待办与风险 - 后续每次任务完成后:更新 `docs/change-log/`(当日文件追加)+ 提交 git,确保其他账号 clone 即恢复上下文。 - `convertx` 依赖 gconv 的"转换失败返回零值"行为(无法区分"0"与非法输入),需要严格转换的场景应在 service 层先校验。 - 本次变更尚未 git 提交,建议尽快 commit。 --- ## 追加(17:30):方向纠正 — 「公共模块」实为公共接口 ### 请求 用户澄清:要新增的是**给前端调用的公共 HTTP 接口**(此前误建成 Go 工具包),确认应规划到 `api/` 契约层。 ### 变更 新增文件: - `api/common/v1/tools.go` — 公共接口契约:`UUIDReq/Res`、`MD5Req/Res`、`RandomReq/Res`、`TimeReq/Res`、`IPReq/Res`(g.Meta 路由元数据) - `internal/controller/common/tools.go` — 控制器实现,薄适配层,复用 `common/tools/*` Go 包 修改文件: - `internal/cmd/cmd.go` — 新增公开分组 `s.Group("/api/common/v1", ...)`(Recover+CORS+HandlerResponse,**无鉴权**) - `common/tools/timex/timex.go` — 修复:`Format` 内部改用 `Layout()` 方法(见决策) - `internal/controller/common/tools.go` — `Time` 用 `now.Layout(...)` - `AGENTS.md` — 目录树与新增「公共接口」小节、注意事项补 gtime 与包名差异 - `PROJECT_STRUCTURE.md` — 目录树补充 `api/common/v1` 验证:`go build ./...`、`go vet` 通过;**实际启动服务冒烟测试** 5 个端点全部返回正确(含修复后 time 格式化)。 ### 决策与理由 - **路由前缀 `/api/common/v1`**:与 `/api/v1`(user)、`/admin/v1`(admin) 平级的独立公开前缀,天然不套登录鉴权;前端三个端(mini/h5/app)通用。 - **契约层放 `api/common/v1`,实现放 `internal/controller/common`**:与 user/admin 完全同构;公共接口不需要 service 层(纯工具计算),controller 直接复用 `common/tools` 包,避免过度分层。 - **🐛 gtime v2.10.2 大坑(已修复)**:`Time.Format()` 参数是 **PHP 风格**(`"Y-m-d H:i:s"`),传 Go layout(`"2006-01-02 15:04:05"`)会原样输出!Go layout 必须用 `Time.Layout()`。`common/tools/timex` 已统一封装为 `Layout` 语义,调用方直接 `timex.Format(t, layout...)` 即可。 - **冒烟测试教训**:`go run` 会 spawn 子进程,`kill %1` 只杀包装进程,残留的 `main.exe` 会继续占用 8000 端口导致后续测试打到旧代码——杀进程需 `netstat -ano | grep :8000` 找 PID 后 `Stop-Process`。 ### 待办与风险 - 本次追加变更同样未提交 git,与上文合并为一次 commit。 - 公共接口已开放无鉴权能力(md5/random/uuid 等),后续新增接口时需评审是否应限流/加签名,避免被滥用。