员工管理模块
1. 新增员工
(1)service层代码
@Override
public void save(EmployeeDTO employeeDTO) {
// 转化为实体类存入数据库
Employee employee = new Employee();
// 对象属性拷贝(须保证属性名一致)
BeanUtils.copyProperties(employeeDTO, employee);
// 设置需要状态,默认正常状态 1表示正常
employee.setStatus(StatusConstant.ENABLE);
// 设置初始默认密码 123456
employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
// 设置当前记录的创建时间和修改时间
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
// 设置当前记录创建人id和修改者id
// 从ThreadLocal里取出id
employee.setCreateUser(BaseContext.getCurrentId());
employee.setUpdateUser(BaseContext.getCurrentId());
employeeMapper.insert(employee);
}
(2)补充学习
1. 尽量使用常量
在模块中定义常量类,数字、常用字符串等尽量使用常量来编码,增强代码复用性,便于在不同环境下进行修改。
2. 对象属性拷贝
在两个对象属性名一致的情况下,可利用BeanUtils.copyProperties()方法,进行对象属性拷贝。这是由Spring框架提供的。
3. 时间类型
LocalDateTime,以LocalDateTime.now()方法获取当前时间。
4. ThreadLocal的应用
为了解决获取线程中employee的id值,jwt解析出登录员工id后,需要将传递给Service的save()方法。
需要注意的是,每次请求都是一个Thread。ThreadLocal 并不是一个Thread,而是Thread的局部变量。 ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。
获取过程:
定义一个操作ThreadLocal的类BaseContext,包含了threadLocal中设置、获取、移除属性的常用方法。
public class BaseContext {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setCurrentId(Long id) {
threadLocal.set(id);
}
public static Long getCurrentId() {
return threadLocal.get();
}
public static void removeCurrentId() {
threadLocal.remove();
}
}
修改jwt验证的拦截器,JwtTokenAdminInterceptor类,在校验令牌成功后添加将id保存到ThreadLocal中的方法。
//2、校验令牌
try {
log.info("jwt校验:{}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
log.info("当前员工id:{}", empId);
// 将id保存到ThreadLocal
BaseContext.setCurrentId(empId);
//3、通过,放行
return true;
}
在ThreadLocal中获取id即可使用BaseContext.getCurrentId()方法获取。
2. 员工分页查询
(1)service层代码
@Override
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
// 开始分页查询
PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize());
Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);
long total = page.getTotal();
List<Employee> records = page.getResult();
return new PageResult(total, records);
}
(2)补充学习
1. 使用PageHelper分页插件简化代码开发
需要引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
调用PageHelper.startPage(int pageNum, int pageSize)方法,表示开始分页。
在编写Mapper层SQL语句时,即可省略limit条件语句的编写,PageHelper可自动补全分页的条件。
2. 动态SQL的编写
3. token令牌过期处理
需要重新登录获取token令牌
4. 时间日期格式处理
PageHelper在封装时间日期类型的字段时,将其封装成了字符串数组。需要在每个实体类的LocalDateTime类型的属性上加上注解@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")。
3. 启用/禁用员工账号
service层代码
public void startOrStop(Integer status, Long id) {
Employee employee = Employee.builder()
.status(status)
.id(id)
.updateTime(LocalDateTime.now())
.updateUser(BaseContext.getCurrentId())
.build();
employeeMapper.update(employee);
}
需要注意update()方法的复用性,编写动态SQL。
4. 编辑员工
第一步,根据id查询员工信息,回显到前端员工编辑页面。第二步,修改编辑员工信息。
service层代码
@Override
public Employee getById(Long id) {
Employee employee = employeeMapper.getById(id);
employee.setPassword("****");
return employee;
}
@Override
public void update(EmployeeDTO employeeDTO) {
Employee employee = new Employee();
BeanUtils.copyProperties(employeeDTO, employee);
employee.setUpdateTime(LocalDateTime.now());
employee.setUpdateUser(BaseContext.getCurrentId());
employeeMapper.update(employee);
}
分类管理模块
1. 新增菜品分类
2. 菜品分类分页查询
3. 删除菜品分类
service代码
public void deleteById(Long id) {
//查询当前分类是否关联了菜品,如果关联了就抛出业务异常
Integer count = dishMapper.countByCategoryId(id);
if(count > 0){
//当前分类下有菜品,不能删除
throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_DISH);
}
//查询当前分类是否关联了套餐,如果关联了就抛出业务异常
count = setmealMapper.countByCategoryId(id);
if(count > 0){
//当前分类下有菜品,不能删除
throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_SETMEAL);
}
//删除分类数据
categoryMapper.deleteById(id);
}