黑马程序员苍穹外卖项目笔记Day2

Day2:员工管理、分类管理

新增员工
项目约定

O 管理端发出的请求,统一使用/admin作为前缀

O 用户端发出的请求,统一使用/user作为前缀

代码开发

根据新增员工接口设计对应的DTO

从前端接收到DTO实体,转化成数据库对应的entity,在Service层添加代码:

/*
     * 新增员工
     * */
    @Override
    public void save(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();

        //对象属性拷贝
        BeanUtils.copyProperties(employeeDTO,employee);

        //设置账号状态,默认正常状态
        employee.setStatus(StatusConstant.ENABLE);

        //设置密码,默认密码123456
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));

        //设置当前记录的创建时间和修改实践
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());

        //设置当前记录创建人id和修改人id
        // TODO 后期需要改为当前登录用户的id
        employee.setCreateUser(10L);
        employee.setUpdateUser(10L);

        employeeMapper.insert(employee);
    }
代码完善

程序存在的问题:

o 录入的用户名已经存在

o 新增员工时,创建人id和修改人id设置为了固定值

1、处理用户名重复问题,设置异常处理器:

//    处理异常信息,处理SQL异常
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        // Duplicate entry 'zhaoliu' for key 'idx_username'
        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2];
            String msg = username + MessageConstant.ALREADY_EXISTS;
            return Result.error(msg);
        }
        else {
            return Result.error(MessageConstant.UNKNOWN_ERROR);
        }
    }

2、获取登录用户的id

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

整个程序在同一线程中执行,获取线程中正在登录的id,通过一个中间件得到:

package com.sky.context;

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();
    }

}
员工的分页查询

需求分析和设计:根据展示员工信息,每页展示10条数据,分页查询时可以根据需要,输入员工姓名进行模糊查询:

contorller层:

//员工分页查询
@ApiOperation(value = "员工分页查询")
@GetMapping("/page")
public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
    log.info("员工分页查询,参数为:{}",employeePageQueryDTO);
    PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);
    return Result.success(pageResult);
}

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);
}

sql语句:

<select id="pageQuery" resultType="com.sky.entity.Employee">
    select *
    from employee
    <where>
        <if test="name!=null and name!=''">
            and name like concat('%',#{name},'%')
        </if>
    </where>
    order by create_time asc
</select>

前后端联调:

黑马程序员苍穹外卖项目笔记Day2_第1张图片

结果优化,代码完善,对操作时间进行完善:

对日期进行格式化:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

或者在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式化处理:

//扩展SpringMVC框架的消息转换器,日期类型的格式化
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    log.info("拓展消息转换器...");
    //创建一个消息转换器
   MappingJackson2HttpMessageConverter convertor = new MappingJackson2HttpMessageConverter();
   //需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
    convertor.setObjectMapper(new JacksonObjectMapper());
    //将自己的消息转换器加入容器中
    converters.add(0,convertor);
}
启用禁用员工账号

controller层:

/**
 * 启用禁用员工账号
 * @param status
 * @param id
 * @return
 */
@ApiOperation(value = "启用禁用员工账号")
@PostMapping("/status/{status}")
public Result startOrStop(@PathVariable("status") Integer status,Long id){
    log.info("启用禁用员工账号:{},{}",status,id);
    employeeService.startOrStop(status,id);
    return Result.success();
}

service实现层:

/**
 * 启用禁用员工账号
 * @param status
 * @param id
 */
@Override
public void startOrStop(Integer status, Long id) {
    // update employee set status = ? where id = ?
    //动态更新,构造一个实体类
    Employee build = Employee.builder()
            .status(status)
            .id(id)
            .build();
    employeeMapper.update(build);
}

数据层:(动态Sql语句,便于重复利用)

<update id="update" parameterType="com.sky.entity.Employee">
    update employee
    <set>
        <if test="name!=null">
            name=#{name},
        </if>
        <if test="username!=null">
            username=#{username},
        </if>
        <if test="password!=null">
            password = #{password},
        </if>
        <if test="phone!=null">
            phone = #{phone},
        </if>
        <if test="sex!=null">
            sex =#{sex},
        </if>
        <if test="idNumber!=null">
            id_number =#{idNumber},
        </if><if test="updateTime!=null">
            update_time =#{updateTime},
        </if>
        <if test="updateUser!=null">
        update_user =#{updateUser},
        </if>
        <if test="status!=null">
            status =#{status},
        </if>
    </set>
        where id= #{id}
</update>
编辑员工

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

1、根据id查询员工信息(用于页面的回显)

2、编辑员工信息(更新到数据库)

controller层:

/**
 * 根据id查询员工信息
 * @param id
 * @return
 */
@ApiOperation(value = "根据id查询员工信息")
@GetMapping("/{id}")
public Result<Employee> getById(@PathVariable Long id){
    Employee employee = employeeService.getById(id);
    return Result.success(employee);
}

/**
 * 编辑员工信息
 * @param employeeDTO
 * @return
 */
@ApiOperation(value = "编辑员工信息")
@PutMapping
public Result update(@RequestBody EmployeeDTO employeeDTO){
    log.info("编辑员工信息,{}",employeeDTO);
    employeeService.update(employeeDTO);
    return null;
}

service实现层:

/**
 * 根据id查询员工信息
 * @param id
 * @return
 */
@Override
public Employee getById(Long id) {
    Employee employee = employeeMapper.getById(id);
    employee.setPassword("******");
    return employee;
}

/**
 * 编辑员工信息
 * @param employeeDTO
 */
@Override
public void update(EmployeeDTO employeeDTO) {
    Employee employee = new Employee();
    BeanUtils.copyProperties(employeeDTO,employee);
    employee.setUpdateUser(BaseContext.getCurrentId());
    employee.setUpdateTime(LocalDateTime.now());
    employeeMapper.update(employee);
}

Dao、mapper层:(update重用动态sql代码)

/**
 * 根据id查询员工信息
 * @param id
 * @return
 */
@Select("select * from employee where id=#{id}")
Employee getById(Long id);
导入分类模块功能代码

菜品分类管理模块业务规则:

1、分类名称必须是唯一

2、分类按照类型可以分为菜品分类套餐分类

3、新添加的分类状态默认为”禁用

接口设计:

1、新增分类

2、分类分页查询

3、根据id删除分类

4、修改分类

5、启用禁用分类

6、根据类型查询分类

导入分类管理模块功能代码:

黑马程序员苍穹外卖项目笔记Day2_第2张图片

你可能感兴趣的:(笔记,java)