校园外卖点餐系统——Day02【员工管理业务开发】

简介: 校园外卖点餐系统——Day02【员工管理业务开发】
❤ 作者主页:欢迎来到我的技术博客😎
❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~*
🍊 如果文章对您有帮助,记得关注、点赞、收藏、评论⭐️⭐️⭐️
📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉

一、完善登录功能

1. 问题分析

前面我们已经完成了后台系统的员工登录功能开发,但是还存在一个问题:用户如果不登录,直接访问系统首页面,照样可以正常访问。

这种设计并不合理,我们希望看到的效果应该是,只有登录成功后才可以访问系统中的页面,如果没有登录则跳转到登录页面。

那么,具体应该怎么实现呢?

答案就是使用过滤器或者拦截器,在过滤器或者拦截器中判断用户是否已经完成登录,如果没有登录则跳转到登录页面。


2. 代码实现

  • 创建自定义过滤器 LoginCheckFilter

    /**
     * 检查用户是否已经完成登录
     */
    @Slf4j
    @WebFilter(filterName = "LoginCheckFilter", urlPatterns = "/*")
    public class LoginCheckFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            log.info("拦截到请求:{}", request.getRequestURI());
            filterChain.doFilter(request, response);
        }
    }
  • 在启动类上加入注解 @ServletComponentScan
  • 完善过滤器的处理逻辑

1、获取本次请求的URL
2、判断本次请求是否需要处理
3、如果不需要处理,则直接放行
4、判断登录状态,如果已登录,则直接放行
5、如果未登录则返回登录结果
在这里插入图片描述

/**
 * 检查用户是否已经完成登录
 */
@Slf4j
@WebFilter(filterName = "LoginCheckFilter", urlPatterns = "/*")
public class LoginCheckFilter implements Filter {

    //路径匹配器,支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1、获取本次请求的URI
        String requestURI = request.getRequestURI();// /backend/index.html

        log.info("拦截到请求:{}", requestURI);

        //定义不需要处理的请求路径
        String[] urls = new String[]{
                "/employee/login",
                "/employee/logout",
                "/backend/**",
                "/front/**"
        };

        //2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);

        //3、如果不需要处理,则直接放行
        if(check) {
            log.info("本次请求{}不需要处理", requestURI);
            filterChain.doFilter(request, response);
            return;
        }

        //4、判断登录状态,如果已登录,则直接放行
        if(request.getSession().getAttribute("employee") != null){
            log.info("用户已登录,用户id为:{}", request.getSession().getAttribute("employee"));
            filterChain.doFilter(request, response);
            return;
        }

        log.info("用户未登录");
        //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        return;

    }

    /**
     * 路径匹配,检查本次请求是否需要放行
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls, String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if(match) {
                return true;
            }
        }
        return false;
    }
}

二、新增员工

1. 需求分析

后台系统中可以管理员工信息,通过新增员工来添加后台系统用户。点击 “添加员工”按钮跳转到新增页面,如下:
在这里插入图片描述

2. 数据模型

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

3. 代码开发

 /**
     * 新增员工
     * @param employee
     * @return
     */
    @PostMapping
    public R<String> save(HttpServletRequest request, @RequestBody Employee employee) {

        log.info("新增员工,员工信息:{}", employee.toString());

        //设置初始密码为123456,需要进行md5加密处理
        employee.setPassword(DigestUtils.md5DigestAsHex("1232456".getBytes()));

        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());

        //获取当前登录用户登录的id
        Long empId = (Long)request.getSession().getAttribute("employee");

        employee.setCreateUser(empId);
        employee.setUpdateUser(empId);

        employeeService.save(employee);

        return R.success("新增员工成功");
    }

前面的程序还存在一个问题,就是当我们在新增员工时输入的账号已经存在,由于employee表中对该字段加入了唯一约束,此时程序会抛出异常:
java.sql.SQLIntegrityConstraintViolationException: Duplicate entry 'heniang' for key 'idx_username'

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

1、在Controller方法中加入try.catch进行异常捕获

2、使用异常处理器进行全局异常捕获

/**
 * 全局异常处理
 */
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 异常处理方法
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
        log.error(ex.getMessage());

        if(ex.getMessage().contains("Duplicate entry")){
            String[] split = ex.getMessage().split(" ");
            String msg = split[2] + "已存在";
            return R.error(msg);
        }

        return R.error("未知错误");
    }
}

三、员工信息分页查询

1. 需求分析

系统中的员工很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。
在这里插入图片描述

2. 代码开发

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

  • 页面发送ajax请求,将分页查询参数(page.pageSize、name)提交到服务端
  • 服务端Controller接收页面提交的数据并调用Service查询数据
  • Service调用Mapper操作数据库,查询分页数据
  • Controller将查询到的分页数据响应给页面
  • 页面接收到分页数据并通过ElementUI的Table组件展示到页面上

配置MP分页插件:

/**
 * 配置MP的分页插件
 */
@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

员工信息分页查询:

/**
     * 员工信息分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name) {
        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);
    }

3. 功能测试

在这里插入图片描述


四、启用/禁用员工账号

1. 需求分析

在员工管理列表页面,可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登录系统,启用后的员工可以正常登录。

需要注意,只有管理员(admin用户)可以对其他普通用户进行启用、禁用操作,所以普通用户登录系统后启用、禁用按钮不显示。

2. 代码开发

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

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

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

3、Service调用Mapper操作数据库
在这里插入图片描述

根据id修改员工信息:

    /**
     * 根据id修改员工信息
     * @param employee
     * @return
     */
    @PutMapping
    public R<String> update(HttpServletRequest request, @RequestBody Employee employee) {
        log.info(employee.toString());

        Long empId = (Long)request.getSession().getAttribute("employee");
        employee.setUpdateTime(LocalDateTime.now());
        employee.setUpdateUser(empId);
        employeeService.updateById(employee);

        return R.success("员工信息修改成功");
    }

