毕业设计实战:基于Spring Boot的校园闲置物品交易网站全栈开发

72 阅读16分钟

一、项目背景:校园数字化时代的闲置资源革新

随着高校学生规模扩大与消费能力提升,校园内闲置物品堆积与资源浪费问题日益突出——据调研显示,2024年高校毕业生人均闲置物品超15件,其中80%仍具备使用价值,但传统线下交易模式存在“信息不对称、交易效率低、安全无保障”等痛点,难以满足学生便捷流转闲置资源的需求。

在“绿色校园”与“数字化生活”建设浪潮下,基于Spring Boot的校园闲置物品交易网站成为破解这一难题的核心方案。系统采用B/S架构,整合Java开发技术与MySQL数据库,实现闲置物品发布、查询、交易、订单管理全流程线上化,构建“管理员统筹监管-学生自主交易”的双向协同模式,为高校打造安全、高效、便捷的闲置资源流转平台,助力校园资源循环利用与数字化管理升级。

二、技术架构:校园闲置交易网站的全栈技术选型

项目以“稳定性、易用性、安全性”为核心设计理念,选用成熟的Java Web技术栈,确保系统适配校园场景下的多角色操作与高频交易需求:

技术模块具体工具/技术核心作用
后端框架Spring Boot 2.x简化配置开发,实现模块化业务逻辑,支持高并发交易处理与权限控制
开发语言Java + JSP实现动态网页渲染与后端业务逻辑开发,兼顾跨平台部署与用户交互体验
数据库MySQL 8.0存储用户信息、物品数据、订单记录、交易日志等核心业务数据
服务器Tomcat 9.0部署Web应用,处理物品发布、订单提交、支付对接等实时业务请求
前端技术HTML + CSS + JavaScript构建简洁直观的操作界面,实现物品展示、购物车管理、订单跟踪等交互功能
架构模式B/S结构支持跨终端访问,学生、管理员无需安装客户端,通过浏览器即可完成操作
开发工具Eclipse + NavicatEclipse实现代码编写与调试,Navicat进行数据库可视化管理与数据维护

三、项目全流程:6步完成校园闲置交易网站开发

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

针对校园闲置交易“信息分散、流程低效、安全无保障”三大痛点,系统聚焦“资源高效流转、交易安全可控、管理便捷透明”,核心需求分为功能性与非功能性两类:

3.1.1 功能性需求:双角色权限体系设计

系统覆盖管理员学生用户两大核心角色,功能边界清晰且协同紧密:

  1. 管理员:统筹平台管理,包括用户管理(账号审核/状态维护)、商品类型管理(分类新增/编辑)、商品信息管理(违规内容审核/下架)、订单管理(异常订单处理/交易跟踪)、系统管理(轮播图配置/资讯发布);
  2. 学生用户:专注闲置交易操作,包括前台功能(首页浏览、商品搜索、资讯查看、购物车管理)、后台功能(个人中心信息维护、商品发布/编辑/删除、我的收藏管理、订单查看/支付/取消)。

3.1.2 非功能性需求

  • 系统安全性:用户密码加盐哈希存储、交易信息加密传输、违规商品审核机制,保障用户信息与交易安全;
  • 响应效率:页面加载时间≤2秒,商品发布、订单提交等核心操作响应时间≤1秒,适配校园网环境;
  • 兼容性:支持Chrome、Edge、Firefox等主流浏览器,适配电脑、平板等终端,满足学生多场景使用需求;
  • 可扩展性:预留功能接口(如校园认证对接、支付接口集成),便于后期升级迭代;
  • 数据一致性:确保商品库存、订单状态、交易记录实时同步,避免数据错乱或丢失。

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

系统采用经典三层架构,实现表现层、业务逻辑层、数据访问层的解耦,确保双角色功能独立且数据协同:

3.2.1 系统总体架构

  1. 表现层(Web层)

    • 界面展示:基于JSP构建双角色专属界面,如用户端的商品详情页、购物车页面,管理员端的用户管理页、订单审核页;
    • 交互处理:通过JavaScript实现表单验证(如手机号格式校验、价格合理性判断)、动态数据加载(如商品分类筛选、订单状态实时更新)、弹窗提示(如交易成功通知),提升操作流畅度。
  2. 业务逻辑层(Service层)

    • 核心业务模块:商品服务(发布/审核/上下架)、订单服务(创建/支付/取消)、用户服务(注册/登录/信息维护)、收藏服务(添加/删除/查看);
    • 规则控制:商品审核规则(违规内容拦截)、订单状态流转规则(待支付→已支付→已完成/已取消)、库存同步规则(下单自动锁定库存,超时未支付释放)。
  3. 数据访问层(DAO层)

    • 数据持久化:通过MyBatis框架实现MySQL数据库的增删改查操作,简化SQL编写;
    • 事务管理:确保关键业务(如商品下单扣减库存、订单支付状态更新)的原子性,避免数据不一致。

