从 PHP 到 AI + Golang:程序员自救转型手记(二十二):改用 AGENTS.md

作者:袖梨 2026-07-16
这是一个系列 Blog,作者将以一个 PHP 全栈工程师的身份,利用 AI 工具(claude code、codex、deepseek、豆包等):从零开始学习 golang 语言,并最终完成 ai-go-mall([github](https://github.com/ai-go-hub/ai-go-mall) | [gitee](https://gitee.com/ai-go-hub/ai-go-mall))开源项目的制作,全程记录分享。

在上一期,我们进行了 “网络请求封装优化”,本期将完成:改用 AGENTS.md

# 改用 AGENTS.md

离上次更新 `CLAUDE.md` 已经过去很长时间了,期间新增了非常多的功能,本次我直接将现有的 `CLAUDE.md` 删除,使用 CC 的 `/init` 命令来重新生成。

生成后我新建了 `/AGENTS.md` 文件,毕竟这才是最通用的,然后于 `.claude/CLAUDE.md` 内只写一行 `@import ../AGENTS.md` 即可。

## 验证

为了验证 `CLAUDE.md` 中的引用有效(因为各个版本的语法不同),我们可以使用 `/memory` 命令,如下,我们可以明确看到 `AGENTS.md @-imported` 字样:

```bash

Memory

Auto-memory: on

1. .claudeCLAUDE.md

❯ 2. L AGENTS.md@-imported

3. User memorySaved in ~/.claude/CLAUDE.md

4. Project memory Checked in at ./CLAUDE.md

5. Open auto-memory folder

Learn more: https://code.claude.com/docs/en/memory

Enter to confirm · Esc to cancel

```

## 全新的 AGENTS.md

`/init` 后人工整理了很久,在其中简要描述了:

- 后端的:`技术栈、分层结构、配置自动加载、路由自动注册、模型自动迁移、身份令牌(Token)、点选验证码(Click Captcha)、统一响应`

- 前端的:`路径别名与入口、路由自动加载、状态管理、请求封装`

> 部分未来还会变动的模块,暂时没有写进来;以下内容为确保显示效果,这里将标题等级做了修改

### AGENTS.md

本文件为 AGENTS 在当前代码库中工作时提供指导。

#### 技术栈

后端:Go1.25 Gin GORM PostgreSQL

前端:Vue3 Element Plus TypeScript Vite Pinia Axios

#### 回答偏好

- 回复使用中文

- 遇到有多种实现方案时,列出选项让我选择,而不是直接选一种

#### 关键约定

- **包名**:全小写、单数、无下划线(`handler`、`service`)

- **文件名**:全小写、下划线分隔(`user_service.go`)

- **只使用 GET 和 POST 请求方式**:大多数 CDN/全站加速 服务对 PUT、DELETE 兼容性差

- **GORM**:使用 `GORM` 的 `Generics API(gorm.G[Model](db)....)`,而不是 `Traditional API`,且在使用 `Generics API` 时,一般应直接使用全局 db 实例(`internalinfradatabasedatabase.go` 中的 `DB` 可获取),调用操作方法时再传递合适的 ctx 即可

- **避免 stutter**:包名已经表达的含义,结构体 / 函数不要再重复,如 `admin.AdminService` 改用 `admin.Service`

### 后端

#### 分层结构

核心应用架构为:泛型驱动的四层架构模式(`internal/`),Handler(控制器)→ Service(业务逻辑)→ Repository(数据访问)→ Model(数据模型)。前三层均有泛型基类(对应目录的 `base.go` 文件),新增子模块时先嵌入再追加自定义方法。

#### 配置自动加载

`internal/infra/config/config.go` 使用 viper,按以下顺序合并(后者覆盖前者):

1. `config/*.yaml`(glob 全部 yaml,按文件名顺序 MergeInConfig)

2. 根目录 `.env.yaml`(若存在,覆盖上述配置;**已 gitignore,不入库**)

3. 环境变量(`AutomaticEnv`)

支持配置热重载(`OnConfigChange` `WatchConfig`),通过 `config.Get()` 取带读写锁的副本。`.env.yaml.example` 是环境配置模板;`config/config.yaml` 是默认配置。新增配置项需同步在 `Config` 结构体加字段。

#### 路由自动注册

`internal/router/registry/registry.go` 维护 `Routes []func(*gin.Engine)`。每个业务路由包在 `init()` 中调用 `registry.Register(...)` 注册自己;`router/index.go` 通过**空白导入** `_ "../router/admin"`、`_ "../router/common"` 触发 `init`,`router.Setup(engine)` 遍历执行。新增路由模块后,需要在 `router/index.go` 加空白导入。

#### 模型自动迁移

`internal/model/model.go` 维护 `registered []any`。各模型文件在 `init()` 中调用 `Register(&Admin{})`;`database.Init()` 调用 `db.AutoMigrate(model.All()...)`。新增模型只需在 `model` 包内写 `init() { Register(&X{}) }`,并创建 `TableName()` 函数。

#### 身份令牌(Token)

`internal/infra/token/token.go` 定义 `Driver` 接口与全局单例 `Manager()`(`sync.Once` 懒初始化,依据 `token.driver` 配置选驱动,当前仅 `database` 驱动)。Token 入库前做 **SHA256**,校验/删除时同样哈希后比对。认证中间件 `middleware/admin_auth.go`:`AdminAuth`(管理员强制登录认证)、`AdminAuthOptional`(管理员可选登录认证),从 `Authorization: Bearer ` 提取,校验后注入 `AdminSession` 到 context。

#### 点选验证码(Click Captcha)

`internal/infra/captcha/click.go` 是核心特色模块之一:在背景图上绘制中文/大写字母/图标元素,带碰撞检测与混淆元素;用户按顺序点击,服务端比对 元素列表 坐标容差。`captcha.yaml` 控制元素类型、数量、过期、字体路径、背景图目录、图标目录及图标中英文名映射。`bootstrap()` 首次调用加载中文字符池与图标元数据,每次 `Create` 顺带清理过期记录。`Check(req, deleteOnSuccess)` 的第二参控制验证成功是否删记录——预验场景传 `false`,登录场景传 `true`。

#### 统一响应

`internal/response/response.go`:响应体 `{code, message, time, data}`,`code=0` 成功、`code=1` 失败(均 HTTP 200)。两种用法:函数式选项 `response.Success(c, response.WithData(x))` / 链式 `response.New(c).Code(...).Message(...).Send()`,日常使用函数式选项用法。

### 前端(web/)

#### 路径别名与入口

- `/@/` → `src/`(tsconfig `paths` 与 vite `resolve.alias` 一致)。

- 入口 `src/main.ts`:注册 pinia(带 `pinia-plugin-persistedstate`)、router、element-plus、i18n、全局 icon。

- 路由用 hash 模式(`createWebHashHistory`)。

#### 静态路由自动加载

`src/router/static.ts` 用 `import.meta.glob('./static/**/*.ts', { eager: true })` 自动收集 `src/router/static/` 下所有 `.ts` 默认导出(`RouteRecordRaw` 或 `RouteRecordRaw[]`)合并进 `staticRoutes`。`src/router/static/adminBase.ts` 定义后台基础路由 `/admin`。新增静态路由只需在该目录加文件。

#### 状态管理(Pinia)

`src/stores/`:`config`(站点/语言/布局,持久化)、`adminInfo`(管理员信息含 token,持久化)、`menu`、`navTab`、`ref`。持久化 key 集中在 `src/stores/constant/cacheKey.ts`。

#### 请求封装(`src/utils/request.ts`)

axios 实例 baseURL 取 `VITE_AXIOS_BASE_URL`。拦截器特性:

- **大小写转换**:请求 camelCase → snake_case,响应 snake_case → camelCase(`convertCase !== false` 时生效,FormData/URLSearchParams/Blob 不转)。

- **重复请求取消**:默认开启(`cancelDuplicate !== false`),按 method url params data 生成 key,新请求 abort 旧请求。

- **loading**:`loading=true` 显示全屏 loading(计数式,支持并发)。

- **Bearer token**:自动从 `useAdminInfo().token` 注入 `Authorization`。 - 新增 API 请求函数放 `src/api/`,参考 `api/admin/index.ts`、`api/common.ts`。","createTime":1783324281,"ext":{"closeTextLink":0,"comment_ban":0,"description":"","focusRead":0},"favNum":0,"html":"","isOriginal":0,"likeNum":0,img_6a58ad0d46a3b30.webp

相关文章

精彩推荐