瑞吉外卖实战

news2024/11/27 22:29:22

https://blog.csdn.net/weixin_43715214/category_12022798.html

大佬记录

项目介绍day01

功能架构

(1)用户层

本项目中在构建系统管理后台的前端页面,我们会用到H5、Vue.js、ElementUI等技术。而在构建移动端应用时,我们会使用到微信小程序。

(2)网关层

Nginx是一个服务器,主要用来作为Http服务器,部署静态资源,访问性能高。在Nginx中还有两个比较重要的作用: 反向代理和负载均衡, 在进行项目部署时,要实现Tomcat的负载均衡,就可以通过Nginx来实现。

(3)应用层

SpringBoot: 快速构建Spring项目, 采用 "约定优于配置" 的思想, 简化Spring项目的配置开发。

Spring: 统一管理项目中的各种资源(bean), 在web开发的各层中都会用到。

SpringMVC:SpringMVC是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合,可以无缝集成。

SpringSession: 主要解决在集群环境下的Session共享问题。

lombok:能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法。

Swagger: 可以自动的帮助开发人员生成接口文档,并对接口进行测试。

(4)数据层

MySQL: 关系型数据库, 本项目的核心业务数据都会采用MySQL进行存储。

MybatisPlus: 本项目持久层将会使用MybatisPlus来简化开发, 基本的单表增删改查直接调用框架提供的方法即可。

Redis: 基于key-value格式存储的内存数据库, 访问速度快, 经常使用它做缓存(降低数据库访问压力, 提供访问效率), 在后面的性能优化中会使用。

(5)工具

git: 版本控制工具, 在团队协作中, 使用该工具对项目中的代码进行管理。

maven: 项目构建工具。

junit:单元测试工具,开发人员功能实现完毕后,需要通过junit对功能进行单元测试。

软件开发介绍

第1阶段: 需求分析

完成产品原型、需求规格说明书的编写。

产品原型,一般是通过网页(html)的形式展示当前的页面展示什么样的数据, 页面的布局是什么样子的,点击某个菜单,打开什么页面,点击某个按钮,出现什么效果,都可以通过产品原型看到。

需求规格说明书, 一般来说就是使用 Word 文档来描述当前项目有哪些功能,每一项功能的需求及业务流程是什么样的,都会在文档中描述。

第2阶段: 设计

设计的内容包含 产品设计、UI界面设计、概要设计、详细设计、数据库设计。

在设计阶段,会出具相关的UI界面、及相关的设计文档。比如数据库设计,需要设计当前项目中涉及到哪些数据库,每一个数据库里面包含哪些表,这些表结构之间的关系是什么样的,表结构中包含哪些字段,字段类型都会在文档中描述清楚。

第3阶段: 编码

编写项目代码、并完成单元测试。

作为软件开发工程师,我们主要的工作就是在该阶段, 对分配给我们的模块功能,进行编码实现。编码实现完毕后,进行单元测试,单元测试通过后再进入到下一阶段。

第4阶段: 测试

在该阶段中主要由测试人员, 对部署在测试环境的项目进行功能测试, 并出具测试报告。

第5阶段: 上线运维

在项目上线之前, 会由运维人员准备服务器上的软件环境安装、配置, 配置完毕后, 再将我们开发好的项目,部署在服务器上运行。

我们作为软件开发工程师, 我们主要的任务是在编码阶段, 但是在一些小的项目组当中, 也会涉及到数据库的设计、测试等方面的工作。

角色分工

开发环境搭建

需求

后台系统

菜品管理(批量删除、起售停售)

• 套餐管理(修改、起售停售)

• 订单明细

移动端

个人中心(退出登录、最新订单查询、历史订单、地址管理-修改地址、地址管理-删除地址)

• 购物车(删除购物车中的商品)

https://blog.csdn.net/weixin_43715214/article/details/126920640

精力全用在写注释上了,笔记黑马没给,懒得截图,就直接看别人的吧

https://blog.csdn.net/weixin_43715214/article/details/126945226?ops_request_misc=&request_id=&biz_id=102&utm_term=%E9%BB%91%E9%A9%AC%E7%91%9E%E5%90%89%E5%A4%96%E5%8D%96ppt&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-126945226.142^v71^one_line,201^v4^add_ask&spm=1018.2226.3001.4187

