Files

19 KiB
Raw Permalink Blame History

Sundynix 前端接入文档

网关地址:http://{GATEWAY_HOST}:8888 所有接口统一经过网关转发,前端只需对接网关地址


一、全局约定

1.1 统一响应格式

所有接口返回 HTTP 200,通过 code 区分业务状态:

{
  "code": 200,
  "msg": "success",
  "data": { ... }
}
code 含义
200 成功
400 业务错误(参数错误、逻辑异常等)
401 未授权(Token 缺失/过期/无效)

1.2 鉴权机制

需要鉴权的接口必须携带以下请求头:

Authorization: Bearer <token>
X-Client-Id: <客户端标识>

Important

  • Authorization 从登录接口获取
  • X-Client-Id 由后台管理端配置的客户端标识(如 sundynix-adminmini-app

1.3 Token 自动续期

网关内置滑动窗口续期机制。当 Token 剩余有效时间 < 1 小时时,响应头会携带新 Token:

X-Refresh-Token: <new_token>

前端需要在响应拦截器中处理:

// axios 响应拦截器
axios.interceptors.response.use((response) => {
  const newToken = response.headers['x-refresh-token']
  if (newToken) {
    // 静默替换本地存储的 Token
    useUserStore().setToken(newToken)
  }
  return response
})

1.4 CORS 说明

网关已配置跨域,前端无需额外处理。已暴露自定义响应头 X-Refresh-Token


二、Auth 服务(/api/auth

2.1 获取图形验证码

🔓 无需鉴权

GET /api/auth/captcha

响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "captchaId": "abc123",
    "captchaImg": "data:image/png;base64,iVBOR..."
  }
}
字段 类型 说明
captchaId string 验证码 ID,登录时回传
captchaImg string Base64 图片,直接赋给 <img src>

2.2 账号密码登录

🔓 无需鉴权

POST /api/auth/login

请求头

X-Client-Id: sundynix-admin

请求体

{
  "account": "admin",
  "password": "123456",
  "captchaId": "abc123",
  "captcha": "5xmn"
}
字段 必填 说明
account 账号
password 密码
captchaId 验证码 ID(从 captcha 接口获取)
captcha 用户输入的验证码

响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "userInfo": {
      "id": "1234567890",
      "name": "张三",
      "account": "admin",
      "nickName": "管理员",
      "phone": "13800138000",
      "avatarId": "file-id-xxx",
      "gender": 1
    }
  }
}

2.3 微信小程序登录

🔓 无需鉴权

POST /api/auth/miniLogin

请求体

{
  "code": "wx_login_code_from_wx.login()",
  "clientId": "mini-app"
}

响应:同 2.2 的响应格式


2.4 手机号登录

🔓 无需鉴权

POST /api/auth/loginByPhone

请求体

{
  "code": "phone_code_from_getPhoneNumber",
  "openId": "用户openId",
  "clientId": "mini-app"
}

响应:同 2.2 的响应格式


2.5 获取当前用户信息(含角色、菜单)

🔒 需要鉴权

GET /api/auth/info

响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "id": "1234567890",
    "name": "张三",
    "account": "admin",
    "nickName": "管理员",
    "phone": "13800138000",
    "avatarId": "file-id-xxx",
    "gender": 1,
    "roles": ["admin", "editor"],
    "menus": [
      {
        "id": "m1",
        "parentId": "0",
        "category": 1,
        "name": "Dashboard",
        "title": "仪表盘",
        "code": "dashboard",
        "path": "/dashboard",
        "permission": "",
        "locale": "menu.dashboard",
        "icon": "icon-dashboard",
        "sort": 1,
        "children": [
          {
            "id": "m2",
            "parentId": "m1",
            "name": "Workplace",
            "title": "工作台",
            "path": "/dashboard/workplace",
            "sort": 1,
            "children": []
          }
        ]
      }
    ],
    "createdAt": 1714000000
  }
}

Tip

  • roles 是角色 code 数组,用于前端权限判断
  • menus 是树形结构,已按 sort 排序,前端直接渲染侧边栏
  • createdAt 是 Unix 时间戳(秒)

2.6 更新个人信息

🔒 需要鉴权

POST /api/auth/update

请求体(所有字段可选,只传需要修改的):

{
  "name": "李四",
  "nickName": "小李",
  "phone": "13900139000",
  "avatarId": "new-file-id"
}

响应

{ "code": 200, "msg": "success" }

