毕业设计实战:基于SpringBoot+Vue的网上购物系统全流程指南

30 阅读10分钟

毕业设计实战:基于SpringBoot+Vue的网上购物系统全流程指南

在开发“网上购物系统”毕业设计时,曾因“订单流程与库存同步设计不当”踩过关键坑——初期订单创建与库存扣减分离,导致超卖问题,耗费2天实现分布式锁才解决📝。基于实战经验,本文将系统拆解网上购物系统开发全流程。

一、需求分析:聚焦电商核心业务

电商系统最易犯的错误是功能繁杂。前期曾尝试添加“智能推荐算法”,最终因偏离“商品管理、购物流程、订单处理”核心需求被导师要求简化。

核心用户与功能

  • 管理员:全系统管理、商家审核、商品审核、订单管理、系统配置
  • 商家:商品管理、订单处理、店铺管理、销售统计
  • 用户:商品浏览、购物车、下单支付、订单跟踪、个人中心

核心业务流程

  1. 购物流程:浏览商品 → 加入购物车 → 提交订单 → 支付 → 商家发货 → 用户收货
  2. 商家流程:入驻申请 → 商品上架 → 订单处理 → 发货 → 售后
  3. 管理流程:审核商家 → 审核商品 → 处理投诉 → 数据分析

二、技术选型:成熟稳定方案

选择“Java 8+SpringBoot 2.7+Vue 2.x+MySQL 8.0+Redis”组合:

技术用途关键技术点
SpringBoot 2.7后端框架自动配置,微服务支持
Vue 2.x + ElementUI前端框架组件化,响应式设计
MySQL 8.0主数据库事务支持,JSON类型
Redis缓存/队列商品缓存,订单队列
RabbitMQ(可选)消息队列异步处理订单,解耦业务

三、数据库设计:重点设计电商核心表

电商系统的核心在于商品-订单-用户的完整链路,以及库存和事务一致性。

核心表结构设计

  1. 用户表 (user):用户ID、账号、密码、姓名、头像、余额、会员状态
  2. 商家表 (merchant):商家ID、账号、店铺名、地址、联系方式、状态
  3. 商品表 (product):商品ID、名称、分类、价格、库存、图片、商家ID、状态
  4. 商品分类表 (category):分类ID、名称、父ID、排序
  5. 购物车表 (cart):用户ID、商品ID、数量、添加时间
  6. 订单表 (order):订单号、用户ID、总金额、状态、地址、支付方式
  7. 订单详情表 (order_item):订单号、商品ID、数量、单价、小计
  8. 地址表 (address):地址ID、用户ID、收货人、电话、地址、是否默认
  9. 支付记录表 (payment):支付ID、订单号、金额、支付方式、状态、时间

关键SQL设计

-- 商品详情页查询(带库存和商家信息)
SELECT 
    p.id, p.name, p.price, p.stock, p.description,
    p.images, p.specifications,
    m.shop_name, m.shop_address, m.contact_info,
    c.category_name
FROM product p
LEFT JOIN merchant m ON p.merchant_id = m.id
LEFT JOIN category c ON p.category_id = c.id
WHERE p.id = #{productId} AND p.status = 1

-- 用户订单列表查询
SELECT 
    o.order_no, o.total_amount, o.status,
    o.create_time, o.pay_time, o.deliver_time,
    COUNT(oi.id) as item_count,
    GROUP_CONCAT(p.name) as product_names
FROM `order` o
LEFT JOIN order_item oi ON o.order_no = oi.order_no
LEFT JOIN product p ON oi.product_id = p.id
WHERE o.user_id = #{userId}
GROUP BY o.order_no
ORDER BY o.create_time DESC

状态流转设计

  • 订单状态:待支付 → 已支付 → 待发货 → 已发货 → 已收货 → 已完成 / 已取消
  • 商品状态:上架中 / 已下架 / 审核中
  • 支付状态:未支付 / 支付中 / 支付成功 / 支付失败
  • 商家状态:审核中 / 正常 / 冻结 / 注销

四、核心功能实现

1. 商品管理模块

// 商品服务层
@Service
@Slf4j
public class ProductService {
    
