API.md 9.2 KB

后端 API 文档

微前端平台后端服务(Spring Boot 2.7 / Java 8 / SQLite)。本文档列出当前全部 HTTP 接口、鉴权要求与示例。

  • Base URL:http://<host>:8080
  • Content-Type:application/json
  • 统一错误响应格式:

    { "code": "ERROR_CODE", "message": "错误描述" }
    

鉴权说明

级别 说明
免鉴权 无需 Token,见各接口标注"免鉴权"
登录态 请求头携带 Authorization: Bearer <token> 即可
角色 需 @RequireRole,如 ADMIN
权限点 需 @RequirePermission,如 user:list

角色/权限随 JWT 下发,修改角色或权限后需重新登录 获取新 Token 生效。

默认管理员:admin / admin123(配置于 application.yml 的 mf.auth.admin)。


1. 基础

GET /api/hello

免鉴权。连通性验证。

响应 200

{ "message": "Hello from backend", "serverTime": "2026-09-22T14:00:00" }

2. 数据源

GET /api/datasource/info

免鉴权。当前数据源信息与健康检查。

响应 200

{ "type": "sqlite", "ping": true, "serverNow": "2026-09-22 14:00:00" }

GET /api/datasource/users

登录态。查询演示用户列表(表 demo_user)。

响应 200

[
  { "id": 1, "name": "Alice", "created_at": "2026-09-22 14:00:00" }
]

POST /api/datasource/users

登录态。新增演示用户。

请求体

{ "name": "Alice" }

响应 200

{ "affected": 1, "name": "Alice" }

POST /api/datasource/users/batch

登录态。批量新增演示用户。

查询参数:prefix(String,前缀)、count(int,数量)

响应 200

{ "affected": 100 }

3. 认证 Auth

POST /api/auth/register

免鉴权。注册,默认分配 USER 角色。

请求体

{ "username": "alice", "password": "123456", "nickname": "爱丽丝" }

响应 200(失败:USER_EXISTS 用户名已存在 / BAD_REQUEST 参数不合法)

{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "tokenType": "Bearer",
  "expiresIn": 7200,
  "id": 2,
  "username": "alice",
  "nickname": "爱丽丝",
  "roles": ["USER"],
  "permissions": []
}

POST /api/auth/login

免鉴权。登录。

请求体

{ "username": "admin", "password": "admin123" }

响应 200(失败:BAD_CREDENTIALS 账号或密码错误 / USER_DISABLED 账号禁用)

{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "tokenType": "Bearer",
  "expiresIn": 7200,
  "id": 1,
  "username": "admin",
  "nickname": "管理员",
  "roles": ["ADMIN"],
  "permissions": ["user:list", "user:create", "role:assign", "..."]
}

GET /api/auth/me

登录态(@RequireAuth)。返回当前登录用户信息。

响应 200(未登录:401 {"code":"UNAUTHORIZED","message":"请先登录"})

{ "id": 1, "username": "admin", "nickname": "管理员", "roles": ["ADMIN"], "permissions": ["..."] }

4. RBAC 用户权限管理

以下接口均需 ADMIN 角色;权限收回时返回 403 {"code":"FORBIDDEN","message":"无角色权限"} 或 无操作权限。

4.1 角色

GET /api/rbac/roles

权限点:role:list。角色列表(含用户数)。

响应 200

[
  { "id": 1, "code": "ADMIN", "name": "超级管理员", "description": null, "created_at": "...", "user_count": 1 }
]

POST /api/rbac/roles

权限点:role:create。创建角色。

请求体

{ "code": "EDITOR", "name": "编辑", "description": "内容编辑" }

响应 200(ROLE_EXISTS:编码已存在)

PUT /api/rbac/roles/{id}

权限点:role:update。更新角色名称/描述。

请求体

{ "name": "资深编辑", "description": "..." }

响应 200(NOT_FOUND:角色不存在)

DELETE /api/rbac/roles/{id}

权限点:role:delete。删除角色(级联清理关联关系)。

响应 200 { "deleted": 3 }

GET /api/rbac/roles/{id}/permissions

权限点:role:assign。查询角色拥有的权限列表。

响应 200

{
  "role": { "id": 1, "code": "ADMIN", "name": "超级管理员" },
  "permissions": [ { "id": 1, "code": "user:list", "name": "user:list" } ]
}

POST /api/rbac/roles/{id}/permissions

权限点:role:assign。覆盖式设置角色拥有的权限。

请求体

{ "ids": [1, 2, 3] }

响应 200:同 GET /api/rbac/roles/{id}/permissions

4.2 权限

GET /api/rbac/permissions

权限点:permission:list。权限点列表。

响应 200

[
  { "id": 1, "code": "user:list", "name": "user:list", "description": null, "created_at": "..." }
]

POST /api/rbac/permissions