3.2.2 核心数据库设计

系统设计多表关联结构,保障双角色业务数据的完整性与关联性,关键数据表如下:

表名核心字段作用
allusers(通用用户表)id(主键)、username(账号)、pwd(密码)、cx(角色类型)存储管理员与学生用户的登录账号信息
yonghu(学生用户表)id(主键)、addtime(创建时间)、yonghuming(用户名)、mima(密码)、xingming(姓名)、shouji(手机号)、youxiang(邮箱)、zhaopian(头像)存储学生用户详细信息
shangpinleixing(商品类型表)id(主键)、addtime(创建时间)、leixing(类型名称)存储闲置物品分类(如书籍、电子产品、生活用品)
shangpinxinxi(商品信息表)id(主键)、addtime(发布时间)、shangpinleixing(商品类型)、shangpinmingcheng(商品名称)、shangpintupian(商品图片)、shangpinxiangqing(商品详情)、jiage(价格)存储闲置物品详细信息
orders(订单表)id(主键)、addtime(下单时间)、dingdanbianhao(订单编号)、shangpinmingcheng(商品名称)、shuliang(数量)、zongjia(总价)、yonghuming(购买用户)、zhuangtai(订单状态)存储交易订单信息

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

基于Spring Boot框架实现系统后端核心业务逻辑,重点解决“商品管理”“订单交易”“收藏管理”三大核心场景:

3.3.1 商品管理功能实现(发布-审核-展示)

@RestController
@RequestMapping("/api/goods")
public class GoodsController {

    @Autowired
    private GoodsService goodsService;

    /**
     * 学生用户发布闲置商品
     */
    @PostMapping("/publish")
    public ResponseEntity<?> publishGoods(@RequestBody GoodsPublishDTO publishDTO, HttpSession session) {
        try {
            // 1. 获取当前登录用户
            String username = (String) session.getAttribute("username");
            if (username == null) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("请先登录");
            }

            // 2. 构建商品信息
            Goods goods = new Goods();
            goods.setShangpinleixing(publishDTO.getShangpinleixing());
            goods.setShangpinmingcheng(publishDTO.getShangpinmingcheng());
            goods.setShangpintupian(publishDTO.getShangpintupian()); // 图片URL存储
            goods.setShangpinxiangqing(publishDTO.getShangpinxiangqing());
            goods.setJiage(publishDTO.getJiage());
            goods.setFaburen(username);
            goods.setZhuangtai("待审核"); // 初始状态:待管理员审核
            goods.setAddtime(new Date());

            // 3. 保存商品信息
            goodsService.saveGoods(goods);
            return ResponseEntity.ok("商品发布成功,等待管理员审核");

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("商品发布失败,请重试");
        }
    }

    /**
     * 管理员审核商品
     */
    @PostMapping("/admin/audit")
    public ResponseEntity<?> auditGoods(@RequestBody GoodsAuditDTO auditDTO, HttpSession session) {
        try {
            // 1. 验证管理员权限
            String role = (String) session.getAttribute("role");
            if (!"管理员".equals(role)) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN).body("无审核权限");
            }

            // 2. 查询商品信息
            Goods goods = goodsService.getGoodsById(auditDTO.getGoodsId());
            if (goods == null) {
                return ResponseEntity.badRequest().body("商品不存在");
            }

            // 3. 更新审核状态
            goods.setZhuangtai(auditDTO.getStatus()); // 通过/驳回
            goods.setShenheyuanyin(auditDTO.getReason()); // 驳回时填写原因
            goodsService.updateGoods(goods);

            return ResponseEntity.ok("商品审核完成,状态:" + auditDTO.getStatus());

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("审核操作失败,请重试");
        }
    }

    /**
     * 前台查询商品列表(支持分类、关键词筛选)
     */
    @GetMapping("/list")
    public ResponseEntity<?> getGoodsList(
            @RequestParam(required = false) String type,
            @RequestParam(required = false) String keyword,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "12") int size) {
        try {
            // 构建查询条件(仅查询审核通过的商品)
            GoodsQuery query = new GoodsQuery();
            query.setShangpinleixing(type);
            query.setKeyword(keyword);
            query.setZhuangtai("已通过");
            query.setPage(page);
            query.setSize(size);

            // 分页查询商品
            PageResult<Goods> result = goodsService.getGoodsList(query);
            return ResponseEntity.ok(result);

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("获取商品列表失败,请重试");
        }
    }
}

