# 用户中心

完整了解做项目的思路，接触一些企业级的开发技术

（尽量少写代码）目标：大家之后都能轻松做出管理系统



末 - 直播内容

1. 开发用户注销前端 7 分钟 / 后端 3 分钟 √
2. 补充用户注册校验逻辑前端 10 分钟 / 后端 10 分钟 √
3. 后端代码优化 20 - 30 min
4. 前端代码优化 5 - 10 min
5. 项目部署上线 1h
   1. 买服务器   10 min
   2. 原生部署	20 - 30 min
   3. 容器部署    20 - 30 min
   4. 绑定域名    5 min
   5. **排查问题** 



## 后端优化

1. 通用返回对象 √

   目的：给对象补充一些信息，告诉前端这个请求在业务层面上是成功还是失败

   200、404、500、502、503

   ```json
   {
       "name": "yupi"
   }
   
   ↓
   
   // 成功
   {
       "code": 0 // 业务状态码
       "data": {
           "name": "yupi"
       },
   	"message": "ok"
   }
   
   
   // 错误
   {
       "code": 50001 // 业务状态码
       "data": null
   	"message": "用户操作异常、xxx"
   }
   ```

   - 自定义错误码

   - 返回类支持返回正常和错误

2. 封装全局异常处理

   1. 定义业务异常类

      1. 相对于 java 的异常类，支持更多字段
      2. 自定义构造函数，更灵活 / 快捷的设置字段

   2. 编写全局异常处理器

      作用：

      1. 捕获代码中所有的异常，内部消化，让前端得到更详细的业务报错 / 信息
      2. 同时屏蔽掉项目框架本身的异常（不暴露服务器内部状态）
      3. 集中处理，比如记录日志

      实现：

      1. Spring AOP：在调用方法前后进行额外的处理

3. todo 全局请求日志和登录校验



### 前端优化

> 直播 0：00 - 0：35 踩坑过程，可跳过

1. 对接后端的返回值，取 data

2. 全局响应处理：

   1. 应用场景：我们需要对接口的 **通用响应** 进行统一处理，比如从 response 中取出 data；或者根据 code 去集中处理错误，比如用户未登录、没权限之类的。

   2. 优势：不用在每个接口请求中都去写相同的逻辑

   3. 实现：参考你用的请求封装工具的官方文档，比如 umi-request（https://github.com/umijs/umi-request#interceptor、https://blog.csdn.net/huantai3334/article/details/116780020

      ）如果你用 **axios**，参考 axios 的文档。创建新的文件，在该文件中配置一个全局请求类。在发送请求时，使用我们自己的定义的全局请求类。



## 用户校验

> 仅适用于用户可信的情况

先让用户自己填：2 - 5 位编号，自觉

后台补充对编号的校验：长度校验、唯一性校验

前端补充输入框，适配后端

> 后期拉取星球数据，定期清理违规用户



终- 直播内容：

1. 完成注册功能的前端开发 15 - 20min √
2. 获取用户的登录态，**获取当前登录用户信息接口**  √
3. 完成用户管理后台的前端开发 20 - 30 min
4. 前端代码瘦身 & 优化 20min
5. 后端代码优化 20min
6. 新需求 - 讨论及开发星球用户校验（简易） ---
7. 
8. 项目扩展思路



### Ant Design Pro（Umi 框架）

app.tsx 项目全局入口文件，定义了整个项目中使用的公共数据（比如用户信息）

access.ts 控制用户的访问权限



首次访问页面（刷新页面），进入 app.tsx，执行 getInitialState 方法，该方法的返回值就是全局可用的状态值。



### ProComponents 高级表单

1. 通过 columns 定义表格有哪些列
2. columns 属性
   - dataIndex 对应返回数据对象的属性
   - title 表格列名
   - copyable 是否允许复制
   - ellipsis 是否允许缩略
   - valueType：用于声明这一列的类型（dateTime、select）



### 待优化点 todo

- 前端密码重复提示（可能有别的优化方式）
- 注册没有友好的提示
- 用户注销
- 优化查询接口（支持更多查询）



MFSU：前端编译优化

Ant Design 组件库 => React 

Ant Design Procomponents => Ant Design

Ant Design Pro 后台管理系统 => Ant Design、React、Ant Design Procomponents、其他的库



## 企业做项目流程

需求分析 => 设计（概要设计、详细设计）=> 技术选型 =>

初始化 / 引入需要的技术 => 写 Demo => 写代码（实现业务逻辑） => 测试（单元测试）=> 代码提交 / 代码评审 => 部署=> 发布

## 需求分析

1. **登录 / 注册**
2. **用户管理（仅管理员可见）对用户的查询或者修改**
3. 用户校验（ **仅星球用户** ）

## 技术选型

前端：三件套 + React + 组件库 Ant Design + Umi + Ant Design Pro（现成的管理系统）

后端：

- java
- spring（依赖注入框架，帮助你管理 Java 对象，集成一些其他的内容）
- springmvc（web 框架，提供接口访问、restful接口等能力）
- mybatis（Java 操作数据库的框架，持久层框架，对 jdbc 的封装）
- mybatis-plus（对 mybatis 的增强，不用写 sql 也能实现增删改查）
- springboot（**快速启动** / 快速集成项目。不用自己管理 spring 配置，不用自己整合各种框架）
- junit 单元测试库
- mysql 数据库

部署：服务器 / 容器（平台）

## 计划

1. 初始化项目

   1. 前端初始化     20 min

      1. 初始化项目 ✔
      2. 引入一些组件之类的 ✔
      3. 框架介绍 / 瘦身 ✔

   2. 后端初始化  20 min

      1. 准备环境（MySQL 之类的）验证 MySQL 是否安装成功 - 连接一下 ✔
      2. 初始化后端项目，引入框架（整合框架）✔

