瑞吉外卖项目实战 -登录退出功能及员工分页查询、添加、修改、权限修改等功能

整理记录下学习整个瑞吉外卖项目,详细代码可在我的Gitee仓库瑞吉外卖实战克隆下载学习使用!

4. 登录功能

4.1 通用结果返回类

此类用于规范封装返回结果,代码如下:

@Data  
public class Result<T> implements Serializable {  
    private Integer code; //编码:1成功,0和其它数字为失败  
    private String msg; //错误信息  
    private T data; //数据  
    private Map map = new HashMap(); //动态数据  
    public static <T> Result<T> success(T object) {  
        Result<T> r = new Result<T>();  
        r.data = object;  
        r.code = 1;  
        return r;  
    }  
    public static <T> Result<T> error(String msg) {  
        Result r = new Result();  
        r.msg = msg;  
        r.code = 0;  
        return r;  
    }  
    public Result<T> add(String key, Object value) {  
        this.map.put(key, value);  
        return this;  
    }  
}

4.2 需求分析

  • 登录页面展示,点击即可,如图
    ![[Pasted image 20230228145748.png]]
  • 查看登录请求信息
    ![[Pasted image 20230228145834.png]]

4.3 数据模型

查看数据模型,打开数据库员工表,结构如图
![[Pasted image 20230228145941.png]]

4.4 代码开发

  • 编写Employee实体类,如下,有源代码也可直接复制
@Data  
public class Employee implements Serializable {  
    private static final long serialVersionUID = 1L;  
    private Long id;  
    private String username;  
    private String name;  
    private String password;  
    private String phone;  
    private String sex;  
    private String idNumber;//身份证号码  
    private Integer status;  
    private LocalDateTime createTime;  
    private LocalDateTime updateTime;  
    private Long createUser;  
    private Long updateUser;  
}
  • 编写Mapper层,代码如下
@Mapper  
public interface EmployeeMapper extends BaseMapper<Employee>{  
}
  • 编写业务层代码,如图![[Pasted image 20230228151310.png]]
  • 编写controller层代码,流程如图
    ![[Pasted image 20230228152702.png]]
    创建EmployeeController类,代码如下:
@Slf4j  
@RestController  
@RequestMapping("/employee")  
//用构造器方法进行bean注入  
@RequiredArgsConstructor  
public class EmployeeController {  
    private final EmployeeService employeeService;  
    //员工登录  
    @PostMapping("/login")  
    public Result<Employee> login(HttpServletRequest request, @RequestBody Employee employee){  
        //1、将页面提交的密码password进行md5加密处理  
        String password = employee.getPassword();  
        password = DigestUtils.md5DigestAsHex(password.getBytes());  
  
        //2、根据页面提交的用户名username查询数据库  
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();  
        queryWrapper.eq(Employee::getUsername,employee.getUsername());  
        Employee emp = employeeService.getOne(queryWrapper);  
  
        //3、如果没有查询到则返回登录失败结果  
        if(emp == null){  
            return Result.error("登录失败");  
        }  
  
        //4、密码比对,如果不一致则返回登录失败结果  
        if(!emp.getPassword().equals(password)){  
            return Result.error("登录失败");  
        }  
  
        //5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果  
        if(emp.getStatus() == 0){  
            return Result.error("账号已禁用");  
        }  
  
        //6、登录成功,将员工id存入Session并返回登录成功结果  
        request.getSession().setAttribute("employee",emp.getId());  
        return Result.success(emp);  
    }  
}

4.5 测试

测试登录功能,断点调试,输入正确账号密码,如图
![[Pasted image 20230228154431.png]]
不正确账号,如图
![[Pasted image 20230228154205.png]]
正确账号,错误密码,如图
![[Pasted image 20230228154330.png]]

5. 退出功能

5.1需求分析

![[Pasted image 20230228154750.png]]

5.2 代码开发

  • 在EmployeeController中添加退出方法,如下:
@PostMapping("/logout")  
public Result<String> logout(HttpServletRequest request){  
    //清理Session中保存的当前登录员工的id  
    request.getSession().removeAttribute("employee");  
    return Result.success("退出成功");  
}

5.3 测试

启动项目并进行登录后,再次点击退出则切换到登录界面,退出成功!

6. 员工管理

6.1 效果展示

  • 在进行员工登录后才能进入到员工管理界面
  • 员工列表。可以添加员工,也可以编辑选中员工信息,还可以选择是否启用或禁用此员工登录
    ![[Pasted image 20230228155615.png]]
  • 添加员工。
    ![[Pasted image 20230228155755.png]]

6.2 完善登录功能

6.2.1问题分析

![[Pasted image 20230228160119.png]]

6.2.2 代码开发

编写过滤器进行完善,并在启动类加注解@ServletComponentSacn,代码如下:

@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")  
@Slf4j  
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-1、判断登录状态,如果已登录,则直接放行  
        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(Result.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;  
    }  
}

6.3 测试

经过直接访问测试后,控制台输出成功,如图
![[Pasted image 20230228174907.png]]

6.4 新增员工功能

6.4.1 需求分析

后台系统可以管理员工信息,通过新增员工来添加后台系统用户,点击[添加员工]按钮跳转到新增页面,如图
![[Pasted image 20230228174948.png]]

6.4.2 数据模型