3.3.2 订单交易功能实现(下单-支付-取消)

@Service
@Transactional
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    /**
     * 创建订单(下单)
     */
    public Order createOrder(OrderCreateDTO createDTO, String username) {
        // 1. 验证商品状态(是否存在且已通过审核)
        Goods goods = goodsMapper.selectById(createDTO.getGoodsId());
        if (goods == null) {
            throw new RuntimeException("商品不存在");
        }
        if (!"已通过".equals(goods.getZhuangtai())) {
            throw new RuntimeException("商品未通过审核,无法购买");
        }

        // 2. 生成订单编号(时间戳+随机数)
        String orderNo = generateOrderNo();

        // 3. 构建订单信息
        Order order = new Order();
        order.setDingdanbianhao(orderNo);
        order.setShangpinmingcheng(goods.getShangpinmingcheng());
        order.setShangpintupian(goods.getShangpintupian());
        order.setShuliang(createDTO.getShuliang());
        order.setJiage(goods.getJiage());
        order.setZongjia(new BigDecimal(goods.getJiage()).multiply(new BigDecimal(createDTO.getShuliang())));
        order.setYonghuming(username);
        order.setShouhuodizhi(createDTO.getShouhuodizhi());
        order.setLianxidianhua(createDTO.getLianxidianhua());
        order.setZhuangtai("待支付");
        order.setAddtime(new Date());

        // 4. 保存订单(事务控制:确保订单创建成功)
        orderMapper.insert(order);
        return order;
    }

    /**
     * 订单支付(更新状态)
     */
    public void payOrder(String orderNo) {
        // 1. 查询订单
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        if (!"待支付".equals(order.getZhuangtai())) {
            throw new RuntimeException("订单状态异常,无法支付");
        }

        // 2. 更新订单状态为“已支付”
        order.setZhuangtai("已支付");
        order.setZhifushijian(new Date());
        orderMapper.update(order);

        // 3. (可选)更新商品状态为“已售出”,避免重复购买
        Goods goods = goodsMapper.selectByGoodsName(order.getShangpinmingcheng());
        if (goods != null) {
            goods.setZhuangtai("已售出");
            goodsMapper.update(goods);
        }
    }

    /**
     * 取消订单(释放商品)
     */
    public void cancelOrder(String orderNo, String username) {
        // 1. 查询订单并验证归属
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        if (!username.equals(order.getYonghuming())) {
            throw new RuntimeException("无权限取消此订单");
        }
        if (!"待支付".equals(order.getZhuangtai())) {
            throw new RuntimeException("订单状态异常,无法取消");
        }

        // 2. 更新订单状态为“已取消”
        order.setZhuangtai("已取消");
        order.setQuxiaoshijian(new Date());
        orderMapper.update(order);

        // 3. 释放商品(恢复为“已通过”状态,允许重新购买)
        Goods goods = goodsMapper.selectByGoodsName(order.getShangpinmingcheng());
        if (goods != null) {
            goods.setZhuangtai("已通过");
            goodsMapper.update(goods);
        }
    }

    /**
     * 生成唯一订单编号
     */
    private String generateOrderNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeStr = sdf.format(new Date());
        Random random = new Random();
        int randomNum = random.nextInt(9000) + 1000; // 4位随机数
        return "ORDER" + timeStr + randomNum;
    }
}

3.3.3 收藏管理功能实现(添加-删除-查看)

@RestController
@RequestMapping("/api/collection")
public class CollectionController {

    @Autowired
    private CollectionService collectionService;

