继续上一节内容本节完成新增员工员工分页查询启用禁用员工账号编辑员工、导入分类模块功能代码

新增员工(完整流程分为以下五个部分)

需求分析设计

产品原型

一般在做需求分析时,往往都是对照着产品原型进行分析,因为产品原型比较直观,便于我们理解业务

在这里插入图片描述

填写表单信息, 点击保存按钮后, 会提交表单数据服务端, 在服务端需要接受数据, 然后将数据保存数据库中。

注意事项账号必须是唯一的、手机号为合法的11位手机号码身份证号为合法的18位身份证号码、密码默认为123456

接口设计

在这里插入图片描述

明确新增员工接口请求路径请求方式请求参数返回数据。

项目约定:

设计

新增员工,其实就是将我们新增页面录入的员工数据插入employee表。status字段已经设置默认值1,表示状态正常。

在这里插入图片描述

代码开发

设计DTO类

前面看到前端传输过来的是json的数据,是否可以使用对应实体类接收呢?

在这里插入图片描述

由于上述入参数和实体类有较大差别,所以还是自定义DTO类。skypojocom.sky.dto定义EmployeeDTO

@Data
public class EmployeeDTO implements Serializable {

    private Long id;

    private String username;

    private String name;

    private String phone;

    private String sex;

    private String idNumber;

}

Controller

skyservercom.sky.controller.adminEmployeeController创建新增员工方法

@PostMapping
@ApiOperation("新增员工")
public Result save(@RequestBody EmployeeDTO employeeDTO){
    log.info("新增员工:{}",employeeDTO);
    employeeService.save(employeeDTO);
    return Result.success();
}

Service

com.sky.server.impl.EmployeeServiceImpl,需要在EmployeeService 接口中先声明方法,后续不再赘述。

public void save(EmployeeDTO employeeDTO) {
    Employee employee = new Employee();

    //对象属性拷贝 employeeDTO拷贝employee 前提是公有属性名字要一致
    BeanUtils.copyProperties(employeeDTO, employee);

    //设置账号状态默认正常状态 1表示正常 0表示锁定
    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);
}

PS:上面的TODO注释高亮显示提醒程序员修复这段代码

Mapper

com.sky.EmployeeMapper声明insert方法

@Insert("insert into employee (name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user,status) " +
        "values " +
        "(#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})")
void insert(Employee employee);

application.yml中已开启驼峰命名,故id_number和idNumber可对应。

mybatis:
  configuration:
    #开启驼峰命名
    map-underscore-to-camel-case: true

功能测试

重启服务访问http://localhost:8080/doc.html进入新增员工接口

在这里插入图片描述

响应码:401 报错通过断点调试进入到JwtTokenAdminInterceptor拦截器发现由于JWT令牌校验失败,导致EmployeeController的save方法没有调用

解决方法:调用员工登录接口获得一个合法的JWT令牌

使用admin用户登录获取令牌

在这里插入图片描述
添加令牌:将合法的JWT令牌添加全局参数中,文档管理–>全局参数设置–>添加参数

在这里插入图片描述

再次进行新增测试,成功,其中,请求头部含有JWT令牌

在这里插入图片描述

在这里插入图片描述

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

注意:后面在测试中再有401 报错可能是JWT令牌过期了。

代码完善 (ThreadLocal 线程局部变量)

目前,程序存在问题主要有两个:1.录入用户名已存,抛出异常没有处理 2.新增员工时,创建人id修改人id设置为固定

问题

username已经添加了唯一约束,不能重复报错

在这里插入图片描述

解决通过全局异常处理器处理进入skyserver模块com.sky.hander包下,GlobalExceptionHandler.java添加方法

