SpringBoot+Vue实现校园二手系统。前后端分离技术【完整功能介绍+实现详情+源码】

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 文章介绍了如何使用SpringBoot和Vue实现一个校园二手系统,采用前后端分离技术。系统具备完整的功能,包括客户端和管理员端的界面设计、个人信息管理、商品浏览和交易、订单处理、公告发布等。技术栈包括Vue框架、ElementUI、SpringBoot、Mybatis-plus和Redis。文章还提供了部分源代码,展示了前后端的请求接口和Redis验证码功能实现,以及系统重构和模块化设计的一些思考。

前言

全部源代码地址传送门

文章内容有点长,建议打开右侧目录导航栏查看。

   **这个系统基本上可以改造为其它类似的系统。后台管理基本上一致。前台进行一些页面样式的改造就可以变成一个新的系统。有时间,做几个变体系统。**

   闲的无聊,把大学时候做的一个系统进行了重构。将项目拆分成完全前后端分离的形式。客户端采用一套、商家端采用一套。后端只负责接口数据的处理(当然也可以只用一套)。对其中的一些页面进行了重新组织和美化。个人信息管理和后台商品信息添加、公告发布等模块做的比较好看一点。我直接仿照CSDN的个人信息管理界面进行的设计,包括头像的上修改。还有商品信息的展示,然后点击某一个商品进行商品详情的查看。公告的上传等等。使用到蛮多新的小技术。说实话,我还是不太满意,vue中的大部分代码有重复的,好想给他全部改成组件的形式。但是由于工作忙,现就这样了。

资料(源代码)

部分源代码在博客的最后给出

   把一个系统拆分成了几个练习使用。我还可以进一步将其改造为分布式微服务系统。其实不难。有时间在改造一下。有需要源码的可以加我联系方式,博客最下方有我的联系方式

在这里插入图片描述

技术栈

前端主要使用:Vue框架、组件使用ElementUI
后端主要使用:SpringBoot框架、Mybatis-plus、Redis等。

提示:主要说大的方面,小的技术点不在赘述

功能划分

1.1 客户端

客户端主要实现的功能划分
在这里插入图片描述

1.2 管理员

管理员方面主要负责的功能划分
在这里插入图片描述

顾客+游客(页面效果展示)

   游客可以免登录浏览商品信息,公告信息;但是不能查看个人信息,订单、购物车等信息。等用户注册登录系统后。这些信息可以看到

一、个人信息

1.1 信息展示

在这里插入图片描述

1.2 修改头像

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

1.3 修改信息

   直接在个人资料修改用户信息,点击保存就行了。还可以进行模拟充值  

在这里插入图片描述

1.4 充值

在这里插入图片描述

1.5 修改密码

在这里插入图片描述

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

1.6 修改手机号

   邮箱和手机号采用数据脱敏的形式,隐藏部分数据。这里修改手机号和邮箱类似,这里使用redis模拟发送验证码,同时保留三分钟的过期时间。在redis中很容易实现。还可以通过接入支付宝,购买他的那个验证码接口次数。可以实现真正的发送验证码到手机。我博客也有写过。这里不在赘述。

在这里插入图片描述

   这里的redis我是直接装在了虚拟机中,采用docker安装redis是真的很方便。

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

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

1.7 修改邮箱

同修改手机号

二、 商品首页

1.1 首页

   首页采用轮播图的形式,这个图片是我随机找的。可以换成校园二手商城类似的。然后商品展示不同的分类对应不同的商品。

在这里插入图片描述

1.2 商品分类

   这里的分类数据我使用的同一个分类下的数据,这个只需要插入一些其它的测试数据就行了。大致思想就是,sql语句查询携带分类信息。查询的数据在对应的内容区域遍历出来。

在这里插入图片描述

1.3 商品详情页面

   这里的详情就是在首页通过点击某一个商品,然后跳转到新的页面。这个新页面根据跳转商品id查询数据库,然后展示出来。这里可以进行购买,或者进行加入购物车等操作。

在这里插入图片描述

二、 购物车

