瑞吉外卖项目学习笔记(二)后台系统的员工管理业务开发

一、完善登录功能

1.1 问题分析

1.2 代码实现

package com.itheima.reggie.filter;//这是一个过滤器类
//登录检查过滤器import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.AntPathMatcher;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 检查用户是否已经完成登录*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {//路径匹配器,支持通配符写法(专门用来路径比较的)public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();/*** 过滤的方法* @param servletRequest* @param servletResponse* @param filterChain* @throws IOException* @throws ServletException*/@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;/*** 1、获取本次请求的URI* 2、判断本次请求是否需要处理(是否需要检查用户已经登录了)【检查登录状态】* 3、如果不需要处理,则直接放行* 4、判断登录状态,如果已登录,则直接放行* 5、如果未登录则返回未登录结果*///1、获取本次请求的URIString requestURI = request.getRequestURI();//日志:拦截到的请求log.info("拦截到的请求:{}", requestURI);//2、判断本次请求是否需要处理(是否需要检查用户已经登录了)【检查登录状态】//定义一些不需要处理的请求路径(直接放行),只拦截针对Controller的请求String[] urls = new String[]{"/employee/login","/employee/logout","/backend/**","/front/**"};//判断是否需要处理boolean check = check(urls, requestURI);//3、如果不需要处理,则直接放行//check = true时不需要处理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;}}//整个for循环都遍历完了都没有匹配上,就返回falsereturn false;}
}

1.3 功能测试

二、新增员工

2.1 需求分析

2.2 数据模型

2.3 代码开发

package com.itheima.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Employee;
import com.itheima.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {//自动装配@Autowiredprivate EmployeeService employeeService;/*** 员工登录* @param request* @param employee* @return*///前端发送的请求是 post 请求@PostMapping("/login")//接收json数据//requset对象可以getpublic R<Employee> login(HttpServletRequest request, @RequestBody Employee employee){/*** 1、将页面提交的密码password进行md5的加密处理* 2、根据页面提交的用户名username查询数据库* 3、如果没有查询到则返回登录失败的结果* 4、密码比对,如果不一致则返回登录失败结果* 5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果* 6、登录成功,将员工id存入Session并返回登录成功结果*/// 1、将页面提交的密码password进行md5的加密处理//从employee中把password拿到String password = employee.getPassword();//调用工具类中的md5加密的方法password = DigestUtils.md5DigestAsHex(password.getBytes());//2、根据页面提交的用户名username查询数据库LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();//添加查询条件queryWrapper.eq(Employee::getUsername, employee.getUsername());//数据库已经对user_name做了唯一约束Employee emp = employeeService.getOne(queryWrapper);//3、如果没有查询到则返回登录失败的结果if(emp == null){return R.error("登录失败");}//4、密码比对,如果不一致则返回登录失败结果if(!password.equals(emp.getPassword())){//密码匹配不成功return R.error("登录失败");}//登录成功//5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果if (emp.getStatus() == 0){return R.error("账号已经被禁用");}//6、登录成功,将员工id存入Session并返回登录成功结果request.getSession().setAttribute("employee", emp.getId());//这是我们从数据库中查出来的对象return R.success(emp);}/*** 退出方法*//*** 员工退出* @param request* @return*/@PostMapping("/logout")public R<String> logout(HttpServletRequest request){//清理Session中保存的当前登录员工的idrequest.getSession().removeAttribute("employee");return R.success("退出成功");}/*** 新增员工* @param employee* @return*/@PostMappingpublic R<String> save(HttpServletRequest request,@RequestBody Employee employee){log.info("新增员工,员工信息:{}",employee.toString());//设置初始密码:123456,需要进行md5加密处理。getBytes():设置成getBytes()数组employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));//登录时间和更新时间employee.setCreateTime(LocalDateTime.now());employee.setUpdateTime(LocalDateTime.now());//获得当前登录用户的idLong empId = (Long) request.getSession().getAttribute("employee");employee.setCreateUser(empId);employee.setUpdateUser(empId);//保存对象employeeService.save(employee);//新增员工成功return R.success("新增员工成功");}
}

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;/*** 全局异常捕获处理* RestController.class, Controller.class:只有有这两个注解的类都会被我们这个类来处理*/
@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());//判断异常获取信息中是否有:Duplicate entry(重复条目)if(ex.getMessage().contains("Duplicate entry")){//根据空格进行分割,把异常信息存储到 split数组中String[] split = ex.getMessage().split(" ");//获取数组中已经用户名信息(唯一约束)String msg = split[2] + "已存在";//输出错误信息(账户已存在的信息)//return 把错误信息输出到页面上return R.error(msg);}//显示到页面的信息return R.error("未知错误");}
}


 