    /**
     * 添加商品到收藏
     */
    @PostMapping("/add")
    public ResponseEntity<?> addCollection(@RequestBody CollectionAddDTO addDTO, HttpSession session) {
        try {
            String username = (String) session.getAttribute("username");
            if (username == null) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("请先登录");
            }

            // 验证是否已收藏
            boolean isCollected = collectionService.checkCollection(username, addDTO.getGoodsId());
            if (isCollected) {
                return ResponseEntity.badRequest().body("该商品已在您的收藏夹中");
            }

            // 添加收藏
            collectionService.addCollection(username, addDTO.getGoodsId(), addDTO.getGoodsName());
            return ResponseEntity.ok("收藏成功");

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("收藏失败,请重试");
        }
    }

    /**
     * 取消收藏
     */
    @PostMapping("/remove")
    public ResponseEntity<?> removeCollection(@RequestParam Long collectionId, HttpSession session) {
        try {
            String username = (String) session.getAttribute("username");
            if (username == null) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("请先登录");
            }

            // 验证收藏归属
            Collection collection = collectionService.getCollectionById(collectionId);
            if (!username.equals(collection.getYonghuming())) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN).body("无权限取消此收藏");
            }

            // 取消收藏
            collectionService.removeCollection(collectionId);
            return ResponseEntity.ok("取消收藏成功");

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("取消收藏失败,请重试");
        }
    }

    /**
     * 查看个人收藏列表
     */
    @GetMapping("/myList")
    public ResponseEntity<?> getMyCollectionList(HttpSession session) {
        try {
            String username = (String) session.getAttribute("username");
            if (username == null) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("请先登录");
            }

            List<CollectionVO> collectionList = collectionService.getCollectionByUsername(username);
            return ResponseEntity.ok(collectionList);

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("获取收藏列表失败,请重试");
        }
    }
}

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

基于JSP + HTML + CSS构建适配管理员、学生用户双角色的前端界面,聚焦“操作便捷性”与“信息清晰度”,核心界面模块如下:

3.4.1 学生用户界面

  1. 前台首页:展示轮播图(校园交易公告)、热门商品推荐(带图片/价格/发布人)、商品分类导航(书籍、电子产品、生活用品等)、搜索框(按名称/类型筛选);
  2. 商品详情页:显示商品名称、价格、详情描述、发布人信息,支持“加入购物车”“立即购买”“收藏”操作,底部展示同类商品推荐;
  3. 个人中心:包含信息维护(修改密码、手机号、邮箱)、我的商品(发布/编辑/下架闲置物品)、我的订单(查看待支付/已支付/已取消订单,支持支付、取消操作)、我的收藏(查看/取消收藏);
  4. 购物车页面:展示已添加商品,支持修改数量、删除商品、批量结算,结算时跳转至收货地址填写页。

3.4.2 管理员界面

  1. 登录界面:输入账号、密码、选择角色(管理员),支持“记住密码”,登录失败提示“账号或密码错误”;
  2. 后台首页:系统概览(用户总数、商品总数、待审核商品数、今日订单数)、快捷操作入口(商品审核、订单管理);
  3. 用户管理页:列表展示学生用户账号信息(用户名、姓名、手机号、注册时间),支持“禁用/启用”账号、查看详情;
  4. 商品管理页:分“待审核”“已通过”“已驳回”“已售出”标签页,支持审核商品(通过/驳回,填写驳回理由)、删除违规商品;
  5. 订单管理页:列表展示所有订单(订单编号、商品名称、购买用户、总价、状态),支持查看详情、处理异常订单(如退款申请)。

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

3.5 第五步:系统测试——确保交易流程稳定

通过多维度测试验证系统功能完整性、安全性与稳定性,覆盖校园闲置交易全流程场景:

3.5.1 功能测试

设计针对性测试用例,验证双角色核心功能是否符合需求:

测试场景预期结果实际结果是否通过
学生发布商品提交后状态为“待审核”,管理员可查看并审核符合预期,审核状态同步实时
管理员审核商品通过后商品在前台展示;驳回后学生收到驳回理由审核逻辑准确,状态更新及时
学生下单支付下单后商品锁定,支付成功后订单状态变为“已支付”,商品标记“已售出”交易流程闭环完整,数据同步无偏差
学生取消订单待支付订单可取消,取消后商品恢复“已通过”状态,允许重新购买库存释放准确,订单状态更新正常
收藏商品操作重复收藏提示“已收藏”,取消收藏后从列表移除收藏逻辑无漏洞,操作反馈清晰

