当前位置: 首页 > 图灵资讯 > 技术篇> 员工管理

员工管理

来源:图灵教育
时间:2023-06-17 13:55:02

1.新员工2-51.1需求分析2-5

员工信息可以在后台系统中管理,后台系统用户可以通过新员工添加,点击【添加员工】按钮转到新页面如下:

员工管理_xml

新员工实际上是在employee表中插入我们新页面输入的员工数据。需要注意的是,employee表中对username字段增加了唯一的约束,因为username是员工的登录账户,必须是唯一的

员工管理_xml_02

1.2代码开发2-6

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

1、页面发送ajax请求,以json的形式向服务端提交新员工页面输入的数据

2、服务器Controler接收页面提交的数据,并调用Service保存数据

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

员工管理_xml_03

Employeronerleler

这里解释@PostMaping后面为什么不加路径,因为点击添加按钮后发起的路径是

http://localhost:8080/employee,这个employee,我们在employecontroler类中添加了

@RequestMapping("/employee“)注释,会自动添加employee

 

//保存员工信息  2-7    @PostMapping    public R save(HttpServletRequest request,@RequestBody Employee employee){        log.info(新员工,员工信息:{}employee.toString());        //设置初始密码123456,MD5加密处理需要进行        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));        employee.setCreateTime(LocalDateTime.now());        employee.setUpdateTime(LocalDateTime.now());        //获得当前登录用户的id,这个id是管理员的id,因为只有管理员增加了员工的右权限        Long empId = (Long) request.getSession().getAttribute("employee");        employee.setCreateUser(empId);        employee.setUpdateUser(empId);        employeeService.save(employee);        return R.success(“新员工成功”);    }

 

测试

员工管理_数据_04

员工管理_服务端_05

1.3解决员工同名异常问题2-8

前面的程序还有一个问题,就是当我们在新员工中输入的账号已经存在时,由于employee表中对字段的唯一约束,此时程序会抛出异常:

员工管理_xml_06

1.3.1解决方法2-8

此时,我们的程序需要异常捕获,通常有两种处理方法:

1、在Controller方法中添加try、异常捕获catch

员工管理_服务端_07

2、使用异常处理器捕获2-82-9

Globalexceptiondler

 

package com.itheima.reggie.common;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import java.sql.SQLIntegrityConstraintViolationException;/** * 全局异常处理   2-8 *////@ContrlerAdvice注释的作用是拦截,例如,拦截添加了Restcontroler注释和controler注释的类别@ControllerAdvice(annotations = {RestController.class, Controller.class})@ResponseBody///返回结果封装成json@slf4jpublic class GlobalExceptionHandler {    /**     * 异常处理方法2-8     * @return     */    //处理SQLIntegrityconstraintiontionexception异常    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){        log.error(ex.getMessage());        //2-9        if(ex.getMessage().contains("Duplicate entry")){            String[] split = ex.getMessage().split(" ");            String msg = split[2] + "已存在";            return R.error(msg);        }        return R.error(“未知错误”);    }}

 

员工管理_xml_08

2.阶段总结2-10

员工管理_服务端_09

3.员工信息分页查询2-113.1需求分析2-111

很多时候,系统中的员工如果在一个页面上全部显示,会显得凌乱,不方便查看,所以列表数据会在一般系统中以分页的形式显示。

员工管理_服务端_10

3.2代码开发2-12

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

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

2、服务器Controler接收页面提交的数据,并调用Service查询数据

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

4、Controller将查询到的分页数据响应到页面

5、页面接收分页数据,并通过elementultable组件显示到页面上

员工管理_服务端_11

MybatisPlusConfigggig代码实现2-13配置MP的分页插件

 

package com.itheima.reggie.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * 配备MP的分页插件  2-13 */@Configurationpublic class MybatisPlusConfig {    @Bean    public MybatisPlusInterceptor mybatisPlusInterceptor(){        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());        return mybatisPlusInterceptor;    }}

 

接口设计

前端注意事项

员工管理_服务端_12

员工管理_xml_13

Employecontroler2-132-14

 

 ////员工信息分页查询 2-13 2-14    @GetMapping("/page")    public R<Page> page(int page,int pageSize,String name){//page第几页,pagesize查询了几个条目        log.info("page = {},pageSize = {},name = {}" ,page,pageSize,name);        //构造分页构造器        Page pageInfo = new Page(page, pageSize);        //构造条件结构器        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();        //添加过滤条件        queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);        ///添加排序条件(使用更新时间排序)        queryWrapper.orderByDesc(Employee::getUpdateTime);        //执行查询        employeeService.page(pageInfo,queryWrapper);        return R.success(pageInfo);    }

 

