【V3 Admin Vite 4.x】教程七:后端配套接口

9,340 阅读2分钟

前言

本系列文章是为了帮助没有直接上手(或上手比较困难)做项目能力的初级前端开发工程师采用 V3 Admin Vite 开源模板来编写业务代码。

如果你是一个有经验的朋友,那建议你直接阅读文档即可:V3 Admin Vite 中文文档,因为本系列教程节奏偏慢。

本系列文章的视频教程版本地址:B 站(群友好心录制,可能会不同步)

文章目的

本文主要是写给想基于本项目编写一个配套后端或想了解项目现有接口的小伙伴。

Begin

RESTful API

本项目并没有写配套的后端代码,但是有其他基于本项目二次开发的作者写了,比如:td27-admin,感兴趣的可以参考一下。(如果你也写了配套后端,欢迎留言让大家知晓)

回到项目本身:现在项目调用的接口是采用 Easy MockFast Mock 来模拟的真实接口(非常感谢这两个平台),模拟接口遵循的是 RESTful 风格,如果不了解 RESTful 风格的小伙伴可以看看这篇简文:✒️ 带你了解前后端进化史 与 RESTful API 的出现

后端接口返回的数据格式

无论是 HTTP 请求还是响应都要将 Content-Type 要设置为 application/json,也就是 JSON。

具体的响应 JSON 格式如下:

{
  code: number
  data: T
  message: string
}

其中 code 就是业务状态码,它是团队内部自行设定的,本项目采用了 code 为 0 时代表一切正常

Token 鉴权

本项目采用将 Token 字符串绑定到 HTTP 请求 headers 的 Authorization 属性中发送给后端进行鉴权这种方式。

// src/utils/service.ts 中对应的前端代码
Authorization: token ? `Bearer ${token}` : undefined,

401 状态码

后端检测到 Token 过期或无效时,应当直接返回 HTTP 状态码为 401 给前端,这时前端将强制返回登录页面。

现有接口

登录模块

该模块是重点,二次开发几乎都绕不过这个模块。

获取验证码
  • method: get
  • url: /api/v1/login/code
  • 响应数据:
{
  "code": 0,
  "data": string, // 验证码 url
  "message": "获取验证码成功"
}
登录
  • method: post
  • url: /api/v1/users/login
  • 发送的 body 参数:
{
  username: string
  password: string
  code: string // 验证码
}
  • 响应数据:
{
  "code": 0,
  "data": {
    "token": string
  },
  "message": "登录成功"
}
获取用户详情
  • method: get
  • url: /api/v1/users/info
  • 响应数据:
{
  "code": 0,
  "data": {
    "username": string,
    "roles": string[]
  },
  "message": "获取用户详情成功"
}

表格模块

这个模块非重点,属于业务模块,可以不看。

  • method: post
  • url: /api/v1/table
  • 发送的 body 参数:
{
  username: string
  password: string
}
  • 响应数据:
{
  "code": 0,
  "data": {},
  "message": "新增成功"
}
  • method: delete
  • url: /api/v1/table/{id}
  • 响应数据:
{
  "code": 0,
  "data": {},
  "message": "删除成功"
}
  • method: put
  • url: /api/v1/table
  • 发送的 body 参数:
{
  id: string
  username: string
  password: string | undefined
}
  • 响应数据:
{
  "code": 0,
  "data": {},
  "message": "修改成功"
}
  • method: get
  • url: /api/v1/table
  • 发送的查询参数:
/api/v1/table?currentPage=1&size=10&username=用户名&phone=手机号
  • 响应数据:
{
  "code": 0,
  "data": {
    list: [], // 当前要展示的表格数据
    total: number // 数据库里的总数
  },
  "message": "获取表格数据成功"
}

Easy Mock 代码

如果你也想用 Easy Mock 开启一份在线 Mock API,可以参考复制下面的代码

登录模块

获取验证码
{
  code: 0,
  data: "@image(100x40, #dcdfe6, #000000, png, V3Admin)",
  message: "获取验证码成功"
}
登录
{
  code: function({
    _req
  }) {
    return ['admin', 'editor'].includes(_req.body.username) ? 0 : 1
  },
  data: {
    token: function({
      _req
    }) {
      return ['admin', 'editor'].includes(_req.body.username) ? "token-" + _req.body.username : ""
    }
  },
  message: function({
    _req
  }) {
    return ['admin', 'editor'].includes(_req.body.username) ? "登录成功" : "账号不存在"
  }
}
获取用户详情
{
  code: 0,
  data: {
    username: function({
      _req
    }) {
      return _req.header.authorization.split('-')[1]
    },
    roles: function({
      _req
    }) {
      return [_req.header.authorization.split('-')[1]]
    }
  },
  message: "获取用户详情成功",
  _res: {
    status: function({
      _req
    }) {
      return ["Bearer token-admin", "Bearer token-editor"].includes(_req.header.authorization) ? 200 : 401
    },
    data: {
      code: 1,
      data: {},
      message: "无效 Token"
    }
  }
}

