苍穹外卖-day02

1:添加员工

   需求分析

   产品原型:

账号必须是唯一的。

手机号必须是合法手机号

身份证号必须是合法身份证号

密码默认为123456

使用Json数据返回给前端,请求方式为post,后端响应给前端的数据应封装成一个标准的Result对象,包括code(成功,失败码),data(JSON格式的数据),msg(提示信息)

项目约定:

管理端发出的请求,统一使用/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

代码开发

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

     1 当前端提交的数据与实体类中对应的字段差别比较大的时候,使用DTO来封装数据,提供前端所需要的字段。

      2 实体类中除了前端传来的属性还有其他属性

      3 创建EmployeeDTO来接收前端传来的数据

2.在新增员工的时候,要将DTO对象转换为实体对象,然后对实体对象进行赋值的时候,可以采用属性拷贝(前提条件:属性名必须是一致的)

3 在设置账号状态的时候,默认正常状态为1,0表示锁定,可以定义一个常量类来表示0和1,尽量不要使用魔法数字。

4 由于密码是默认123456,可以设置一个常量类

代码完善 

程序存在的问题:

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

解决:

在handler中捕获相应的异常并且处理

    /**
     * 处理SQL异常
     * @param ex
     * @return
     */
    @ExceptionHandler
    public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){
        // Duplicate entry 'zhangsan' for key 'employee.idx_username'
        String message = ex.getMessage();
        if(message.contains("Duplicate entry")){
            String[] split = message.split(" ");
            String username = split[2] ;
            // String msg = username + "已存在" ;
            String msg = username + MessageConstant.ALREADY_EXISIS ;
            return Result.error(msg) ;
        }else{
            return Result.error("未知错误");
        }
    }

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

ThreadLocal

解决:

从jwt中拿到用户信息:

后续请求中,前端会携带JWT令牌,通过JWT令牌(在拦截器哪里)可以解析出当前员工id

问题:解析出ID之后,如何将ID传给Service中的save方法呢?

使用ThreadLocal线程解决:

ThreadLocal并不是一个Thread,而是Thread的局部变量

ThreadLocal为每一个线程单独提供了一份存储空间,具有线程隔离效果,只有在线程内才能获取到对应的值,线程外不能访问。

客户端每发起一次请求,都会对应一个单独的线程。

可以通过下面代码获取当前线程ID;

System.out.println("当前线程ID  : " + Thread.currentThread().getId());

ThreadLocal常用方法:

pubLic void set(T value):设置当前线程局部变量的值

public T get(): 返回当前线程对应的线程局部变量的值

public void remove():移除当前线程的线程局部变量

在sky-common中的context中包装了相应的方法:

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

}

然后直接在JwtTokenAdminIntercepter中设置ID,然后再ServiceImpl中获取即可

2.员工分页查询

需求分析与设计

业务规则:

    根据页码展示员工信息

    每页展示10条数据

    分页查询可以根据需要,输入员工姓名进行查询

查询一般使用Get方法:

请求参数:

    name:员工姓名

     page:页码

     pageSize:每页记录数

返回数据:

代码开发

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