员工登录

//EmployeeController
@PostMapping("/login")
    public R<Employee> login(HttpServletRequest request,@RequestBody Employee employee){
        // 通过request获取Session,把登录成功的信息传进去;@RequestBody用于接受JSON数据
        //1、将页面提交的密码password进行md5加密处理
        String password = employee.getPassword();//拿到密码
        password = DigestUtils.md5DigestAsHex(password.getBytes());//工具类md5加密

        //2、根据页面提交的用户名username查询数据库
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Employee::getUsername,employee.getUsername());
        Employee emp = employeeService.getOne(queryWrapper);//数据库有唯一索引,用getOne

        //3、如果没有查询到则返回登录失败结果
        if(emp == null){
            return R.error("该账号未注册,登录失败");
        }

        //4、密码比对,如果不一致则返回登录失败结果
        if(!emp.getPassword().equals(password)){
            return R.error("账号或密码输入错误,登录失败");
        }

        //5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
        if(emp.getStatus() == 0){
            return R.error("账号已禁用");
        }
        //6、登录成功,将员工id存入Session并返回登录成功结果
        request.getSession().setAttribute("employee",emp.getId());
        return R.success(emp);
    }

退出后台

 @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request){
        //清理Session中保存的当前登录员工的id
        request.getSession().removeAttribute("employee");
        return R.success("退出成功");
    }

Day02员工管理业务开发

2.1完善登录功能

http://t.csdn.cn/GkgbY