2.4 功能测试

2.5 总结

1、根据产品原型明确业务需求

2、重点分析数据的流转过程和数据格式

3、通过debug断点调试跟踪程序执行过程

三、员工信息分页查询

3.1 需求分析

在后台显示界面,一页显示出所有员工信息不利于查看。

解决方法:将员工信息进行分页展示

  • 输入框:可以添加过滤条件,在添加过滤条件的同时进行分页处理
  • 页码展示、可以跳转到相应的页码、也可直接点击相应的页码

3.2 代码开发

3.2.1 梳理程序执行流程

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

分页插件的使用:

MyBatisPlus 给我们提供了一个分页插件。

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;/*** 配置MybatisPlus 的分页插件,配置类要加 @Configuration 注解*/
@Configuration
public class MyBatisPlusConfig {//拦截器@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());return mybatisPlusInterceptor;}
}

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

//返回泛型Page,这个是MyBatisPlus 封装的类//方法中的形参指的是:前端页面传递给我们的值/*** 员工信息的分页查询* @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);return null;}

分页查询设置

//返回泛型Page,这个是MyBatisPlus 封装的类//方法中的形参指的是:前端页面传递给我们的值/*** 员工信息的分页查询* @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);//底层是基于MyBatisPlus提供的分页插件进行分页//1、构建分页构造器(分页条件:告诉MyBatisPlus我要查第几页,第几条)Page pageInfo = new Page(page, pageSize);//2、构造条件构造器(封装过滤分页条件)LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper();//添加过滤条件,like查询//判断name是否为null,然后再来添加条件queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);//添加排序条件(就是相当于在SQL语句中加一个OrderBy)queryWrapper.orderByDesc(Employee::getUpdateTime);//3、执行查询employeeService.page(pageInfo,queryWrapper);return R.success(pageInfo);}

3.3 功能测试

四、启动 / 禁用员工账号

4.1 需求分析

  1. 只有管理员(admin 用户)可以对其他普通用户进行启用、禁用操作
  2. 普通用户登录系统后启用、禁用按钮不显示
  3. 账户禁用的员工不能登录系统
  4. 账户启用的员工可以正常登录
  5. 如果某个员工账户状态为正常,则按钮显示为 “禁用”
  6. 如果员工账户状态为已禁用,则按钮显示为 “启用”

4.2 代码开发

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

  1. 页面发送 ajax 请求,将参数(id、status)提交到服务端
  2. 服务端 Controller 接收页面提交的数据并调用 Service 更新数据
  3. Service 调用 Mapper 操作数据库

本质:是一个更新操作(Update),修改状态码

启用、禁用(或者是编辑)员工账号,本质上就是一个更新操作,也就是对 status 状态字段进行操作。

在 Controller 中创建 update 方法,此方法是一个通用的修改员工信息的方法。

4.3 功能测试

4.4 代码修复

五、编辑员工信息

5.1 需求分析

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

5.2 代码开发

