员工管理、分类管理(day02)

新增员工

需求分析和设计

产品原型:

注意事项:

  1. 账号必须是唯一的
  2. 手机号为合法的11位手机号码
  3. 身份证号为合法的18位身份证号码
  4. 密码默认为123456

接口设计: 

本项目约定:

  • 管理端发出的请求,统一使用**/admin**作为前缀。
  • 用户端发出的请求,统一使用**/user**作为前缀。

数据库设计(employee表):

字段名

数据类型

说明

备注

id

bigint

主键

自增

name

varchar(32)

姓名

username

varchar(32)

用户名

唯一

password

varchar(64)

密码

phone

varchar(11)

手机号

sex

varchar(2)

性别

id_number

varchar(18)

身份证号

status

Int

账号状态

1正常 0锁定

create_time

Datetime

创建时间

update_time

datetime

最后修改时间

create_user

bigint

创建人id

update_user

bigint

最后修改人id

代码开发

注意:

  • 当前端提交的数据和实体类中对应的属性差别比较大时,建议使用 DTO 来封装数据

EmployeeController中创建新增员工方法,接收前端提交的参数:

在EmployeeService接口中声明新增员工方法:

在EmployeeServiceImpl中实现新增员工方法:

EmployeeMapper中声明insert方法:

功能测试

功能测试方式:

通过接口文档测试
通过前后端联调测试

注意:由于开发阶段前端和后端是并行开发的,后端完成某个功能后,此时前端对应的功能可能还没有开发完成,导致无法进行前后端联调测试。所以在开发阶段,后端测试主要以接口文档测试为主。

启动服务: 访问http://localhost:8080/doc.html,进入新增员工接口
响应码:401 报错

报错原因: 由于JWT令牌校验失败,导致EmployeeController的save方法没有被调用
解决方法: 调用员工登录接口获得一个合法的JWT令牌

使用admin用户登录获取令牌

添加令牌:

  • 将合法的JWT令牌添加到全局参数中
  • 文档管理–>全局参数设置–>添加参数

接口测试:

前后端联调测试

代码完善

目前,程序存在的问题主要有两个:

  • 录入的用户名已存,抛出的异常后没有处理
  • 新增员工时,创建人id和修改人id设置为固定值

问题一

描述: 录入的用户名已存在,抛出的异常后没有处理


问题二

描述: 新增员工时,创建人 id 和修改人 id 设置为固定值

思考: 解析出登录员工 id 后,如何传递给 Service 的 save 方法?

  • 通过 ThreadLocal 进行传递。

ThreadLocal

  • ThreadLocal 并不是一个 Thread,而是 Thread 的局部变量。
  • ThreadLocal 为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。

注意:

  • 客户端发送的每次请求,后端的 Tomcat 服务器都会分配一个单独的线程来处理请求

ThreadLocal 常用方法:

  • public void set(T value) 设置当前线程的线程局部变量的值
  • public T get() 返回当前线程所对应的线程局部变量的值
  • public void remove() 移除当前线程的线程局部变量

 在拦截器中解析出当前登录员工id,并放入线程局部变量中:

在Service中获取线程局部变量中的值:

员工分页查询

需求分析和设计

业务规则

  • 根据页码展示员工信息
  • 每页展示10条数据
  • 分页查询时可以根据需要,输入员工姓名进行查询

接口设计: 

代码开发

根据分页查询接口设计对应的DTO

后面所有的分页查询,统一都封装成PageResult对象:

员工信息分页查询后端返回的对象类型为:Result<PageResult>

根据接口定义创建分页查询方法:

EmployeeService接口中声明pageQuery方法:

EmployeeServiceImpl 中实现 pageQuery 方法:

注意:此处使用 mybatis 的分页插件 PageHelper 来简化分页代码的开发。底层基于 mybatis 的拦截器实现。

EmployeeMapper 中声明 pageQuery 方法:

在 EmployeeMapper.xml 中编写SQL

功能测试

注意jwt令牌的时间有效期

可以通过接口文档进行测试,也可以进行前后端联调测试,最后操作时间字段展示有问题,如下:

代码完善

问题描述: 操作时间字段显示有问题。

方式一:在属性上加入注解,对日期进行格式化

方式二:在 WebMvcConfiguration 中扩展Spring MVC的消息转换器,统一对日期类型进行格式化处理

/**
     * 扩展Spring MVC框架的消息转换器
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//        super.extendMessageConverters(converters);
        log.info("扩展消息转换器");
        //创建一个消息转换器
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为消息转换器设置一个对象转换器,对象转换器可以讲java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        //将自己的消息转换器加入容器中
        converters.add(0,converter);
    }
package com.sky.json;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    //public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知属性时不报异常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化时,属性不存在的兼容处理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //注册功能模块 例如,可以添加自定义序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}

 注意:不要写错了

启用禁用员工账号

需求分析和设计

产品原型:

业务规则:

  • 分类名称必须是唯一的
  • 分类按照类型可以分为菜品分类和套餐分类
  • 新添加的分类状态默认为“禁用”

接口设计:

代码开发

根据接口设计中的请求参数形式对应的在 EmployeeController 中创建启用禁用员工账号的方法:

EmployeeService 接口中声明启用禁用员工账号的业务方法:

EmployeeServiceImpl 中实现启用禁用员工账号的业务方法:

EmployeeMapper 接口中声明 update 方法:

EmployeeMapper.xml 中编写SQL:

功能测试

可以通过接口文档进行测试,最后完成前后端联调测试即可

编辑员工

需求分析和设计

产品原型:

编辑员工功能涉及到两个接口:

根据id查询员工信息
编辑员工信息


代码开发

EmployeeController 中创建 getById 方法:

EmployeeService 接口中声明 getById 方法:

EmployeeServiceImpl 中实现 getById 方法:

EmployeeMapper 接口中声明 getById 方法:
可以先通过接口测试确认数据回显是否有问题,如果没有问题再继续开发

EmployeeController 中创建 update 方法:

EmployeeService 接口中声明 update 方法:

EmployeeServiceImpl 中实现 update 方法:

    /**
     * 编辑员工信息
     * @param employeeDTO
     */
    @Override
    public void update(EmployeeDTO employeeDTO) {
        // update employee set ... where id = ?
        Employee employee = new Employee();
        
        //对象的属性拷贝
        BeanUtils.copyProperties(employeeDTO, employee);
        //设置修改人和修改时间
        employee.setUpdateUser(BaseContext.getCurrentId());
        employee.setUpdateTime(LocalDateTime.now());

        employeeMapper.update(employee);
    }

功能测试

通过Swagger接口文档进行测试,通过后再前后端联调测试即可

导入分类模块功能代码

需求分析和设计

产品原型:

业务规则:

分类名称必须是 唯一
分类按照类型可以分为 菜品分类 套餐分类
新添加的分类状态默认为 “禁用”

接口设计:

新增分类
分类分页查询
根据 id 删除分类
修改分类
启用禁用分类
根据类型查询分类

数据库设计(category)

代码导入

上一节:

项目概述、开发环境搭建(day01)-优快云博客

下一节:

菜品管理(day03)-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值