项目背景

对本次项目的背景以及目标进行描述,方便开发者理解需求,对齐上下文。

xxx…

相关资料

PRD、设计稿等相关资料,可以通过插入“语雀内容”卡片快速引入关联的语雀文档 也可以通过“本地文件”、“附件”上传其他资料。

需求文档

参与人

项目负责人 @朽木白(xiumubai)
产品经理 @朽木白(xiumubai)
设计师 @朽木白(xiumubai)
工程师 @朽木白(xiumubai)

功能模块

通过插入“思维图”卡片、“表格”卡片,描述本项目涉及到的功能与场景。

测试用例

需求排期

技术方案

技术选型

前端:react+router6+zarm。
后端:egg+mysql。

验证码实现

安装react-captcha-code插件
使用方式:

  1. import Captcha from "react-captcha-code";
  2. const Login = () => {
  3. const captchaRef = useRef();
  4. const [captcha, setCaptcha] = useState(''); // 验证码变化后存储值
  5. // 验证码变化,回调方法
  6. const handleChange = useCallback((captcha) => {
  7. setCaptcha(captcha)
  8. }, []);
  9. return (
  10. <>
  11. <Input
  12. clearable
  13. type="text"
  14. placeholder="请输入验证码"
  15. onChange={(value) => setVerify(value)}
  16. />
  17. <Captcha ref={captchaRef} charNum={4} onChange={handleChange} />
  18. </>
  19. )
  20. }

效果展示:
image.png

token鉴权

后端token鉴权
使用插件:egg-jwt
登录成功以后,生成token加盐,返回给前端token

  1. 'use strict';
  2. const Controller = require('egg').Controller;
  3. const defaultAvatar = 'http://s.yezgea02.com/1615973940679/WeChat77d6d2ac093e247c361f0b8a7aeb6c2a.png';
  4. class UserController extends Controller {
  5. async login() {
  6. const { ctx, app } = this;
  7. const { username, password } = ctx.request.body;
  8. const userInfo = await ctx.service.user.getUserByName(username);
  9. // 没找到用户
  10. if (!userInfo && userInfo.id) {
  11. ctx.body = {
  12. code: 500,
  13. msg: '账号不存在',
  14. data: null,
  15. };
  16. return;
  17. }
  18. // 找到用户,判断密码是否正确
  19. if (userInfo && password !== userInfo.password) {
  20. ctx.body = {
  21. code: 500,
  22. msg: '账号密码错误',
  23. data: null,
  24. };
  25. return;
  26. }
  27. // 生成 token 加盐
  28. const token = app.jwt.sign({
  29. id: userInfo.id,
  30. username: userInfo.username,
  31. exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60), // token 有效期为 24 小时
  32. }, app.config.jwt.secret);
  33. ctx.body = {
  34. code: 200,
  35. message: '登录成功',
  36. data: {
  37. token,
  38. },
  39. };
  40. }
  41. // 验证token方法
  42. async test() {
  43. const { ctx, app } = this;
  44. // 通过 token 解析,拿到 user_id
  45. const token = ctx.request.header.authorization; // 请求头获取 authorization 属性,值为 token
  46. // 通过 app.jwt.verify + 加密字符串 解析出 token 的值
  47. const decode = await app.jwt.verify(token, app.config.jwt.secret);
  48. // 响应接口
  49. ctx.body = {
  50. code: 200,
  51. message: '获取成功',
  52. data: {
  53. ...decode,
  54. },
  55. };
  56. }
  57. }
  58. module.exports = UserController;

流程图

通过“流程图”卡片对系统流程进行梳理。

设计流程图的功能可以画出流程图,技术评审更加方便

数据库设计

  1. -- `account-book`.`user` definition
  2. CREATE TABLE `user` (
  3. `id` int NOT NULL AUTO_INCREMENT,
  4. `username` varchar(100) NOT NULL,
  5. `avatar` varchar(100) NOT NULL,
  6. `signature` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  7. `password` varchar(100) NOT NULL,
  8. PRIMARY KEY (`id`)
  9. ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  1. -- `account-book`.bill definition
  2. CREATE TABLE `bill` (
  3. `id` int NOT NULL AUTO_INCREMENT,
  4. `pay_type` float NOT NULL,
  5. `amount` varchar(100) NOT NULL,
  6. `date` varchar(100) NOT NULL,
  7. `type_id` int NOT NULL,
  8. `type_name` varchar(100) NOT NULL,
  9. `user_id` int NOT NULL,
  10. `remark` varchar(100) NOT NULL,
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  1. -- `account-book`.`type` definition
  2. CREATE TABLE `type` (
  3. `id` int NOT NULL AUTO_INCREMENT,
  4. `name` varchar(100) NOT NULL,
  5. `type` int NOT NULL,
  6. `user_id` int NOT NULL,
  7. PRIMARY KEY (`id`)
  8. ) 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

里程碑

通过“日历卡片”或者“思维图”卡片的时间轴视图,对研发时间计划进行排期。

技术方案 - 图2