2. 数据库设计
3. **登录 / 注册** 20min ✔
   1. 后端       20min ✔
      1. 规整项目目录 2 min
      2. 实现基本数据库操作（操作 user 表）
         1. 模型 user 对象 => 和数据库的字段关联，自动生成
      3. 写登录逻辑
   2. 前端       20min
      1. 删除多余代码

4. 用户管理（仅管理员可见） 20 min

   2. 后端 ✔
   2. 前端





## 笔记

三种初始化 Java 项目的方式

1. GitHub 搜现成的代码
2. SpringBoot 官方的模板生成器（https://start.spring.io/）
3. 直接在 IDEA 开发工具中生成  ✔

如果要引入 java 的包，可以去 maven 中心仓库寻找（http://mvnrepository.com/）





## 数据库设计 30 min

什么是数据库？存数据的

数据库里有什么？数据表（理解为 excel 表格）

java 操作数据库，代替人工



什么是设计数据库表？

有哪些表（模型）？表中有哪些字段？字段的类型？数据库字段添加索引？

表与表之间的关联~



**性别是否需要加索引？**

用户表：

id（主键）bigint

username 昵称  varchar

userAccount 登录账号 

avatarUrl 头像 varchar

gender 性别 tinyint

userPassword 密码  varchar

phone 电话 varchar

email 邮箱 varchar

userStatus 用户状态 int  0 - 正常 

createTime 创建时间（数据插入时间）datetime

updateTime 更新时间（数据更新时间）datetime

isDelete 是否删除 0 1（逻辑删除）tinyint

userRole 用户角色 0 - 普通用户 1 - 管理员

### 自动生成器的使用

 MyBatisX 插件，自动根据数据库生成 domain 实体对象、mapper（操作数据库的对象）、mapper.xml（定义了 mapper对象和数据库的关联，可以在里面自己写 SQL）、service（包含常用的增删改查）、serviceImpl（具体实现 service）



### 今日计划

1. 开发完成后端登录功能 20 min（单机登录 => 后续改造为分布式 / 第三方登录）✔
2. 开发后端用户的管理接口 5 min（用户的查询 / 状态更改）✔
3. 后端接口测试 ✔
4. 开发前端用户登录注册功能 40 min - 1h
5. 讨论如何校验用户（星球的小伙伴可以使用）



### 注册逻辑

1. 用户在前端输入账户和密码、以及校验码（todo）
2. 校验用户的账户、密码、校验密码，是否符合要求
   1. 非空
   2. 账户长度 **不小于** 4 位
   3. 密码就 **不小于** 8 位吧
   4. 账户不能重复
   5. 账户不包含特殊字符
   6. 密码和校验密码相同
3. 对密码进行加密（密码千万不要直接以明文存储到数据库中）
4. 向数据库插入用户数据



### 登录接口

接受参数：用户账户、密码

请求类型：POST 

请求体：JSON 格式的数据

> 请求参数很长时不建议用 get

返回值：用户信息（ **脱敏** ）

### 逻辑

1. 校验用户账户和密码是否合法

   1. 非空
   2. 账户长度 **不小于** 4 位
   3. 密码就 **不小于** 8 位吧
   4. 账户不包含特殊字符

2. 校验密码是否输入正确，要和数据库中的密文密码去对比

3. 用户信息脱敏，隐藏敏感信息，防止数据库中的字段泄露

4. 我们要记录用户的登录态（session），将其存到服务器上（用后端 SpringBoot 框架封装的服务器 tomcat 去记录）

   cookie

5. 返回脱敏后的用户信息



## 控制层 Controller 封装请求

application.yml 指定接口全局 api

```
servlet:
  context-path: /api
```



``` 
@RestController 适用于编写 restful 风格的 api，返回值默认为 json 类型
```

controller 层倾向于对请求参数本身的校验，不涉及业务逻辑本身（越少越好）

service 层是对业务逻辑的校验（有可能被 controller 之外的类调用）





### 如何知道是哪个用户登录了？

（javaweb 这一块）

1. 连接服务器端后，得到一个 session 状态（匿名会话），返回给前端

2. 登录成功后，得到了登录成功的 session，并且给该sessio n设置一些值（比如用户信息），返回给前端一个设置 cookie 的 ”命令“ 

   **session => cookie** 

3. 前端接收到后端的命令后，设置 cookie，保存到浏览器内

4. 前端再次请求后端的时候（相同的域名），在请求头中带上cookie去请求

5. 后端拿到前端传来的 cookie，找到对应的 session

6. 后端从 session 中可以取出基于该 session 存储的变量（用户的登录信息、登录名）



## 用户管理接口

！！！ 必须鉴权

1. 查询用户
   1. 允许根据用户名查询
2. 删除用户



## 写代码流程

先做设计

代码实现

持续优化！！！（复用代码、提取公共逻辑 / 常量）



## 前后端交互

前端需要向后端发送请求

前端 ajax 来请求后端

axios 封装了 ajax

request 是 ant design 项目又封装了一次

追踪 request 源码：用到了 umi 的插件、requestConfig 是一个配置



## 代理

正向代理：替客户端向服务器发送请求，可以解决跨域问题

反向代理：替服务器统一接收请求。

怎么搞代理？

Nginx 服务器

Node.js 服务器



原本请求：http://localhost:8000/api/user/login

代理到请求：http://localhost:8080/api/user/login

![](https://qiniuyun.code-nav.cn/img/image-20220319005859098.png)





























