毕业设计实战:基于Spring Boot的点餐平台网站全栈开发

49 阅读11分钟

一、项目背景:数字化时代的餐饮服务革新

随着移动互联网的快速发展和消费习惯的深刻变革,传统餐饮行业面临着效率低下、服务单一、管理困难等严峻挑战。据统计,2024年中国在线外卖市场规模预计超过1万亿元,移动端餐饮用户规模达4亿,近90%的消费者倾向于通过线上平台完成餐饮消费。

在"互联网+餐饮"模式深入发展的背景下,基于Spring Boot的点餐平台网站成为连接餐厅和消费者的重要数字化桥梁。系统采用成熟的B/S架构,通过信息化手段实现了从菜品展示、在线点餐到订单管理的全流程数字化服务。本毕业设计以现代餐饮消费需求为导向,建立了"管理员统筹-用户点餐"的双向协同机制,为餐饮行业数字化转型提供了创新的技术解决方案。

二、技术架构:点餐平台的全栈技术选型

项目以"高性能、高可用、用户体验"为核心理念,采用业界成熟的Java Web开发技术栈:

技术模块具体工具/技术核心作用
后端框架Spring Boot 2.x构建高性能后端服务,提供完整的MVC解决方案
数据库MySQL 8.0存储用户信息、菜品数据、订单记录、评价信息等
前端技术JSP + Bootstrap + JavaScript构建现代化点餐界面,实现良好的用户交互
架构模式B/S结构实现跨平台访问,用户只需浏览器即可使用
开发工具Eclipse + NavicatEclipse集成开发,Navicat数据库管理
服务器Tomcat 9.0Web应用部署和业务请求处理
缓存技术Redis提升系统性能,处理高并发点餐

三、项目全流程:6步完成点餐平台开发

3.1 第一步:需求分析——明确平台核心价值

传统餐饮服务存在"等待时间长、信息不透明、服务效率低"三大痛点,本系统聚焦"便捷、透明、高效",核心需求分为功能性与非功能性两类:

3.1.1 功能性需求

  1. 双角色权限体系

    • 管理员:首页、个人中心、用户管理、菜品分类管理、菜品信息管理、菜品评价管理、系统管理、订单管理;
    • 用户:首页、个人中心、菜品评价管理、我的收藏管理、订单管理。
  2. 核心点餐功能

    • 菜品信息服务:菜品展示、分类管理、搜索筛选;
    • 在线点餐功能:购物车管理、订单生成、支付处理;
    • 评价系统功能:订单评价、评分管理、内容审核;
    • 用户管理功能:注册登录、信息维护、收藏管理。
  3. 辅助服务功能

    • 资讯管理:菜品资讯、活动公告、行业动态;
    • 客服支持:在线咨询、问题解答、售后服务;
    • 数据统计:销售数据、用户行为、经营分析。

3.1.2 非功能性需求

  • 系统安全性:严格的用户认证和交易保护机制;
  • 高并发处理:用餐高峰期的高并发点餐场景;
  • 数据一致性:确保菜品信息和订单数据的准确无误;
  • 响应及时性:页面加载和点餐操作的快速响应。

3.2 第二步:系统设计——构建整体架构

系统采用经典的三层架构模式,实现表现层、业务逻辑层和数据访问层的有效分离:

3.2.1 系统总体架构

  1. 表现层(Web层)

    • 用户界面:基于JSP的动态页面,适配不同设备访问;
    • 前端交互:通过JavaScript实现丰富的用户交互体验。
  2. 业务逻辑层(Service层)

    • 核心业务:菜品服务、订单服务、用户服务、评价服务;
    • 业务规则:库存验证、价格计算、状态管理、通知提醒。
  3. 数据访问层(DAO层)

    • 数据持久化:通过MyBatis框架实现数据库操作;
    • 事务管理:确保业务操作的数据一致性。

3.2.2 核心数据库设计

系统包含多个核心业务表,确保点餐平台数据的完整性和业务关联性:

表名核心字段作用
users(用户表)id、yonghuming、mima、xingming、touxiang、xingbie、lianxidianhua存储用户基本信息
caipinxinxi(菜品信息表)id、caipinmingcheng、caipinfenlei、tupian、cailiao、fenliang、jiage存储菜品详细信息
orders(订单表)id、dingdanbianhao、caipinmingcheng、shuliang、zongjia、zhuangtai记录订单信息
caipinpingjia(菜品评价表)id、dingdanbianhao、caipinmingcheng、pingfen、pingjianeirong记录评价信息