1.1 查看购物车商品

   购物车中的商品进行购买后,会自动删除在购物车中保留的商品信息。你也可以选择不删除,目前是只能进行单个商品的结算。有时间做一下一个订单进行多个商品的结算

在这里插入图片描述

1.2 购买

   购买的时候,会出现收获地址。和商品的一信息。

在这里插入图片描述

1.3 删除购物车商品

在这里插入图片描述

三、 订单

1.1 查看订单

在这里插入图片描述

1.2 查看订单状态

   在进行付款后,可以查看订单的信息状态。这里提示,订单状态使用int类型的数字替代,展示到前台的时候替换成对应的文字就可以

在这里插入图片描述

四、 公告

   公告这里点击左侧的公告列表,右侧的内容会替换对应公告内容。  

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

五、登录(顾客)

   说实话、这个登录页面有点丑。但是我不想换了。我还有其它不同的登录页面。懒得换了  

在这里插入图片描述

六、注册页面

在这里插入图片描述

管理员(页面效果展示)

提示:后台管理,基本上就是一些表格。增删改查

一、查看数据

   这个就是用到了echart,我也写过怎样使用。这个数据可以替换来自数据库中实际的数据  

在这里插入图片描述

二、管理用户信息

1.1 查看用户信息

在这里插入图片描述

1.2 修改用户信息

   一般来说是不允许修改的。这里为了练习使用。就修改吧。实在不想修改,就把操作中的修改按钮屏蔽掉。  

在这里插入图片描述

1.3 删除用户信息

在这里插入图片描述

1.4 添加用户信息

   按照常理,这里是不应该有的这个添加用户操作。为了练习弹窗的功能。就写出来了。你也可以屏蔽掉  

在这里插入图片描述

三、商品种类

   这里新添加相同的商品种类,会提示错误信息。不能重复添加相同商品种类。不在演示。

1.1 添加商品种类

在这里插入图片描述

1.2 修改商品信息

在这里插入图片描述

1.3 删除商品信息

二次提示删除操作

在这里插入图片描述

四、商品详情

1.1 查看商品详情

在这里插入图片描述

对应商品图片浏览

在这里插入图片描述

1.2 添加商品

   这里的商品图片上传,是和表格数据一块提交到后台保存的数据库的。大致流程,首先点击图片上传,选择图片。然后先发一个接口到后端。将图片复制到其它位置。返回前端保存该图片的位置。然后再次将表格内容和图片地址一块发送给后端。将数据放入数据库。要访问图片,只需要根据图片地址访问就可以。减少数据库存储的呢内容。  

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

此时前台可以看到商品的商品
在这里插入图片描述

如果将商品上架情况改为未上架
在这里插入图片描述
前台不展示
在这里插入图片描述

1.3 修改商品

   点击修改商品信息。这里图片的修改,只需要重新上传一个图片就可以。相当于换了一个图片保存的地址。弊端,没有将之前的图片删除。可以优化,但是目前先不搞

在这里插入图片描述

修改后,预览修改后的图片,修改成功。

在这里插入图片描述

1.4 删除商品

其实也就是二次提示确认
在这里插入图片描述

五、订单信息

1.1 查看订单

   这里管理员可以看到商品的发货情况,然后根据订单情况,选择操作。  

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

1.2 发货

在这里插入图片描述

六、公告信息

1.1 查看公告

在这里插入图片描述

1.2 添加公告

   这里通过vue集成Quill可以实现编辑框的样式

在这里插入图片描述
添加公告
在这里插入图片描述

前台查看公告

   这个时间排序可以调整,查询数据的时候,按照注册的时间顺序就可以。  

在这里插入图片描述

1.3 修改公告

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

1.4 删除公告

也是进行二次确认删除

在这里插入图片描述

在这里插入图片描述

删除成功。
在这里插入图片描述

七、登录界面

在这里插入图片描述

部分源码

1、前端

1.1 项目结构

在这里插入图片描述

1.2 部分源码

一些接口数据请求


//用户调用的一些接口

import { Get, Post, Put, MyPut, Patch, Delete } from "@/api/request";