@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
//要过滤的东西(过滤器名字,拦截哪些路径)
@Slf4j
public class LoginCheckFilter implements Filter{
    //AntPathMatcher路径匹配器,支持通配符
    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/**",//移动端页面静态资源
                "/common/**", "/user/sendMsg", "/user/login"
        };
        //2、判断本次请求是否需要处理
        boolean check = check(urls, requestURI);

        //3、如果不需要处理,则直接放行
        if(check){
            log.info("本次请求{}不需要处理,直接放行",requestURI);
            filterChain.doFilter(request,response);
            return;
        }
        //4-1、需要处理,判断 员工 登录状态,如果已登录,则直接放行filterChain.doFilter
        if(request.getSession().getAttribute("employee") != null){
            log.info("员工已登录,员工id为:{}",request.getSession().getAttribute("employee"));
            Long empId = (Long) request.getSession().getAttribute("employee");
            BaseContext.setCurrentId(empId);

            filterChain.doFilter(request,response);
            return;
        }

        //4-2、判断 用户 登录状态,如果已登录,则直接放行
        if(request.getSession().getAttribute("user") != null){
            log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("user"));
            Long userId = (Long) request.getSession().getAttribute("user");
            BaseContext.setCurrentId(userId);
            filterChain.doFilter(request,response);
            return;
        }

        log.info("用户未登录");
        //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        //把R转成JSON 输出’NOTLOGIN‘和request.js里面响应拦截器的条件匹配
        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;
    }
}

2.2新增员工

@ControllerAdvice(annotations = {RestController.class, Controller.class})
//AOP通知(annotations={拦截加了 XX.class的注解的Controller} )
@ResponseBody//返回JSON数据的方法需要加这个注解
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 异常处理方法
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)//(要处理的异常类)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
        log.error(ex.getMessage());
        if(ex.getMessage().contains("Duplicate entry")){//异常信息包含这个字段就是重复错误
            String[] split = ex.getMessage().split(" ");
            String msg = split[2] + "已存在";//根据字段输出得知name在[2]
            return R.error(msg);
        }
        return R.error("未知错误");
    }
}
@PostMapping
    public R<String> save(HttpServletRequest request,@RequestBody Employee employee){
        log.info("新增员工,员工信息:{}",employee.toString());
        //设置初始密码123456,需要进行md5加密处理
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));

        //employee.setCreateTime(LocalDateTime.now());//LocalDateTime.now():获取系统当前time
        //employee.setUpdateTime(LocalDateTime.now());
        //获得当前登录用户的id
        //Long empId = (Long) request.getSession().getAttribute("employee");

        //employee.setCreateUser(empId);
        //employee.setUpdateUser(empId);

        employeeService.save(employee);
        //继承了MabatisPlus的IService接口写的save
        return R.success("新增员工成功");
    }

2.3员工信息分页查询

@GetMapping("/page")
    public R<Page> page(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 R.success(pageInfo);
    }

启用/禁用员工账号

编辑员工信息

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

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

相关文章

计算机网络连环炮40问

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

Day09 C++STL入门基础知识六——deque容器 构造函数-赋值操作-大小操作-插入删除-数据存储-排序操作【全面深度剖析+例题代码展示】

无人问津的日子&#xff0c;我为自己喝彩&#xff01; 文章目录1. 基本概念1.1 功能1.2 与vector区别1.3 图解1.4 内部工作原理1.5 deque 容器的迭代器也是支持随机访问的2. 构造函数2.1 函数原型2.2 代码展示2.3 测试结果2.4 小think2.4.1 小问题2.4.2 思路2.4.3 修改2.4.4 测…

从零开始的数模(六)python在高等数学和线性代数中的应用

科学计算设计数值计算和符号计算&#xff0c;在python中作基础数值计算用numpy和scipy工具库&#xff0c;作符号运算用sympy工具库 sympy工具库–符号运算 符号运算基本知识 1.利用symbols函数创建符号变量构造多个符号变量时中间以空格分隔 2.利用符号变量创建表达式 3.利用…

Hive整合HBase,操作HBase表

Hive over HBase原理 Hive与HBase利用两者本身对外的API来实现整合&#xff0c;主要是靠HBaseStorageHandler进行通信&#xff0c;利用 HBaseStorageHandler&#xff0c;Hive可以获取到Hive表对应的HBase表名&#xff0c;列簇以及列&#xff0c;InputFormat和 OutputFormat类&…

STS:Surround-view Temporal Stereo for Multi-view 3D Detection——论文笔记

参考代码&#xff1a;None 1. 概述 介绍&#xff1a;这篇文章提出的方法是对LSS中深度估计部分进行改进&#xff0c;其改进的点是在深度估计部分引入立体匹配去估计周视相机下的深度信息&#xff0c;其中立体匹配使用前后视频帧进行构建&#xff08;可以看作是时序信息的使用&…

node-sass安装失败的解决方案

Nodejs 新版安装过程需要安装node-sass模块&#xff0c;开始一直无法安装成功&#xff0c;网上找了很多方法都无法解决&#xff0c;找了很久才找到的解决方案。 1.1 node-sass安装前准备 Option 2: Install dependencies and configuration manually Install Visual C Build E…

Python处理zip压缩文件

文章目录ZipFile对象写入压缩文件读取和解压缩常用属性ZipInfoZipFile对象 顾名思义&#xff0c;zipfile是处理zip文件的模块&#xff0c;其中最重要的类是ZipFile&#xff0c;其构造函数为 ZipFile(file, moder, compressionZIP_STORED, allowZip64True, compresslevelNone,…

使用VGG网络训练发生错误RuntimeError: CUDA out of memory解决方案:

问题在使用VGG网络训练Mnisist数据集时&#xff0c;发生错误RuntimeError: CUDA out of memory. Tried to allocate 392.00 MiB (GPU 0; 2.00 GiB total capacity; 1.45 GiB already allocated; 0 bytes free; 1.47 GiB reserved in total by PyTorch) If reserved memory is &…

发布详解 | Flutter 3.7 稳定版发布

新年伊始&#xff0c;由 Flutter 3.7 正式版来「打头阵」&#xff01;我们与整个 Flutter 社区成员们继续在 Flutter 3.7 中优化了框架&#xff0c;包括创建自定义菜单栏和层叠式菜单、更好的国际化工具支持、新的调试工具以及其他功能和特性等。新的稳定版里&#xff0c;我们在…

JUC面试(十二)——AQS

AQS juc.locks包下 AbstractQueuedSynchronizer&#xff0c;抽象的队列同步器 aqs是用来构建锁或者其它同步器组件的重量级基础框架及整个JUC体系的基石&#xff0c; 通过内置的FIFO队列来完成资源获取线程的排队工作&#xff0c;并通过一个int类变量表示持有锁的状态&#x…

极限运算法则——“高等数学”

各位CSDN的uu们你们好啊&#xff0c;今天&#xff0c;小雅兰学习的内容是极限运算法则 回顾 无穷小的极限运算法则 定理1&#xff1a;两个无穷小的和是无穷小 定理2&#xff1a;有界函数与无穷小的乘积是无穷小 极限的四则运算法则 定理3 定理4 定理5&#xff1a;极限的保序性…

实现自己的数据库二

一 前言上次数据库支持了一个测试表的插入和查询&#xff0c;但是数据全部保存到磁盘中的&#xff0c;如果程序重启后&#xff0c;数据都会全部丢了&#xff0c;所以需要持久化到磁盘上&#xff0c;像sqlite一样&#xff0c;简单的将数据库的数据保存到一个磁盘文件上。二 实现…

【BBuf的CUDA笔记】六,总结 FasterTransformer Encoder(BERT) 的cuda相关优化技巧

这里总结 FasterTransformer Encoder(BERT) 的cuda相关优化技巧 解读&#xff1a;https://github.com/NVIDIA/FasterTransformer/blob/main/docs/bert_guide.md &#xff0c;优化点解读之前是翻译了下 Faster Transformer BERT 的文档&#xff0c;然后省略了运行样例等环节&…

【Datewhale一起吃瓜 Task4】啃瓜第五章

支持向量机 任务&#xff1a;找到超平面 在样本空间中&#xff0c;找到最好的超平面把样本分开&#xff0c;即找到正中间的超平面 满足 该超平面 分开了两类该超平面 最大化支持向量间隔该超平面处于 间隔中间&#xff0c;到所有支持向量距离相等 如何找&#xff1a;表示出…

从聚水潭到金蝶云星空通过接口集成数据

从聚水潭到金蝶云星空通过接口集成数据数据源系统:聚水潭聚水潭成立于2014年&#xff0c;创始人兼CEO骆海东拥有近三十年传统及电商ERP的研发和实施部署经验。聚水潭创建之初&#xff0c;以电商SaaSERP切入市场&#xff0c;凭借出色的产品和服务&#xff0c;快速获得市场的肯定…

【论文简述】Attention-Aware Multi-View Stereo(CVPR 2020)

一、论文简述 1. 第一作者&#xff1a;Keyang Luo 2. 发表年份&#xff1a;2020 3. 发表期刊&#xff1a;CVPR 4. 关键词&#xff1a;MVS、代价体、注意力机制、正则化 5. 探索动机&#xff1a; However, the feature matching results from different channels are usual…

仿写Dubbo-MyRpc

基础 在仿写Dubbo之前&#xff0c;需要了解一些技术&#xff0c;像Java反射&#xff0c;Java代理&#xff0c;Java Socket以及Dubbo相关概念。 项目结构 项目gitee地址&#xff1a;https://gitee.com/AGi_R/framework my-common 整个项目的公共资源库。存放一些公共的注解&…

拦截器、过滤器、监听器

目录一、拦截器1. 拦截器是什么?2. 设置拦截器a. 定义拦截器b. 配置加载拦截器c. 新建页面二、过滤器1. 使用原因2. Filter概念图3. Filter编程三、监听器一、拦截器 拦截器&#xff1a;必须保证页面有访问controller的操作&#xff0c;否则拦截不了 1. 拦截器是什么? 概念…

OpenWrt软路由空间扩容

文章目录预备知识OpenWrt系统固件分类EXT4固件扩容方式新建分区扩容操作步骤直接扩容操作步骤SQUASHFS固件扩容方式新建分区扩容直接扩容EFI引导固件的额外操作参考预备知识 OpenWrt系统固件分类 EXT4固件 固件包名称中包含有ext4关键字&#xff0c;可以参考固件分类关键字示意…

设计模式 - 创建型模式_建造者模式

文章目录创建型模式概述Case模拟工程Bad ImplBetter Impl &#xff08;建造者模式重构代码&#xff09;小结创建型模式 创建型模式提供创建对象的机制&#xff0c; 能够提升已有代码的灵活性和可复⽤性。 类型实现要点工厂方法定义⼀个创建对象的接⼝&#xff0c;让其⼦类⾃⼰…