3.5.2 非功能测试

  • 安全性测试:尝试越权访问(学生查看管理员后台、修改他人订单),均被权限拦截;抓包验证用户密码传输加密,商品审核机制可拦截违规内容(如违禁品);
  • 响应速度测试:页面加载平均时间1.5秒,商品发布、订单提交响应时间≤0.8秒,适配校园网低带宽环境;
  • 兼容性测试:在Chrome、Edge、Firefox浏览器及平板端访问,界面适配正常,功能操作无异常;
  • 并发测试:模拟50名学生同时浏览商品、10名学生同时下单,系统无卡顿,订单数据无重复或丢失。

3.6 第六步:问题排查与优化——提升用户体验

开发过程中针对校园交易场景关键问题制定优化方案,确保系统适配实际需求:

  1. 问题1:商品图片上传失败或显示异常

    • 原因:初始未限制图片格式与大小,大文件上传超时,格式不兼容导致显示错误;
    • 解决方案:添加图片校验(仅支持JPG/PNG格式,大小≤5MB),使用图片压缩工具压缩上传文件,前端预览功能确认上传效果,图片上传成功率提升至99%。
  2. 问题2:学生下单后长时间未支付,商品一直锁定

    • 原因:无订单超时机制,导致商品长期锁定,影响其他用户购买;
    • 解决方案:添加“订单超时自动取消”功能,待支付订单超过30分钟未支付,系统自动取消并恢复商品状态为“已通过”,同时发送消息提醒用户。
  3. 问题3:商品搜索结果不准确,筛选效率低

    • 原因:初始仅支持精确匹配搜索,未建立索引,大量商品时查询缓慢;
    • 解决方案:优化搜索逻辑,支持模糊匹配(如输入“英语”可匹配“英语四级真题”“英语词典”),在商品名称、类型字段建立数据库索引,搜索响应时间从2秒降至0.5秒。

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

4.1 开发过程中的技术挑战

  1. 权限控制精度:需严格区分管理员与学生用户功能边界,避免学生越权操作(如修改他人订单、审核商品),通过Spring拦截器实现角色校验,确保权限无漏洞;
  2. 数据一致性保障:订单创建与商品状态更新、取消订单与商品库存释放需原子性执行,通过Spring事务管理避免单边操作成功导致的数据错乱;
  3. 用户体验细节:校园场景下学生更关注交易便捷性与安全性,需简化操作流程(如一键发布商品、免密支付选项),同时增加交易双方联系方式隐藏(如仅显示部分手机号),保护隐私。

4.2 给后续开发者的建议

  1. 优先实现核心流程:先完成“商品发布-审核-下单-支付”核心链路,再扩展附加功能(如校园认证、评价系统),避免前期功能冗余导致开发周期延长;
  2. 强化安全防护:增加校园邮箱注册验证(确保用户为在校学生)、交易纠纷调解模块(管理员介入处理退款、货不对板问题),提升平台公信力;
  3. 优化移动端适配:当前系统以PC端为主,后续可开发响应式页面或微信小程序,支持学生在手机端便捷发布、购买闲置物品,适配校园移动使用场景;
  4. 增加社交属性:添加“校园圈子”模块,允许学生发布闲置交易需求、分享交易经验,提升平台活跃度与用户粘性。

五、项目资源与发展展望

5.1 项目核心资源

本项目提供完整开发资料,便于后续学习与二次开发:

  • 源码资源:完整的Spring Boot后端代码、JSP前端页面代码(含HTML/CSS/JavaScript);
  • 数据库资源:MySQL建表语句、初始化测试数据(含管理员账号、示例商品/订单数据);
  • 文档资源:需求分析文档、系统设计文档(含ER图、架构图)、测试报告、部署指南(含Tomcat配置步骤);
  • 工具资源:数据库连接工具类、权限拦截器、图片上传工具类。

5.2 系统扩展方向

  1. 校园认证对接:集成高校统一身份认证系统(如校园一卡通账号登录),确保用户均为在校师生,杜绝校外人员违规交易;
  2. 评价与信誉体系:交易完成后,买卖双方可互相评价(评分+文字),生成用户信誉等级,高信誉用户获得优先展示权益,降低交易风险;
  3. 闲置捐赠模块:增加“公益捐赠”功能,学生可将闲置物品捐赠给校园公益组织,平台生成捐赠证书,助力校园公益;
  4. 数据统计分析:新增管理员数据看板,展示商品分类占比、交易高峰时段、热门商品类型,为校园资源管理提供数据支持。

如果本文对您的Spring Boot学习、校园闲置交易网站相关毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多校园管理类系统项目实战案例!