三、System 服务(/api/sys

Important

以下所有接口均需要鉴权(Authorization: Bearer <token>


3.1 客户端管理

创建客户端

POST /api/sys/client/create
{
  "clientId": "sundynix-admin",
  "name": "Web管理端",
  "grantType": "password",
  "additionalInfo": "",
  "activeTimeout": 7200
}
字段 必填 说明
clientId 客户端唯一标识
name 客户端名称
grantType 授权类型
additionalInfo 附加信息
activeTimeout Token 有效期(秒),默认 7200

更新客户端

POST /api/sys/client/update
{
  "id": "客户端记录ID",
  "name": "新名称",
  "activeTimeout": 3600
}

删除客户端

POST /api/sys/client/delete
{ "ids": ["id1", "id2"] }

客户端列表

POST /api/sys/client/list
{
  "current": 1,
  "pageSize": 10,
  "name": ""
}

响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "list": [
      {
        "id": "xxx",
        "clientId": "sundynix-admin",
        "name": "Web管理端",
        "grantType": "password",
        "additionalInfo": "",
        "activeTimeout": 7200
      }
    ],
    "total": 1,
    "current": 1,
    "size": 10
  }
}

3.2 角色管理

创建角色

POST /api/sys/role/create
{
  "name": "管理员",
  "code": "admin",
  "sort": 1,
  "menuIds": ["menu-id-1", "menu-id-2"]
}

更新角色

POST /api/sys/role/update
{
  "id": "角色ID",
  "name": "超级管理员",
  "code": "super-admin",
  "sort": 0,
  "menuIds": ["menu-id-1", "menu-id-2", "menu-id-3"]
}

Note

menuIds全量替换,传什么就关联什么。不传或空数组则清除所有菜单关联。

删除角色

POST /api/sys/role/delete
{ "ids": ["role-id-1"] }

角色列表

POST /api/sys/role/list
{
  "current": 1,
  "pageSize": 10,
  "name": ""
}

响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "list": [
      {
        "id": "xxx",
        "name": "管理员",
        "code": "admin",
        "sort": 1,
        "menuIds": ["m1", "m2"]
      }
    ],
    "total": 1
  }
}

3.3 菜单管理

创建菜单

POST /api/sys/menu/create
{
  "parentId": "0",
  "category": 1,
  "name": "Dashboard",
  "title": "仪表盘",
  "code": "dashboard",
  "path": "/dashboard",
  "permission": "",
  "locale": "menu.dashboard",
  "icon": "icon-dashboard",
  "sort": 1
}
字段 说明
parentId 父级ID,顶级菜单传 "0" 或空字符串
category 类型:1=菜单 2=按钮/权限
name 路由 name(英文,如 Dashboard
title 显示标题(中文,如 仪表盘
code 权限标识(如 dashboard
path 路由路径(如 /dashboard
permission 操作权限标识
locale 国际化 key
icon 图标名称
sort 排序值,越小越靠前

更新菜单

POST /api/sys/menu/update
{
  "id": "菜单ID",
  "title": "新标题",
  "sort": 2
}

删除菜单

POST /api/sys/menu/delete
{ "ids": ["menu-id-1"] }

Warning

删除菜单会同步清除该菜单与所有角色的关联关系

菜单列表(树形)

GET /api/sys/menu/list

无参数。返回完整的树形菜单结构。

响应

{
  "code": 200,
  "msg": "success",
  "data": [
    {
      "id": "m1",
      "parentId": "0",
      "category": 1,
      "name": "System",
      "title": "系统管理",
      "code": "system",
      "path": "/system",
      "icon": "icon-settings",
      "sort": 99,
      "children": [
        {
          "id": "m2",
          "parentId": "m1",
          "name": "User",
          "title": "用户管理",
          "path": "/system/user",
          "sort": 1,
          "children": []
        }
      ]
    }
  ]
}

根据角色获取菜单

POST /api/sys/menu/byRole
{ "id": "角色ID" }

响应:同菜单列表格式,但只包含该角色关联的菜单


3.4 用户管理(后台管理)

用户列表

POST /api/sys/user/list
{
  "current": 1,
  "pageSize": 10,
  "name": "",
  "account": ""
}

响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "list": [
      {
        "id": "xxx",
        "name": "张三",
        "account": "admin",
        "nickName": "管理员",
        "phone": "13800138000",
        "gender": 1,
        "createdAt": 1714000000
      }
    ],
    "total": 1
  }
}

创建用户

POST /api/sys/user/create
{
  "name": "张三",
  "account": "zhangsan",
  "password": "123456",
  "phone": "13800138000",
  "nickName": "小张",
  "roleIds": ["role-id-1", "role-id-2"]
}
字段 必填 说明
name 姓名
account 账号(唯一)
password 密码
phone 手机号
nickName 昵称
roleIds 关联角色ID数组

更新用户

POST /api/sys/user/update
{
  "id": "用户ID",
  "name": "李四",
  "phone": "13900139000",
  "roleIds": ["role-id-1"]
}

删除用户

POST /api/sys/user/delete
{ "ids": ["user-id-1", "user-id-2"] }

重置密码

POST /api/sys/user/resetPassword
{
  "id": "用户ID",
  "password": "newpassword123"
}

3.5 字典管理

创建字典

POST /api/sys/dict/create
{
  "type": "gender",
  "label": "男",
  "value": "1",
  "sort": 1,
  "desc": "性别-男"
}

更新字典

POST /api/sys/dict/update
{
  "id": "字典ID",
  "label": "女",
  "value": "2"
}

删除字典

POST /api/sys/dict/delete
{ "ids": ["dict-id-1"] }

字典列表

POST /api/sys/dict/list
{
  "current": 1,
  "pageSize": 10,
  "type": "gender"
}

响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "list": [
      {
        "id": "xxx",
        "type": "gender",
        "label": "男",
        "value": "1",
        "sort": 1,
        "desc": "性别-男"
      }
    ],
    "total": 2
  }
}

