【Java项目实战】瑞吉外卖-03 员工管理业务开发

五、新增员工信息功能

需求分析

后台系统中管理员工信息,通过新增员工来添加后台系统用户。点击[添加员工]按钮跳转到新增页面,如下:

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第1张图片

数据模型

新增员工,其实就是将新增页面录入的员工数据插入到employee表中。需要注意,employee表中对username字段加入了唯一约束,因为username是员工的登录账户,必须是唯一的。employee表中的status字段已经设置了默认值1,表示状态正常。

代码开发

在开发代码之前,需要梳理以下整个程序的执行过程:

1.页面发送ajax请求,将新增员工页面中的输入的数据以json的形式提交到服务端;

2.服务端Controller接收页面提交的数据并调用Service将数据进行保存;

3.Service调用Mapper操作数据库,保存数据。

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第2张图片

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第3张图片

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第4张图片

 存在的问题:

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第5张图片

 在common包中添加异常处理器进行全局异常捕获,如果使用try、catch需要重复书写

package com.huangzx.reggie.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局异常处理
 */
@ControllerAdvice(annotations = {RestController.class, Controller.class}) //拦截带有这些Controller注解的类
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 异常处理方法
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class) //捕获的异常类别
    public R ExceptionHandler(SQLIntegrityConstraintViolationException ex){
        log.error(ex.getMessage());
        if(ex.getMessage().contains("Duplicate entry")){ //该类型报错中含有的字段
            String[] split = ex.getMessage().split(" "); //对报的错误Duplicate entry 'zhangsan' for key 'employee.idx_username' 进行分割
            String msg = split[2] + "已存在!";
            return R.error(msg); //返回页面信息
        }
        return R.error("未知错误!");
    }
}

 当添加重复的账户,会报错

 六、员工信息分页查询

 需求分析

系统中的员工很多的时候,如果在一个页面中全部展示处理会显得比较乱,不便于查看,所以一般的系统中都会以分页的形式来展示列表数据。

代码开发

整个程序的执行过程:

1.页面发送ajax请求,将分页查询参数(page、pagesize、name)提交到服务端;

2.服务端Controller接收页面提交的数据并调用Service查询数据;

3.Service调用Mapper操作数据库,查询分页数据;

4.Controller将查询到的分页数据响应给页面;

5.页面接收到分页数据并通过ElementUI的Table组件展示到页面上。

前端页面需要服务端返回的数据,R中使用Page泛型

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第6张图片

创建MybatisPlus分页查询插件 

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第7张图片

    /**
     * 员工信息分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R page(int page,int pageSize,String name){  //前端页面需要服务端返回的数据是res.data.records,res.data.total,所以这里使用Page泛型在进行分页查询的时候,会查询名字,所以加入name
        log.info("page={},pageSize={},name={}",page,pageSize,name);

        //构造分页构造器
        Page pageInfo = new Page();
        //构造条件构造器
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
        //添加过滤条件
        queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name); //判断查询name是否为空
          //添加排序条件
        queryWrapper.orderByDesc(Employee::getUpdateTime);
        //执行查询
        employeeService.page(pageInfo,queryWrapper);
        return R.success(pageInfo);
    }

七、启用/禁用员工账户 

需求分析

在员工管理表页面,可以对某个员工账户进行启用或者禁用操作,账户禁用的员工不能登录系统,启用后的员工可以正常登录。需要注意:只有管理员(admin用户)可以对其他普通用户进行启用、禁用操作,所以普通用户登录系统后启用、禁用按钮不显示。

如果某个员工账户状态为正常,则按钮显示为“禁用”,如果员工账户状态为已禁用,则按钮显示为“启用”。

页面如何做到只有管理员admin能够看到启用、禁用按钮的?

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第8张图片

如果账户状态为正常,则按钮显示为禁用,否则为启用。

代码开发

 程序执行过程:

1.页面发送ajax请求,将参数(id、status)提交到服务端;

2.服务端Controller接收页面提交的数据并调用Service更新数据;

3.Service调用Mapper操作数据库。

 页面中ajax请求是如何发送的?

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第9张图片

 启用、禁用员工账户,本质上就是一个更新操作,也就是对status状态字段进行操作,在Controller中创建update方法,此方法是一个通用的修改员工信息的方法。

功能测试

测试过程中没有报错,但是功能并没有实现,查看数据库中的数据也没有变化。查看控制台输出的SQL:

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第10张图片

通过观察控制台输出的SQL发现页面传递过来的员工的id的值和数据库中的id值不一致,这是因为分页查询时服务端响应给页面的数据中的id的值为19位数字,类型为long,而页面中js处理long型数字只能精确到前16位,所以最终通过ajax请求提交给服务端的时候id变了。

如何解决问题:

可以在服务端给页面响应json数据时进行处理,将long型数据统一转为String字符串。

 实现步骤:

1.提供对象转换器JacksonObjectMapper,基于Jackson进行Java对象到json对象数据的转换;

2.在WebMvcConfig配置类中扩展Spring mvc的消息转换器,在此消息转换器中使用提供的对象转换器进行Java对象到json数据的转换。

通用类Common中添加JacksonObjectMapper类

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
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.math.BigInteger;
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_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(BigInteger.class, ToStringSerializer.instance)
                .addSerializer(Long.class, ToStringSerializer.instance)
                .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);
    }
}

在WebmvcConfig类中添加消息转换器

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第11张图片

八、修改员工信息

需求分析

在员工管理列表页面点击编辑按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击保存按钮完成操作。

代码开发

程序执行流程:

1.点击编辑按钮时,页面跳转到add.html,并在url中携带参数(员工id) add.html页面为公共页面,新增员工和编辑员工都是在此页面操作

2.在add.html页面获取url中的参数(员工id);

3.发送ajax请求,请求服务端,同时提交员工id参数;

4.服务端接收请求,根据员工id查询员工信息,将员工信息以json形式响应给页面;

5.页面接收服务端响应的json数据,通过VUE的数据绑定进行员工信息回显;

6.点击保存按钮,发送ajax请求,将页面中的员工信息以json方式提交给服务端;

7.服务端接收员工信息,并进行处理,完成后给页面响应;

8.页面接收到服务端响应信息后进行相应处理。

前端add.html中,传入id后判断是要修改员工信息,还是要添加员工信息;如果修改员工信息,init()中传入员工信息,在性别属性中,通过状态0或者1判断是男还是女

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第12张图片

【Java项目实战】瑞吉外卖-03 员工管理业务开发_第13张图片

 修改员工信息后,点击保存,此时相当于公用之前的添加员工信息操作。

你可能感兴趣的:(java,开发语言)