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

一、完善登录功能

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.rhkb.cn/news/337155.html

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

相关文章

docker compose完成简单项目部署

1. 项目环境 centos7 docker mysql redis ruoyi项目 ruoyi项目链接&#xff1a;https://gitee.com/y_project/RuoYi-Vue.git 2. 进行项目前后端代码打包 后端打包&#xff1a; 修改mysql连接的相关配置文件 RuoYi-Vue/ruoyi-admin/src/main/resources/application-dru…

vue实现左侧拖拽拉伸,展开收起

需求&#xff1a;1.左侧是个树形结构&#xff0c;有的文字过长展示不全&#xff0c;想通过拖拽显示全部的数据 2.展开收起 实现图中效果 <div class"catalog-drag"><svg t"1687228434888" class"icon" viewBox"0 0 1…

AWS中国峰会2024 半日游

亚马逊云科技中国峰会于2024年5月29-30日在上海举办 今年就去了半天&#xff0c;去年也是去过的&#xff0c;不过今年的活动个人感觉比去年略微凌乱了一点。 今年的峰会方向和去年一致&#xff0c;均是AI方向的各项内容&#xff08;基础架构、安全、服务、游戏、驾驶、各行各…

平衡二叉树的应用举例

AVL 是一种自平衡二叉搜索树&#xff0c;其中任何节点的左右子树的高度之差不能超过 1。 AVL树的特点&#xff1a; 1、它遵循二叉搜索树的一般属性。 2、树的每个子树都是平衡的&#xff0c;即左右子树的高度之差最多为1。 3、当插入新节点时&#xff0c;树会自我平衡。因此…

【计算机毕设】基于SpringBoot的房产销售系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 研究目的 随着房地产市场的发展和互联网技术的进步&#xff0c;传统的房产销售模式逐渐向线上转移。设计并实现一个基于Spring Boot的房产销售系统&#xff0…

代理IP怎么检测?如何判断IP好坏?

当我们的数字足迹无处不在&#xff0c;隐私保护显得愈发重要。而代理IP就像是我们的隐身斗篷&#xff0c;让我们在各项网络业务中更加顺畅。 我们常常看到别人购买了代理IP服务后&#xff0c;用在线检测网站检查IP&#xff0c;相当于一个”售前检验““售后质检”的作用。但是…

[ROS 系列学习教程] 建模与仿真 - Xacro 语法

ROS 系列学习教程(总目录) 本文目录 一、属性与属性块二、数学表达式三、宏3.1 宏的基本使用3.2 属性块做为宏的入参3.3 任意数量元素做为宏的入参3.4 指定多个块元素的处理顺序3.5 宏嵌套3.6 默认参数3.7 局部属性 四、Rospack 命令五、包含其他 xacro 文件六、条件语句七、YA…

html+CSS部分基础运用9

项目1 参会注册表 1.设计参会注册表页面&#xff0c;效果如图9-1所示。 图9-1 参会注册表页面 项目2 设计《大学生暑期社会实践调查问卷》 1.设计“大学生暑期社会实践调查问卷”页面&#xff0c;如图9-2所示。 图9-2 大学生暑期社会调查表页面 2&#xff0e;调查表前导语的…

【C++】C++11新特性:列表初始化、声明、新容器、右值引用、万能引用和完美转发

目录 一、列表初始化 1.1 { } 初始化 1.2 std::initializer_list 二、声明 2.1 auto 2.2 decltype 2.3 nullptr 三、新容器 四、右值引用和移动语义 4.1 左值和左值引用 4.2 右值和右值引用 4.3 左值引用与右值引用比较 4.4 右值引用使用场景和意义&#xff1a;移…

Spring Boot 项目中使用 JSP

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

fmql之CAN调试

刚刚把zynq的CAN调成功。那么现在就要把程序移植到fmql了。 老规矩&#xff0c;Procise导入vivado的.bd和.xci文件。 Procise下create block也可以&#xff0c;但是不能自动约束引脚&#xff0c;只能手动写代码。 PeripheralTest CanExample中用到了CAN0和CAN1&#xff1a;…

msvcp140.dll是什么东西?如何修复电脑提示msvcp140.dll丢失的多种方法

文件名为 msvcp140.dll&#xff0c;这是一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;属于Microsoft Visual C 2015 Redistributable的一部分。全称为 "Microsoft C Runtime Library" 或 "Microsoft C Runtime Library"&#xff0c;表明该文…

如何使用 Connector API 将数据提取到 Elasticsearch Serverless 中

作者&#xff1a;来自 Elastic Jedr Blaszyk Elasticsearch 支持一系列摄取方法。 其中之一是 Elastic Connectors&#xff0c;它将 SQL 数据库或 SharePoint Online 等外部数据源与 Elasticsearch 索引同步。 连接器对于在现有数据之上构建强大的搜索体验特别有用。 例如&…

ESP32入门:1、VSCode+PlatformIO环境搭建(离线快速安装)

文章目录 背景安装vscode安装配置中文 安装Platform IO安装PIO 新建ESP32工程参考 背景 对于刚接触单片机的同学&#xff0c;使用vscodeplatformIO来学习ESP32是最方便快捷的&#xff0c;比IDF框架简单&#xff0c;且比arduino文件管理性能更好。但是platformIO安装较为麻烦&a…

uniapp 添加字体ttf

效果图如下 一、逻辑概述 在uniapp中使用字体&#xff0c;一共分成两种情况&#xff0c;一种是普通vue页面&#xff0c;一种是nvue页面引入字体。。 1.vue页面引入字体需要如下步骤 1. 先选择下载一种字体&#xff1a;字体格式一般为 ttf后缀名 黄凯桦律师手写体免费下载和在线…

代码随想录算法训练营第三十二 | ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

122.买卖股票的最佳时机II 讲解链接&#xff1a;https://programmercarl.com/1005.K%E6%AC%A1%E5%8F%96%E5%8F%8D%E5%90%8E%E6%9C%80%E5%A4%A7%E5%8C%96%E7%9A%84%E6%95%B0%E7%BB%84%E5%92%8C.html 简单思路&#xff1a;逐个计算连续两天的股票差值&#xff0c;sum初始为零&…

期末速成 ——计算机组成原理(2)数值的表示与运算

目录 一、定点数的表示 &#xff08;一&#xff09;无符号数和有符号数的表示 &#xff08;二&#xff09;机器数的定点表示 &#xff08;三&#xff09;原码、补码、反码、移码 (1)原码表示法 二、浮点数的表示 三、溢出判断 (一)采用一位符号位 (二)采用双符号位 四…

Qt Creator(Qt 6.6)拷贝一行

Edit - Preference - Environment&#xff1a; 可看到&#xff0c;拷贝一行的快捷键是&#xff1a; ctrl Ins

Django——Admin站点(Python)

#前言&#xff1a; 该博客为小编Django基础知识操作博客的最后一篇&#xff0c;主要讲解了关于Admin站点的一些基本操作&#xff0c;小编会继续尽力更新一些优质文章&#xff0c;同时欢迎大家点赞和收藏&#xff0c;也欢迎大家关注等待后续文章。 一、简介&#xff1a; Djan…

Firefox国际版

Firefox国际版官方网址&#xff1a; Download the Firefox Browser in English (US) and more than 90 other languagesEveryone deserves access to the internet — your language should never be a barrier. That’s why — with the help of dedicated volunteers around…