毕业设计实战:基于SpringBoot的电子产品销售系统设计与实现全攻略

0 阅读13分钟

毕业设计实战:基于SpringBoot的电子产品销售系统设计与实现全攻略

在开发“基于SpringBoot的电子产品销售系统”毕业设计时,曾因“订单状态与库存管理脱节”踩过关键坑——初期未设计清晰的订单状态机和会员价联动机制,导致用户下单后库存未及时扣减、会员与非会员价格计算混乱、订单支付超时后库存未回滚,耗费4天重构订单管理模块、引入会员价机制和订单超时自动取消功能才解决问题📝。基于此次实战经验,本文精简拆解核心开发流程,附避坑要点与实操细节,为同类毕设提供可落地的实施参考。

一、需求分析:聚焦商品+订单双核心,避免功能冗余

部分同学易陷入“功能堆砌”误区,比如我曾耗时3天开发“电子产品参数对比”模块,最终因偏离“商品管理、购物车、订单处理、会员价”核心需求被导师要求删减。明确“商品发布→用户浏览→加入购物车→下单支付→库存扣减→会员价优惠”的业务闭环,是降低返工率的关键。

1. 核心角色与功能(精简版)

角色核心功能
管理员用户管理、产品类别管理、电子产品管理、留言板管理、订单管理、系统管理(通知公告、在线客服、轮播图)
用户注册登录、电子产品浏览/搜索/收藏/评论、购物车管理、下单支付、订单查询、在线客服、个人中心

2. 需求避坑要点

  • 拒绝空想调研:邀请15名电子产品爱好者和5名商家模拟“用户浏览商品→加入购物车→会员价结算→下单支付→库存扣减→订单跟踪”完整流程,基于“用户需要知道会员优惠和订单状态”需求,增设“会员价标识”和“订单状态跟踪”模块,实用性远大于冗余的“参数对比”;
  • 明确约束条件:提前规定“产品编号自动生成(格式:DZ+年月日+序号)”“会员价默认-1表示无会员价”“下单时扣减库存,支付失败自动回滚”“订单状态包括未支付、已支付、已发货、已完成、已取消”,为系统实现提供明确依据。

二、技术选型:稳定框架+会员价联动,新手可上手

前期曾尝试引入Redis缓存商品库存,因数据一致性难保证且学习成本高,调试耗时3天。最终确定“成熟框架+数据库事务”组合:

技术工具选型理由避坑提醒
Spring Boot 2.x + MyBatis-Plus快速开发,简化配置,高效实现CRUD和业务逻辑,声明式事务管理方便事务注解@Transactional记得在Service层添加;下单和库存扣减必须加事务
Vue 2.x + ElementUI组件丰富,快速构建前后台界面,表格和表单组件好用订单状态用标签展示;会员价用金色标识
MySQL 5.7存储用户、商品、订单、购物车等核心业务数据金额字段用Decimal类型;事务要保证订单和库存一致性
Thymeleaf(可选)服务端模板引擎,适合快速开发后台管理界面毕设时间充裕可统一用Vue

三、数据库设计:业务关联清晰,支撑商品-订单-会员闭环

数据库设计直接影响后续开发效率。前期因未设计“会员价字段”和“订单状态流转机制”,导致会员与非会员价格混乱、订单取消后库存未回滚。