3.6 操作日志

日志列表

POST /api/sys/log/list
{
  "current": 1,
  "pageSize": 20,
  "method": "POST",
  "path": "/api/auth/login",
  "status": 200
}

响应

{
  "code": 200,
  "msg": "success",
  "data": {
    "list": [
      {
        "id": "xxx",
        "clientId": "sundynix-admin",
        "ip": "192.168.1.100",
        "method": "POST",
        "path": "/api/auth/login",
        "status": 200,
        "latency": 52000000,
        "agent": "Mozilla/5.0...",
        "errorMessage": "",
        "body": "{\"account\":\"admin\"...}",
        "resp": "{\"code\":200...}",
        "userId": "user-id-xxx",
        "createdAt": 1714000000
      }
    ],
    "total": 100
  }
}

Note

latency 单位是纳秒,前端显示时需转换:(latency / 1000000).toFixed(0) + 'ms'

删除日志

POST /api/sys/log/delete
{ "ids": ["log-id-1", "log-id-2"] }

四、前端接入参考

4.1 Axios 封装建议

import axios from 'axios'

const request = axios.create({
  baseURL: 'http://192.168.100.4:8888', // 网关地址
  timeout: 10000,
})

// 请求拦截器
request.interceptors.request.use((config) => {
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  config.headers['X-Client-Id'] = 'sundynix-admin'  // 你的客户端标识
  return config
})

// 响应拦截器
request.interceptors.response.use((response) => {
  // Token 自动续期
  const newToken = response.headers['x-refresh-token']
  if (newToken) {
    localStorage.setItem('token', newToken)
  }

  const { code, msg, data } = response.data
  if (code === 401) {
    // 跳转登录
    window.location.href = '/login'
    return Promise.reject(new Error(msg))
  }
  if (code !== 200) {
    return Promise.reject(new Error(msg))
  }
  return data
})

export default request

4.2 API 分组

// api/auth.ts
export const authApi = {
  captcha: () => request.get('/api/auth/captcha'),
  login: (data: LoginReq) => request.post('/api/auth/login', data),
  getUserInfo: () => request.get('/api/auth/info'),
  updateUser: (data: UpdateUserReq) => request.post('/api/auth/update', data),
}

// api/system.ts
export const clientApi = {
  list: (data: PageReq) => request.post('/api/sys/client/list', data),
  create: (data: ClientReq) => request.post('/api/sys/client/create', data),
  update: (data: ClientUpdateReq) => request.post('/api/sys/client/update', data),
  delete: (ids: string[]) => request.post('/api/sys/client/delete', { ids }),
}

export const roleApi = {
  list: (data: PageReq) => request.post('/api/sys/role/list', data),
  create: (data: RoleReq) => request.post('/api/sys/role/create', data),
  update: (data: RoleUpdateReq) => request.post('/api/sys/role/update', data),
  delete: (ids: string[]) => request.post('/api/sys/role/delete', { ids }),
}