员工管理_服务端_14

4.禁用员工账号2-17

只不过是修改status,0禁用,1启用

4.1需求分析

在员工管理列表页面上,可以启用或禁止员工账户。禁用账户的员工不能登录系统,启用后的员工可以正常登录。

需要注意的是,只有管理员(admin用户)才能启用和禁止其他普通用户,因此不显示普通用户登录系统后的启用和禁用按钮。

员工管理_xml_15

4.2代码开发2-19

员工管理_数据_16

开发流程2-20

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

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

2、服务器Controler接收页面提交的数据,并调用Service更新数据

3、Service调用Maper操作数据库

员工管理_xml_17

启用和禁用员工账户本质上是一种更新操作,即操作status状态字段,在controller中创建update方法。这种方法是修改员工信息的通用方法

Employecontroler2-2000

 

 ////根据id修改员工信息  2-20    //启用禁用员工  2-20    @PutMapping    public R<String> update(HttpServletRequest request,@RequestBody Employee employee){        log.info(employee.toString());        ///从session中取出更新人的iddon        Long empId = (Long) request.getSession().getAttribute("employee");        employee.setUpdateTime(LocalDateTime.now());///更新时间        employee.setUpdateUser(empId);///更新人id        employeeService.updateById(employee);        return R.success(成功修改员工信息);    }

 

结果数据库没有成功更新

员工管理_xml_18

员工管理_xml_19

代码修复2-21

我们已经发现了问题的原因,即js在处理long数据时失去了精度,导致提交的id与数据库中的id不一致。(js只能保证前16位的准确性,但我们的id是19位)

如何解决这个问题?

当服务端响应json数据时,我们可以处理long数据,将long数据统一转换为string字符串如下:

具体实现步骤:2-21

1)为JacksonobjectMaper提供对象转换器,基于Jackson转换Java对象到Json数据(已在数据中提供,直接复制到项目中使用)

2)在WebMvcconfig配置类中扩展Springmvc的消息转换器,使用提供的对象转换器转换Java对象到Json数据

Jacksonjectmapper2-21

 

package com.itheima.reggie.common;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对象   2-21 * 将JSON分析为Java对象的过程称为 [Java对象从JSON反序列化] * JSON是从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);    }}

 

修改WebMvconfig配置类2-21

 

/**     * 扩展MVC框架的消息转换器  2-21     * @param converters     */    @Override    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {        log.info(”扩展新闻转换器...");        ////创建信息转换器对象        MapingJacksonHttpMessageConverter messageConverter = new MapingJacksonHttpMessageConverter();        //设置对象转换器(设置为我们自己的信息转换器),Jackson将Java对象转化为json        messageConverter.setObjectMapper(new JacksonObjectMapper());        ///将上述信息转换器对象添加到MVC框架的转换器集合中        ///这里这个0 索引的目的是把我们的信息转换器放在集合的前面,优先使用        converters.add(0,messageConverter);    }

 

测试成功

员工管理_数据_20

5.编辑员工信息2-2335.1需求分析2-23

员工管理_xml_21

5.2代码开发2-23

在开发代码之前,需要对操作过程和相应程序的执行过程进行梳理:

1、点击编辑按钮时,页面跳转到add.html,并在url中携带参数[员IID]

2、在add.url中的参数[员IID]在html页面上获取

3、发送ajax请求,请求服务端,并提交员工id参数

4、服务端接收请求,根据员工ID查询员工信息,以json的形式响应员工信息

5、页面接收服务端响应的json数据,并通过VUE数据绑定显示员工信息

6、点击保存按钮,发送ajax请求,以json的形式向服务端提交页面中的员工信息

7、服务端接收员工信息并处理,完成后响应页面

8、页面在收到服务端响应信息后进行相应处理

注意:add.html页面是公共页面,新员工和编辑员工都在这个页面上操作

显然,这是一条restful风格的路径,需要使用@Pathvariable来获取路径中的值

员工管理_xml_22

员工管理_服务端_23

编辑员工信息Employecontroller2-25

 

 /**     * 根据id查询员工信息     * @param id     * @return     */    @GetMapping("/{id})//restful风格    public R<Employee> getById(@PathVariable Long id){        log.info(”根据id查询员工信息...");        Employee employee = employeeService.getById(id);        if(employee != null){            return R.success(employee);        }        return R.error(未查询相应员工信息);    }

 

员工管理_xml_24

修改名称并保存(以下是保存的实用方法和方法启用禁用那里的代码是一个,本质上是修改的)