/**
 * 处理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 + MessageConstant.ALREADY_EXISTS;
        return Result.error(msg);
    }else{
        return Result.error(MessageConstant.UNKNOWN_ERROR);
    }
}

进入sky-common模块,在MessageConstant.java添加

public static final String ALREADY_EXISTS = "已存在";

再次,接口测试

在这里插入图片描述

问题

描述:新增员工时,创建人id修改人id设置为固定值,应该动态的设置为当前登录用户id

在这里插入图片描述

解决通过某种方式动态获取当前登录员工的id。员工登录成功后会生成JWT令牌并响应前端,后续请求中,前端会携带JWT令牌,通过JWT令牌可以解析出当前登录员工id,但是解析登录员工id后,如何传递给Servicesave方法?

可以通过ThreadLocal进行传递

ThreadLocal 并不是一个Thread,而是Thread局部变量
ThreadLocal为每个线程提供单独一份存储空间具有线程隔离效果,只有在线程内才能获取到对应的值,线程外则不能访问,而客户端发起的每一次请求都是一个单独的线程。常用方法:

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

所以解决流程如下

在这里插入图片描述

初始工程sky-common模块已经封装了 ThreadLocal 操作工具类:

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

}

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

@Component
@Slf4j
public class JwtTokenAdminInterceptor implements HandlerInterceptor {

	...
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
			...
            Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
            log.info("当前员工id:", empId);
            /将用户id存储到ThreadLocal
            BaseContext.setCurrentId(empId);
			...
	}
}

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

public void save(EmployeeDTO employeeDTO) {
    //.............................

    //设置当前记录创建人id和修改人id
    employee.setCreateUser(BaseContext.getCurrentId());
    employee.setUpdateUser(BaseContext.getCurrentId());
    employeeMapper.insert(employee);
}

测试:使用admin(id=1)用户登录后添加一条记录

在这里插入图片描述

在这里插入图片描述

代码提交

点击提交

在这里插入图片描述

提交过程中,出现提示继续push

在这里插入图片描述

在这里插入图片描述

员工分页查询

系统中的员工很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页方式展示列表数据。而在我们分页查询页面中, 除了分页条件以外,还有一个查询条件 “员工姓名”。

在这里插入图片描述

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

请添加图片描述

请求参数类型为Query,不是json格式提交,在路径直接拼接。/admin/employee/page?name=zhangsan。返回数据中records数组中使用Employee实体类对属性进行封装

设计DTO类,根据请求参数进行封装,在sky-pojo模块中,EmployeePageQueryDTO

@Data
public class EmployeePageQueryDTO implements Serializable {
    //员工姓名
    private String name;
    //页码
    private int page;
    //每页显示记录数
    private int pageSize;
}

后面所有的分页查询,统一都封装为PageResult对象。在sky-common模块。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {
    private long total; //总记录数
    private List records; //当前页数据集合
}

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

Controller层

sky-server模块中,com.sky.controller.admin.EmployeeController

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

Service实现

在EmployeeServiceImpl中实现pageQuery方法:

public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
   // select * from employee limit 0,10
   //开始分页查询
   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);
}

注意:此处使用 mybatis 的分页插件 PageHelper 来简化分页代码的开发底层基于 mybatis拦截器实现。故在pom.xml文中添加依赖(初始工程添加)

<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper-spring-boot-starter</artifactId>
   <version>${pagehelper}</version>
</dependency>

Mapper层

EmployeeMapper 中声明 pageQuery

Page<Employee> pageQuery(EmployeePageQueryDTO employeePageQueryDTO);

src/main/resources/mapper/EmployeeMapper.xml编写动态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 desc
</select>

重启服务:访问http://localhost:8080/doc.html进入员工分页查询

在这里插入图片描述

在这里插入图片描述

前后联调测试发现最后操作时间格式不清晰,在代码完善中解决

在这里插入图片描述

代码完善 扩展Spring MVC消息转化器 extendMessageConverters

下面进行代码完善。

方式

属性上加上注解,对日期进行格式化

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
	...
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

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

但这种方式,需要每个时间属性上都要加上该注解,使用较麻烦,且不能全局处理

方式二(推荐 )

配置类WebMvcConfiguration中扩展SpringMVC的消息转换器消息转换器作用就是对我们后端返回给前端的数据进行统一处理,我们这里需要一对日期类型进行格式处理。
WebMvcConfiguration继承父类WebMvcConfigurationSupport,这个spring我们提供的,web层的配置类一般都会去继承它,拓展消息转换器就需要重写父类里的extendMessageConverters方法,写的代码都是固定的。

WebMvcConfiguration

/**
 * 扩展Spring MVC框架的消息转化器
 * @param converters
 */
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {//该方法在程序启动时就会被调用到
    log.info("扩展消息转换器...");
    //创建一个消息转换对象
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    //需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
    converter.setObjectMapper(new JacksonObjectMapper());
    //设置完对象转换器还需要将自己的消息转化器加入器中 converters存放的是我们整个spring mvc框架使用到的消息转换
    converters.add(0,converter);//存入容器指定索引,否则如果插入到最后默认是使用不到的,我们希望优先使用自己的消息转换器,放在第一位
}

时间格式的对象转换器JacksonObjectMapper已经提前写好,存放在sky-common模块的json包下

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {//继承jackson包里的ObjectMapper类 是json处理的一个类
//代码写法比较固定,知道当前类起什么作用就行
    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);

        //下面可以看到其实是对我们这种比如LocalDateTime这种类型设置了反序列化器(Deserializer)和序列化器(Serializer)
        //同时也针对转换的格式进行了指定
        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);
    }
}

添加后,再次测试

在这里插入图片描述

功能完成,提交代码,和新增员工代码提交一致,不再赘述。

启用禁用员工账号

在这里插入图片描述

可以对状态为“启用” 的员工账号进行“禁用”操作,可以对状态为“禁用”的员工账号进行“启用”操作,状态为“禁用”的员工账号不能登录系统

请添加图片描述