export default {

    //注销
    logout: (params) => {
        return Get('http://localhost:8282/user/logout', params)
    },
    //登录
    Login: (params) => {
        return Get('http://localhost:8282/user/userLogin', params)
    },
    //判断是否登录
    isLogin: (params) => {
        return Get('http://localhost:8282/user/isLogin', params)
    },
    //注册
    Register: (params) => {
        return Post('http://localhost:8282/user/register', params)
    },

    findAllGoodsInfo: (params) => {
        return Get('http://localhost:8282/goodsInfo/getInfo', params)
    },

    findGoodsDetail: (params) => {
        return Get('http://localhost:8282/goodsInfo/GoodsDetail', params)
    },

    /**
     * 购物车 addCartShopInfo
     */
    addCartShopInfo: (params) => {
        return Post('http://localhost:8282/cartshop/add', params)
    },

    queryCartShopInfo: (params) => {
        return Get('http://localhost:8282/cartshop/find', params)
    },

    deleteCartShopInfo: (params) => {
        return Delete('http://localhost:8282/cartshop/delete', params)
    },

    /**
     * 订单
     */

    addOrder: (params) => {
        return Post('http://localhost:8282/order/add', params)
    },
    queryOrder: (params) => {
        return Get('http://localhost:8282/order/findAll', params)
    },

    onPaymoney: (params) => {
        return Put('http://localhost:8282/order/paymoney', params)
    },

    onRefund: (params) => {
        return Put('http://localhost:8282/order/refund', params)
    },

    onCancelRefund: (params) => {
        return Put('http://localhost:8282/order/cancelRefund', params)
    },

    onReturnable: (params) => {
        return Put('http://localhost:8282/order/onReturnable', params)
    },

    onCancelReturnable: (params) => {
        return Put('http://localhost:8282/order/onCancelReturnable', params)
    },

    /**
     * 用户信息
     */
    updateFaceImage: (params) => {
        return Put('http://localhost:8282/user/updateFaceImage', params)
    },

    rechargeMoney: (params) => {
        return Put('http://localhost:8282/user/rechargeMoney', params)
    },
    findUserById: (params) => {
        return Get('http://localhost:8282/user/findUserById', params)
    },

    onChangePWD: (params) => {
        return Put('http://localhost:8282/user/changePwd', params)
    },

    UpdateUserInfo: (params) => {
        return Put('http://localhost:8282/user/updateUserInfo', params)
    },


    //获取验证码
    GetCode: (params) => {
        return Get('http://localhost:8282/user/getCode', params)
    },

    //验证验证码
    VerifyCode: (params) => {
        return Get('http://localhost:8282/user/verifyCode', params)
    },

    //修改手机号
    UpdatePhone: (params) => {
        return Put('http://localhost:8282/user/updatePhone', params)
    },

    /**
     * 公告
     */
    findAllAnnounceInfo: (params) => {
        return Get('http://localhost:8282/announce/findAllAnnounceInfo', params)
    },

}

//管理员
import { Get, Post, Put, MyPut, Patch, Delete } from "@/api/request";