package com.sky.result;
​
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
​
import java.io.Serializable;
import java.util.List;
​
/**
 * 封装分页查询结果
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {
​
    private long total; //总记录数
​
    private List records; //当前页数据集合
​
}

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

Controller中:.


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

EmployeeService中添加方法:

    PageResult page(EmployeePageQueryDTO employeePageQueryDTO);

在impl实现类中实现该方法

@Override
    public PageResult page(EmployeePageQueryDTO employeePageQueryDTO) {
        PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
        Page<Employee> page=employeeMapper.pageQuery(employeePageQueryDTO);
        return new PageResult(page.getTotal(),page.getResult());
    }

注意:

首先调用Mybatisz中的插件PageHelper实现分页的功能

PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());

实现的原理:

还是用到ThreadLocal原理,每次请求都会对应一个单独的线程,那么就可以将page和pagesize设置成当前线程的局部变量 , 后面就可以直接调用到这两个参数 ;

在EmployeeMapper文件中采用xml来编写对应的sql语句

    Page<Employee> pageQuery(EmployeePageQueryDTO employeePageQueryDTO);

在对应的EmployeeMapper.xml中

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

代码完善:

解决方式:

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

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

在WebMvcConfiguration中扩展Spring Mvc的消息转换器,统一对日期进行格式化处理

3 启用禁用员工账号

需求分析与设计

业务规则:

   可以对状态为"启用“的员工账号进行"禁用”操作

    可以对状态为"禁用“的员工账号进行"启用”操作

     状态为禁用的员工账号不能登录系统

接口设计:

代码开发

本质上,是根据员工id,去修改Status

Controller

注意:

status是路径参数,需要加@PathVariable注解

Service

impl

Mapper

xml

这里使用动态sql编写sql语句

编辑员工:

需求分析

编辑员工功能设计到两个接口

    根据id查询员工信息  get请求方式

     编辑员工信息  put请求方式

代码开发

Controller:

Service

Impl



Mapper

xml

修改:

查询:

5 导入分类模块功能代码

需求分析:

后台系统中可以管理分类信息,分类包括两种类型,分别是菜品类和套餐类

分析菜品分类相关功能

新增菜品分类:当我们在后台系统中添加菜品的时候,需要选择一个菜品分类,在移动端也会按照菜品分类来展示对应的菜品

菜品分类分页查询:系统中的分类很多的时候,如果在一个页面中全部展示出来的话,会显得特别乱,不便于查看,所以一般都分页的方式来展示对应的列表数据

根据id删除菜品分类:在分类管理列表页面,可以对某个分类进行删除操作,当该分类关联了菜品或者套餐的时候,不允许删除。

修改菜品分类:在分类管理列表页面点击修改按钮,弹出修改窗口,在修改窗口回显分类信息进行修改,最后确定按钮完成修改操作。

启用禁用菜品分类:在分类管理列表页面,可以对某个分类进行启用或者禁用操作

分类类型查询:当点击分类类型下拉框的时候,从数据库中查询所有的菜品分类数据进行展示

代码实现:

DishMapper

package com.sky.mapper;
​
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
​
@Mapper
public interface DishMapper {
​
    /**
     * 根据分类id查询菜品数量
     * @param categoryId
     * @return
     */
    @Select("select count(id) from dish where category_id = #{categoryId}")
    Integer countByCategoryId(Long categoryId);
​
}

SetmealMapper

package com.sky.mapper;
​
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
​
@Mapper
public interface SetmealMapper {
​
    /**
     * 根据分类id查询套餐的数量
     * @param id
     * @return
     */
    @Select("select count(id) from setmeal where category_id = #{categoryId}")
    Integer countByCategoryId(Long id);
​
}

CategoryMapper

package com.sky.mapper;
​
import com.github.pagehelper.Page;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
​
import java.util.List;
​
@Mapper
public interface CategoryMapper {
​
    /**
     * 插入数据
     * @param category
     */
    @Insert("insert into category(type, name, sort, status, create_time, update_time, create_user, update_user)" +
            " VALUES" +
            " (#{type}, #{name}, #{sort}, #{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")
    void insert(Category category);
​
    /**
     * 分页查询
     * @param categoryPageQueryDTO
     * @return
     */
    Page<Category> pageQuery(CategoryPageQueryDTO categoryPageQueryDTO);
​
    /**
     * 根据id删除分类
     * @param id
     */
    @Delete("delete from category where id = #{id}")
    void deleteById(Long id);
​
    /**
     * 根据id修改分类
     * @param category
     */
    void update(Category category);
​
    /**
     * 根据类型查询分类
     * @param type
     * @return
     */
    List<Category> list(Integer type);
}

CategoryMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.CategoryMapper">

    <select id="pageQuery" resultType="com.sky.entity.Category">
        select id, type, name, sort, status,
               create_time, update_time,
               create_user, update_user from category
        <where>
            <if test="name != null and name != ''">
                name like concat('%',#{name},'%')
            </if>
            <if test="type != null">
                and type = #{type}
            </if>
        </where>
        order by sort asc , create_time desc
    </select>

    <update id="update" parameterType="com.sky.entity.Category">
        update category
        <set>
            <if test="type != null">
                type = #{type},
            </if>
            <if test="name != null">
                name = #{name},
            </if>
            <if test="sort != null">
                sort = #{sort},
            </if>
            <if test="status != null">
                status = #{status},
            </if>
            <if test="updateTime != null">
                update_time = #{updateTime},
            </if>
            <if test="updateUser != null">
                update_user = #{updateUser}
            </if>
        </set>
        where id = #{id}
    </update>

    <select id="list" resultType="com.sky.entity.Category">
        select * from category
        where status = 1
        <if test="type != null">
            and type = #{type}
        </if>
        order by sort asc,create_time desc
    </select>
</mapper>

Service

CategoryService

package com.sky.service;

import com.sky.dto.CategoryDTO;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import com.sky.result.PageResult;
import java.util.List;

public interface CategoryService {

    /**
     * 新增分类
     * @param categoryDTO
     */
    void save(CategoryDTO categoryDTO);

    /**
     * 分页查询
     * @param categoryPageQueryDTO
     * @return
     */
    PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO);

    /**
     * 根据id删除分类
     * @param id
     */
    void deleteById(Long id);

    /**
     * 修改分类
     * @param categoryDTO
     */
    void update(CategoryDTO categoryDTO);

    /**
     * 启用、禁用分类
     * @param status
     * @param id
     */
    void startOrStop(Integer status, Long id);

    /**
     * 根据类型查询分类
     * @param type
     * @return
     */
    List<Category> list(Integer type);
}

