本文档详细描述了 Goravel Admin 后台管理系统的所有 API 接口。
- Base URL:
http://localhost:3000/api/admin - 认证方式: JWT Bearer Token
- 请求格式: JSON
- 响应格式: JSON
为避免文档与实现漂移,当前以 routes/admin.go 和 Swagger 产物为准。以下是已对齐的关键接口:
- 认证与会话:
POST /loginGET /login/captchaGET /infoPOST /logoutGET /heartbeat
- 通知中心:
GET /notificationsGET /notifications/unread-countGET /notifications/recentPOST /notifications/ws-ticket(获取一次性 WS ticket)POST /notifications/{id}/readPOST /notifications/read-all
- WebSocket:
GET /ws/admin/notifications(非/api/admin/*前缀)- 仅支持
ticket参数进行鉴权,不再支持tokenquery
- 日志:
GET /operation-logsGET /login-logsGET /system-logs
- 监控:
GET /monitor/system-infoGET /monitor/system-info/stream
说明:本文后续部分若与上述不一致,请以上述“契约同步说明”和实际路由为准。
POST /loginGET /login/captchaGET /infoPOST /logoutGET /heartbeatPUT /profilePUT /password
GET /notificationsGET /notifications/unread-countGET /notifications/recentPOST /notifications/ws-ticketPOST /notifications/{id}/readPOST /notifications/read-allPOST /notificationsGET /ws/admin/notifications?ticket={ticket}
GET /operation-logsGET /login-logsGET /system-logsGET /dashboard/countGET /dashboard/user-access-sourceGET /dashboard/weekly-user-activityGET /dashboard/monthly-salesGET /dashboard/recent-activitiesGET /dashboard/streamGET /monitor/system-infoGET /monitor/system-info/stream
GET /usersPOST /users/{id}/update-balancePUT /users/{id}/passwordPOST /users/exportGET /user-balance-logsPOST /user-balance-logsGET /user-balance-logs/statisticsGET /ordersPOST /orders/exportPOST /orders/importGET /orders/export/status/{id}GET /paymentsGET /payments/{id}POST /payments/exportGET /payments/export/status/{id}
GET /attachmentsPOST /attachments/uploadPOST /attachments/chunk(action=init|upload|merge)GET /attachments/chunk(action=progress)GET /attachments/{id}/previewGET /attachments/{id}/downloadPUT /attachments/{id}/display-nameDELETE /attachments/{id}POST /attachments/batch-deleteGET /exportsGET /exports/{id}/downloadDELETE /exports/{id}POST /exports/batch-delete
{
"code": 200,
"message": "操作成功",
"data": {}
}{
"code": 200,
"message": "操作成功",
"data": {
"list": [],
"page": 1,
"page_size": 10,
"total": 100
}
}{
"code": 400,
"message": "错误信息",
"data": null
}| 状态码 | 说明 |
|---|---|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未认证或 Token 过期 |
| 403 | 无权限访问 |
| 404 | 资源不存在 |
| 422 | 验证失败 |
| 500 | 服务器内部错误 |
POST /login请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
| captcha_id | string | 否 | 验证码ID |
| captcha_code | string | 否 | 验证码 |
请求示例:
{
"username": "admin",
"password": "admin123"
}响应示例:
{
"code": 200,
"message": "登录成功",
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"expires_at": "2024-01-01T12:00:00Z"
}
}POST /logout
Authorization: Bearer {token}响应示例:
{
"code": 200,
"message": "退出成功",
"data": null
}GET /login/captcha响应示例:
{
"code": 200,
"data": {
"captcha_id": "abc123",
"captcha_image": "data:image/png;base64,..."
}
}GET /info
Authorization: Bearer {token}响应示例:
{
"code": 200,
"data": {
"id": 1,
"username": "admin",
"nickname": "超级管理员",
"email": "admin@example.com",
"avatar": "",
"department_id": 1,
"department": {
"id": 1,
"name": "总部"
},
"roles": [
{
"id": 1,
"name": "超级管理员",
"slug": "super-admin"
}
],
"permissions": ["admin.index", "admin.store", "..."],
"menus": []
}
}PUT /password
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| old_password | string | 是 | 原密码 |
| password | string | 是 | 新密码 |
| password_confirmation | string | 是 | 确认新密码 |
GET /admins
Authorization: Bearer {token}查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| page | int | 页码,默认 1 |
| page_size | int | 每页条数,默认 10 |
| username | string | 用户名(模糊搜索) |
| nickname | string | 昵称(模糊搜索) |
| status | int | 状态:0-禁用,1-启用 |
| department_id | int | 部门ID |
| order_by | string | 排序,如 id:desc |
响应示例:
{
"code": 200,
"data": {
"list": [
{
"id": 1,
"username": "admin",
"nickname": "超级管理员",
"email": "admin@example.com",
"phone": "",
"avatar": "",
"status": 1,
"department_id": 1,
"department": {"id": 1, "name": "总部"},
"roles": [{"id": 1, "name": "超级管理员"}],
"created_at": "2024-01-01T00:00:00Z",
"last_login_at": "2024-01-01T12:00:00Z"
}
],
"page": 1,
"page_size": 10,
"total": 1
}
}POST /admins
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名(唯一) |
| password | string | 是 | 密码 |
| nickname | string | 是 | 昵称 |
| string | 否 | 邮箱 | |
| phone | string | 否 | 手机号 |
| avatar | string | 否 | 头像URL |
| department_id | int | 否 | 部门ID |
| role_ids | []int | 否 | 角色ID数组 |
| status | int | 否 | 状态,默认 1 |
GET /admins/{id}
Authorization: Bearer {token}PUT /admins/{id}
Authorization: Bearer {token}DELETE /admins/{id}
Authorization: Bearer {token}PUT /admins/{id}/password
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| password | string | 是 | 新密码 |
GET /roles
Authorization: Bearer {token}查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| page | int | 页码 |
| page_size | int | 每页条数 |
| name | string | 角色名称(模糊搜索) |
| status | int | 状态 |
POST /roles
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 角色名称 |
| slug | string | 是 | 角色标识(唯一) |
| description | string | 否 | 描述 |
| permission_ids | []int | 否 | 权限ID数组 |
| menu_ids | []int | 否 | 菜单ID数组 |
| status | int | 否 | 状态 |
| sort | int | 否 | 排序 |
GET /roles/{id}
Authorization: Bearer {token}PUT /roles/{id}
Authorization: Bearer {token}DELETE /roles/{id}
Authorization: Bearer {token}GET /menus
Authorization: Bearer {token}响应示例:
{
"code": 200,
"data": {
"list": [
{
"id": 1,
"parent_id": 0,
"title": "系统管理",
"slug": "system",
"icon": "Setting",
"path": "/system",
"component": "",
"type": 1,
"status": 1,
"sort": 1,
"children": [
{
"id": 2,
"parent_id": 1,
"title": "管理员管理",
"slug": "admin",
"path": "/system/admin",
"component": "admin/AdminList",
"type": 2,
"status": 1
}
]
}
]
}
}POST /menus
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| parent_id | int | 否 | 父级ID,默认 0 |
| title | string | 是 | 菜单标题 |
| slug | string | 是 | 菜单标识 |
| icon | string | 否 | 图标名称 |
| path | string | 否 | 路由路径 |
| component | string | 否 | 组件路径 |
| type | int | 是 | 类型:1-目录,2-菜单,3-按钮 |
| status | int | 否 | 状态 |
| sort | int | 否 | 排序 |
GET /menus/{id}
Authorization: Bearer {token}PUT /menus/{id}
Authorization: Bearer {token}DELETE /menus/{id}
Authorization: Bearer {token}GET /permissions
Authorization: Bearer {token}POST /permissions
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 权限名称 |
| slug | string | 是 | 权限标识(唯一) |
| method | string | 是 | HTTP 方法(GET/POST/PUT/DELETE) |
| path | string | 是 | API 路径 |
| menu_id | int | 否 | 关联菜单ID |
| status | int | 否 | 状态 |
PUT /permissions/{id}
Authorization: Bearer {token}DELETE /permissions/{id}
Authorization: Bearer {token}GET /departments
Authorization: Bearer {token}POST /departments
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 部门名称 |
| parent_id | int | 否 | 父部门ID |
| leader | string | 否 | 负责人 |
| phone | string | 否 | 联系电话 |
| string | 否 | 邮箱 | |
| status | int | 否 | 状态 |
| sort | int | 否 | 排序 |
PUT /departments/{id}
Authorization: Bearer {token}DELETE /departments/{id}
Authorization: Bearer {token}GET /dictionaries
Authorization: Bearer {token}POST /dictionaries
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| parent_id | int | 否 | 父级ID(0为字典类型) |
| name | string | 是 | 名称 |
| code | string | 是 | 编码 |
| value | string | 否 | 值 |
| description | string | 否 | 描述 |
| status | int | 否 | 状态 |
| sort | int | 否 | 排序 |
PUT /dictionaries/{id}
Authorization: Bearer {token}DELETE /dictionaries/{id}
Authorization: Bearer {token}GET /blacklists
Authorization: Bearer {token}POST /blacklists
Authorization: Bearer {token}请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ip | string | 是 | IP地址(支持单IP、CIDR、范围) |
| remark | string | 否 | 备注 |
| status | int | 否 | 状态 |
IP 格式示例:
- 单个 IP:
192.168.1.100 - CIDR 格式:
192.168.1.0/24 - IP 范围:
192.168.1.1-192.168.1.100
PUT /blacklists/{id}
Authorization: Bearer {token}DELETE /blacklists/{id}
Authorization: Bearer {token}DELETE /blacklists/batch
Authorization: Bearer {token}请求参数:
{
"ids": [1, 2, 3]
}GET /operation-logs
Authorization: Bearer {token}查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| admin_id | int | 管理员ID |
| module | string | 模块 |
| action | string | 操作 |
| start_date | string | 开始日期 |
| end_date | string | 结束日期 |
GET /login-logs
Authorization: Bearer {token}查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| admin_id | int | 管理员ID |
| ip | string | IP地址 |
| status | int | 状态:0-失败,1-成功 |
| start_date | string | 开始日期 |
| end_date | string | 结束日期 |
GET /system-logs
Authorization: Bearer {token}查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| level | string | 日志级别(error/warning/info/debug) |
| trace_id | string | 追踪ID |
| start_date | string | 开始日期 |
| end_date | string | 结束日期 |
GET /dashboard/count
Authorization: Bearer {token}响应示例:
{
"code": 200,
"data": {
"admin_count": 10,
"role_count": 5,
"menu_count": 30,
"login_count_today": 15,
"operation_count_today": 100,
"recent_logins": [],
"recent_operations": []
}
}GET /online-admins
Authorization: Bearer {token}DELETE /online-admins/{id}
Authorization: Bearer {token}POST /online-admins/batch-kick-out
Authorization: Bearer {token}请求参数:
{
"token_ids": "1,2,3"
}GET /monitor/system-info
Authorization: Bearer {token}GET /monitor/system-info/stream
Authorization: Bearer {token}响应示例:
{
"code": 200,
"data": {
"cpu": {
"cores": 8,
"usage": 25.5
},
"memory": {
"total": 16384,
"used": 8192,
"usage": 50.0
},
"disk": {
"total": 512000,
"used": 256000,
"usage": 50.0
},
"go": {
"version": "go1.21",
"goroutines": 50,
"gc_pause": "1.2ms"
}
}
}POST /attachments/upload
Authorization: Bearer {token}
Content-Type: multipart/form-data请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | file | 是 | 文件 |
| type | string | 否 | 类型(image/document/video) |
POST /attachments/chunk
Authorization: Bearer {token}
Content-Type: multipart/form-data说明:当前分片上传采用统一接口,通过
action参数区分:
action=init:初始化action=upload:上传分片action=merge:合并分片action=progress:查询进度(通常 GET)
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | file | 是 | 分片文件 |
| chunk_id | string | 是 | 分片标识 |
| chunk_index | int | 是 | 分片索引 |
| total_chunks | int | 是 | 总分片数 |
| filename | string | 是 | 原始文件名 |
POST /attachments/chunk
Authorization: Bearer {token}
Content-Type: multipart/form-data请求参数:
{
"chunk_id": "abc123",
"filename": "large-file.zip",
"total_chunks": 10
}POST /notifications/ws-ticket
Authorization: Bearer {token}响应示例:
{
"code": 200,
"message": "success",
"data": {
"ticket": "01jvxxxxxxxxxxxxxxxxxxxxxx",
"expires_in": 60
}
}ws://localhost:3000/ws/admin/notifications?ticket={ticket}
消息格式:
{
"type": "notification",
"data": {
"id": 1,
"title": "新通知",
"content": "通知内容",
"created_at": "2024-01-01T12:00:00Z"
}
}GET /notifications
Authorization: Bearer {token}POST /notifications/{id}/read
Authorization: Bearer {token}POST /notifications/read-all
Authorization: Bearer {token}错误码定义在 app/errors/codes.go,格式为 XXYYYY:
XX: 模块 (10-认证, 20-权限, 30-验证, 40-业务, 50-系统)YYYY: 具体错误
| 错误码 | 说明 |
|---|---|
| 10001 | 用户名或密码错误 |
| 10002 | 账号已被禁用 |
| 10003 | Token 已过期 |
| 10004 | Token 已被撤销 |
| 10005 | 验证码错误 |
| 10006 | 登录尝试次数超限 |
| 10007 | Token 无效 |
| 错误码 | 说明 |
|---|---|
| 20001 | 无权限访问 |
| 20002 | 资源不存在 |
| 20003 | 访问被拒绝 |
| 错误码 | 说明 |
|---|---|
| 30001 | 参数验证失败 |
| 30002 | 数据已存在 |
| 30003 | 数据不存在 |
| 30004 | 格式无效 |
| 错误码 | 说明 |
|---|---|
| 40001 | 操作失败 |
| 40002 | 删除失败 |
| 40003 | 更新失败 |
| 40004 | 创建失败 |
| 40005 | 上传失败 |
| 40006 | 导出失败 |
| 错误码 | 说明 |
|---|---|
| 50001 | 服务器内部错误 |
| 50002 | 数据库错误 |
| 50003 | 缓存错误 |
| 50004 | 队列错误 |
| 50005 | 第三方服务错误 |
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...所有列表接口支持以下分页参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| page | int | 1 | 页码 |
| page_size | int | 10 | 每页条数(最大 100) |
| order_by | string | id:desc | 排序(字段:方向) |
所有时间字段使用 ISO 8601 格式:2024-01-01T12:00:00Z
- 后端审计时间(如
created_at/updated_at)以统一基准存储与返回。 - 仅当请求显式携带时区信息时,后端才会对响应中的时间字段做展示层转换。
- 支持以下时区输入(优先级从高到低):
timezone参数、X-Timezone请求头、Timezone请求头。 - 未携带时区时,不执行响应时间字段转换,返回后端原值。
- 默认转换字段白名单:
created_at、updated_at、deleted_at(兼容驼峰命名)。 - 可通过配置
app.response_time_fields(逗号分隔)扩展需要转换的字段。
通过请求头指定语言:
Accept-Language: zh-CN支持的语言:
zh-CN- 简体中文en-US- English