export default {
    getListData: (params) => {
        return Get('../../static/data.json', params);
    },
    postListData: (params) => {
        return Post('../../static/data.json', params);
    },
    deleteListData: (params) => {
        return Delete('../../static/data.json', params);
    },
    Register: (params) => {
        return Post('http://localhost:8282/user/register', params)
    },
    adminRegister: (params) => {
        return Post('http://localhost:8282/admin/register', params)
    },
    Login: (params) => {
        return Post('http://localhost:8282/user/login', params)
    },

    findAllUser: (params) => {
        return Get('http://localhost:8282/user/findAllUser', params)
    },

    findAllAdmin: (params) => {
        return Get('http://localhost:8282/admin/findAllUser', params)
    },
    submitUpdateAdminForm: (params) => {
        return Put('http://localhost:8282/admin/updateUserInfo', params)
    },

    handleAdminDelete: (params) => {
        return Delete('http://localhost:8282/admin/deleteUser/', params)
    },

    submitUpdateUserForm: (params) => {
        return Put('http://localhost:8282/user/updateUserInfo', params)
    },

    handleDelete: (params) => {
        return Delete('http://localhost:8282/user/deleteUser/', params)
    },

    /**
     * 商品种类
     */
    addTypeInfo: (params) => {
        return Post('http://localhost:8282/typeInfo/addTypeInfo', params)
    },
    findAllTypeInfo: (params) => {
        return Get('http://localhost:8282/typeInfo/findAllTypeInfo', params)
    },
    handleDeleteTypeInfo: (params) => {
        return Delete('http://localhost:8282/typeInfo/deleteTypeInfo', params)
    },
    submitUpdateUserForm: (params) => {
        return Put('http://localhost:8282/typeInfo/updateTypeInfo', params)
    },

    /**
     * 商品详情
     */
    getTypeInfoOption: (params) => {
        return Get('http://localhost:8282/goodsInfo/getTypeInfo', params)
    },

    addGoodsInfo: (params) => {
        return Post('http://localhost:8282/goodsInfo/addGoodsInfo', params)
    },
    handleDeleteGoodsInfo: (params) => {
        return Delete('http://localhost:8282/goodsInfo/deleteGoodsInfo', params)
    },
    updateGoodsInfo: (params) => {
        return Put('http://localhost:8282/goodsInfo/updateGoodsInfo', params)
    },

    findAllGoodsInfo: (params) => {
        return Get('http://localhost:8282/goodsInfo/findAllGoodsInfo', params)
    },
    updateSaleStatus: (params) => {
        return Put('http://localhost:8282/goodsInfo/updateSaleStatus',params)
    },

    /**
     * 文件上传
     */
    uploadFile: (params) => {
        return Post('http://localhost:8282/goodsInfo/upload', params);
    },

    /**
     * 订单
     */
    findAllOrder: (params) => {
        return Get('http://localhost:8282/order/findAllOrderInfo', params)
    },

    onShipments: (params) => {
        return Put('http://localhost:8282/order/shipments', params)
    },

    /**
     * 公告
     */
    findAllAnnounceInfo: (params) => {
        return Get('http://localhost:8282/announce/findAllAnnounceInfo', params)
    },

    addAnnounceInfo: (params) => {
        return Post('http://localhost:8282/announce/addAnnounceInfo', params)
    },

    handleDeleteAnnounceInfo: (params) => {
        return Delete('http://localhost:8282/announce/deleteAnnounceInfo', params)
    },

    submitUpdateAnnounce: (params) => {
        return Put('http://localhost:8282/announce/updateAnnounceInfo', params)
    },

}

2、后端

1.1 项目结构

在这里插入图片描述

1.2 部分源码

这个是redis关于验证码的部分代码


/**
 * @author zyz
 * @version 1.0
 * @data 2022/12/5 14:18
 * @Description:
 */
@RestController
public class RedisController {

    @Autowired
    private RedisTemplate redisTemplate;

    //六位数验证码
    public static String getRandom() {
        Random random = new Random();
        String code = "";
        for (int i = 0; i < 6; i++) {
            int rand = random.nextInt(10);
            code += rand;
        }
        return code;

    }

    /**
     * 发送手机号、获取验证码
     *
     * @return
     */
    @RequestMapping(value = "/user/getCode", method = RequestMethod.GET)
    public Result getVerifyCode(@RequestParam Map<String, Object> maps) {
        String phone = (String) maps.get("phone");
        //手机发送次数key
        String countKey = "verifyCode" + phone + "count";
        //验证码key
        String codeKey = "verifyCode" + phone + "code";
        //每个手机1小时发送三次
        Integer count = (Integer) redisTemplate.opsForValue().get(countKey);

        if (count == null) {
            //第一次发送
            redisTemplate.opsForValue().set(countKey, 1, 60 * 60, TimeUnit.SECONDS);
            System.out.println("第几次发送:" + count);

        } else if (count <= 2) {
            Integer nums = ++count;
            redisTemplate.opsForValue().set(countKey, nums,  60 * 60, TimeUnit.SECONDS);
            System.out.println("第几次发送:" + count);

        } else {
            System.out.println("请一个小时后再次尝试");
            return Result.error().data("errMessage", "请一个小时后再次尝试");
        }
        //发送验证码到redis中
        String vcode = getRandom();
        System.out.println("生成的验证码是:" + vcode);
        redisTemplate.opsForValue().set(codeKey, vcode, 120, TimeUnit.SECONDS);
        return Result.ok().data("vcode", vcode);

    }