Impl

package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.CategoryDTO;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 分类业务层
 */
@Service
@Slf4j
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private SetmealMapper setmealMapper;

    /**
     * 新增分类
     * @param categoryDTO
     */
    public void save(CategoryDTO categoryDTO) {
        Category category = new Category();
        //属性拷贝
        BeanUtils.copyProperties(categoryDTO, category);

        //分类状态默认为禁用状态0
        category.setStatus(StatusConstant.DISABLE);

        //设置创建时间、修改时间、创建人、修改人
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        category.setCreateUser(BaseContext.getCurrentId());
        category.setUpdateUser(BaseContext.getCurrentId());

        categoryMapper.insert(category);
    }

    /**
     * 分页查询
     * @param categoryPageQueryDTO
     * @return
     */
    public PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO) {
        PageHelper.startPage( categoryPageQueryDTO.getPage(),
                 categoryPageQueryDTO.getPageSize());
        //下一条sql进行分页自动加入limit关键字分页
        Page<Category> page = categoryMapper.pageQuery(categoryPageQueryDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 根据id删除分类
     * @param id
     */
    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);
    }

    /**
     * 修改分类
     * @param categoryDTO
     */
    public void update(CategoryDTO categoryDTO) {
        Category category = new Category();
        BeanUtils.copyProperties(categoryDTO,category);

        //设置修改时间、修改人
        category.setUpdateTime(LocalDateTime.now());
        category.setUpdateUser(BaseContext.getCurrentId());

        categoryMapper.update(category);
    }

    /**
     * 启用、禁用分类
     * @param status
     * @param id
     */
    public void startOrStop(Integer status, Long id) {
        Category category = Category.builder()
                .id(id)
                .status(status)
                .updateTime(LocalDateTime.now())
                .updateUser(BaseContext.getCurrentId())
                .build();
        categoryMapper.update(category);
    }

    /**
     * 根据类型查询分类
     * @param type
     * @return
     */
    public List<Category> list(Integer type) {
        return categoryMapper.list(type);
    }
}

Controller

package com.sky.controller.admin;
​
import com.sky.dto.CategoryDTO;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.CategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
​
/**
 * 分类管理
 */
@RestController
@RequestMapping("/admin/category")
@Api(tags = "分类相关接口")
@Slf4j
public class CategoryController {
​
    @Autowired
    private CategoryService categoryService;
​
    /**
     * 新增分类
     * @param categoryDTO
     * @return
     */
    @PostMapping
    @ApiOperation("新增分类")
    public Result<String> save(@RequestBody CategoryDTO categoryDTO){
        log.info("新增分类:{}", categoryDTO);
        categoryService.save(categoryDTO);
        return Result.success();
    }
​
    /**
     * 分类分页查询
     * @param categoryPageQueryDTO
     * @return
     */
    @GetMapping("/page")
    @ApiOperation("分类分页查询")
    public Result<PageResult> page(CategoryPageQueryDTO categoryPageQueryDTO){
        log.info("分页查询:{}", categoryPageQueryDTO);
        PageResult pageResult = categoryService.pageQuery(categoryPageQueryDTO);
        return Result.success(pageResult);
    }
​
    /**
     * 删除分类
     * @param id
     * @return
     */
    @DeleteMapping
    @ApiOperation("删除分类")
    public Result<String> deleteById(Long id){
        log.info("删除分类:{}", id);
        categoryService.deleteById(id);
        return Result.success();
    }
​
    /**
     * 修改分类
     * @param categoryDTO
     * @return
     */
    @PutMapping
    @ApiOperation("修改分类")
    public Result<String> update(@RequestBody CategoryDTO categoryDTO){
        categoryService.update(categoryDTO);
        return Result.success();
    }
​
    /**
     * 启用、禁用分类
     * @param status
     * @param id
     * @return
     */
    @PostMapping("/status/{status}")
    @ApiOperation("启用禁用分类")
    public Result<String> startOrStop(@PathVariable("status") Integer status, Long id){
        categoryService.startOrStop(status,id);
        return Result.success();
    }
​
    /**
     * 根据类型查询分类
     * @param type
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据类型查询分类")
    public Result<List<Category>> list(Integer type){
        List<Category> list = categoryService.list(type);
        return Result.success(list);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值