1. 核心表结构(精选12张表)

  • 管理员表(users):id、username、password(MD5加密)、role、addtime;
  • 用户表(yonghu):id、zhanghao(账号)、mima(密码)、xingming(姓名)、nianling(年龄)、xingbie(性别)、shouji(手机)、youxiang(邮箱)、touxiang(头像)、money(余额)、vip(是否会员)、addtime;
  • 产品类别表(chanpinleibie):id、chanpinleibie(产品类别)、addtime;
  • 电子产品表(dianzichanpin):id、chanpinbianhao(产品编号)、chanpinmingcheng(产品名称)、chanpinleibie(产品类别)、pinpai(品牌)、guige(规格)、fengmian(封面)、shangjiariqi(上架日期)、chanpinjieshao(产品介绍)、onelimittimes(单限)、alllimittimes(库存)、thumbsupnum(赞)、crazilynum(踩)、clicktime、clicknum、price(价格)、vipprice(会员价)、addtime;
  • 购物车表(cart):id、tablename(商品表名)、userid(用户id)、goodid(商品id)、goodname(商品名称)、picture(图片)、buynumber(购买数量)、price(单价)、discountprice(会员价)、addtime;
  • 订单表(orders):id、orderid(订单编号)、tablename(商品表名)、userid(用户id)、goodid(商品id)、goodname(商品名称)、picture(图片)、buynumber(购买数量)、price(价格)、total(总价格)、type(支付类型)、status(订单状态)、address(地址)、tel(电话)、consignee(收货人)、remark(备注)、logistics(物流)、addtime;
  • 地址表(address):id、userid(用户id)、address(地址)、name(收货人)、phone(电话)、isdefault(是否默认地址)、addtime;
  • 收藏表(shoucang):id、userid、refid、tablename、name、picture、type(收藏类型)、addtime;
  • 留言板表(liuyanban):id、userid、username、avatarurl、content、cpicture、reply、rpicture、addtime;
  • 在线客服表(zaixiankefu):id、userid、adminid、ask(提问)、reply(回复)、isreply(是否回复)、addtime;
  • 通知公告表(tongzhigonggao):id、title、introduction、picture、content、addtime;
  • token表(token):id、userid、username、tablename、role、token、addtime、expiratedtime。

2. 关键业务SQL示例

示例SQL(查询用户订单及商品会员价):

-- 查询用户的订单记录,包含商品会员价信息
SELECT 
    o.*,
    d.price as normal_price,
    d.vipprice as vip_price,
    CASE WHEN u.vip = '是' THEN d.vipprice ELSE d.price END as actual_price
FROM orders o
LEFT JOIN dianzichanpin d ON o.goodid = d.id
LEFT JOIN yonghu u ON o.userid = u.id
WHERE o.userid = #{userId}
ORDER BY o.addtime DESC

关键避坑:会员价字段默认-1表示无会员价;下单时根据用户会员状态计算实际价格;订单超时需自动取消并回滚库存。

四、核心功能实现:8大模块满足答辩需求

无需复杂功能,优先完成以下8个核心模块,其中会员价计算与库存联动是答辩重点。

1. 用户管理(基础模块)

  • 核心逻辑:用户注册登录、个人信息维护、余额管理、会员状态管理;
  • 页面设计:注册登录界面;个人中心显示头像、姓名、余额、会员标识;
  • 代码要点(用户注册与会员判断):
public void addYonghu(Yonghu user) {
    // 校验账号是否重复
    LambdaQueryWrapper<Yonghu> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Yonghu::getZhanghao, user.getZhanghao());
    if (yonghuMapper.selectCount(wrapper) > 0) {
        throw new RuntimeException("账号已存在");
    }
    user.setMoney(0f);
    user.setVip("否");
    user.setAddtime(new Date());
    yonghuMapper.insert(user);
}

// 判断用户是否为会员
public boolean isVip(Long userId) {
    Yonghu user = yonghuMapper.selectById(userId);
    return "是".equals(user.getVip());
}

2. 电子产品管理(核心资源模块)

  • 核心逻辑:管理员发布商品(名称、类别、品牌、规格、价格、会员价、库存)→用户浏览、搜索、收藏、评论;
  • 页面设计:商品卡片式展示,显示名称、图片、价格、会员价(金色标识)、库存;详情页展示完整信息;
  • 代码要点(商品发布与库存管理):
@Transactional
public void addDianzichanpin(Dianzichanpin product) {
    // 生成商品编号
    String bianhao = "DZ" + new SimpleDateFormat("yyyyMMdd").format(new Date()) 
                     + String.format("%04d", new Random().nextInt(10000));
    product.setChanpinbianhao(bianhao);
    product.setThumbsupnum(0);
    product.setCrazilynum(0);
    product.setClicknum(0);
    product.setAddtime(new Date());
    dianzichanpinMapper.insert(product);
    
    log.info("管理员发布了商品:{}", product.getChanpinmingcheng());
}