权限点:permission:create。新增权限点。

请求体

{ "code": "report:export", "name": "导出报表", "description": "..." }

响应 200(PERMISSION_EXISTS:编码已存在)

DELETE /api/rbac/permissions/{id}

权限点:permission:delete。删除权限点(级联清理关联关系)。

响应 200 { "deleted": 5 }

4.3 用户授权

POST /api/rbac/users/{id}/roles

权限点:role:assign。覆盖式设置用户拥有的角色。

请求体

{ "ids": [1, 2] }

响应 200:同 GET /api/rbac/users/{id}/auth

GET /api/rbac/users/{id}/auth

权限点:role:assign。查询用户的角色与权限。

响应 200

{
  "userId": 2,
  "roles": [ { "id": 2, "code": "USER", "name": "普通用户" } ],
  "permissions": [ { "id": 6, "code": "data:query", "name": "data:query" } ]
}

4.4 当前用户

GET /api/rbac/me

登录态。当前登录用户的角色与权限(同 /api/auth/me 的 roles/permissions,从库中实时查)。

响应 200

{
  "userId": 1,
  "roles": [ { "id": 1, "code": "ADMIN", "name": "超级管理员" } ],
  "permissions": [ "..." ]
}

5. 菜单权限 Menu

独立菜单权限体系,与接口权限(sys_permission)完全解耦:菜单可见性只由“用户的角色 → 角色被授予的菜单”决定(sys_role_menu),不依赖任何权限点编码。

因此管理端接口仅校验 ADMIN 角色(不使用 @RequirePermission);/current 实时查库返回,修改菜单授权后无需重新登录即可生效(这与角色/权限需重新登录的机制不同)。

用户可见菜单树 = 其所有角色被授予菜单的并集,下发时自动向上补全父级、剔除空目录。

GET /api/menu/current

登录态(@RequireAuth)。当前用户可见菜单树。

响应 200(未登录:401)

[
  {
    "id": 1, "parent_id": null, "name": "工作台", "type": "menu",
    "route": "/dashboard", "component": "dashboard/index", "icon": "HomeFilled",
    "sort": 1, "visible": 1, "status": 1, "created_at": "...", "children": []
  },
  {
    "id": 2, "parent_id": null, "name": "系统管理", "type": "dir",
    "route": null, "component": null, "icon": "Setting",
    "sort": 1, "visible": 1, "status": 1, "created_at": "...",
    "children": [
      {
        "id": 3, "parent_id": 2, "name": "用户管理", "type": "menu",
        "route": "/system/user", "component": "system/user/index", "icon": "User",
        "sort": 1, "visible": 1, "status": 1, "created_at": "...", "children": []
      }
    ]
  }
]

GET /api/menu/tree

角色:ADMIN。全量菜单树(管理端,含停用/隐藏项)。

响应 200:同上树形结构,返回全部节点。

POST /api/menu

角色:ADMIN。新建菜单(自动授权给 ADMIN 角色)。

请求体

{
  "parentId": null,
  "name": "报表中心",
  "type": "menu",
  "route": "/report",
  "component": "report/index",
  "icon": "DataAnalysis",
  "sort": 3,
  "visible": 1,
  "status": 1
}

响应 200:新建后的菜单记录(NOT_FOUND 不存在 / PARAM 名称缺失)。

PUT /api/menu/{id}

角色:ADMIN。更新菜单(缺失字段沿用原值)。

请求体:同 POST(可只传需改字段)。

响应 200:更新后的菜单记录(NOT_FOUND:菜单不存在)。

DELETE /api/menu/{id}

角色:ADMIN。删除菜单,级联删除其全部子菜单并清理 sys_role_menu 关联。

响应 200 { "deleted": 6 }

GET /api/menu/role/{roleId}

角色:ADMIN。查询某角色被授予的菜单 id 列表。

响应 200

[ 1, 3, 7 ]

POST /api/menu/role/{roleId}

角色:ADMIN。覆盖式设置某角色拥有的菜单。

请求体

{ "ids": [1, 3, 7] }

响应 200

{ "roleId": 3, "menuIds": [1, 3, 7] }

6. 常见错误码

code HTTP 说明
TOKEN_INVALID 200 Token 无效或已过期
UNAUTHORIZED 401 未登录(见 /api/auth/me、拦截器)
FORBIDDEN 403 无角色/权限
BAD_CREDENTIALS 200 用户名或密码错误
USER_EXISTS 200 用户名已被注册
USER_DISABLED 200 账号已禁用
USER_NOT_FOUND 200 用户不存在
ROLE_EXISTS / PERMISSION_EXISTS 200 编码重复
NOT_FOUND 200 资源不存在
BAD_REQUEST 200 请求参数不合法
DB_ERROR 500 数据源异常
INTERNAL_ERROR 500 服务器内部错误