    /**
     * 验证验证码
     *
     * @return
     */
    @RequestMapping(value = "/user/verifyCode", method = RequestMethod.GET)
    public Result verifyCode(@RequestParam Map<String, Object> maps) {
        String phone = (String) maps.get("phone");
        String code = (String) maps.get("code");
        //验证码的key
        String codeKey = "verifyCode" + phone + "code";
        String redisCode = (String) redisTemplate.opsForValue().get(codeKey);

        //判断
        if (redisCode.equals(code)) {
            return Result.ok();
        } else {
            return Result.error();
        }

    }

    @GetMapping(value = "/getName")
    public String testRedis() {
        //设置值到redis
        redisTemplate.opsForValue().set("name", "lucy");
        //从redis获取值
        String name = (String) redisTemplate.opsForValue().get("name");
        return name;
    }
}

后语

做系统是学习提升最快的方式了

相关文章
|
11天前
|
前端开发 安全 Java
基于springboot+vue开发的会议预约管理系统
一个完整的会议预约管理系统,包含前端用户界面、管理后台和后端API服务。 ### 后端 - **框架**: Spring Boot 2.7.18 - **数据库**: MySQL 5.6+ - **ORM**: MyBatis Plus 3.5.3.1 - **安全**: Spring Security + JWT - **Java版本**: Java 11 ### 前端 - **框架**: Vue 3.3.4 - **UI组件**: Element Plus 2.3.8 - **构建工具**: Vite 4.4.5 - **状态管理**: Pinia 2.1.6 - **HTTP客户端
97 4
基于springboot+vue开发的会议预约管理系统
|
4月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
446 1
|
1月前
|
前端开发 JavaScript Java
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
本系统基于SpringBoot与Vue3开发,实现校园食堂评价功能。前台支持用户注册登录、食堂浏览、菜品查看及评价发布;后台提供食堂、菜品与评价管理模块,支持权限控制与数据维护。技术栈涵盖SpringBoot、MyBatisPlus、Vue3、ElementUI等,适配响应式布局,提供完整源码与数据库脚本,可直接运行部署。
85 0
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
|
2月前
|
Java 数据库连接 API
Java 8 + 特性及 Spring Boot 与 Hibernate 等最新技术的实操内容详解
本内容涵盖Java 8+核心语法、Spring Boot与Hibernate实操,按考试考点分类整理,含技术详解与代码示例,助力掌握最新Java技术与应用。
107 2
|
3月前
|
监控 数据可视化 JavaScript
springboot + vue的MES系统生产计划管理源码
MES系统(制造执行系统)的生产计划管理功能是其核心模块之一,涵盖生产计划制定与优化、调度排程、进度监控反馈、资源管理调配及可视化报告五大方面。系统基于SpringBoot + Vue-Element-Plus-Admin技术栈开发,支持多端应用(App、小程序、H5、后台)。通过实时数据采集与分析,MES助力企业优化生产流程,适用于现代化智能制造场景。
159 1
|
4月前
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。
647 10
|
3月前
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
264 0
|
前端开发 JavaScript Java
SpringBoot实现国际化i18n功能
SpringBoot实现国际化i18n功能
1208 0
SpringBoot实现国际化i18n功能
|
5月前
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
420 7
|
4月前
|
供应链 JavaScript BI
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发
这是一款专为小微企业打造的 SaaS ERP 管理系统,基于 SpringBoot+Vue+ElementUI+UniAPP 技术栈开发,帮助企业轻松上云。系统覆盖进销存、采购、销售、生产、财务、品质、OA 办公及 CRM 等核心功能,业务流程清晰且操作简便。支持二次开发与商用,提供自定义界面、审批流配置及灵活报表设计,助力企业高效管理与数字化转型。
451 2
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发