export const menuApi = {
  list: () => request.get('/api/sys/menu/list'),
  byRole: (id: string) => request.post('/api/sys/menu/byRole', { id }),
  create: (data: MenuReq) => request.post('/api/sys/menu/create', data),
  update: (data: MenuUpdateReq) => request.post('/api/sys/menu/update', data),
  delete: (ids: string[]) => request.post('/api/sys/menu/delete', { ids }),
}

export const userApi = {
  list: (data: UserListReq) => request.post('/api/sys/user/list', data),
  create: (data: UserCreateReq) => request.post('/api/sys/user/create', data),
  update: (data: UserUpdateReq) => request.post('/api/sys/user/update', data),
  delete: (ids: string[]) => request.post('/api/sys/user/delete', { ids }),
  resetPassword: (data: ResetPasswordReq) => request.post('/api/sys/user/resetPassword', data),
}

export const dictApi = {
  list: (data: DictListReq) => request.post('/api/sys/dict/list', data),
  create: (data: DictReq) => request.post('/api/sys/dict/create', data),
  update: (data: DictUpdateReq) => request.post('/api/sys/dict/update', data),
  delete: (ids: string[]) => request.post('/api/sys/dict/delete', { ids }),
}

export const logApi = {
  list: (data: LogListReq) => request.post('/api/sys/log/list', data),
  delete: (ids: string[]) => request.post('/api/sys/log/delete', { ids }),
}

4.3 TypeScript 类型定义

// ========== Auth ==========
interface LoginReq {
  account: string
  password: string
  captchaId: string
  captcha: string
}

interface LoginResp {
  token: string
  userInfo: UserInfo
}

interface UserInfo {
  id: string
  name: string
  account: string
  nickName: string
  phone: string
  avatarId: string
  gender: number      // 0=未知 1=男 2=女
  roles?: string[]    // 角色 code 列表(仅 /info 接口返回)
  menus?: MenuItem[]  // 菜单树(仅 /info 接口返回)
  createdAt?: number  // Unix 时间戳(秒)
}

interface MenuItem {
  id: string
  parentId: string
  category: number   // 1=菜单 2=按钮
  name: string       // 路由名(英文)
  title: string      // 显示标题(中文)
  code: string
  path: string
  permission: string
  locale: string
  icon: string
  sort: number
  children: MenuItem[]
}

// ========== System ==========
interface ClientInfo {
  id: string
  clientId: string
  name: string
  grantType: string
  additionalInfo: string
  activeTimeout: number // Token有效期(秒)
}

interface RoleInfo {
  id: string
  name: string
  code: string
  sort: number
  menuIds: string[]
}

interface DictInfo {
  id: string
  type: string
  label: string
  value: string
  sort: number
  desc: string
}

interface OperationRecordInfo {
  id: string
  clientId: string
  ip: string
  method: string
  path: string
  status: number
  latency: number   // 纳秒
  agent: string
  errorMessage: string
  body: string
  resp: string
  userId: string
  createdAt: number // Unix 时间戳(秒)
}

// ========== 通用 ==========
interface PageReq {
  current?: number
  pageSize?: number
}

interface PageResp<T> {
  list: T[]
  total: number
}

五、接口速查表

模块 方法 路径 鉴权 说明
Auth GET /api/auth/captcha 获取验证码
POST /api/auth/login 账号密码登录
POST /api/auth/miniLogin 小程序登录
POST /api/auth/loginByPhone 手机号登录
GET /api/auth/info 获取用户信息+角色+菜单
POST /api/auth/update 更新个人信息
客户端 POST /api/sys/client/create 创建客户端
POST /api/sys/client/update 更新客户端
POST /api/sys/client/delete 删除客户端
POST /api/sys/client/list 客户端列表
角色 POST /api/sys/role/create 创建角色
POST /api/sys/role/update 更新角色
POST /api/sys/role/delete 删除角色
POST /api/sys/role/list 角色列表
菜单 POST /api/sys/menu/create 创建菜单
POST /api/sys/menu/update 更新菜单
POST /api/sys/menu/delete 删除菜单
GET /api/sys/menu/list 菜单列表(树形)
POST /api/sys/menu/byRole 按角色查菜单
用户 POST /api/sys/user/list 用户列表
POST /api/sys/user/create 创建用户
POST /api/sys/user/update 更新用户
POST /api/sys/user/delete 删除用户
POST /api/sys/user/resetPassword 重置密码
字典 POST /api/sys/dict/create 创建字典
POST /api/sys/dict/update 更新字典
POST /api/sys/dict/delete 删除字典
POST /api/sys/dict/list 字典列表
日志 POST /api/sys/log/list 操作日志列表
POST /api/sys/log/delete 删除日志