项目背景
对本次项目的背景以及目标进行描述,方便开发者理解需求,对齐上下文。
相关资料
PRD、设计稿等相关资料,可以通过插入“语雀内容”卡片快速引入关联的语雀文档 也可以通过“本地文件”、“附件”上传其他资料。
参与人
项目负责人 | @朽木白(xiumubai) |
---|---|
产品经理 | @朽木白(xiumubai) |
设计师 | @朽木白(xiumubai) |
工程师 | @朽木白(xiumubai) |
功能模块
通过插入“思维图”卡片、“表格”卡片,描述本项目涉及到的功能与场景。
需求排期
技术方案
技术选型
前端:react+router6+zarm。
后端:egg+mysql。
验证码实现
安装react-captcha-code
插件
使用方式:
import Captcha from "react-captcha-code";
const Login = () => {
const captchaRef = useRef();
const [captcha, setCaptcha] = useState(''); // 验证码变化后存储值
// 验证码变化,回调方法
const handleChange = useCallback((captcha) => {
setCaptcha(captcha)
}, []);
return (
<>
<Input
clearable
type="text"
placeholder="请输入验证码"
onChange={(value) => setVerify(value)}
/>
<Captcha ref={captchaRef} charNum={4} onChange={handleChange} />
</>
)
}
token鉴权
后端token鉴权
使用插件:egg-jwt
登录成功以后,生成token加盐,返回给前端token
'use strict';
const Controller = require('egg').Controller;
const defaultAvatar = 'http://s.yezgea02.com/1615973940679/WeChat77d6d2ac093e247c361f0b8a7aeb6c2a.png';
class UserController extends Controller {
async login() {
const { ctx, app } = this;
const { username, password } = ctx.request.body;
const userInfo = await ctx.service.user.getUserByName(username);
// 没找到用户
if (!userInfo && userInfo.id) {
ctx.body = {
code: 500,
msg: '账号不存在',
data: null,
};
return;
}
// 找到用户,判断密码是否正确
if (userInfo && password !== userInfo.password) {
ctx.body = {
code: 500,
msg: '账号密码错误',
data: null,
};
return;
}
// 生成 token 加盐
const token = app.jwt.sign({
id: userInfo.id,
username: userInfo.username,
exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60), // token 有效期为 24 小时
}, app.config.jwt.secret);
ctx.body = {
code: 200,
message: '登录成功',
data: {
token,
},
};
}
// 验证token方法
async test() {
const { ctx, app } = this;
// 通过 token 解析,拿到 user_id
const token = ctx.request.header.authorization; // 请求头获取 authorization 属性,值为 token
// 通过 app.jwt.verify + 加密字符串 解析出 token 的值
const decode = await app.jwt.verify(token, app.config.jwt.secret);
// 响应接口
ctx.body = {
code: 200,
message: '获取成功',
data: {
...decode,
},
};
}
}
module.exports = UserController;
流程图
通过“流程图”卡片对系统流程进行梳理。
数据库设计
-- `account-book`.`user` definition
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(100) NOT NULL,
`avatar` varchar(100) NOT NULL,
`signature` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
`password` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- `account-book`.bill definition
CREATE TABLE `bill` (
`id` int NOT NULL AUTO_INCREMENT,
`pay_type` float NOT NULL,
`amount` varchar(100) NOT NULL,
`date` varchar(100) NOT NULL,
`type_id` int NOT NULL,
`type_name` varchar(100) NOT NULL,
`user_id` int NOT NULL,
`remark` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- `account-book`.`type` definition
CREATE TABLE `type` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`type` int NOT NULL,
`user_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
API 设计
前后端开发必须使用api文档,一般公司使用yapi
,后端会现在yapi上面把接口格式写好,前端按照这个格式去写前端页面。各自进行开发。
api文档:https://www.apifox.cn/apidoc/shared-bb27b693-bcf0-4f89-b17e-7e4c94ab39b5
里程碑
通过“日历卡片”或者“思维图”卡片的时间轴视图,对研发时间计划进行排期。