md
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
# portal-mini-go 接口文档
|
||||
# portal-mini-go 后台管理接口文档
|
||||
|
||||
> 基于 Go + gin 的中后台/门户后端服务。本文档描述当前已实现的 HTTP 接口、鉴权方式、统一响应结构、错误码与数据模型。
|
||||
> 基于 Go + gin 的中后台管理后端服务。本文档描述**后台管理(`/api/admin`)**相关接口。小程序端接口见 `miniapp-api.md`。
|
||||
|
||||
## 1. 概述
|
||||
|
||||
- **基础路径**:`/`
|
||||
- **基础路径**:`/api/admin`
|
||||
- **服务地址**:由 `configs/config.yaml` 中 `server.port` 决定(默认 `8080`),例如 `http://localhost:8080`。
|
||||
- **统一响应**:所有接口均返回 `HTTP 200`,业务结果通过响应体中的 `code` 字段判断(见 §3)。
|
||||
- **路由分层**:
|
||||
- `/api/ma`:小程序端接口,通过请求头 `X-App-ID` 鉴权(校验小程序是否被纳管且启用)。
|
||||
- `/api/admin`:后台管理接口,通过 `Authorization: Bearer <JWT>` 鉴权。
|
||||
- `/healthz`:健康检查,无需鉴权。
|
||||
- **统一响应**:所有接口均返回 `HTTP 200`,业务结果通过响应体中的 `code` 字段判断(见 §2.4)。
|
||||
- **鉴权方式**:后台接口需在请求头携带 `Authorization: Bearer <JWT>`,由 `AdminAuth` 中间件校验(登录接口除外)。
|
||||
- **全局接口**:`GET /healthz` 为健康检查,无需鉴权,返回 `{"code":0,"msg":"ok","data":{"status":"ok"}}`。
|
||||
|
||||
## 2. 公共约定
|
||||
|
||||
@@ -19,8 +17,7 @@
|
||||
| Header | 必填 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `Content-Type` | 是(POST/PUT) | 固定为 `application/json`。 |
|
||||
| `X-App-ID` | 是(小程序接口) | 微信小程序的 AppID,标识调用方小程序身份。 |
|
||||
| `Authorization` | 是(后台接口) | 后台登录后下发的 JWT,格式 `Bearer <token>`。 |
|
||||
| `Authorization` | 是(登录除外) | 后台登录后下发的 JWT,格式 `Bearer <token>`。 |
|
||||
|
||||
### 2.2 统一响应结构
|
||||
|
||||
@@ -34,21 +31,19 @@
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `code` | int | 业务码。`0` 表示成功;非 `0` 表示失败(见 §3 错误码)。 |
|
||||
| `code` | int | 业务码。`0` 表示成功;非 `0` 表示失败(见 §2.4)。 |
|
||||
| `msg` | string | 结果描述。`0` 时为 `ok`,失败时为人可读信息。 |
|
||||
| `data` | object/null | 业务数据,成功时有内容,失败时通常省略。 |
|
||||
|
||||
> 约定:错误统一由 `ErrorHandler` 中间件转换,handler 内不直接散落 `c.JSON` 处理错误。
|
||||
|
||||
### 2.3 鉴权中间件
|
||||
|
||||
| 分组 | 中间件 | 校验逻辑 |
|
||||
| --- | --- | --- |
|
||||
| `/api/ma` | `MiniAppAuth` | 校验请求头 `X-App-ID` 对应一个「已启用且未删除」的被纳管小程序;通过后将 `app_id` 与小程序主键 `mini_id` 注入上下文。 |
|
||||
| `/api/admin` | `AdminAuth` | 校验 `Authorization: Bearer <JWT>`(HS256)。校验通过后将 `admin_id` 注入上下文。 |
|
||||
| 全局 | `Recovery` / `Trace` / `ErrorHandler` | panic 恢复、trace_id 注入、错误统一转换。 |
|
||||
| 中间件 | 校验逻辑 |
|
||||
| --- | --- |
|
||||
| `AdminAuth` | 校验 `Authorization: Bearer <JWT>`(HS256)。校验通过后将 `admin_id` 注入上下文;登录接口 `POST /api/admin/login` 不挂载此中间件。 |
|
||||
|
||||
## 3. 错误码
|
||||
> 全局还挂载 `Recovery`(panic 恢复)、`Trace`(注入 trace_id)、`ErrorHandler`(统一错误转换)。错误由中间件转换,handler 内不直接散落 `c.JSON` 处理错误。
|
||||
|
||||
### 2.4 错误码
|
||||
|
||||
| 业务码 | 常量 | 含义 |
|
||||
| --- | --- | --- |
|
||||
@@ -56,95 +51,16 @@
|
||||
| `40000` | `ErrBadRequest` | 请求参数错误 / 非法输入(`ext` 非合法 JSON 等) |
|
||||
| `40100` | `ErrUnauthorized` | 未认证 / 登录失败 / token 无效或过期 |
|
||||
| `40300` | `ErrForbidden` | 禁止访问 |
|
||||
| `40400` | `ErrNotFound` | 资源不存在 / 小程序未注册 |
|
||||
| `50000` | `ErrServer` | 服务内部错误(含微信调用、会话写入、token 签发等) |
|
||||
| `40400` | `ErrNotFound` | 资源不存在(如小程序 ID 不存在) |
|
||||
| `50000` | `ErrServer` | 服务内部错误(含 token 签发等) |
|
||||
|
||||
> 非 `BizError` 的未知错误一律归为 `50000`。
|
||||
|
||||
## 4. 接口列表
|
||||
## 3. 接口列表
|
||||
|
||||
### 4.1 健康检查
|
||||
### 3.1 `POST /api/admin/login`
|
||||
|
||||
#### `GET /healthz`
|
||||
|
||||
无需鉴权。
|
||||
|
||||
**响应示例**
|
||||
|
||||
```json
|
||||
{ "code": 0, "msg": "ok", "data": { "status": "ok" } }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.2 小程序接口(前缀 `/api/ma`)
|
||||
|
||||
所有接口需在请求头携带 `X-App-ID`(已启用且被纳管的小程序)。当前示例实现为 `app1`,后续小程序按相同结构扩展。
|
||||
|
||||
#### `POST /api/ma/login`
|
||||
|
||||
小程序登录:通过微信 `code2session` 换取 `openid`/`unionid`,落库用户并向客户端下发会话 token。
|
||||
|
||||
**请求头**
|
||||
|
||||
```
|
||||
X-App-ID: <微信小程序 AppID>
|
||||
```
|
||||
|
||||
**请求体**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "081abc..." // 必填,微信登录 code
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `code` | string | 是 | 小程序 `wx.login` 获取的临时登录 code。 |
|
||||
|
||||
**响应**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"token": "a1b2c3...48位hex字符串",
|
||||
"user": {
|
||||
"id": 1,
|
||||
"mini_id": 3,
|
||||
"openid": "oABC...",
|
||||
"union_id": "oXYZ...",
|
||||
"nickname": "",
|
||||
"avatar": "",
|
||||
"created_at": "2026-10-25T10:00:00Z",
|
||||
"updated_at": "2026-10-25T10:00:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `token` 为 `24` 字节随机值的 hex 编码(48 字符),对应会话在 Redis/内存存储中保留 `7` 天。后续小程序业务接口应携带该 token 完成用户身份识别。
|
||||
|
||||
**curl 示例**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/ma/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-App-ID: wx1234567890" \
|
||||
-d '{"code":"081abc..."}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.3 后台管理接口(前缀 `/api/admin`)
|
||||
|
||||
所有接口需在请求头携带 `Authorization: Bearer <JWT>`。
|
||||
|
||||
#### `POST /api/admin/login`
|
||||
|
||||
后台管理员登录,签发 JWT。
|
||||
后台管理员登录,签发 JWT。无需 `Authorization` 头。
|
||||
|
||||
**请求体**
|
||||
|
||||
@@ -174,20 +90,24 @@ curl -X POST http://localhost:8080/api/admin/login \
|
||||
-d '{"username":"admin","password":"admin123"}'
|
||||
```
|
||||
|
||||
#### `GET /api/admin/info`
|
||||
### 3.2 `GET /api/admin/info`
|
||||
|
||||
受保护接口示例,需有效 JWT,返回当前管理员 ID。
|
||||
|
||||
**请求头**:`Authorization: Bearer <JWT>`
|
||||
|
||||
**响应**
|
||||
|
||||
```json
|
||||
{ "code": 0, "msg": "ok", "data": { "admin_id": "1" } }
|
||||
```
|
||||
|
||||
#### `POST /api/admin/miniapps`
|
||||
### 3.3 `POST /api/admin/miniapps`
|
||||
|
||||
新建被纳管小程序。
|
||||
|
||||
**请求头**:`Authorization: Bearer <JWT>`
|
||||
|
||||
**请求体**
|
||||
|
||||
```json
|
||||
@@ -206,16 +126,18 @@ curl -X POST http://localhost:8080/api/admin/login \
|
||||
| `name` | string | 是 | 小程序名称。 |
|
||||
| `description` | string | 否 | 描述。 |
|
||||
| `app_id` | string | 是 | 微信 AppID,全局唯一。 |
|
||||
| `app_secret` | string | 是 | 微信 AppSecret(不会在响应中返回)。 |
|
||||
| `app_secret` | string | 是 | 微信 AppSecret(**不会在响应中返回**)。 |
|
||||
| `status` | int8 | 否 | 状态:`0` 停用,`1` 启用。缺省为 `1`。 |
|
||||
| `ext` | string | 否 | 扩展字段,必须为合法 JSON 字符串(允许空串)。 |
|
||||
|
||||
**响应**:返回创建后的 `MiniProgram` 对象(见 §5.1),`app_secret` 字段不返回。
|
||||
**响应**:返回创建后的 `MiniProgram` 对象(见 §4.1),`app_secret` 字段不返回。
|
||||
|
||||
#### `PUT /api/admin/miniapps/:id`
|
||||
### 3.4 `PUT /api/admin/miniapps/:id`
|
||||
|
||||
按 ID 局部更新小程序。
|
||||
|
||||
**请求头**:`Authorization: Bearer <JWT>`
|
||||
|
||||
**路径参数**
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
@@ -238,18 +160,22 @@ curl -X POST http://localhost:8080/api/admin/login \
|
||||
|
||||
**响应**:返回更新后的 `MiniProgram` 对象。
|
||||
|
||||
#### `GET /api/admin/miniapps/:id`
|
||||
### 3.5 `GET /api/admin/miniapps/:id`
|
||||
|
||||
查询单个小程序。
|
||||
|
||||
**请求头**:`Authorization: Bearer <JWT>`
|
||||
|
||||
**路径参数**:`id`(uint64)。
|
||||
|
||||
**响应**:返回 `MiniProgram` 对象;不存在返回 `40400`。
|
||||
|
||||
#### `GET /api/admin/miniapps`
|
||||
### 3.6 `GET /api/admin/miniapps`
|
||||
|
||||
分页列表查询小程序。
|
||||
|
||||
**请求头**:`Authorization: Bearer <JWT>`
|
||||
|
||||
**查询参数**
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
@@ -265,7 +191,7 @@ curl -X POST http://localhost:8080/api/admin/login \
|
||||
"code": 0,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"list": [ { "id": 1, "name": "示例小程序", "app_id": "wx123...", "status": 1, "...": "..." } ],
|
||||
"list": [ { "id": 1, "name": "示例小程序", "app_id": "wx123...", "status": 1 } ],
|
||||
"total": 1,
|
||||
"page": 1,
|
||||
"size": 20
|
||||
@@ -273,10 +199,19 @@ curl -X POST http://localhost:8080/api/admin/login \
|
||||
}
|
||||
```
|
||||
|
||||
#### `DELETE /api/admin/miniapps/:id`
|
||||
**curl 示例**
|
||||
|
||||
```bash
|
||||
curl "http://localhost:8080/api/admin/miniapps?status=1&page=1&size=20" \
|
||||
-H "Authorization: Bearer <JWT>"
|
||||
```
|
||||
|
||||
### 3.7 `DELETE /api/admin/miniapps/:id`
|
||||
|
||||
软删除小程序(置 `deleted_at`)。
|
||||
|
||||
**请求头**:`Authorization: Bearer <JWT>`
|
||||
|
||||
**路径参数**:`id`(uint64)。
|
||||
|
||||
**响应**
|
||||
@@ -285,16 +220,9 @@ curl -X POST http://localhost:8080/api/admin/login \
|
||||
{ "code": 0, "msg": "ok" }
|
||||
```
|
||||
|
||||
**curl 示例(列表)**
|
||||
## 4. 数据模型
|
||||
|
||||
```bash
|
||||
curl "http://localhost:8080/api/admin/miniapps?status=1&page=1&size=20" \
|
||||
-H "Authorization: Bearer <JWT>"
|
||||
```
|
||||
|
||||
## 5. 数据模型
|
||||
|
||||
### 5.1 MiniProgram(被纳管小程序)
|
||||
### 4.1 MiniProgram(被纳管小程序)
|
||||
|
||||
| 字段 | 类型 | JSON | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -308,22 +236,7 @@ curl "http://localhost:8080/api/admin/miniapps?status=1&page=1&size=20" \
|
||||
| `CreatedAt` | time | `created_at` | 创建时间。 |
|
||||
| `UpdatedAt` | time | `updated_at` | 更新时间。 |
|
||||
|
||||
### 5.2 User(小程序用户)
|
||||
|
||||
| 字段 | 类型 | JSON | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `ID` | uint64 | `id` | 主键,自增。 |
|
||||
| `MiniID` | uint64 | `mini_id` | 所属小程序主键(关联 `mini_programs.id`)。 |
|
||||
| `OpenID` | string | `openid` | 微信 openid。 |
|
||||
| `UnionID` | string | `union_id` | 微信 unionid(可为空)。 |
|
||||
| `Nickname` | string | `nickname` | 昵称。 |
|
||||
| `Avatar` | string | `avatar` | 头像 URL。 |
|
||||
| `CreatedAt` | time | `created_at` | 创建时间。 |
|
||||
| `UpdatedAt` | time | `updated_at` | 更新时间。 |
|
||||
|
||||
> 用户由 `(mini_id, open_id)` 唯一标识。
|
||||
|
||||
## 6. 配置说明
|
||||
## 5. 配置说明(后台相关)
|
||||
|
||||
配置由 `configs/config.yaml` + 环境变量(支持 `${ENV}` 占位符)加载。敏感信息(DB 密码、JWT Secret)应通过环境变量注入,禁止硬编码。
|
||||
|
||||
@@ -335,9 +248,7 @@ curl "http://localhost:8080/api/admin/miniapps?status=1&page=1&size=20" \
|
||||
| `admin.jwt_secret` | 后台 JWT 签名密钥。 |
|
||||
| `admin.token_ttl` | 后台 JWT 有效期(如 `24h`)。 |
|
||||
|
||||
## 7. 备注与后续扩展
|
||||
## 6. 备注
|
||||
|
||||
- **小程序会话**:`/api/ma/login` 返回的 token 为会话凭证,当前示例在 `/api/ma` 下仅实现 `login`;业务接口应在路由中增加基于该 token 的用户身份中间件后再登记。
|
||||
- **后台账号**:`/api/admin/login` 当前为固定示例账号,生产环境需接入数据库与密码哈希校验。
|
||||
- **会话存储**:默认 `MemoryStore`(单实例),多实例部署应替换为 Redis 实现(复用 `session.Store` 接口)。
|
||||
- **多小程序**:新增 `app2`..`app10` 时,按 `internal/handler/miniapp/app1`、`internal/service/miniapp/app1` 的目录结构各自建包,在 `router.New` 中注册即可,互不耦合。
|
||||
- **后台账号**:`POST /api/admin/login` 当前为固定示例账号,生产环境需接入数据库与密码哈希校验。
|
||||
- **小程序管理**:本分组下的 `miniapps` 接口用于纳管微信小程序配置(增删改查),是小程序端 `X-App-ID` 鉴权的数据来源。新增/修改这些接口时须同步更新本文档。
|
||||
@@ -0,0 +1,137 @@
|
||||
# portal-mini-go 小程序端接口文档
|
||||
|
||||
> 基于 Go + gin 的微信小程序后端服务。本文档描述**小程序端(`/api/ma`)**相关接口。后台管理接口见 `admin-api.md`。
|
||||
|
||||
## 1. 概述
|
||||
|
||||
- **基础路径**:`/api/ma`
|
||||
- **服务地址**:由 `configs/config.yaml` 中 `server.port` 决定(默认 `8080`),例如 `http://localhost:8080`。
|
||||
- **统一响应**:所有接口均返回 `HTTP 200`,业务结果通过响应体中的 `code` 字段判断(见 §2.4)。
|
||||
- **鉴权方式**:小程序端所有接口需在请求头携带 `X-App-ID`,由 `MiniAppAuth` 中间件校验该小程序是否被纳管且启用。
|
||||
- **全局接口**:`GET /healthz` 为健康检查,无需鉴权,返回 `{"code":0,"msg":"ok","data":{"status":"ok"}}`。
|
||||
|
||||
## 2. 公共约定
|
||||
|
||||
### 2.1 请求头
|
||||
|
||||
| Header | 必填 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `Content-Type` | 是(POST/PUT) | 固定为 `application/json`。 |
|
||||
| `X-App-ID` | 是 | 微信小程序的 AppID,标识调用方小程序身份;必须对应一个「已启用且未删除」的被纳管小程序。 |
|
||||
|
||||
### 2.2 统一响应结构
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "ok",
|
||||
"data": { }
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `code` | int | 业务码。`0` 表示成功;非 `0` 表示失败(见 §2.4)。 |
|
||||
| `msg` | string | 结果描述。`0` 时为 `ok`,失败时为人可读信息。 |
|
||||
| `data` | object/null | 业务数据,成功时有内容,失败时通常省略。 |
|
||||
|
||||
### 2.3 鉴权中间件
|
||||
|
||||
| 中间件 | 校验逻辑 |
|
||||
| --- | --- |
|
||||
| `MiniAppAuth` | 校验请求头 `X-App-ID` 对应一个「已启用且未删除」的被纳管小程序;通过后将 `app_id` 与小程序主键 `mini_id` 注入上下文,供后续 handler/service 使用。 |
|
||||
|
||||
> 全局还挂载 `Recovery`(panic 恢复)、`Trace`(注入 trace_id)、`ErrorHandler`(统一错误转换)。错误由中间件转换,handler 内不直接散落 `c.JSON` 处理错误。
|
||||
|
||||
### 2.4 错误码
|
||||
|
||||
| 业务码 | 常量 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| `0` | — | 成功 |
|
||||
| `40000` | `ErrBadRequest` | 请求参数错误 / 非法输入 |
|
||||
| `40100` | `ErrUnauthorized` | 未认证 / 登录失败 / token 无效或过期 |
|
||||
| `40300` | `ErrForbidden` | 禁止访问 |
|
||||
| `40400` | `ErrNotFound` | 资源不存在 / 小程序未注册(如 `X-App-ID` 无效) |
|
||||
| `50000` | `ErrServer` | 服务内部错误(含微信调用、会话写入等) |
|
||||
|
||||
> 非 `BizError` 的未知错误一律归为 `50000`。
|
||||
|
||||
## 3. 接口列表
|
||||
|
||||
### 3.1 `POST /api/ma/login`
|
||||
|
||||
小程序登录:通过微信 `code2session` 换取 `openid`/`unionid`,落库用户并向客户端下发会话 token。
|
||||
|
||||
**请求头**
|
||||
|
||||
```
|
||||
X-App-ID: <微信小程序 AppID>
|
||||
```
|
||||
|
||||
**请求体**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "081abc..." // 必填,微信登录 code
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `code` | string | 是 | 小程序 `wx.login` 获取的临时登录 code。 |
|
||||
|
||||
**响应**
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "ok",
|
||||
"data": {
|
||||
"token": "a1b2c3...48位hex字符串",
|
||||
"user": {
|
||||
"id": 1,
|
||||
"mini_id": 3,
|
||||
"openid": "oABC...",
|
||||
"union_id": "oXYZ...",
|
||||
"nickname": "",
|
||||
"avatar": "",
|
||||
"created_at": "2026-10-25T10:00:00Z",
|
||||
"updated_at": "2026-10-25T10:00:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `token` 为 `24` 字节随机值的 hex 编码(48 字符),对应会话保留 `7` 天。后续小程序业务接口应携带该 token 完成用户身份识别(当前示例仅实现 `login`)。
|
||||
|
||||
**curl 示例**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/ma/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-App-ID: wx1234567890" \
|
||||
-d '{"code":"081abc..."}'
|
||||
```
|
||||
|
||||
## 4. 数据模型
|
||||
|
||||
### 4.1 User(小程序用户)
|
||||
|
||||
| 字段 | 类型 | JSON | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `ID` | uint64 | `id` | 主键,自增。 |
|
||||
| `MiniID` | uint64 | `mini_id` | 所属小程序主键(关联 `mini_programs.id`)。 |
|
||||
| `OpenID` | string | `openid` | 微信 openid。 |
|
||||
| `UnionID` | string | `union_id` | 微信 unionid(可为空)。 |
|
||||
| `Nickname` | string | `nickname` | 昵称。 |
|
||||
| `Avatar` | string | `avatar` | 头像 URL。 |
|
||||
| `CreatedAt` | time | `created_at` | 创建时间。 |
|
||||
| `UpdatedAt` | time | `updated_at` | 更新时间。 |
|
||||
|
||||
> 用户由 `(mini_id, open_id)` 唯一标识。
|
||||
|
||||
## 5. 备注与后续扩展
|
||||
|
||||
- **多小程序**:新增 `app2`..`app10` 时,按 `internal/handler/miniapp/app1`、`internal/service/miniapp/app1` 的目录结构各自建包,在 `router.New` 中注册即可,互不耦合。新增小程序后须在本文档补充其接口。
|
||||
- **会话存储**:默认 `MemoryStore`(单实例),多实例部署应替换为 Redis 实现(复用 `session.Store` 接口)。
|
||||
- **业务接口**:当前 `/api/ma` 下仅实现 `login`;新增业务接口时,应在路由中增加基于会话 token 的用户身份中间件后再登记,并同步更新本文档 §3。
|
||||
Reference in New Issue
Block a user