// 库存扣减
public void reduceStock(Long productId, int quantity) {
    Dianzichanpin product = dianzichanpinMapper.selectById(productId);
    if (product.getAlllimittimes() < quantity) {
        throw new RuntimeException("库存不足");
    }
    product.setAlllimittimes(product.getAlllimittimes() - quantity);
    dianzichanpinMapper.updateById(product);
}

// 库存回滚(订单取消时)
public void rollbackStock(Long productId, int quantity) {
    Dianzichanpin product = dianzichanpinMapper.selectById(productId);
    product.setAlllimittimes(product.getAlllimittimes() + quantity);
    dianzichanpinMapper.updateById(product);
}

3. 购物车管理(交易准备模块)

  • 核心逻辑:用户将商品加入购物车→根据会员状态显示会员价→修改数量;
  • 页面设计:购物车列表显示商品名称、图片、单价(会员价标识)、数量、总价;
  • 代码要点(购物车添加与价格计算):
public void addCart(Cart cart, Long userId) {
    // 校验是否已存在
    LambdaQueryWrapper<Cart> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Cart::getGoodid, cart.getGoodid())
           .eq(Cart::getUserid, userId);
    Cart existCart = cartMapper.selectOne(wrapper);
    
    // 获取商品价格(根据会员状态)
    Dianzichanpin product = dianzichanpinMapper.selectById(cart.getGoodid());
    boolean isVip = isVip(userId);
    float actualPrice = getActualPrice(product, isVip);
    
    cart.setPrice(actualPrice);
    cart.setDiscountprice(isVip ? product.getVipprice() : -1f);
    
    if (existCart != null) {
        existCart.setBuynumber(existCart.getBuynumber() + cart.getBuynumber());
        cartMapper.updateById(existCart);
    } else {
        cart.setUserid(userId);
        cart.setAddtime(new Date());
        cartMapper.insert(cart);
    }
}

// 获取实际价格(会员价或原价)
private float getActualPrice(Dianzichanpin product, boolean isVip) {
    if (isVip && product.getVipprice() != null && product.getVipprice() > 0) {
        return product.getVipprice();
    }
    return product.getPrice();
}

4. 订单管理(核心业务流程)

  • 核心逻辑:用户确认下单→创建订单→扣减库存→支付→发货→确认收货;
  • 页面设计:订单列表显示订单编号、商品名称、数量、总价、状态;支持支付、取消、确认收货;
  • 代码要点(订单创建与会员价联动):
@Transactional
public Orders createOrder(Long userId, List<Cart> cartItems, Address address) {
    // 1. 生成订单编号
    String orderId = "DD" + System.currentTimeMillis();
    Orders mainOrder = null;
    
    // 2. 获取用户会员状态
    boolean isVip = isVip(userId);
    
    for (Cart cart : cartItems) {
        // 3. 获取商品及价格
        Dianzichanpin product = dianzichanpinMapper.selectById(cart.getGoodid());
        float actualPrice = getActualPrice(product, isVip);
        
        // 4. 校验库存
        if (product.getAlllimittimes() < cart.getBuynumber()) {
            throw new RuntimeException("商品 " + product.getChanpinmingcheng() + " 库存不足");
        }
        
        // 5. 创建订单项
        Orders order = new Orders();
        order.setOrderid(orderId);
        order.setUserid(userId);
        order.setGoodid(cart.getGoodid());
        order.setGoodname(cart.getGoodname());
        order.setPicture(cart.getPicture());
        order.setBuynumber(cart.getBuynumber());
        order.setPrice(actualPrice);
        order.setTotal(actualPrice * cart.getBuynumber());
        order.setStatus("未支付");
        order.setAddress(address.getAddress());
        order.setTel(address.getPhone());
        order.setConsignee(address.getName());
        order.setAddtime(new Date());
        ordersMapper.insert(order);
        
        // 6. 扣减库存
        reduceStock(cart.getGoodid(), cart.getBuynumber());
        
        // 7. 删除购物车记录
        cartMapper.deleteById(cart.getId());
        
        if (mainOrder == null) mainOrder = order;
    }
    
    // 8. 设置订单超时自动取消(定时任务)
    scheduleOrderTimeout(orderId);
    
    log.info("用户 {} 创建订单 {}", userId, orderId);
    return mainOrder;
}