3.3 第三步:后端核心功能实现——Spring Boot架构

基于Spring Boot框架实现系统后端核心功能,重点解决"菜品管理"和"订单处理"问题:

3.3.1 菜品管理功能实现

@RestController
@RequestMapping("/api/dish")
public class DishController {
    
    @Autowired
    private DishService dishService;
    
    /**
     * 获取菜品列表
     */
    @GetMapping("/list")
    public ResponseEntity<?> getDishList(
            @RequestParam(required = false) String fenlei,
            @RequestParam(required = false) String keyword,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "12") int size) {
        try {
            DishQuery query = new DishQuery();
            query.setFenlei(fenlei);
            query.setKeyword(keyword);
            query.setPage(page);
            query.setSize(size);
            
            PageResult<Dish> result = dishService.getDishList(query);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("获取菜品列表失败");
        }
    }
    
    /**
     * 添加菜品信息
     */
    @PostMapping("/add")
    public ResponseEntity<?> addDish(@RequestBody DishAddDTO addDTO) {
        try {
            // 验证管理员权限
            if (!hasManagementPermission()) {
                return ResponseEntity.badRequest().body("无操作权限");
            }
            
            // 创建菜品信息
            Dish dish = new Dish();
            dish.setCaipinmingcheng(addDTO.getCaipinmingcheng());
            dish.setCaipinfenlei(addDTO.getCaipinfenlei());
            dish.setTupian(addDTO.getTupian());
            dish.setCailiao(addDTO.getCailiao());
            dish.setFenliang(addDTO.getFenliang());
            dish.setJiage(addDTO.getJiage());
            dish.setCaipinjieshao(addDTO.getCaipinjieshao());
            dish.setKucun(addDTO.getKucun());
            dish.setAddtime(new Date());
            
            dishService.addDish(dish);
            return ResponseEntity.ok("菜品添加成功");
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("菜品添加失败");
        }
    }
    
    /**
     * 获取菜品详情
     */
    @GetMapping("/detail/{id}")
    public ResponseEntity<?> getDishDetail(@PathVariable Long id) {
        try {
            Dish dish = dishService.getDishById(id);
            if (dish == null) {
                return ResponseEntity.badRequest().body("菜品不存在");
            }
            
            return ResponseEntity.ok(dish);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("获取菜品详情失败");
        }
    }
    
    /**
     * 搜索菜品
     */
    @GetMapping("/search")
    public ResponseEntity<?> searchDishes(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "12") int size) {
        try {
            DishQuery query = new DishQuery();
            query.setKeyword(keyword);
            query.setPage(page);
            query.setSize(size);
            
            PageResult<Dish> result = dishService.searchDishes(query);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("搜索菜品失败");
        }
    }
    
    /**
     * 获取推荐菜品
     */
    @GetMapping("/recommend")
    public ResponseEntity<?> getRecommendedDishes(@RequestParam(defaultValue = "6") int size) {
        try {
            List<Dish> recommendedDishes = dishService.getRecommendedDishes(size);
            return ResponseEntity.ok(recommendedDishes);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().body("获取推荐菜品失败");
        }
    }
}

3.3.2 购物车服务实现

@Service
@Transactional
public class CartService {
    
    @Autowired
    private CartMapper cartMapper;
    
    @Autowired
    private DishService dishService;
    
    /**
     * 添加菜品到购物车
     */
    public Cart addToCart(CartAddDTO addDTO) {
        // 验证用户信息
        User user = userService.getUserByUsername(addDTO.getYonghuming());
        if (user == null) {
            throw new RuntimeException("用户信息不存在");
        }
        
        // 验证菜品信息
        Dish dish = dishService.getDishById(addDTO.getDishId());
        if (dish == null) {
            throw new RuntimeException("菜品信息不存在");
        }
        
        // 检查库存
        if (dish.getKucun() < addDTO.getShuliang()) {
            throw new RuntimeException("菜品库存不足");
        }
        
        // 检查购物车是否已有该菜品
        Cart existingCart = cartMapper.selectCartByUserAndDish(
            addDTO.getYonghuming(), addDTO.getDishId());
        
        if (existingCart != null) {
            // 更新数量
            existingCart.setShuliang(existingCart.getShuliang() + addDTO.getShuliang());
            cartMapper.updateCart(existingCart);
            return existingCart;
        } else {
            // 创建新的购物车记录
            Cart cart = new Cart();
            cart.setYonghuming(addDTO.getYonghuming());
            cart.setCaipinmingcheng(dish.getCaipinmingcheng());
            cart.setCaipinfenlei(dish.getCaipinfenlei());
            cart.setTupian(dish.getTupian());
            cart.setJiage(dish.getJiage());
            cart.setShuliang(addDTO.getShuliang());
            cart.setAddtime(new Date());
            
            cartMapper.insertCart(cart);
            return cart;
        }
    }
    