测试过程中没有报错,但是功能并没有实现,查看数据库中的数据也没有变化。观察控制台输出的SQL:
在这里插入图片描述
SQL执行的结果是更新的数据行数为0,仔细观察id的值,和数据库中对应记录的id值并不相同:
在这里插入图片描述


代码修复
通过观察控制台输出的SQL发现页面传递过来的员工id的值和数据库中的id值不一致,这是怎么回事呢?

分页查询时服务端响应给页面的数据中id的值为19位数字,类型为long。

页面中js处理long型数字只能精确到前16位,所以最终通过ajax请求提交给服务端的时候id就改变了。

前面我们已经发现了问题的原因,即js对long型数据进行处理时丢失精度,导致提交的id和数据库中的id不一致。

如何解决这个问题?

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


具体实现步骤

(1) 提供对象转换器JacksonobjectMapper,基于Jackson进行Java对象到json数据的转换

/**
 * 对象映射器:基于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);
    }
}

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

 /**
     * 扩展mvc框架的消息转换器
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器...");
        //创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        //设置对象转换器,底层使用Jackson将Java对象转为json
        messageConverter.setObjectMapper(new JacksonObjectMapper());
        //将上面的消息转换器对象追加到mvc框架的转换器集合中
        converters.add(0,messageConverter);
    }

3. 功能测试

在这里插入图片描述


五、编辑员工信息

1. 需求分析

在员工管理列表页面点击编辑按钮,跳转到编辑页面,在编辑页面回显员工并进行修改,最后点击按钮完成编辑操作。
在这里插入图片描述


2. 代码实现

在开发代码之前需要梳理一下操作过程和对应的程序的执行流程:
1、点击编辑按钮时,页面跳转到add.html,并在url中携带参数[员工id]

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

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

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

     /**
     * 根据id查询员工信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    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("没有查询到对应员工信息");
    }

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

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

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

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

注意: add.html页面为公共页面,新增员工和编辑员工都是在此页面操作,所以该代码部分与之前添加员工代码对应,不需要重写。


创作不易,如果有帮助到你,请给文章==点个赞和收藏==,让更多的人看到!!!
==关注博主==不迷路,内容持续更新中。

目录
相关文章
|
6月前
|
前端开发 JavaScript Java
Java中规模软件开发实训——掌握财务自由的关键!解锁智能家庭记账系统的神奇力量!(家庭记账软件)
​ ✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(html css js) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页
78 0
直销公排系统模式制度开发搭建讲解
直销公排系统模式制度开发搭建讲解
|
9月前
|
安全 区块链 数据库
互助拍卖竞拍抢单模式系统开发项目方案丨DAPP拍卖竞拍抢拍互助系统开发(案例开发)/开发逻辑/源码运营版
    dapp的开发和运行基于智能合约,智能合约是一种运行在区块链上的自动执行合约,它可以实现自动化的交易和管理逻辑,And automatically supervise and execute according to the set rules.Dapp achieves decentralized data storage,business logic,and value exchange through smart contracts.
|
10月前
|
SQL 安全 前端开发
神游网旅游网站系统的设计与实现_kaic
旅游业走过了改革开放,到现在依旧蓬勃发展。但是放眼国际社会,我们在旅游业发展的深度和广度上所做的努力还远远不够。在贵州,旅游业也将成为我过经济崛起中的重要一环。目前,我们生活在一个信息时代里。无论是工作,学习还是生活时,我们都已经离不开计算机网络技术的陪伴。同样的,随着社会的飞速发展和人们意识观念的转变,现代人已不仅追求物质生活,也要满足一定的精神生活,而旅游恰是最能满足日常精神生活。基于此,一款能根据需求提供给用户全套服务的旅游管理网站更值得人们信赖。本系统采用了JSP、SQL Server、Java等设计开发了一个现代化的旅游管理网站,在传统基本功能上,加强了系统的建设和运行机制。其功能主
|
11月前
|
消息中间件 JavaScript 小程序
支付系统就该这么设计,稳的一批!!
支付系统就该这么设计,稳的一批!!
|
Java 数据库连接 测试技术
校园外卖点餐系统——Day03【分类管理业务开发】
校园外卖点餐系统——Day03【分类管理业务开发】
108 0
校园外卖点餐系统——Day03【分类管理业务开发】
|
JSON 前端开发 Java
校园外卖点餐系统——Day04【菜品管理业务开发】
校园外卖点餐系统——Day04【菜品管理业务开发】
131 0
校园外卖点餐系统——Day04【菜品管理业务开发】
|
安全 前端开发 数据安全/隐私保护
企业如何借助码匠,实现员工核酸提醒?
众所周知,疫情当前,常态化核酸是我们必须遵守的防疫政策,因此码匠搭建了一个核酸提醒应用。
406 0
企业如何借助码匠,实现员工核酸提醒?
|
大数据
智慧党员平台建设,组织部党员积分管理系统开发方案
智慧党建是运用信息化技术,整合各方资源,更有效的加强组织管理,提高服务群众水平,扩大党在网络世界的存在感和数字化影响力,提高党的执政能力,巩固党的执政基础的新平台、新模式、新形态。
219 0
智慧党建信息化管理平台建设,党员积分系统开发app
智慧党建信息化管理平台的建设为基层党组织提供管理、学习、活动、监督、考核等功能于一体的信息化应用平台,通过优化工作流程、统一标准、整合资源等方式,使党建工作向数字化、信息化方向转变。
173 0

热门文章

最新文章