    @Autowired
    private ProductMapper productMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // 获取商品详情(带缓存)
    public ProductDetailVO getProductDetail(Long productId) {
        String cacheKey = "product:detail:" + productId;
        
        // 1. 尝试从缓存获取
        ProductDetailVO detail = (ProductDetailVO) redisTemplate.opsForValue().get(cacheKey);
        if (detail != null) {
            return detail;
        }
        
        // 2. 缓存未命中,查询数据库
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }
        
        // 3. 获取商家信息
        Merchant merchant = merchantMapper.selectById(product.getMerchantId());
        
        // 4. 组装VO
        detail = ProductDetailVO.builder()
                .product(product)
                .merchant(merchant)
                .build();
        
        // 5. 放入缓存,设置过期时间
        redisTemplate.opsForValue().set(cacheKey, detail, 30, TimeUnit.MINUTES);
        
        return detail;
    }
    
    // 扣减库存(使用乐观锁)
    @Transactional
    public boolean reduceStock(Long productId, Integer quantity) {
        // 使用乐观锁方式扣减库存
        int rows = productMapper.reduceStockWithOptimisticLock(productId, quantity);
        return rows > 0;
    }
}

2. 购物车模块

// 购物车服务
@Service
public class CartService {
    
    // 添加商品到购物车
    public void addToCart(Long userId, Long productId, Integer quantity) {
        // 1. 验证商品是否存在且上架
        Product product = productMapper.selectById(productId);
        if (product == null || product.getStatus() != 1) {
            throw new BusinessException("商品不存在或已下架");
        }
        
        // 2. 验证库存
        if (product.getStock() < quantity) {
            throw new BusinessException("库存不足");
        }
        
        // 3. 查询购物车中是否已存在该商品
        CartItem cartItem = cartMapper.selectByUserAndProduct(userId, productId);
        if (cartItem != null) {
            // 已存在,更新数量
            cartMapper.updateQuantity(cartItem.getId(), cartItem.getQuantity() + quantity);
        } else {
            // 不存在,新增
            cartItem = new CartItem();
            cartItem.setUserId(userId);
            cartItem.setProductId(productId);
            cartItem.setQuantity(quantity);
            cartItem.setCreateTime(new Date());
            cartMapper.insert(cartItem);
        }
    }
    
    // 获取购物车列表(带商品信息)
    public List<CartItemVO> getCartList(Long userId) {
        List<CartItem> cartItems = cartMapper.selectByUserId(userId);
        return cartItems.stream().map(item -> {
            Product product = productMapper.selectById(item.getProductId());
            return CartItemVO.builder()
                    .id(item.getId())
                    .product(product)
                    .quantity(item.getQuantity())
                    .selected(item.getSelected())
                    .build();
        }).collect(Collectors.toList());
    }
}

3. 订单模块(核心难点)

// 订单服务(分布式锁防止超卖)
@Service
@Slf4j
public class OrderService {
    
    @Autowired
    private RedissonClient redissonClient;
    