    /**
     * 获取用户购物车
     */
    public List<Cart> getUserCart(String yonghuming) {
        return cartMapper.selectCartsByUser(yonghuming);
    }
    
    /**
     * 更新购物车菜品数量
     */
    public boolean updateCartQuantity(Long cartId, Integer quantity) {
        Cart cart = cartMapper.selectCartById(cartId);
        if (cart == null) {
            throw new RuntimeException("购物车记录不存在");
        }
        
        // 验证库存
        Dish dish = dishService.getDishByName(cart.getCaipinmingcheng());
        if (dish.getKucun() < quantity) {
            throw new RuntimeException("菜品库存不足");
        }
        
        cart.setShuliang(quantity);
        cartMapper.updateCart(cart);
        
        return true;
    }
    
    /**
     * 删除购物车菜品
     */
    public boolean removeFromCart(Long cartId) {
        Cart cart = cartMapper.selectCartById(cartId);
        if (cart == null) {
            throw new RuntimeException("购物车记录不存在");
        }
        
        cartMapper.deleteCart(cartId);
        return true;
    }
    
    /**
     * 清空用户购物车
     */
    public boolean clearUserCart(String yonghuming) {
        cartMapper.deleteCartsByUser(yonghuming);
        return true;
    }
    
    /**
     * 计算购物车总金额
     */
    public BigDecimal calculateCartTotal(String yonghuming) {
        List<Cart> cartItems = getUserCart(yonghuming);
        return cartItems.stream()
                .map(item -> item.getJiage().multiply(new BigDecimal(item.getShuliang())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

3.3.3 订单服务实现

@Service
@Transactional
public class OrderService {
    
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private CartService cartService;
    
    @Autowired
    private DishService dishService;
    
    /**
     * 创建订单
     */
    public Order createOrder(OrderCreateDTO createDTO) {
        // 验证用户信息
        User user = userService.getUserByUsername(createDTO.getYonghuming());
        if (user == null) {
            throw new RuntimeException("用户信息不存在");
        }
        
        // 生成订单编号
        String orderNumber = generateOrderNumber();
        
        // 计算订单总金额
        BigDecimal totalAmount = BigDecimal.ZERO;
        List<OrderItem> orderItems = new ArrayList<>();
        
        for (OrderItemDTO itemDTO : createDTO.getItems()) {
            Dish dish = dishService.getDishById(itemDTO.getDishId());
            if (dish == null) {
                throw new RuntimeException("菜品信息不存在: " + itemDTO.getDishId());
            }
            
            // 验证库存
            if (dish.getKucun() < itemDTO.getShuliang()) {
                throw new RuntimeException("菜品库存不足: " + dish.getCaipinmingcheng());
            }
            
            // 计算菜品总价
            BigDecimal itemTotal = dish.getJiage().multiply(new BigDecimal(itemDTO.getShuliang()));
            totalAmount = totalAmount.add(itemTotal);
            
            // 创建订单项
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderNumber(orderNumber);
            orderItem.setCaipinmingcheng(dish.getCaipinmingcheng());
            orderItem.setCaipinfenlei(dish.getCaipinfenlei());
            orderItem.setTupian(dish.getTupian());
            orderItem.setJiage(dish.getJiage());
            orderItem.setShuliang(itemDTO.getShuliang());
            orderItem.setZongjia(itemTotal);
            orderItems.add(orderItem);
            
            // 更新菜品库存
            dish.setKucun(dish.getKucun() - itemDTO.getShuliang());
            dishService.updateDish(dish);
        }
        
        // 创建订单
        Order order = new Order();
        order.setDingdanbianhao(orderNumber);
        order.setYonghuming(createDTO.getYonghuming());
        order.setXingming(user.getXingming());
        order.setLianxidianhua(user.getLianxidianhua());
        order.setDizhi(createDTO.getDizhi());
        order.setZongjine(totalAmount);
        order.setZhuangtai("待支付");
        order.setAddtime(new Date());
        
        orderMapper.insertOrder(order);
        
        // 保存订单项
        for (OrderItem item : orderItems) {
            orderMapper.insertOrderItem(item);
        }
        
        // 清空购物车
        cartService.clearUserCart(createDTO.getYonghuming());
        
        return order;
    }
    
    /**
     * 支付订单
     */
    public boolean payOrder(String orderNumber) {
        Order order = orderMapper.selectOrderByNumber(orderNumber);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if (!"待支付".equals(order.getZhuangtai())) {
            throw new RuntimeException("订单状态异常");
        }
        
        // 更新订单状态
        order.setZhuangtai("已支付");
        order.setZhifushijian(new Date());
        orderMapper.updateOrder(order);
        
        return true;
    }
    
    /**
     * 生成订单编号
     */
    private String generateOrderNumber() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStr = sdf.format(new Date());
        Random random = new Random();
        int randomNum = random.nextInt(9000) + 1000;
        return "DD" + timeStr + randomNum;
    }
    
    /**
     * 取消订单
     */
    public boolean cancelOrder(String orderNumber) {
        Order order = orderMapper.selectOrderByNumber(orderNumber);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if (!"待支付".equals(order.getZhuangtai())) {
            throw new RuntimeException("订单状态不允许取消");
        }
        
        // 恢复菜品库存
        List<OrderItem> orderItems = orderMapper.selectOrderItemsByOrderNumber(orderNumber);
        for (OrderItem item : orderItems) {
            Dish dish = dishService.getDishByName(item.getCaipinmingcheng());
            if (dish != null) {
                dish.setKucun(dish.getKucun() + item.getShuliang());
                dishService.updateDish(dish);
            }
        }
        
        order.setZhuangtai("已取消");
        orderMapper.updateOrder(order);
        
        return true;
    }
    
    /**
     * 获取用户订单
     */
    public List<Order> getUserOrders(String yonghuming) {
        return orderMapper.selectOrdersByUser(yonghuming);
    }
}

3.3.4 评价服务实现

@Service
@Transactional
public class ReviewService {
    
    @Autowired
    private ReviewMapper reviewMapper;
    
    @Autowired
    private OrderService orderService;
    
    /**
     * 提交菜品评价
     */
    public Review submitReview(ReviewSubmitDTO submitDTO) {
        // 验证订单信息
        Order order = orderService.getOrderByNumber(submitDTO.getDingdanbianhao());
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 验证订单状态(只有已完成订单才能评价)
        if (!"已完成".equals(order.getZhuangtai())) {
            throw new RuntimeException("只有已完成的订单才能评价");
        }
        
        // 检查是否已评价
        if (reviewMapper.selectReviewByOrder(submitDTO.getDingdanbianhao()) != null) {
            throw new RuntimeException("该订单已评价");
        }
        
        // 创建评价记录
        Review review = new Review();
        review.setDingdanbianhao(submitDTO.getDingdanbianhao());
        review.setCaipinmingcheng(submitDTO.getCaipinmingcheng());
        review.setCaipinfenlei(submitDTO.getCaipinfenlei());
        review.setPingfen(submitDTO.getPingfen());
        review.setTianjiatupian(submitDTO.getTianjiatupian());
        review.setPingjianeirong(submitDTO.getPingjianeirong());
        review.setPingjiariqi(new Date());
        review.setYonghuming(submitDTO.getYonghuming());
        review.setSfsh("待审核");
        
        reviewMapper.insertReview(review);
        
        return review;
    }
    
    /**
     * 审核评价
     */
    public boolean reviewReview(Long reviewId, ReviewAuditDTO auditDTO) {
        Review review = reviewMapper.selectReviewById(reviewId);
        if (review == null) {
            throw new RuntimeException("评价记录不存在");
        }
        
        review.setSfsh(auditDTO.getSfsh());
        review.setShhf(auditDTO.getShhf());
        reviewMapper.updateReview(review);
        
        return true;
    }
    
    /**
     * 获取菜品评价
     */
    public List<Review> getDishReviews(String caipinmingcheng) {
        return reviewMapper.selectReviewsByDish(caipinmingcheng);
    }
    
    /**
     * 计算菜品平均评分
     */
    public Double calculateDishRating(String caipinmingcheng) {
        List<Review> reviews = reviewMapper.selectReviewsByDish(caipinmingcheng);
        if (reviews.isEmpty()) {
            return 0.0;
        }
        
        double totalScore = reviews.stream()
                .mapToDouble(review -> Double.parseDouble(review.getPingfen()))
                .sum();
        
        return totalScore / reviews.size();
    }
}

3.4 第四步:前端界面实现——双角色适配界面

基于JSP + Bootstrap构建适配双角色的点餐平台界面,确保界面清晰、操作便捷:

3.4.1 用户功能界面

  • 菜品浏览:菜品列表、详情查看、分类筛选;
  • 购物车管理:菜品添加、数量修改、批量删除;
  • 订单管理:订单查看、支付操作、历史记录;
  • 评价管理:订单评价、历史评价、评分管理。

3.4.2 管理员功能界面

  • 菜品管理:菜品维护、分类管理、库存管理;
  • 订单管理:订单处理、状态更新、数据统计;
  • 评价管理:评价审核、内容管理、数据统计;
  • 用户管理:用户信息、权限分配、状态管理。 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

3.5 第五步:系统测试——确保平台稳定可靠

通过全面的测试策略确保系统质量,重点测试点餐平台核心功能和业务流程:

3.5.1 功能测试

设计完整测试用例,覆盖主要业务场景:

测试场景预期结果实际结果是否通过
菜品信息管理操作成功,信息完整操作成功,信息完整
购物车功能添加成功,数量正确添加成功,数量正确
订单创建流程创建成功,状态正确创建成功,状态正确
支付流程验证支付成功,状态更新支付成功,状态更新
评价系统功能评价成功,审核正常评价成功,审核正常

3.5.2 性能测试

  • 并发测试:系统支持500用户同时在线点餐;
  • 数据准确性:菜品信息和订单数据准确无误;
  • 安全测试:用户隐私和交易安全得到有效保障;
  • 压力测试:用餐高峰期系统稳定性验证。

3.6 第六步:问题排查与优化——提升系统性能

开发过程中遇到的主要技术问题及解决方案:

  1. 库存并发控制:多用户同时下单时的库存扣减冲突;
  2. 订单状态管理:订单全生命周期的状态一致性保证;
  3. 支付集成优化:多种支付方式的集成和异常处理;
  4. 评价系统设计:评价审核和菜品评分的实时更新。

四、毕业设计复盘:经验总结与实践建议

4.1 开发过程中的技术挑战

  1. 高并发场景处理:用餐高峰期大量用户同时下单;
  2. 库存一致性保证:多用户同时操作时的库存准确扣减;
  3. 支付流程复杂:多种支付渠道的集成和回调处理;
  4. 用户体验优化:点餐流程的简洁性和操作便捷性。

4.2 给后续开发者的建议

  1. 重视并发控制:点餐系统要特别关注高并发场景的处理;
  2. 完善库存管理:库存预警、自动补货、库存同步机制;
  3. 支付流程优化:支付超时、失败等异常情况的处理;
  4. 缓存策略设计:合理使用缓存提升系统性能;
  5. 扩展性考虑:系统架构要支持后续的会员体系、优惠活动等功能扩展。

五、项目资源与发展展望

5.1 项目核心资源

本项目提供完整的开发资料:

  • 后端源码:完整的Spring Boot项目源码;
  • 前端页面:基于JSP的前端页面资源;
  • 数据库脚本:MySQL数据库建表语句和测试数据;
  • API文档:完整的业务接口文档;
  • 部署文档:详细的系统部署和配置指南。

5.2 系统扩展方向

  1. 移动端支持:开发微信小程序或APP移动端;
  2. 智能推荐:基于用户行为的智能菜品推荐;
  3. 会员体系:会员等级、积分、优惠券系统;
  4. 数据分析:消费行为分析和精准营销;
  5. 多商家支持:支持平台化多商家入驻管理。

如果本文对您的Spring Boot学习、点餐平台网站相关毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多电商系统项目实战案例!