目录
文章末尾获取源码、软件和教程~
系统背景
随着人们生活习惯的变更,使用线上点餐的频率越来越高,外卖点餐系统逐渐成为生活中不可或缺的一部分。为此移动端的外卖点餐系统是解决实际生活需求的一个重要工具。
系统总体设计
运行环境
-
Java 开发工具包:jdk v1.8
-
Java依赖管理工具:maven v3.3.9
-
后端代码开发工具:idea
-
前端代码开发工具:WebStorm
-
数据库可视化工具:Navicat
-
数据库:MySQL
技术选型
-
SpringBoot
-
MybatisPlus
-
Vue
-
ElementUI
系统架构
系统用例
不同的角色具有不同的功能
系统详细设计
系统功能截图
后端-登入页
后端-员工管理
后端-分类管理
后端-菜品管理
后端-套餐管理
后端-订单明细
用户前端-登入页
用户前端-购买页
用户前端-个人中心
系统核心功能设计
登入过滤器
核心代码如下:
@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/**", "/common/**", "/user/sendMsg", "/user/login" }; //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")); 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"))); 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; } }
自动填充操作数据
核心代码如下:
@Data public class Dish implements Serializable { private static final long serialVersionUID = 1L; private Long id; //菜品名称 private String name; //菜品分类id private Long categoryId; //菜品价格 private BigDecimal price; //商品码 private String code; //图片 private String image; //描述信息 private String description; //0 停售 1 起售 private Integer status; //顺序 private Integer sort; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT) private Long createUser; @TableField(fill = FieldFill.INSERT_UPDATE) private Long updateUser;
MD5加密
密码采用加密,就算是后台人员也无法直接查看和破解密码,极大保障用户数据安全
RESTful架构风格
采用这种架构风格,前后端对接能很好地进行交互
代码如下:
@RestController @RequestMapping("/setmeal") @Slf4j public class SetmealController { @Autowired private SetmealService setmealService; @Autowired private CategoryService categoryService; @Autowired private SetmealDishService setmealDishService; /** * 新增套餐 * @param setmealDto * @return */ @PostMapping public R<String> save(@RequestBody SetmealDto setmealDto){ log.info("套餐信息:{}",setmealDto); setmealService.saveWithDish(setmealDto); return R.success("新增套餐成功"); } /** * 套餐分页查询 * @param page * @param pageSize * @param name * @return */ @GetMapping("/page") public R<Page> page(int page,int pageSize,String name){ //分页构造器对象 Page<Setmeal> pageInfo = new Page<>(page,pageSize); Page<SetmealDto> dtoPage = new Page<>(); LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>(); //添加查询条件,根据name进行like模糊查询 queryWrapper.like(name != null,Setmeal::getName,name); //添加排序条件,根据更新时间降序排列 queryWrapper.orderByDesc(Setmeal::getUpdateTime); setmealService.page(pageInfo,queryWrapper); //对象拷贝 BeanUtils.copyProperties(pageInfo,dtoPage,"records"); List<Setmeal> records = pageInfo.getRecords(); List<SetmealDto> list = records.stream().map((item) -> { SetmealDto setmealDto = new SetmealDto(); //对象拷贝 BeanUtils.copyProperties(item,setmealDto); //分类id Long categoryId = item.getCategoryId(); //根据分类id查询分类对象 Category category = categoryService.getById(categoryId); if(category != null){ //分类名称 String categoryName = category.getName(); setmealDto.setCategoryName(categoryName); } return setmealDto; }).collect(Collectors.toList()); dtoPage.setRecords(list); return R.success(dtoPage); } /** * 删除套餐 * @param ids * @return */ @DeleteMapping public R<String> delete(@RequestParam List<Long> ids){ log.info("ids:{}",ids); setmealService.removeWithDish(ids); return R.success("套餐数据删除成功"); } /** * 修改菜品 * @return */ @PostMapping("/status/{status}") public R<String> updateStatus(@PathVariable Integer status,@RequestParam List<Long> ids){ Setmeal dish = new Setmeal(); dish.setStatus(status); setmealService.update(dish, Wrappers.lambdaQuery(Setmeal.class).in(Setmeal::getId, ids)); return R.success("成功"); } /** * 根据条件查询套餐数据 * @param setmeal * @return */ @GetMapping("/list") public R<List<Setmeal>> list(Setmeal setmeal){ LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(setmeal.getCategoryId() != null,Setmeal::getCategoryId,setmeal.getCategoryId()); queryWrapper.eq(setmeal.getStatus() != null,Setmeal::getStatus,setmeal.getStatus()); queryWrapper.orderByDesc(Setmeal::getUpdateTime); List<Setmeal> list = setmealService.list(queryWrapper); return R.success(list); } }
数据存储设计
##
表结构
-
地址簿
-
菜品分类
-
后端员工
-
前端用户
获取源码
觉得不错就点赞、收藏、关注、评论 吧。致力于将企业开发模式运用于项目学习中,在项目的学习中,同时了解企业开发模式和业务设计。商务合作/学习交流/源码获取私聊我。