    @Transactional(rollbackFor = Exception.class)
    public String createOrder(Long userId, OrderCreateDTO createDTO) {
        String orderNo = generateOrderNo();
        
        // 使用分布式锁,防止重复下单和超卖
        RLock lock = redissonClient.getLock("order:create:" + userId);
        try {
            // 尝试获取锁,最多等待5秒,锁持有10秒
            boolean locked = lock.tryLock(5, 10, TimeUnit.SECONDS);
            if (!locked) {
                throw new BusinessException("操作频繁,请稍后重试");
            }
            
            try {
                // 1. 验证购物车商品
                List<CartItem> cartItems = validateCartItems(userId, createDTO.getCartItemIds());
                
                // 2. 计算总金额
                BigDecimal totalAmount = calculateTotalAmount(cartItems);
                
                // 3. 创建订单主表
                Order order = new Order();
                order.setOrderNo(orderNo);
                order.setUserId(userId);
                order.setTotalAmount(totalAmount);
                order.setStatus(OrderStatusEnum.PENDING_PAYMENT.getCode());
                order.setCreateTime(new Date());
                orderMapper.insert(order);
                
                // 4. 创建订单详情并扣减库存
                for (CartItem cartItem : cartItems) {
                    // 扣减库存(带重试机制)
                    boolean stockReduced = reduceStockWithRetry(cartItem.getProductId(), cartItem.getQuantity());
                    if (!stockReduced) {
                        throw new BusinessException("商品库存不足: " + cartItem.getProductId());
                    }
                    
                    // 创建订单详情
                    OrderItem orderItem = new OrderItem();
                    orderItem.setOrderNo(orderNo);
                    orderItem.setProductId(cartItem.getProductId());
                    orderItem.setQuantity(cartItem.getQuantity());
                    orderItem.setUnitPrice(getProductPrice(cartItem.getProductId()));
                    orderItem.setSubtotal(orderItem.getUnitPrice().multiply(new BigDecimal(cartItem.getQuantity())));
                    orderItemMapper.insert(orderItem);
                }
                
                // 5. 清空购物车
                cartMapper.deleteByIds(createDTO.getCartItemIds());
                
                return orderNo;
                
            } finally {
                lock.unlock();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new BusinessException("创建订单失败");
        }
    }
    
    // 扣减库存带重试
    private boolean reduceStockWithRetry(Long productId, Integer quantity) {
        int retryCount = 3;
        while (retryCount-- > 0) {
            try {
                return reduceStock(productId, quantity);
            } catch (Exception e) {
                log.warn("扣减库存失败,重试中: productId={}, retryCount={}", productId, retryCount);
                if (retryCount == 0) {
                    throw e;
                }
                try {
                    Thread.sleep(100); // 短暂等待后重试
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new BusinessException("操作中断");
                }
            }
        }
        return false;
    }
}

4. 支付模块

// 支付服务
@Service
public class PaymentService {
    
    @Autowired
    private OrderService orderService;
    
    // 支付订单
    @Transactional
    public boolean payOrder(String orderNo, PaymentMethod method) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (order.getStatus() != OrderStatusEnum.PENDING_PAYMENT.getCode()) {
            throw new BusinessException("订单状态异常");
        }
        
        // 模拟支付过程
        boolean paymentSuccess = mockPayment(order, method);
        
        if (paymentSuccess) {
            // 更新订单状态
            order.setStatus(OrderStatusEnum.PAID.getCode());
            order.setPayTime(new Date());
            order.setPaymentMethod(method.getCode());
            orderMapper.updateById(order);
            
            // 发送支付成功消息(异步通知商家)
            sendPaymentSuccessMessage(orderNo);
            
            return true;
        }
        
        return false;
    }
    
    // 订单状态查询
    public OrderStatusVO queryOrderStatus(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            return null;
        }
        
        return OrderStatusVO.builder()
                .orderNo(orderNo)
                .status(order.getStatus())
                .statusDesc(OrderStatusEnum.getByCode(order.getStatus()).getDesc())
                .createTime(order.getCreateTime())
                .payTime(order.getPayTime())
                .deliverTime(order.getDeliverTime())
                .receiveTime(order.getReceiveTime())
                .build();
    }
}

5. 接口设计

# 商品相关
GET    /api/products?page=1&size=10&category=1      # 商品列表
GET    /api/products/{id}                           # 商品详情
POST   /api/products/search                         # 商品搜索

# 购物车相关
GET    /api/cart                                    # 购物车列表
POST   /api/cart                                    # 添加商品
PUT    /api/cart/{id}                               # 更新数量
DELETE /api/cart/{id}                               # 删除商品

# 订单相关
POST   /api/orders                                  # 创建订单
GET    /api/orders                                  # 订单列表
GET    /api/orders/{orderNo}                        # 订单详情
POST   /api/orders/{orderNo}/pay                    # 支付订单
PUT    /api/orders/{orderNo}/cancel                 # 取消订单

# 支付相关
POST   /api/payment/callback                        # 支付回调
GET    /api/payment/status/{orderNo}                # 支付状态

# 用户相关
POST   /api/auth/login                              # 登录
POST   /api/auth/register                           # 注册
GET    /api/user/profile                            # 用户信息
PUT    /api/user/profile                            # 更新信息
GET    /api/user/addresses                          # 地址列表
POST   /api/user/addresses                          # 新增地址

五、页面设计与实现

1. 首页设计

  • 头部导航:搜索框、分类导航、用户入口
  • 轮播图:广告位和活动推广
  • 商品推荐:热门商品、新品上市、特价商品
  • 分类展示:按商品分类展示

