客户要做网站建设话术,门户网站栏目规范化建设,北海哪家公司做网站建设研发,义乌来料加工网瑞吉外卖-Day02课程内容完善登录功能新增员工员工信息分页查询启用/禁用员工账号编辑员工信息1. 完善登录功能1.1 问题分析前面我们已经完成了后台系统的员工登录功能开发#xff0c;但是目前还存在一个问题#xff0c;接下来我们来说明一个这个问题#xff0c; 以及如何处理…瑞吉外卖-Day02课程内容完善登录功能新增员工员工信息分页查询启用/禁用员工账号编辑员工信息1. 完善登录功能1.1 问题分析前面我们已经完成了后台系统的员工登录功能开发但是目前还存在一个问题接下来我们来说明一个这个问题 以及如何处理。1). 目前现状用户如果不登录直接访问系统首页面照样可以正常访问。 2). 理想效果上述这种设计并不合理我们希望看到的效果应该 是只有登录成功后才可以访问系统中的页面如果没有登录, 访问系统中的任何界面都直接跳转到登录页面。那么具体应该怎么实现呢可以使用我们之前讲解过的 过滤器、拦截器来实现在过滤器、拦截器中拦截前端发起的请求判断用户是否已经完成登录如果没有登录则返回提示信息跳转到登录页面。1.2 思路分析过滤器具体的处理逻辑如下A. 获取本次请求的URIB. 判断本次请求, 是否需要登录, 才可以访问C. 如果不需要则直接放行D. 判断登录状态如果已登录则直接放行E. 如果未登录, 则返回未登录结果如果未登录,我们需要给前端返回什么样的结果呢? 这个时候, 我们可以去看看前端是如何处理的 ?1.3 代码实现1). 定义登录校验过滤器自定义一个过滤器 LoginCheckFilter 并实现 Filter 接口, 在doFilter方法中完成校验的逻辑。 那么接下来, 我们就根据上述分析的步骤, 来完成具体的功能代码实现: AntPathMatcher 拓展:介绍: Spring中提供的路径匹配器 ;通配符规则: 2). 开启组件扫描需要在引导类上, 加上Servlet组件扫描的注解, 来扫描过滤器配置的WebFilter注解 扫描上之后 过滤器在运行时就生效了。ServletComponentScan 的作用: 在SpringBoot项目中, 在引导类/配置类上加了该注解后, 会自动扫描项目中(当前包及其子包下)的WebServlet , WebFilter , WebListener 注解, 自动注册Servlet的相关组件 ;1.4 功能测试代码编写完毕之后我们需要将工程重启一下然后在浏览器地址栏直接输入系统管理后台首页然后看看是否可以跳转到登录页面即可。我们也可以通过debug的形式来跟踪一下代码执行的过程。对于前端的代码, 也可以进行debug调试。F12打开浏览器的调试工具, 找到我们前面提到的request.js, 在request.js的响应拦截器位置打上断点。2. 新增员工2.1 需求分析后台系统中可以管理员工信息通过新增员工来添加后台系统用户。点击[添加员工]按钮跳转到新增页面如下当填写完表单信息, 点击保存按钮后, 会提交该表单的数据到服务端, 在服务端中需要接受数据, 然后将数据保存至数据库中。2.2 数据模型新增员工其实就是将我们新增页面录入的员工数据插入到employee表。employee表中的status字段已经设置了默认值1表示状态正常。需要注意employee表中对username字段加入了唯一约束因为username是员工的登录账号必须是唯一的。2.3 程序执行流程在开发代码之前我们需要结合着前端页面发起的请求 梳理一下整个程序的执行过程A. 点击保存按钮, 页面发送ajax请求将新增员工页面中输入的数据以json的形式提交到服务端, 请求方式POST, 请求路径 /employeeB. 服务端Controller接收页面提交的数据并调用Service将数据进行保存C. Service调用Mapper操作数据库保存数据2.4 代码实现在EmployeeController中增加save方法, 用于保存用户员工信息。A. 在新增员工时 按钮页面原型中的需求描述 需要给员工设置初始默认密码 123456 并对密码进行MD5加密。B. 在组装员工信息时, 还需要封装创建时间、修改时间创建人、修改人信息(从session中获取当前登录用户)。2.5 功能测试代码编写完毕之后我们需要将工程重启, 完毕之后直接访问管理系统首页, 点击 员工管理 页面中的 添加员工 按钮, 输入员工基本信息, 然后点击 保存 进行数据保存, 保存完毕后, 检查数据库中是否录入员工数据。当我们在测试中添加用户时 输入了一个已存在的用户名时前端界面出现错误提示信息 而此时服务端已经报错了 报错信息如下 出现上述的错误 主要就是因为在 employee 表结构中我们针对于username字段建立了唯一索引添加重复的username数据时违背该约束就会报错。但是此时前端提示的信息并不具体用户并不知道是因为什么原因造成的该异常我们需要给用户提示详细的错误信息 。2.6 全局异常处理2.6.1 思路分析要想解决上述测试中存在的问题我们需要对程序中可能出现的异常进行捕获通常有两种处理方式A. 在Controller方法中加入 try...catch 进行异常捕获形式如下 如果采用这种方式虽然可以解决但是存在弊端需要我们在保存其他业务数据时也需要在Controller方法中加上try...catch进行处理代码冗余不通用。B. 使用异常处理器进行全局异常捕获采用这种方式来实现我们只需要在项目中定义一个通用的全局异常处理器就可以解决本项目的所有异常。2.6.2 全局异常处理器在项目中自定义一个全局异常处理器在异常处理器上加上注解 ControllerAdvice,可以通过属性annotations指定拦截哪一类的Controller方法。 并在异常处理器的方法上加上注解 ExceptionHandler 来指定拦截的是那一类型的异常。异常处理方法逻辑: 指定捕获的异常类型为 SQLIntegrityConstraintViolationException解析异常的提示信息, 获取出是那个值违背了唯一约束 组装错误信息并返回所属包: com.itheima.reggie.common注解说明: 上述的全局异常处理器上使用了的两个注解 ControllerAdvice , ResponseBody , 他们的作用分别为: ControllerAdvice : 指定拦截那些类型的控制器; ResponseBody: 将方法的返回值 R 对象转换为json格式的数据, 响应给页面; 上述使用的两个注解, 也可以合并成为一个注解 RestControllerAdvice 2.6.3 测试全局异常处理器编写完毕之后我们需要将项目重启, 完毕之后直接访问管理系统首页, 点击 员工管理 页面中的 添加员工 按钮。当我们在测试中添加用户时 输入了一个已存在的用户名时前端界面出现如下错误提示信息3. 员工分页查询3.1 需求分析系统中的员工很多的时候如果在一个页面中全部展示出来会显得比较乱不便于查看所以一般的系统中都会以分页的方式来展示列表数据。而在我们的分页查询页面中, 除了分页条件以外还有一个查询条件 员工姓名。请求参数搜索条件 员工姓名(模糊查询)分页条件 每页展示条数 页码响应数据总记录数结果列表3.2 程序执行流程3.2.1 页面流程分析在开发代码之前需要梳理一下整个程序的执行过程。A. 点击菜单打开员工管理页面时执行查询 B. 搜索栏输入员工姓名,回车,执行查询:1). 页面发送ajax请求将分页查询参数(page、pageSize、name)提交到服务端2). 服务端Controller接收页面提交的数据, 并组装条件调用Service查询数据3). Service调用Mapper操作数据库查询分页数据4). Controller将查询到的分页数据, 响应给前端页面5). 页面接收到分页数据, 并通过ElementUI的Table组件展示到页面上3.2.2 前端代码介绍1). 访问员工列表页面/member/list.html时, 会触发Vuejs中的钩子方法, 在页面初始化时调用created方法从上述的前端代码中我们可以看到, 执行完分页查询, 我们需要给前端返回的信息中需要包含两项 : records 中封装结果列表, total中封装总记录数 。而在组装请求参数时 , page、pageSize 都是前端分页插件渲染时的参数2). 在getMemberList方法中, 通过axios发起异步请求axios发起的异步请求会被声明在 request.js 中的request拦截器拦截, 在其中对get请求进行进一步的封装处理最终发送给服务端的请求为 : GET请求 , 请求链接 /employee/page?page1pageSize10namexxx3.3 代码实现3.3.1 分页插件配置当前我们要实现的分页查询功能而在MybatisPlus要实现分页功能就需要用到MybatisPlus中提供的分页插件要使用分页插件就要在配置类中声明分页插件的bean对象。3.3.2 分页查询实现在上面我们已经分析了页面在进行分页查询时 具体的请求信息如下:请求说明请求方式GET请求路径/employee/page请求参数page , pageSize , name那么查询完毕后我们需要给前端返回什么样的结果呢? 在上述我们也分析了, 查询返回的结果数据data中应该封装两项信息, 分别为: records 封装分页列表数据, total 中封装符合条件的总记录数。 那么这个时候, 在定义controller方法的返回值类型R时, 我们可以直接将 MybatisPlus 分页查询的结果 Page 直接封装返回, 因为Page中的属性如下: 那么接下来就依据于这些已知的需求和条件完成分页查询的代码实现。 具体的逻辑如下: A. 构造分页条件B. 构建搜索条件 - name进行模糊匹配C. 构建排序条件 - 更新时间倒序排序D. 执行查询E. 组装结果并返回具体的代码实现如下: 3.4 功能测试代码编写完毕之后我们需要将工程重启, 完毕之后直接访问管理系统首页, 默认就会打开员工管理的列表页面, 我们可以查看列表数据是否可以正常展示, 也可以通过分页插件来测试分页功能, 及员工姓名的模糊查询功能。在进行测试时可以使用浏览器的监控工具查看页面和服务端的数据交互细节。 并借助于debug的形式 根据服务端参数接收及逻辑执行情况。测试过程中可以发现对于员工状态字段status服务端返回的是状态码1或者0但是页面上显示的则是“正常”或者“已禁用”这是因为页面中在展示数据时进行了处理。4. 启用/禁用员工账号4.1 需求分析在员工管理列表页面可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登录系统启用后的员工可以正常登录。如果某个员工账号状态为正常则按钮显示为 禁用如果员工账号状态为已禁用则按钮显示为启用。需要注意只有管理员admin用户可以对其他普通用户进行启用、禁用操作所以普通用户登录系统后启用、禁用按钮不显示。A. admin 管理员登录B. 普通用户登录4.2 程序执行流程4.2.1 页面按钮动态展示在上述的需求中,我们提到需要实现的效果是 : 只有管理员admin用户可以对其他普通用户进行启用、禁用操作所以普通用户登录系统后启用、禁用按钮不显示 , 页面中是怎么做到只有管理员admin能够看到启用、禁用按钮的1). 在列表页面(list.html)加载时, 触发钩子函数created, 在钩子函数中, 会从localStorage中获取到用户登录信息, 然后获取到用户名2). 在页面中, 通过Vue指令v-if进行判断,如果登录用户为admin将展示 启用/禁用 按钮, 否则不展示4.2.2 执行流程分析1). 当管理员admin点击 启用 或 禁用 按钮时, 调用方法statusHandlescope.row : 获取到的是这一行的数据信息 ;2). statusHandle方法中进行二次确认, 然后发起ajax请求, 传递id、status参数最终发起异步请求, 请求服务端, 请求信息如下 请求说明请求方式PUT请求路径/employee请求参数{id:xxx,status:xxx}{...params} : 三点是ES6中出现的扩展运算符。作用是遍历当前使用的对象能够访问到的所有属性并将属性放入当前对象中。4.3 代码实现在开发代码之前需要梳理一下整个程序的执行过程1). 页面发送ajax请求将参数(id、status)提交到服务端2). 服务端Controller接收页面提交的数据并调用Service更新数据3). Service调用Mapper操作数据库启用、禁用员工账号本质上就是一个更新操作也就是对status状态字段进行操作。在Controller中创建update方法此方法是一个通用的修改员工信息的方法。4.4 功能测试代码编写完毕之后我们需要将工程重启。 然后访问前端页面 进行 启用 或 禁用 的测试。测试过程中没有报错但是功能并没有实现查看数据库中的数据也没有变化。但是从控制台输出的日志 可以看出确实没有更新成功。而在我们的数据库表结构中 并不存在该ID 数据库中 风清扬 对应的ID为 14200383456349184014.5 代码修复4.5.1 原因分析通过观察控制台输出的SQL发现页面传递过来的员工id的值和数据库中的id值不一致这是怎么回事呢在分页查询时服务端会将返回的R对象进行json序列化转换为json格式的数据而员工的ID是一个Long类型的数据而且是一个长度为 19 位的长整型数据 该数据返回给前端是没有问题的。那么具体的问题出现在哪儿呢问题实际上 就出现在前端JS中 js在对长度较长的长整型数据进行处理时 会损失精度 从而导致提交的id和数据库中的id不一致。 这里我们也可以做一个简单的测试代码如下 4.5.2 解决方案要想解决这个问题也很简单我们只需要让js处理的ID数据类型为字符串类型即可, 这样就不会损失精度了。同样 大家也可以做一个测试 那么在我们的业务中, 我们只需要让分页查询返回的json格式数据库中, long类型的属性, 不直接转换为数字类型, 转换为字符串类型就可以解决这个问题了 , 最终返回的结果为 : 4.5.3 代码修复由于在SpringMVC中, 将Controller方法返回值转换为json对象, 是通过jackson来实现的, 涉及到SpringMVC中的一个消息转换器MappingJackson2HttpMessageConverter, 所以我们要解决这个问题, 就需要对该消息转换器的功能进行拓展。具体实现步骤1). 提供对象转换器JacksonObjectMapper基于Jackson进行Java对象到json数据的转换资料中已经提供直接复制到项目中使用2). 在WebMvcConfig配置类中扩展Spring mvc的消息转换器在此消息转换器中使用提供的对象转换器进行Java对象到json数据的转换1). 引入JacksonObjectMapper2). 在WebMvcConfig中重写方法extendMessageConverters5. 编辑员工信息5.1 需求分析在员工管理列表页面点击 编辑 按钮跳转到编辑页面在编辑页面回显员工信息并进行修改最后点击 保存 按钮完成编辑操作。那么从上述的分析中我们可以看出当前实现的编辑功能,我们需要实现两个方法:A. 根据ID查询, 用于页面数据回显B. 保存修改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). 页面接收到服务端响应信息后进行相应处理注意add.html页面为公共页面新增员工和编辑员工都是在此页面操作5.3 代码实现5.3.1 根据ID查询经过上述的分析,我们看到,在根据ID查询员工信息时,请求信息如下: 请求说明请求方式GET请求路径/employee/{id}代码实现: 在EmployeeController中增加方法, 根据ID查询员工信息。5.3.2 修改员工经过上述的分析,我们看到,在修改员工信息时,请求信息如下: 请求说明请求方式PUT请求路径/employee请求参数{.......} json格式数据代码实现: 在EmployeeController中增加方法, 根据ID更新员工信息。5.4 功能测试代码编写完毕之后我们需要将工程重启。 然后访问前端页面 按照前面分析的操作流程进行测试查看数据是否正常修改即可。