表格模块

{
  code: 0,
  data: {},
  message: "新增成功"
}
{
  code: 0,
  data: {},
  message: "删除成功"
}
{
  code: 0,
  data: {},
  message: "修改成功"
}
{
  code: 0,
  data: {
    total: function({
      _req,
      Mock
    }) {
      const username = _req.query.username
      const phone = _req.query.phone
      if (username || phone) return 1
      return 100
    },
    list: function({
      _req,
      Mock
    }) {
      const res = []
      const username = _req.query.username
      const phone = _req.query.phone
      if (username || phone) {
        res.push(
          Mock.mock({
            id: "@id",
            username: username ? username : "@name",
            phone: phone ? phone : /^1[3-9]\d{9}$/,
            email: "@email",
            "roles|1": ["admin", "editor"],
            status: "@boolean",
            createTime: "@datetime"
          })
        )
      } else {
        const length = Math.min(_req.query.size, 100)
        for (let i = 0; i < length; i++) {
          res.push(
            Mock.mock({
              id: "@id",
              username: "@name",
              phone: /^1[3-9]\d{9}$/,
              email: "@email",
              "roles|1": ["admin", "editor"],
              status: "@boolean",
              createTime: "@datetime"
            })
          )
        }
      }
      return res
    }
  },
  message: "获取表格数据成功",
  _res: {
    status: function({
      _req
    }) {
      return ["Bearer token-admin", "Bearer token-editor"].includes(_req.header.authorization) ? 200 : 401
    },
    data: {
      code: 1,
      data: {},
      message: "无效 Token"
    }
  }
}

Fast Mock 代码

如果你也想用 Fast Mock 开启一份在线 Mock API,可以参考复制下面的代码

登录模块

获取验证码
{
  code: 0,
  data: "@image(100x40, #dcdfe6, #000000, png, V3Admin)",
  message: "获取验证码成功"
}
登录
{
  code: function({
    _req
  }) {
    return ['admin', 'editor'].includes(_req.body.username) ? 0 : 1
  },
  data: {
    token: function({
      _req
    }) {
      return ['admin', 'editor'].includes(_req.body.username) ? "token-" + _req.body.username : ""
    }
  },
  message: function({
    _req
  }) {
    return ['admin', 'editor'].includes(_req.body.username) ? "登录成功" : "账号不存在"
  }
}
获取用户详情
{
  code: function({
    _req
  }) {
    return ["Bearer token-admin", "Bearer token-editor"].includes(_req.headers.authorization) ? 0 : 401
  },
  data: {
    username: function({
      _req
    }) {
      return _req.headers.authorization?.split('-')[1]
    },
    roles: function({
      _req
    }) {
      return [_req.headers.authorization?.split('-')[1]]
    }
  },
  message: function({
    _req
  }) {
    return ["Bearer token-admin", "Bearer token-editor"].includes(_req.headers.authorization) ? "获取用户详情成功" : "无效 Token"
  }
}

表格模块

{
  code: 0,
  data: {},
  message: "新增成功"
}
{
  code: 0,
  data: {},
  message: "删除成功"
}
{
  code: 0,
  data: {},
  message: "修改成功"
}
{
  code: function({
    _req
  }) {
    return ["Bearer token-admin", "Bearer token-editor"].includes(_req.headers.authorization) ? 0 : 401
  },
  data: {
    total: 100,
    list: function({
      _req,
      Mock
    }) {
      let res = [];
      let username = _req.query.username;
      let phone = _req.query.phone;
      if (username || phone) {
        res.push(
          Mock.mock({
            id: "@id",
            username: username ? username : "@name",
            phone: phone ? phone : /^1[3-9]\d{9}$/,
            email: "@email",
            "roles|1": ["admin", "editor"],
            status: "@boolean",
            createTime: "@datetime"
          })
        )
      } else {
        let length = Math.min(_req.query.size ?? 10, 100);
        for (let i = 0; i < length; i++) {
          res.push(
            Mock.mock({
              id: "@id",
              username: "@name",
              phone: /^1[3-9]\d{9}$/,
              email: "@email",
              "roles|1": ["admin", "editor"],
              status: "@boolean",
              createTime: "@datetime"
            })
          )
        }
      }
      return res;
    }
  },
  message: function({
    _req
  }) {
    return ["Bearer token-admin", "Bearer token-editor"].includes(_req.headers.authorization) ? "获取表格数据成功" : "无效 Token"
  }
}

为什么接口这么少?

因为项目本身的目标是中后台管理系统的基础解决方案,是拿给大家做二次开发的(我个人更喜欢在开源项目基础上做加法,而不是做减法),所以并会不引入太多乱七八糟的业务代码和业务接口。

End

本系列所有手摸手教程

  • 掘金专栏(文字版)
  • B 站(视频版是群友好心录制,可能会不同步)

V3 Admin Vite 相关链接