2. 商品详情页

  • 商品图片:多图轮播、放大镜功能
  • 商品信息:名称、价格、规格、库存
  • 商家信息:店铺名、评分、联系方式
  • 购买操作:数量选择、加入购物车、立即购买
  • 商品详情:图文详情、规格参数、用户评价

3. 购物车页面

  • 商品列表:图片、名称、价格、数量、小计
  • 操作功能:选择/取消、修改数量、删除
  • 结算信息:商品总数、总金额、优惠信息
  • 结算按钮:跳转到订单确认页

4. 订单确认页

  • 收货地址:选择或新增地址
  • 商品清单:确认购买的商品和数量
  • 支付方式:微信、支付宝、余额支付
  • 订单信息:商品总价、运费、优惠、实付金额
  • 提交订单:生成订单,跳转到支付

5. 个人中心

  • 我的订单:全部、待支付、待发货、待收货、已完成
  • 我的收藏:收藏的商品列表
  • 收货地址:地址管理
  • 账户安全:密码修改、绑定手机 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

六、系统测试

核心测试场景

测试场景测试步骤预期结果测试重点
购物流程浏览→加购→下单→支付订单状态正确流转库存扣减、状态同步
并发下单多个用户同时购买同一商品库存正确扣减,无超卖分布式锁、事务
支付流程支付→回调→状态更新订单状态变为已支付支付状态一致性
取消订单用户取消待支付订单库存恢复,订单取消库存回滚机制

性能测试

  • 并发用户:模拟100用户同时购物
  • 响应时间:关键页面<2秒,API<500ms
  • 数据库压力:商品表10万条数据下查询性能
  • 缓存效果:对比使用Redis前后的性能差异

安全测试

  • SQL注入:输入特殊字符测试
  • XSS攻击:提交脚本代码测试
  • 越权访问:尝试访问他人订单
  • 重复提交:快速点击提交按钮

七、答辩准备要点

演示重点

  1. 完整购物流程:从浏览到支付的完整演示
  2. 并发场景演示:展示如何防止超卖
  3. 后台管理功能:商家和管理员操作演示
  4. 移动端适配:不同设备上的显示效果

技术亮点

  • 分布式锁防超卖:Redisson实现分布式锁
  • 缓存优化:Redis缓存热点数据
  • 事务一致性:Spring事务管理
  • 接口安全:JWT认证、参数校验
  • 异步处理:订单创建后的异步通知

常见问题准备

  • Q:如何防止商品超卖? A:数据库乐观锁 + Redis分布式锁 + 库存预扣

  • Q:如何保证支付安全? A:HTTPS传输 + 签名验证 + 回调验证 + 对账机制

  • Q:系统如何应对高并发? A:Nginx负载均衡 + Redis缓存 + 数据库读写分离 + 消息队列

  • Q:如何设计商品库存? A:真实库存 + 预扣库存 + 安全库存,不同场景使用不同库存字段

  • Q:订单号如何生成? A:时间戳 + 随机数 + 业务类型,保证全局唯一

项目价值体现

  • 用户体验:简洁的购物流程,快速的响应
  • 商家价值:完善的店铺管理工具
  • 管理效率:后台管理系统提高运营效率
  • 扩展性:模块化设计便于功能扩展
  • 安全性:多层次的安全防护机制

结语

网上购物系统是经典的毕业设计选题,技术覆盖面广,业务逻辑完整。重点需要解决的是高并发下的数据一致性完整的购物流程设计

开发建议顺序

  1. 先设计数据库表结构(特别是商品、订单、用户核心表)
  2. 实现用户认证和商品浏览基础功能
  3. 完成购物车和下单流程(重点解决库存问题)
  4. 集成支付功能(可先模拟支付)
  5. 实现后台管理功能
  6. 进行性能优化和安全加固
  7. 编写测试用例和文档

避坑提醒

  • 库存扣减一定要在事务中完成
  • 订单号生成要保证唯一性
  • 支付回调要验证签名
  • 敏感操作要记录日志
  • 前端要做好输入验证

若需要完整的网上购物系统源码、数据库设计、部署教程,可在评论区留言"网上购物系统"获取相关资料。

祝各位同学毕设顺利!🛒💰