在开发代码之前需要梳理一下操作过程喝对应的程序的执行流程:

  1. 点击编辑按钮时,页面跳转到 add.html ,并在 url 中携带参数【员工 id】
  2. 在 add.html 页面获取 url 中的参数【员工 id】
  3. 发送 ajax 请求,请求服务端,同时提交员工 id 参数
  4. 服务端接收请求,根据员工 id 查询员工信息,将员工信息以 json 形式响应给页面
  5. 页面接收服务端响应的 json 数据,通过 VUE 的数据绑定进行员工信息回显
  6. 点击保存按钮,发送 ajax 请求,将页面中的员工信息以 json 方式提交给服务端
  7. 服务端接收员工信息,并进行处理,完成后给页面响应
  8. 页面接收到服务端响应信息后进行相应处理

5.3 功能测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/19894.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS鸿蒙学习笔记(28)@entry和@Component的生命周期

entry和Component的生命周期 entry和Component的关系Component生命周期Entry生命周期 生命周期流程图生命周期展示示例代码参考资料 HarmonyOS的生命周期可以分为Compnent的生命周期和Entry的生命周期&#xff0c;也就是自定义组件的生命周期和页面的生命周期。 entry和Compone…

【传知代码】双深度学习模型实现结直肠癌检测(论文复现)

前言&#xff1a;在医学领域&#xff0c;科技的进步一直是改变人类生活的关键驱动力之一。随着深度学习技术的不断发展&#xff0c;其在医学影像诊断领域的应用正日益受到关注。结直肠癌是一种常见但危害极大的恶性肿瘤&#xff0c;在早期发现和及时治疗方面具有重要意义。然而…

快手发布大模型产品“可图”,超20种创新AI图像玩法限免上线

近日&#xff0c;快手自研大模型产品“可图”&#xff08;Kolors&#xff09;正式对外开放&#xff0c;支持文生图和图生图两类功能&#xff0c;已上线20余种AI图像玩法。目前&#xff0c;用户可以通过“可图大模型”官方网站和微信小程序&#xff0c;免费使用各项AI图像功能。…

纯分享#126个电商平台集合(包含60个不同国家)值得一看

01 亚洲 中国 淘宝&#xff1a;拥有大量的卖家和商品种类&#xff0c;主要面向中国市场。天猫:淘宝旗下的B2C电商平台&#xff0c;提供品质保证、正品保障的商品。京东:中国第二大B2C电商平台&#xff0c;提供品质保证、正品保障的商品。苏宁易购: 中国家电连锁巨头苏宁旗下的…

反VC情绪:加密市场需要新的分布式代币发行方式

GME事件 GME事件反应了社交媒体在金融决策中的影响力&#xff0c;散户投资者群体通过集体行动&#xff0c;改变了很多人对股市的看法和参与方式。 GME事件中&#xff0c;meme扮演了核心角色。散户投资者使用各种meme来沟通策略、激励持股行为&#xff0c;创造了一种反对华尔街…

【车载开发系列】汽车开发常用工具说明

【车载开发系列】汽车开发常用工具说明 【车载开发系列】汽车开发常用工具说明 【车载开发系列】汽车开发常用工具说明一. CANbedded二. Davinci Configurator Pro三. Davinci Developer-AUTOSAR软件组件设计工具四. MICROSAR五. MICROSAR OS六. CANdelaStudio七. Volcano VSB八…

Mysql基础教程(11):DISTINCT

MySQL DISTINCT 用法和实例 当使用 SELECT 查询数据时&#xff0c;我们可能会得到一些重复的行。比如学生表中有很多重复的年龄。如果想得到一个唯一的、没有重复记录的结果集&#xff0c;就需要用到 DISTINCT 关键字。 MySQL DISTINCT用法 在 SELECT 语句中使用 DISTINCT 关…

Spring Boot 项目中使用 JSP

文章目录 Spring Boot 项目中使用 JSP项目结构引入依赖包编写页面和后台运行方式一&#xff1a;Maven 命令运行方式二&#xff1a;在 IDEA 中运行方式三&#xff1a;打 war 包部署运行 Spring Boot 项目中使用 JSP 在 Spring Boot 项目中不是不可以使用 JSP 。想在 Spring Boo…

【React】封装一个好用方便的消息框(Hooks Bootstrap 实践)

