# portal-mini-go 后台管理接口文档 > 基于 Go + gin 的中后台管理后端服务。本文档描述**后台管理(`/api/admin`)**相关接口。小程序端接口见 `miniapp-api.md`。 ## 1. 概述 - **基础路径**:`/api/admin` - **服务地址**:由 `configs/config.yaml` 中 `server.port` 决定(默认 `8080`),例如 `http://localhost:8080`。 - **统一响应**:所有接口均返回 `HTTP 200`,业务结果通过响应体中的 `code` 字段判断(见 §2.4)。 - **鉴权方式**:后台接口需在请求头携带 `Authorization: Bearer `,由 `AdminAuth` 中间件校验(登录接口除外)。 - **全局接口**:`GET /healthz` 为健康检查,无需鉴权,返回 `{"code":0,"msg":"ok","data":{"status":"ok"}}`。 ## 2. 公共约定 ### 2.1 请求头 | Header | 必填 | 说明 | | --- | --- | --- | | `Content-Type` | 是(POST/PUT) | 固定为 `application/json`。 | | `Authorization` | 是(登录除外) | 后台登录后下发的 JWT,格式 `Bearer `。 | ### 2.2 统一响应结构 ```json { "code": 0, "msg": "ok", "data": { } } ``` | 字段 | 类型 | 说明 | | --- | --- | --- | | `code` | int | 业务码。`0` 表示成功;非 `0` 表示失败(见 §2.4)。 | | `msg` | string | 结果描述。`0` 时为 `ok`,失败时为人可读信息。 | | `data` | object/null | 业务数据,成功时有内容,失败时通常省略。 | ### 2.3 鉴权中间件 | 中间件 | 校验逻辑 | | --- | --- | | `AdminAuth` | 校验 `Authorization: Bearer `(HS256)。校验通过后将 `admin_id` 注入上下文;登录接口 `POST /api/admin/login` 不挂载此中间件。 | > 全局还挂载 `Recovery`(panic 恢复)、`Trace`(注入 trace_id)、`ErrorHandler`(统一错误转换)。错误由中间件转换,handler 内不直接散落 `c.JSON` 处理错误。 ### 2.4 错误码 | 业务码 | 常量 | 含义 | | --- | --- | --- | | `0` | — | 成功 | | `40000` | `ErrBadRequest` | 请求参数错误 / 非法输入(`ext` 非合法 JSON、用户状态非法等) | | `40100` | `ErrUnauthorized` | 未认证 / 登录失败 / token 无效或过期 | | `40300` | `ErrForbidden` | 禁止访问 | | `40400` | `ErrNotFound` | 资源不存在(如小程序 / 用户 ID 不存在) | | `50000` | `ErrServer` | 服务内部错误(含 token 签发等) | > 非 `BizError` 的未知错误一律归为 `50000`。 ## 3. 接口列表 ### 3.1 `POST /api/admin/login` 后台管理员登录,签发 JWT。无需 `Authorization` 头。 **请求体** ```json { "username": "admin", "password": "admin123" } ``` | 字段 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `username` | string | 是 | 管理员账号(当前示例固定 `admin`)。 | | `password` | string | 是 | 密码(当前示例固定 `admin123`;生产应接 DB + 密码哈希)。 | **响应** ```json { "code": 0, "msg": "ok", "data": { "token": "" } } ``` **curl 示例** ```bash curl -X POST http://localhost:8080/api/admin/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"admin123"}' ``` ### 3.2 `GET /api/admin/info` 受保护接口示例,需有效 JWT,返回当前管理员 ID。 **请求头**:`Authorization: Bearer ` **响应** ```json { "code": 0, "msg": "ok", "data": { "admin_id": "1" } } ``` ### 3.3 `POST /api/admin/miniapps` 新建被纳管小程序。 **请求头**:`Authorization: Bearer ` **请求体** ```json { "name": "示例小程序", "description": "用于演示", "app_id": "wx1234567890", "app_secret": "secret-xxxx", "status": 1, "ext": "{\"k\":\"v\"}" } ``` | 字段 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `name` | string | 是 | 小程序名称。 | | `description` | string | 否 | 描述。 | | `app_id` | string | 是 | 微信 AppID,全局唯一。 | | `app_secret` | string | 是 | 微信 AppSecret(**不会在响应中返回**)。 | | `status` | int8 | 否 | 状态:`0` 停用,`1` 启用。缺省为 `1`。 | | `ext` | string | 否 | 扩展字段,必须为合法 JSON 字符串(允许空串)。 | **响应**:返回创建后的 `MiniProgram` 对象(见 §4.1),`app_secret` 字段不返回。 ### 3.4 `PUT /api/admin/miniapps/:id` 按 ID 局部更新小程序。 **请求头**:`Authorization: Bearer ` **路径参数** | 参数 | 类型 | 说明 | | --- | --- | --- | | `id` | uint64 | 小程序主键。 | **请求体**(所有字段均为可选,仅在提供时更新;`ext` 若提供需为合法 JSON) ```json { "name": "新名称", "description": "新描述", "app_secret": "new-secret", "status": 0, "ext": "{\"theme\":\"dark\"}" } ``` > 字段以指针区分「未提供」与「置空」;若全部为空则不更新,直接返回原记录。 **响应**:返回更新后的 `MiniProgram` 对象。 ### 3.5 `GET /api/admin/miniapps/:id` 查询单个小程序。 **请求头**:`Authorization: Bearer ` **路径参数**:`id`(uint64)。 **响应**:返回 `MiniProgram` 对象;不存在返回 `40400`。 ### 3.6 `GET /api/admin/miniapps` 分页列表查询小程序。 **请求头**:`Authorization: Bearer ` **查询参数** | 参数 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | `status` | int8 | `-1`(全部) | 按状态筛选:`0` 停用,`1` 启用,`-1` 全部。 | | `page` | int | `1` | 页码,从 1 开始。 | | `size` | int | `20` | 每页条数。 | **响应** ```json { "code": 0, "msg": "ok", "data": { "list": [ { "id": 1, "name": "示例小程序", "app_id": "wx123...", "status": 1 } ], "total": 1, "page": 1, "size": 20 } } ``` **curl 示例** ```bash curl "http://localhost:8080/api/admin/miniapps?status=1&page=1&size=20" \ -H "Authorization: Bearer " ``` ### 3.7 `DELETE /api/admin/miniapps/:id` 软删除小程序(置 `deleted_at`)。 **请求头**:`Authorization: Bearer ` **路径参数**:`id`(uint64)。 **响应** ```json { "code": 0, "msg": "ok" } ``` ### 3.8 `GET /api/admin/users` 分页列表查询小程序端用户,支持按小程序与关键字(昵称 / OpenID)过滤。 **请求头**:`Authorization: Bearer ` **查询参数** | 参数 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | `mini_id` | uint64 | `0`(全部) | 按所属小程序筛选;`0` 表示不限小程序。 | | `keyword` | string | 空 | 模糊匹配 `nickname` 或 `openid`(前后自动加 `%`)。 | | `page` | int | `1` | 页码,从 1 开始。 | | `size` | int | `20` | 每页条数。 | **响应** ```json { "code": 0, "msg": "ok", "data": { "list": [ { "id": 1, "mini_id": 10, "openid": "oABC...", "union_id": "", "nickname": "张三", "avatar": "https://...", "status": 1, "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z" } ], "total": 1, "page": 1, "size": 20 } } ``` **curl 示例** ```bash curl "http://localhost:8080/api/admin/users?mini_id=10&keyword=张三&page=1&size=20" \ -H "Authorization: Bearer " ``` ### 3.9 `GET /api/admin/users/:id` 查询单个用户详情(后台视角,不限小程序)。 **请求头**:`Authorization: Bearer ` **路径参数** | 参数 | 类型 | 说明 | | --- | --- | --- | | `id` | uint64 | 用户主键。 | **响应**:返回 `User` 对象(见 §4.2);不存在返回 `40400`。 ### 3.10 `PUT /api/admin/users/:id` 编辑用户资料(昵称 / 头像 / 状态)。字段均为可选,仅在提供时更新。 **请求头**:`Authorization: Bearer ` **路径参数**:`id`(uint64)。 **请求体** ```json { "nickname": "新昵称", "avatar": "https://new-avatar.png", "status": 0 } ``` | 字段 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `nickname` | string | 否 | 昵称,提供即更新。 | | `avatar` | string | 否 | 头像 URL,提供即更新。 | | `status` | int8 | 否 | 状态:`0` 禁用,`1` 正常;非法值返回 `40000`。 | > 所有字段以指针区分「未提供」与「置空」;若全部为空则不更新,直接返回原记录。 **响应**:返回更新后的 `User` 对象。 ### 3.11 `POST /api/admin/users/:id/status` 禁用 / 启用用户。 **请求头**:`Authorization: Bearer ` **路径参数**:`id`(uint64)。 **请求体** ```json { "status": 0 } ``` | 字段 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `status` | int8 | 是(binding:`required`) | `0` 禁用,`1` 正常;非法值返回 `40000`。 | **响应**:返回更新后的 `User` 对象。 ## 4. 数据模型 ### 4.1 MiniProgram(被纳管小程序) | 字段 | 类型 | JSON | 说明 | | --- | --- | --- | --- | | `ID` | uint64 | `id` | 主键,自增。 | | `Name` | string | `name` | 名称。 | | `Description` | string | `description` | 描述。 | | `AppID` | string | `app_id` | 微信 AppID,全局唯一。 | | `AppSecret` | string | `app_secret` | **不返回**(json `-`)。 | | `Status` | int8 | `status` | `0` 停用,`1` 启用。 | | `Ext` | string | `ext` | 扩展 JSON 文本。 | | `CreatedAt` | time | `created_at` | 创建时间。 | | `UpdatedAt` | time | `updated_at` | 更新时间。 | ### 4.2 User(小程序端用户) | 字段 | 类型 | JSON | 说明 | | --- | --- | --- | --- | | `ID` | uint64 | `id` | 主键,自增。 | | `MiniID` | uint64 | `mini_id` | 所属小程序(`mini_programs.id`)。 | | `OpenID` | string | `openid` | 微信 OpenID,与 `mini_id` 共同唯一。 | | `UnionID` | string | `union_id` | 微信 UnionID(可能为空)。 | | `Nickname` | string | `nickname` | 昵称。 | | `Avatar` | string | `avatar` | 头像 URL。 | | `Status` | int8 | `status` | `0` 禁用,`1` 正常(默认 `1`)。 | | `CreatedAt` | time | `created_at` | 创建时间。 | | `UpdatedAt` | time | `updated_at` | 更新时间。 | ## 5. 配置说明(后台相关) 配置由 `configs/config.yaml` + 环境变量(支持 `${ENV}` 占位符)加载。敏感信息(DB 密码、JWT Secret)应通过环境变量注入,禁止硬编码。 | 配置项 | 说明 | | --- | --- | | `server.port` / `server.mode` | 服务端口、运行模式(`release` 时 gin 进入 ReleaseMode)。 | | `mysql.*` | MySQL 连接与连接池参数,拼装为 DSN。 | | `logging.level` / `logging.format` | 日志级别与格式(text/json)。 | | `admin.jwt_secret` | 后台 JWT 签名密钥。 | | `admin.token_ttl` | 后台 JWT 有效期(如 `24h`)。 | ## 6. 备注 - **后台账号**:`POST /api/admin/login` 当前为固定示例账号,生产环境需接入数据库与密码哈希校验。 - **小程序管理**:本分组下的 `miniapps` 接口用于纳管微信小程序配置(增删改查),是小程序端 `X-App-ID` 鉴权的数据来源。新增/修改这些接口时须同步更新本文档。 - **用户管理**:`/api/admin/users` 下的接口用于后台管理各小程序端用户(列表、详情、编辑、禁用/启用)。`User` 模型新增的 `status` 字段需手动在数据库中加列后方可生效(因项目未开启 AutoMigrate): ```sql ALTER TABLE users ADD COLUMN status TINYINT NOT NULL DEFAULT 1; ``` 新增/修改这些接口时须同步更新本文档。