// 订单支付
@Transactional
public void payOrder(String orderId) {
    // 更新订单状态
    LambdaUpdateWrapper<Orders> wrapper = new LambdaUpdateWrapper<>();
    wrapper.eq(Orders::getOrderid, orderId)
           .eq(Orders::getStatus, "未支付")
           .set(Orders::getStatus, "已支付");
    int updated = ordersMapper.update(null, wrapper);
    
    if (updated == 0) {
        throw new RuntimeException("订单状态异常,请刷新后重试");
    }
    
    log.info("订单 {} 支付成功", orderId);
}

// 订单取消(超时或用户主动取消)
@Transactional
public void cancelOrder(String orderId) {
    // 1. 查询订单项
    List<Orders> orderList = ordersMapper.selectList(
        new LambdaQueryWrapper<Orders>().eq(Orders::getOrderid, orderId)
    );
    
    // 2. 回滚库存
    for (Orders order : orderList) {
        if ("已支付".equals(order.getStatus())) {
            rollbackStock(order.getGoodid(), order.getBuynumber());
        }
    }
    
    // 3. 更新订单状态
    LambdaUpdateWrapper<Orders> wrapper = new LambdaUpdateWrapper<>();
    wrapper.eq(Orders::getOrderid, orderId)
           .in(Orders::getStatus, "未支付", "已支付")
           .set(Orders::getStatus, "已取消");
    ordersMapper.update(null, wrapper);
    
    log.info("订单 {} 已取消", orderId);
}

5. 订单超时自动取消(定时任务)

@Component
public class OrderTimeoutTask {
    
    @Scheduled(cron = "0 */5 * * * ?") // 每5分钟执行一次
    @Transactional
    public void cancelTimeoutOrders() {
        // 查询超过30分钟未支付的订单
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -30);
        Date timeout = calendar.getTime();
        
        List<Orders> timeoutOrders = ordersMapper.selectList(
            new LambdaQueryWrapper<Orders>()
                .eq(Orders::getStatus, "未支付")
                .lt(Orders::getAddtime, timeout)
                .groupBy(Orders::getOrderid)
        );
        
        Set<String> orderIds = timeoutOrders.stream()
            .map(Orders::getOrderid)
            .collect(Collectors.toSet());
        
        for (String orderId : orderIds) {
            cancelOrder(orderId);
            log.info("订单 {} 超时自动取消", orderId);
        }
    }
}

6. 地址管理(收货模块)

  • 核心逻辑:用户维护收货地址(收货人、电话、地址),支持设置默认地址;
  • 页面设计:地址列表显示收货人、电话、地址、默认标识;支持增删改查;
  • 代码要点:设置默认地址时取消其他默认地址。

7. 留言板/在线客服(互动模块)

  • 核心逻辑:用户留言反馈/在线咨询→管理员回复;
  • 页面设计:留言板显示留言内容、图片、回复;在线咨询支持问答;
  • 代码要点:支持留言图片上传;客服回复状态跟踪。

五、电子产品销售特色功能设计(关键加分项)

电子产品销售系统的核心在于“商品-购物车-订单-库存全流程联动+会员价优惠”,以下是实测有效的设计方案:

1. 商品-购物车-订单全流程追溯

环节记录内容可追溯信息
商品发布商品编号、名称、类别、品牌、价格、会员价、库存什么商品、多少钱、会员价多少
购物车商品名称、数量、单价(会员价标识)、总价加了什么、加了多少
订单创建订单编号、商品信息、收货地址、订单状态什么时候买的、发到哪、什么状态
库存扣减商品ID、扣减数量、剩余库存扣了多少、还剩多少
订单支付支付时间、支付金额付了多少钱、什么时候付的

2. 会员价计算机制

// 会员价计算工具类
public class PriceCalculator {
    