引言 以 Bootstrap 为例&#xff0c;使用模态框编写一个简单的消息框&#xff1a; import { useState } from "react"; import { Modal } from "react-bootstrap"; import Button from "react-bootstrap/Button"; import bootstrap/dist/css/b…

打开C语言常用的内存函数大门(二)—— memmove()函数 (内含memmove的讲解和模拟实现)

文章目录 1. 前言2. memmove()函数2.1 memmove()函数与memcpy()函数的差异2.2 memmove()函数的原型2.3 memmove()函数的使用案例 3. memmove()函数的模拟实现4. 总结 1. 前言 在之前&#xff0c;我向大家介绍了C语言中的一个常用的内存函数memcpy函数。如果你还没看的话&#…

12k Star!Continue:Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖!

原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; 12k Star&#xff01;Continue&#xff1a;Github Copilot 开源本地版、开发效率和隐私保护兼得、丰富功能、LLM全覆盖&#xff01; &…

Beamer中二阶导、一阶导数的显示问题

Beamer中二阶导、一阶导数的显示问题 在beamer中表示 f ′ f f′和 f ′ ′ f f′′时发现导数符号距离 f f f很近 \documentclass{beamer} \usepackage{amsmath,amssymb}\begin{document} \begin{frame}\frametitle{Derivative}Derivative:\[f^{\prime}(x) \quad f \quad…

conda与pip的镜像源与代理设置

conda与pip的镜像源与代理设置 一、前言二、conda镜像源设置2.1conda默认镜像源介绍2.2通过终端设置镜像源2.3通过配置文件设置镜像源 三、pip镜像源设置3.1pip默认镜像源介绍3.2通过终端临时设置镜像源3.3通过配置文件设置一个或多个镜像源 四、conda代理设置4.1通过终端设置代…

数据结构与算法笔记:基础篇 - 栈:如何实现浏览器的前进和后退功能?

概述 浏览器的前进、后退功能&#xff0c;你肯定很熟悉吧&#xff1f; 当依次访问完一串页面 a-b-c 之后&#xff0c;点击浏览器的后退按钮&#xff0c;就可以查看之前浏览过的页面 b 和 a。当后退到页面 a&#xff0c;点击前进按钮&#xff0c;就可以重新查看页面 b 和 c。但…

放开了去的 ulimit

放开了去的 ulimit 放开了去的 ulimitulimit简介临时修改打开文件数目永久修改系统总打开句柄限制更多信息 放开了去的 ulimit ulimit简介 对于高并发或者频繁读写文件的应用程序而言&#xff0c;有时可能需要修改系统能够打开的最多文件句柄数&#xff0c;否则就可能会出现t…

HTTPS 原理技术

HTTPS原理技术 背景简介原理总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日子。本文内容并非完全原创&am…

Element-ui使用上传时弹框选择文件类型

实现效果 1&#xff0c;点击上传&#xff0c;上传文件&#xff1b; 2&#xff0c;选择文件&#xff1b; 3&#xff0c;弹框选择文件类型&#xff1b; 4&#xff0c;选择类型后确定上传&#xff1b; 一&#xff0c;上传 跳过&#xff1b; 二&#xff0c;定义弹框下拉框…

Coolmuster Android Assistant: 手机数据管理的全能助手

在数字化时代&#xff0c;智能手机不仅是通讯工具&#xff0c;更是个人数据的中心。随着数据量的不断增加&#xff0c;如何有效管理和保护这些数据成为了一个重要议题。Coolmuster Android Assistant应运而生&#xff0c;它是一款专为安卓用户设计的综合数据管理软件&#xff0…

EXCEL数据透视图中的日期字段,怎样自动分出年、季度、月的功能?

在excel里&#xff0c;这个果然是有个设置的地方&#xff0c;修改后就好了。 点击文件选项卡&#xff0c;选项&#xff0c;在高级里&#xff0c;将图示选项的勾选给取消&#xff0c;然后再创建数据透视表或透视图&#xff0c;日期就不会自动组合了&#xff1a; 这个选项只对新…

Ubuntu22.04之解决:忘记登录密码(二百三十二)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…