新增员工就是将新增页面录入员工数据插入到employee表中,但注意的是employee表中对应的username字段加了唯一约束,登录账号,必须唯一。
26a926b621b6.png)
其中对应的状态status也为默认1,![[Pasted image 20230228175457.png]]

6.4.3 代码开发

controller层添加新增方法

    @PostMapping  
    public Result<String> save(HttpServletRequest request,@RequestBody Employee employee){  
        log.info("新增员工,员工信息:{}",employee.toString());  
  
        //设置初始密码123456,需要进行md5加密处理  
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".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 Result.success("新增员工成功");  
    }

6.4.4 测试

功能测试,登录之后添加员工,如图![[Pasted image 20230228191639.png]]
后台显示插入成功,如图![[Pasted image 20230228191708.png]]

6.4.5 改进

  • 若再次添加同样的数据则会报错,添加exception处理类,如下:
@ControllerAdvice(annotations = {RestController.class, Controller.class})  
@ResponseBody  
@Slf4j  
public class GlobalExceptionHandler {  
    /**  
     * 异常处理方法,处理数据库重复添加问题  
     * @return  
     */  
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)  
    public Result<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){  
        log.error(ex.getMessage());  
  
        if(ex.getMessage().contains("Duplicate entry")){  
            String[] split = ex.getMessage().split(" ");  
            String msg = split[2] + "已存在";  
            return Result.error(msg);  
        }  
        return Result.error("未知错误");  
    }
  • 输入同样数据再次测试,如图,会提示已存在
    ![[Pasted image 20230228204803.png]]
    ![[Pasted image 20230228204822.png]]

6.5 员工分页查询功能

6.5.1 需求分析

系统中一般员工数据比较多,一般采用分页查询来显示列表数据,如图![[Pasted image 20230228205120.png]]

6.5.2 代码开发

  • 添加MyBatisPlus分页查询拦截器,如下:
@Configuration  
public class MyBatisPlusConfig{  
    //加入分页查询拦截  
    @Bean  
    public MybatisPlusInterceptor mybatisPlusInterceptor(){  
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();  
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());  
        return mybatisPlusInterceptor;  
    }  
}
  • 添加查询接口,如下:
@GetMapping("/page")  
public Result<Page> getEmployeesPage(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 Result.success(pageInfo);  
}

6.5.3 测试

启动项目后刷新前台,测试成功,如图
![[Pasted image 20230228213715.png]]

6.6 启用/禁用员工账号功能

6.6.1 需求分析

![[Pasted image 20230228214547.png]]
管理员可以禁用或启用用户,如图
![[Pasted image 20230228214710.png]]
普通用户不能操作,如图![[Pasted image 20230228214735.png]]

6.6.2 代码开发

  • 编写对象转换器,防止数据精度丢失,比如Long数据丢精度失,代码如下:
/**  
 * 对象映射器:基于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);  
    }  
}
  • 配置映射器,在之前的WebMVCConfig类中添加上文定义的扩展器。如下:
/**  
 * 扩展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);  
}
  • 编写禁用员工账号controller层,如下
@PutMapping  
public Result<String> updateEmployee(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 Result.success("员工信息修改成!");  
}

6.6.3 测试

点击禁用或启用成功,如图
![[Pasted image 20230301105402.png]]
![[Pasted image 20230301105415.png]]

6.7 编辑员工信息功能

6.7.1 需求

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

6.7.2 代码开发

  • 编写获取员工信息代码,如下:
 @GetMapping("/{id}")  
public Result getEmployeeById(@PathVariable Long id){  
    log.info("查找id为{}的员工信息",id);  
    Employee employee = employeeService.getById(id);  
    if(employee == null) return Result.error("获取信息失败!");  
    return Result.success(employee);  
}

6.7.3 测试

改jerry账号姓名为李四如图![[Pasted image 20230301111133.png]]
保存后如图显示,修改成功
![[Pasted image 20230301111330.png]]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
瑞吉外卖项目是一个基于黑马课程资源的项目,该项目包含了许多功能模块。然而,根据引用的描述,黑马课程中并没有完整开发和讲解所有的模块,导致学习者在完成课程后还存在一些不完整的模块。为了解决这个问题,引用提供了一个补充资源,该资源完整实现了瑞吉外卖项目的所有功能模块,并且在后端部分提供了相应的接口。 在引用中提到,套餐管理的启售、停售和修改以及后台订单展示和查询是瑞吉外卖项目中的一些功能。具体的代码可以在作者的博客中找到。 为了更好地管理共同使用的类,引用建议创建一个名为"common"的新包,并将返回结果类放入其中。该结果类名为"R<T>",类中定义了以下属性和方法: - code属性表示编码,值为1表示成功,值为0或其他数字表示失败。 - msg属性表示错误信息。 - data属性表示数据。 - map属性为动态数据的存储。 - success方法用于返回成功结果。 - error方法用于返回失败结果。 - add方法用于向map属性中添加动态数据。 综上所述,瑞吉外卖项目是基于黑马课程资源的项目,但存在一些未开发和讲解的模块。为了解决这个问题,可以参考引用提供的资源来完整实现项目的所有功能模块。套餐管理和后台订单展示与查询是瑞吉外卖项目中的一些功能,相关代码可以在引用提到的作者的博客中找到。为了更好地管理共同使用的类,可以按照引用的建议创建一个新的包,并将返回结果类放入其中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值