作者:UOrb
声明:文章为稀土掘金技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!
前言
首先我 不是 专业的后端,所以服务端的技术方案设计可能不那么 专业,比如 功能设计 那块其实应该更加详细的,会涉及到一些 状态判定、数据来源、 业务逻辑 等一些内容(当然这一块的内容大部分是从需求文档中转化而来的),我这里只是简单的应用接口的排列;数据库设计也是一样,不够专业,只是直白的设计。
不过虽然相对来说粗糙了一些,但是麻雀虽小五脏俱全吧!
其中 接口设计(单独转换之后也可以叫做接口文档)是对前端开发 影响 最大的了,前端的业务逻辑和接口数据 Mock 都需要 依赖 它。
在前后端分离的情况下,前后端同时进行开发,没有预先进行接口设计(接口文档)的话,对前端的影响是非常大的,最常见的就是前端只能把静态页面先写完,等后端接口出来后再配合着进行业务逻辑的开发,然后大部分的工作量都堆积在后期,就导致了加班或项目延期等情况;就算是前端预先根据需求和设计稿自定义了数据结构,等后端接口给出后通过数据模型转换,也是变相的增加了前端的工作量和负担。
项目背景
这里大部分都是从 需求文档 中的引用,所以就不再重写了。
此处省略一万个字...
技术选型
服务端语言毫无疑问是 Node.js
服务端框架将会使用 Nest.js,原因是 Nest.js 是一套 方案、架构 ,同时也会更加贴近真实的后端开发,熟悉 Java 的 Spring 框架的兄弟就会感觉 Nest.js 非常像 Spring,缺点是国内 Nest.js 不太繁荣,也很少有其相关教程,只能翻翻官方文档比较难上手;
数据库使用 mysql5.7 和 redis
功能设计
这里需要根据需求文档、原型图或设计图来设计出功能模块以及相关的一些规则和约定,大多数情况其实就是 产品需求 转换成后端技术需求的一个过程。
登陆
涉及接口
- 用户注册接口
- 用户登陆认证接口
- 用户信息获取接口
个人中心
涉及接口
- 用户信息获取接口
- 文档查询接口
- 获取用户空间列表接口
- 新增用户空间接口
- 编辑指定空间接口
- 删除指定空间接口
- 获取指定空间的知识库列表接口
- 新增指定空间的知识库接口
- 编辑指定知识库接口
- 删除指定知识库接口
知识库
涉及接口
- 获取指定知识库信息接口
- 编辑指定知识库信息接口
- 获取指定知识库的文档列表接口
- 新增指定空间文档接口
- 修改指定文档配置接口
- 删除指定文档接口
最近浏览
涉及接口
- 文档查询接口
- 获取用户浏览文档记录列表接口
回收站
涉及接口
- 文档查询接口
- 获取用户已删除列表接口
- 恢复文档接口
- 直接删除接口
文档
涉及接口
- 获取指定文档信息数据接口
- 编辑/保存指定文档接口
- 修改指定文档配置接口
数据库设计
这里需要根据需求文档和转换后的技术需求(功能设计)的内容进行数据库的设计,大体就是看有多少种 载体 ,每个载体基本上就可以设计成一个 数据表 再根据 需求 设计字段,基本上除了业务会用到的数据字段常规的都会带上 创建人、创建时间、更新人、更新时间、私有状态(假删除等逻辑判断) 之类的字段,基本上你业务逻辑梳理(需求 or 功能设计)清楚了,数据库设计基本上不会有太大的问题。
用户表
CREATE TABLE `online_document`.`user` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '唯一 ID',
`name` VARCHAR(45) NULL COMMENT '昵称',
`username` VARCHAR(45) NOT NULL COMMENT '帐号',
`password` VARCHAR(45) NOT NULL COMMENT '密码',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC),
UNIQUE INDEX `username_UNIQUE` (`username` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COMMENT = '用户';
空间表
CREATE TABLE `online_document`.`space` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '唯一ID',
`user_id` INT UNSIGNED NOT NULL COMMENT '所属用户',
`name` VARCHAR(45) NOT NULL COMMENT '空间名',
`describe` VARCHAR(255) NULL COMMENT '简介',
`create` INT NULL COMMENT '创建人',
`create_time` DATETIME NULL COMMENT '创建时间',
`update` INT NULL COMMENT '更新人',
`update_time` DATETIME NULL COMMENT '更新时间',
`status` CHAR(1) NOT NULL DEFAULT 1 COMMENT '状态 1: 正常; 0: 删除',
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COMMENT = '空间';
知识库表
CREATE TABLE `online_document`.`library` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT UNSIGNED NOT NULL COMMENT '所属用户',
`space_id` INT UNSIGNED NOT NULL COMMENT '所属空间',
`name` VARCHAR(45) NOT NULL COMMENT '知识库名称',
`describe` VARCHAR(255) NULL COMMENT '简介',
`create` INT NULL COMMENT '创建人',
`create_time` DATETIME NULL COMMENT '创建时间',
`update` INT NULL COMMENT '更新人',
`update_time` DATETIME NULL COMMENT '更新时间',
`status` CHAR(1) NOT NULL DEFAULT 1 COMMENT '状态 1: 正常; 0: 删除',
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COMMENT = '知识库';
文档表
CREATE TABLE `online_document`.`doc` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '唯一 ID',
`user_id` INT UNSIGNED NOT NULL COMMENT '所属用户',
`space_id` INT UNSIGNED NOT NULL COMMENT '所属空间',
`library_id` INT UNSIGNED NOT NULL COMMENT '所属知识库',
`content_id` INT UNSIGNED NOT NULL COMMENT '文档内容',
`title` VARCHAR(45) NULL COMMENT '文档标题',
`create` INT NULL COMMENT '创建人',
`create_time` DATETIME NULL COMMENT '创建时间',
`update` INT NULL COMMENT '更新人',
`update_time` DATETIME NULL COMMENT '更新时间',
`status` CHAR(1) NOT NULL DEFAULT 1 COMMENT '状态 1: 正常; 0: 删除',
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COMMENT = '文档';
文档内容表
CREATE TABLE `online_document`.`content` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '唯一 ID',
`doc_id` INT NOT NULL COMMENT '所属文档',
`content` LONGTEXT NULL COMMENT '文档内容',
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COMMENT = '文档内容';
浏览记录表
CREATE TABLE `online_document`.`doc_record` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT NOT NULL COMMENT '所属用户',
`doc_id` INT NOT NULL COMMENT '所属文档',
`space_id` INT NOT NULL COMMENT '所属空间',
`library_id` INT NOT NULL COMMENT '所属知识库',
`doc_title` VARCHAR(45) NULL COMMENT '文档标题',
`visit_time` DATETIME NOT NULL COMMENT '访问时间',
`status` CHAR(1) NOT NULL DEFAULT 1 COMMENT '状态 1: 正常; 0: 删除',
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
COMMENT = '浏览记录';
接口设计
接口设计在常规文档中可能更多的使用 表格 的形式,不过写 表格 会花费更多的时间和精力,相对来说就会更精准和详细一些,我这里使用的类 JSON 字符串的形式来书写的。
用户模块
用户注册接口
请求地址:/api/register
请求类型:POST
请求体:
{
name: string // 昵称
username: string // 帐号
password: string // 密码
}
响应体:
{
msg: string // 消息
code: number // 状态码
data: {
token: string // 认证
}
}
用户登陆认证接口
请求地址:/api/login
请求类型:POST
请求体:
{
name: string // 昵称
username: string // 帐号
password: string // 密码
}
响应体: { msg: string // 消息 code: number // 状态码 data: { token: string // 认证 } }
用户信息获取接口
请求地址:/api/user
请求类型:GET
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: {
id: number // 用户 id
name: string // 用户昵称
}
}
空间模块
获取用户空间列表接口
请求地址:/api/space
请求类型:GET
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: [
{
id: number // 空间 ID
name: string // 空间名称
describe: string // 空间简介
}
]
}
新增用户空间接口
请求地址:/api/space
请求类型:POST
请求体:
{
name: string // 空间名称
describe: string // 空间简介
}
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 创建成功;false 创建失败
}
编辑指定空间接口
请求地址:/api/space/:id
请求类型:PATCH
请求体:
{
name: string // 空间名称
describe: string // 简介
}
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 编辑成功;false 编辑失败
}
删除指定空间接口
请求地址:/api/space/:id
请求类型:DELETE
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 删除成功;false 删除失败
}
知识库模块
获取指定空间的知识库列表接口
请求地址:/api/library?spaceId=1
请求类型:GET
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: [
{
id: number // 知识库 ID
name: string // 知识库名称
describe: string // 知识库简介
}
]
}
新增指定空间的知识库接口
请求地址:/api/library
请求类型:POST
请求体:
{
spaceId: // 空间 ID
name: string // 知识库名称
describe: string // 知识库简介
}
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 创建成功;false 创建失败
}
编辑指定知识库接口
请求地址:/api/library/:id
请求类型:PATCH
请求体:
{
name: string // 知识库名称
describe: string // 知识库简介
}
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 编辑成功;false 编辑失败
}
删除指定知识库接口
请求地址:/api/library/:id
请求类型:DELETE
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 删除成功;false 删除失败
}
获取指定知识库信息接口
请求地址:/api/library/:id
请求类型:GET
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: {
id: number // 知识库 ID
userId: number // 所属用户
spaceId: number // 所属空间 ID
name: string // 知识库名称
describe: string // 知识库简介
create: number // 创建人
createTime: string // 创建时间
update: number // 更新人
updateTime: string // 更新时间
}
}
获取指定知识库的文档列表接口
请求地址:/api/library/:id/doc
请求类型:GET
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: [
{
id: number // 文章 ID
userId: number // 所属用户
spaceId: number // 所属空间 ID
libraryId: number // 所属知识库 ID
contentId: number // 内容 ID
title: string // 标题
create: number // 创建人
createTime: string // 创建时间
update: number // 更新人
updateTime: string // 更新时间
}
]
}
文档模块
获取指定文档内容数据接口
请求地址:/api/doc/:docId/:contentId
请求类型:GET
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: {
id: number // 内容 ID
content: string // 文档内容
}
}
新增指定知识库文档接口
请求地址:/api/doc
请求类型:POST
请求体:
{
spaceId: string // 所属空间
libraryId: string // 所属知识库
}
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 创建成功;false 创建失败
}
更新指定文档接口
请求地址:/api/doc/:id/:contentId
请求类型:PATCH
请求体:
{
content: string // 文档内容
}
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 更新成功;false 更新失败
}
修改指定文档配置信息接口
请求地址:/api/doc/:id
请求类型:PATCH
请求体:
{
title: string // 文档名称
... // 其他
}
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 修改成功;false 修改失败
}
删除指定文档接口
请求地址:/api/doc/:id
请求类型:DELETE
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 删除成功;false 删除失败
}
浏览记录模块
用户注册接口
请求地址:/api/user/recode 请求类型:GET 请求体:无 响应体:
{
msg: string // 消息
code: number // 状态码
data: {
currPage: number // 当前页码
pageSize: number // 每页数量
total: number // 总数
list: [
{
id: number // 记录 ID
userId: number // 所属用户
spaceId: number // 所属空间
libraryId: number // 所属知识库
docId: number // 所属文档
docTitle: string // 文档标题
visitTime: string // 访问时间
}
]
}
}
回收站模块
获取用户已删除列表接口
请求地址:/api/recycle
请求类型:GET
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: [
{
id: number // 文章 ID
userId: number // 所属用户
spaceId: number // 所属空间 ID
libraryId: number // 所属知识库 ID
contentId: number // 内容 ID
title: string // 标题
create: number // 创建人
createTime: string // 创建时间
update: number // 更新人
updateTime: string // 更新时间
}
]
}
回复指定文档接口
请求地址:/api/recycle/:id
请求类型:PATCH
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 恢复成功;false 恢复失败
}
彻底删除指定文档接口
请求地址:/api/recycle/:id
请求类型:DELETE
请求体:无
响应体:
{
msg: string // 消息
code: number // 状态码
data: boolean // true 删除成功;false 删除失败
}
总结
技术方案是为了研究解决各类技术问题,有针对性、系统性的提出方法和应对措施及相关对策。
技术方案对项目的质量和周期有着紧密的关联,技术方案相当于定下了一个大纲和具体方向,对项目的规范化、标准化、工作量估算以及具体的研发过程有着重要的指导作用。