瑞吉外賣項目學習筆記(二)后臺系統的員工管理業務開發

一、完善登錄功能

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.pswp.cn/bicheng/19894.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/19894.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/19894.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

華為OD機試-最大坐標值

題目描述與示例 題目描述 小明在玩一個游戲&#xff0c;游戲規則如下&#xff1a;在游戲開始前&#xff0c;小明站在坐標軸原點處&#xff08;坐標值為 0&#xff09;給定一組指令和一個幸運數&#xff0c;每個指令都是一個整數&#xff0c;小明按照指定的要求前進或者后退指…

解析Java中1000個常用類:FunctionalInterface類,你學會了嗎?

Java 8 引入了一系列新的特性和改進,其中之一便是函數式編程。函數式接口(Functional Interface)是函數式編程的核心概念之一。本文將深入探討 FunctionalInterface 注解,介紹其用法、重要性,并通過示例展示如何在實際開發中應用函數式接口。 什么是函數式接口? 函數式…

有向圖的拓撲排序

文章目錄 概念及模板例題 雜務 概念及模板 有向圖的拓撲排序是指將有向無環圖中的所有頂點排成一個線性序列&#xff0c;使得圖中任意一對頂點u和v&#xff0c;若邊(u, v)在圖中&#xff0c;則u在該序列中排在v的前面。 例如&#xff0c;假設有n個任務&#xff0c;這些任務需…

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函數。如果你還沒看的話&#…

碼隨想錄算法訓練營Day 52 | 動態規劃part13 | 300.最長遞增子序列、674. 最長連續遞增序列 、718. 最長重復子數組

代碼隨想錄算法訓練營Day 52 | 動態規劃part13 | 300.最長遞增子序列、674. 最長連續遞增序列 、718. 最長重復子數組 文章目錄 代碼隨想錄算法訓練營Day 52 | 動態規劃part13 | 300.最長遞增子序列、674. 最長連續遞增序列 、718. 最長重復子數組300.最長遞增子序列一、一維DP…

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…

C# 讀取txt大文件

1GB以下 using System.Text;namespace DotnetReadTxt;class Program {static void Main(string[] args){try{Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);var gb2312 Encoding.GetEncoding("GB2312");int index 0;using (StreamReader sr ne…

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…