    // 获取商品实际价格
    public static float getActualPrice(Dianzichanpin product, boolean isVip) {
        if (isVip && product.getVipprice() != null && product.getVipprice() > 0) {
            return product.getVipprice();
        }
        return product.getPrice();
    }
    
    // 计算订单总价(批量)
    public static float calculateTotal(List<Cart> cartItems, boolean isVip) {
        float total = 0;
        for (Cart item : cartItems) {
            Dianzichanpin product = getProduct(item.getGoodid());
            float price = getActualPrice(product, isVip);
            total += price * item.getBuynumber();
        }
        return total;
    }
}

3. 库存预警机制

// 定时任务:检查库存低于阈值的商品
@Component
public class StockAlertTask {
    
    @Scheduled(cron = "0 0 9 * * ?") // 每天上午9点执行
    public void checkStock() {
        List<Dianzichanpin> list = dianzichanpinMapper.selectList(null);
        for (Dianzichanpin product : list) {
            if (product.getAlllimittimes() <= 5) {
                log.warn("商品 {} 库存不足,当前库存:{}", 
                    product.getChanpinmingcheng(), product.getAlllimittimes());
                // 可发送通知给管理员
            }
        }
    }
}

4. 热门商品推荐

-- 基于销量、收藏量、点击量推荐热门商品
SELECT 
    d.*,
    COUNT(DISTINCT o.id) as order_count,
    COUNT(DISTINCT s.id) as collect_count,
    (COUNT(DISTINCT o.id) * 0.5 + COUNT(DISTINCT s.id) * 0.3 + d.clicknum * 0.2) as hot_score
FROM dianzichanpin d
LEFT JOIN orders o ON d.id = o.goodid AND o.status = '已完成'
LEFT JOIN shoucang s ON d.id = s.refid AND s.type = '1'
GROUP BY d.id
ORDER BY hot_score DESC
LIMIT 10

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

六、测试与答辩:流程演示为主,突出电商购物闭环

1. 核心测试用例

测试场景操作步骤预期结果
商品发布全流程管理员发布商品(含会员价)→用户查看商品信息正确显示;会员价金色标识
会员价测试会员用户与非会员用户查看同一商品会员看到会员价,非会员看到原价
购物车流程用户添加商品到购物车→价格计算购物车显示正确价格(会员价/原价)
下单支付流程用户下单→支付→库存扣减订单生成;库存减少;订单状态更新
订单取消流程用户取消订单→库存回滚订单状态更新为已取消;库存恢复
超时自动取消订单30分钟未支付订单自动取消;库存回滚

2. 答辩准备技巧

  • 演示流程:分角色演示(管理员端 + 用户端)→ 管理员发布电子产品(设置会员价)→ 用户A注册为普通用户 → 用户B注册为会员 → 对比查看商品价格差异 → 用户B将商品加入购物车 → 用户B下单 → 支付 → 库存扣减 → 管理员发货 → 用户B确认收货 → 订单完成 → 展示完整的商品-购物车-订单-库存-会员价管理闭环;
  • 业务讲解:准备一页PPT展示系统功能结构图(图4-2),说明每个模块的作用和角色定位;
  • 技术亮点:重点讲解会员价计算机制、下单与库存扣减的事务一致性、订单超时自动取消;
  • 突出问题解决:讲清“如何保证会员与非会员价格正确”(根据用户会员状态动态计算)、“如何保证库存不超卖”(下单时扣减库存+事务)、“订单超时如何自动取消”(定时任务+状态检测);提前预判“为什么要设计会员价字段”,回答“吸引会员用户,提高用户粘性和复购率”。

结语

本文核心是“聚焦商品-订单-会员核心业务、实现电商购物闭环、设计完整的电子产品销售系统”。毕设无需复杂系统,把商品管理+购物车+订单管理+会员价的业务逻辑讲透、实现一个可运行的电子产品销售系统、展示完整的购物闭环,即可成为答辩亮点。

若需完整项目源码(带详细注释)、测试数据SQL脚本、订单超时取消完整代码,可在评论区留言“SpringBoot电子产品销售系统”获取;开发中遇问题(如事务一致性、会员价计算、库存并发控制),也可留言咨询~ 祝毕设顺利!🎉