路径参数携带状态值。同时,把id传递过去,id的类型是Query类型,即通过地址栏传参的方式传入id,明确对哪个用户进行操作

Controller层

sky-server模块中,EmployeeController 中创建启用禁用员工账号的方法

@PostMapping("/status/{status}")
@ApiOperation("启用禁用员工账号")
public Result startOrStop(@PathVariable Integer status,Long id){
    log.info("启用禁用员工账号:{},{}",status,id);
    employeeService.startOrStop(status,id);//后绪步骤定义
    return Result.success();
}

Service层实现

EmployeeServiceImpl

public void startOrStop(Integer status, Long id) {
    Employee employee = Employee.builder()
            .status(status)
            .id(id)
            .build();

    employeeMapper.update(employee);
}

Mapper层

EmployeeMapper 接口声明 update 方法

void update(Employee employee);

在 EmployeeMapper.xml编写动态SQL:

<update id="update" parameterType="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>

测试:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

测试完毕,提交代码。

编辑员工

在这里插入图片描述

在这里插入图片描述

注:点击修改时,数据应该正常回显到修改页面。点击 “保存” 按钮完成编辑操作

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

根据id查询员工信息
请添加图片描述

编辑员工信息

请添加图片描述

回显员工信息功能

EmployeeController 中创建 getById:

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

EmployeeServiceImpl 中实现 getById 方法:

public Employee getById(Long id) {
    Employee employee = employeeMapper.getById(id);
    employee.setPassword("****");//回显给前端展示的信息不展示密码
    return employee;
}

EmployeeMapper 接口中声明 getById 方法:

@Select("select * from employee where id = #{id}")
Employee getById(Long id);

修改员工信息功能

EmployeeController 中创建 update 方法:

@PutMapping
@ApiOperation("编辑员工信息")
public Result update(@RequestBody EmployeeDTO employeeDTO){
    log.info("编辑员工信息:{}", employeeDTO);
    employeeService.update(employeeDTO);
    return Result.success();
}

EmployeeServiceImpl 中实现 update 方法:

    public void update(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeDTO, employee);

        employee.setUpdateTime(LocalDateTime.now());
        employee.setUpdateUser(BaseContext.getCurrentId());//获取线程局部变量中的值

        employeeMapper.update(employee);
    }

实现启用禁用员工账号功能时,已实现employeeMapper.update(employee),所以在此不需写Mapper层代码。

分别测试根据id查询员工信息和编辑员工信息两个接口:

在这里插入图片描述

在这里插入图片描述

前后联调测试也通过,提交代码。

导入分类模块功能代码

在这里插入图片描述

后台系统中可以管理分类信息,分类包括两种类型,分别是菜品分类和套餐分类。先来分析菜品分类相关功能。

新增菜品分类菜品分类分页查询根据id删除菜品分类(要注意的是当分类关联菜品或者套餐时,此分类不允许删除)、修改菜品分类(点击修改按钮,弹出修改窗口,在修改窗口回显分类信息)、启用禁用菜品分类分类类型查询(当点击分类类型下拉框时,从数据库中查询所有的菜品分类数据进行展示)

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

根据上述原型图分析,菜品分类模块共涉及如下6个接口:

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

category结构

字段名 数据类型 说明 备注
id bigint 主键 自增
name varchar(32) 类名 唯一
type int 分类类型 1菜品分类 2套餐分类
sort int 排序字段 用于分类数据的排序
status int 状态 1启用 0禁用
create_time datetime 创建时间
update_time datetime 最后修改时间
create_user bigint 创建人id
update_user bigint 最后修改人id

导入资料中的分类管理模块功能代码即可

在这里插入图片描述

可按照mapper–>service–>controller依次导入,这样代码不会显示相应的报错进入到sky-server模块中:

Mapper层

DishMapper.java

@Mapper
public interface DishMapper {

    /**
     * 根据分类id查询菜品数量
     * @param categoryId
     * @return
     */
    @Select("select count(id) from dish where category_id = #{categoryId}")
    Integer countByCategoryId(Long categoryId);

}

SetmealMapper.java

@Mapper
public interface SetmealMapper {

    /**
     * 根据分类id查询套餐的数量
     * @param id
     * @return
     */
    @Select("select count(id) from setmeal where category_id = #{categoryId}")
    Integer countByCategoryId(Long id);

}

CategoryMapper.java

@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,进入到resources/mapper目录

<?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 * from category
        <where>
            <if test="name != null and name != ''">
                and 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="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="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.java

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

CategoryServiceImpl.java

@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层

CategoryController.java

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

导入完毕后还需要编译,确保代码无错误

在这里插入图片描述

重启服务,功能太多,直接前后联调测试:

在这里插入图片描述

测试通过提交代码。

原文地址:https://blog.csdn.net/weixin_43739821/article/details/134580408

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_34870.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注