基于Springboot+Vue实现前后端分离商城管理系统
项目编号:BS-SC-030
一,项目简介
新新商城,一款基于 Springboot+Vue 的电商项目,前后端分离项目。完整的实现了一个商城系统应有的基本功能,包括但不限于以下主要功能模块:
前端商城用户
- 用户注册登陆
- 商品信息分类和品牌浏览
- 全文搜索
- 添加购物车管理
- 在线购买商品:使用支付宝沙箱在线支付
- 个人信息管理
- 个人订单管理
- 在线退换货功能
- 退款功能
后台用户管理功能
- 商品分类管理
- 商品品牌管理
- 商品规格管理
- 商品采购管理
- 供应商管理
- 订单管理
- 退货退款管理
- 轮播图设置管理
- 用户管理
- 权限角色管理
- 个人信息管理
项目后台基于Springboot+MybatisPlus开发实现,前端使用VUE+Element开发实现,前后端分离开发,前端通过调用后台接口来进行相应的交互处理。
亮点技术:短信发送验证码、阿里云OSS云存储商品图片、邮箱自动发邮件验证操作权限,Shiro权限管理,数据加密处理,支付宝沙箱技术应用,Redis数据缓存处理。
项目功能完整,界面优雅大方,人机交互流畅,是一个难得的毕业设计作品。
二,环境介绍
语言环境:Java: jdk1.8
数据库:Mysql: mysql5.7 Redis:5.0.10
应用服务器:Tomcat: tomcat8.5.31
开发工具:IDEA或eclipse
技术应用:
后端技术
技术 |
说明 |
官网 |
SpringBoot |
容器+MVC框架 |
https://spring.io/projects/spring-boot |
Shiro |
认证和授权框架 |
Apache Shiro Simple. Java. Security. |
MyBatis |
ORM框架 |
http://www.mybatis.org/mybatis-3/zh/index.html |
MySQL |
数据库 |
https://www.mysql.com/ |
Redis |
分布式缓存 |
https://redis.io/ |
Druid |
数据库连接池 |
https://github.com/alibaba/druid |
前端技术
技术 |
说明 |
官网 |
Vue |
前端框架 |
https://vuejs.org/ |
Vue-router |
路由框架 |
https://router.vuejs.org/ |
Vuex |
全局状态管理框架 |
https://vuex.vuejs.org/ |
Element |
前端UI框架 |
https://element.eleme.io |
Axios |
前端HTTP框架 |
https://github.com/axios/axios |
vue-clipboard2 |
将内容复制到剪贴板 |
https://github.com/Inndy/vue-clipboard2 |
vuex-persistedstate |
vuex持久化 |
https://www.npmjs.com/package/vuex-persistedstate |
nprogress |
进度条控件 |
https://github.com/rstacruz/nprogress |
开发环境
工具 |
版本号 |
下载 |
JDK |
1.8 |
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html |
Mysql |
5.7 |
https://www.mysql.com/ |
Redis |
5.0.10 |
https://redis.io/download |
第三方技术
工具 |
官网 |
支付宝沙箱技术 |
沙箱环境 | 开放平台 |
OSS 存储 |
阿里云-为了无法计算的价值 |
阿里云短信服务 |
阿里云-为了无法计算的价值 |
QQ邮箱服务 |
登录QQ邮箱 |
三,系统展示
下面展示一下项目的主要核心功能:
前端用户操作
用户注册:会对邮箱发验证码验证,要求必须真实有效邮箱
用户登陆
首页
商品购买
购物车
结算付款
我的订单:可以申请退款、收货后可以申请退货等操作
后台管理用户功能
后台首页
商品管理:可以实现商品添加、编辑、删除、下架、查询等,另可以对商品分类、品牌、规则、采购信息进行管理,以及对供应商进行管理,不再一一展示。菜单上的功能都是齐全的。
订单管理:可以进行发货、退货、退款等相关操作
营销管理
主要对前端展示的广告轮播图进行管理
用户和权限管理:可以对管理员、顾客、角色进行管理操作
四,核心代码展示
package com.qiu.controller;import com.qiu.entity.Banner;
import com.qiu.service.BannerService;
import com.qiu.util.general.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** @author ZNZ* @email 469603589@qq.com* @date 2022/12/31 16:23* @description 商品类别*/
@CrossOrigin
@RestController
public class BannerController {@Autowiredprivate BannerService bannerService;@RequestMapping(value = "/banner/add")public CommonResult addBanner(Banner banner) {if (bannerService.insertData(banner)) {return CommonResult.success("商品轮播图添加成功", banner);}return CommonResult.error("商品轮播图添加失败");}@RequestMapping(value = "/banner/update")public CommonResult updateType(Banner banner) {if (bannerService.updateById(banner)) {return CommonResult.success("商品轮播图修改成功", banner);}return CommonResult.error("商品轮播图修改失败");}@RequestMapping(value = "/banner/deleteById")public CommonResult deleteTypeById(Integer bannerId) {if (bannerService.deleteById(bannerId)) {return CommonResult.success("商品轮播图删除成功", "bannerId: " + bannerId);}return CommonResult.error("商品轮播图删除失败");}@RequestMapping(value = "/banner/findAll")public CommonResult findAllType() {List<Banner> banners = bannerService.selectAll();if (banners != null) {return CommonResult.success("商品轮播图查询成功", banners);}return CommonResult.error("商品轮播图查询失败");}@RequestMapping(value = "/banner/findById")public CommonResult findById(Integer bannerId) {Banner banner = bannerService.selectById(bannerId);if (banner != null) {return CommonResult.success("商品轮播图查询成功", banner);}return CommonResult.error("商品轮播图查询失败");}
}
package com.qiu.controller;import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import com.qiu.constant.UserStatusEnum;
import com.qiu.entity.Role;
import com.qiu.entity.User;
import com.qiu.service.RoleService;
import com.qiu.service.UserService;
import com.qiu.util.general.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;/*** @author ZNZ* @email 469603589@qq.com* @date 2022/12/6 17:10* @description 登录、退出、修改个人信息等业务操作*/
@Slf4j
@CrossOrigin
@RestController
public class OperateController {private static final String EMAIL_FLAG = "@";@Autowiredprivate RoleService roleService;@Autowiredprivate UserService userService;/*** 登录操作** @param username 用户登录的账号* @param password 用户登录的密码*/@RequestMapping(value = "/login", produces = {"application/json;charset=UTF-8"})public CommonResult doLogin(String username, String password) {User user;if (username.contains(EMAIL_FLAG)) {//包含@符号,代表用户通过邮箱账号登录user = userService.selectByKey(username);} else {//不包含@符号,代表用户通过手机号登录user = userService.selectByPhone(username);}if (user == null) {return CommonResult.error("账号不存在");}String encodePassword = SaSecureUtil.md5BySalt(password, user.getAccountNumber());if (!encodePassword.equals(user.getPassword())) {return CommonResult.error("用户名或密码错误");}// 账号被锁定if (!user.getUserState()) {StpUtil.disable(user.getUserId(), -1);}StpUtil.login(user.getUserId());//更新最后登录时间user.setLoginTime(new Date());userService.updateById(user);//存放用户信息Map<String, Object> info = new HashMap<>(4);info.put("user", user);//存放sessionId, 即 tokeninfo.put("sessionId", StpUtil.getTokenInfo().getTokenValue());List<Role> roles = userService.getRoleList(user.getUserId());Set<String> roseNames = roles.stream().map(Role::getRoleName).collect(Collectors.toSet());Set<String> roseDescribes = roles.stream().map(Role::getRoleDescribe).collect(Collectors.toSet());info.put("role", roseNames);info.put("roleInfo", roseDescribes);return CommonResult.success("登录成功", info);}/*** 注销登录*/@RequestMapping(value = "/logout")public CommonResult logout() {StpUtil.logout();return CommonResult.success("注销成功");}/*** 判断key是否存在 目前用于判断邮箱是否被注册过** @param email 邮箱号(账号)*/@RequestMapping(value = "/allow/existUser")public CommonResult existUser(String email) {Boolean isExist = userService.existsWithPrimaryKey(email);if (isExist != null) {return CommonResult.success("查询成功", isExist);}return CommonResult.error("查询失败");}/*** 判断手机号phone是否存在 目前被用于绑定手机号时,确认手机号已被绑定** @param telephone 手机号*/@RequestMapping(value = "/allow/existPhone")public CommonResult existPhone(String telephone) {Boolean isExist = userService.existsWithPrimaryPhone(telephone);if (isExist != null) {return CommonResult.success("手机号查询成功", isExist);}return CommonResult.error("手机号查询失败");}/*** 重置密码、找回密码** @param account 账号* @param password 密码*/@RequestMapping(value = "/allow/resetpwd")public CommonResult resetPwd(String account, String password) {if (account != null && password != null) {String encodePassword = SaSecureUtil.md5BySalt(password, account);Integer id = userService.selectIdByKey(account);User user = new User();user.setUserId(id);user.setPassword(encodePassword);if (userService.updateById(user)) {return CommonResult.success("重置密码成功", user);}return CommonResult.error("重置密码失败");}return CommonResult.error("用户数据不存在");}/*** 注册新用户** @param user 用户信息*/@RequestMapping(value = "/allow/add")public CommonResult add(User user) {if (user.getPassword() != null && user.getUserName() != null) {String encodePassword = SaSecureUtil.md5BySalt(user.getPassword(), user.getAccountNumber());user.setPassword(encodePassword);user.setUserState(true);user.setStatus(UserStatusEnum.CUSTOMER);if (userService.insertData(user)) {log.info("用户添加成功,用户信息:{}", user);return CommonResult.success("注册成功", user);} else {return CommonResult.error("注册失败");}}return CommonResult.error("用户数据不存在");}/*** 更新用户信息** @param user 用户信息*/@RequestMapping(value = "/allow/update")public CommonResult update(User user) {if (user.getUserState() != null && user.getUserState()) {StpUtil.untieDisable(user.getUserId());}if (userService.updateById(user)) {return CommonResult.success("信息保存成功", user);}return CommonResult.error("信息保存失败");}
}
package com.qiu.controller;import com.alibaba.fastjson.JSON;
import com.qiu.entity.Logistics;
import com.qiu.entity.Order;
import com.qiu.entity.Product;
import com.qiu.service.LogisticsService;
import com.qiu.service.OrderService;
import com.qiu.service.ProductService;
import com.qiu.util.general.CommonResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;/*** @author ZNZ* @email 469603589@qq.com* @date 2022/12/28 18:11* @description 订单相关业务*/@RestController
@CrossOrigin
public class OrderController {private static final String VIP = "Vip";private static final String COLLECT_GOODS_STATE = "已收货";@Autowiredprivate OrderService orderService;@Autowiredprivate ProductService productService;@Autowiredprivate LogisticsService logisticsService;@Autowiredprivate RedisTemplate<String, String> redisTemplate;@RequestMapping(value = "/order/findById")public CommonResult findOrderById(Integer orderId) {Order order = orderService.selectById(orderId);if (orderId != null) {return CommonResult.success("订单信息查询成功", order);}return CommonResult.error("订单信息查询失败");}@RequestMapping(value = "/order/findOrderInfo")public CommonResult findOrderInfo(String userAccount) {List<Map<String, Object>> orderMap = orderService.selectAllOrder(userAccount);if (orderMap != null) {return CommonResult.success("订单信息查询成功", orderMap);}return CommonResult.error("订单信息查询失败");}@RequestMapping(value = "/order/findAll")public CommonResult findAllOrder() {List<Order> orders = orderService.selectAll();if (orders != null) {return CommonResult.success("订单信息查询成功", orders);}return CommonResult.error("订单信息查询失败");}@RequestMapping(value = "/order/findCount")public CommonResult findCount() {Integer count = orderService.selectCount();if (count != null) {return CommonResult.success("订单数量查询成功", count);}return CommonResult.error("订单数量查询失败");}@RequestMapping(value = "/order/add")public CommonResult addOrder(Order order) {if (order != null) {if (order.getProductNo().contains(VIP)) {return handleMemberOrders(order);}return handleMerchandiseOrders(order);} else {return CommonResult.error("订单数据不完整");}}@RequestMapping(value = "/order/cartOrder")public CommonResult cartOrder(String orderNo, String ordersInfo, String cartIds) {List<String> cartIdList = JSON.parseArray(cartIds, String.class);List<Order> orders = JSON.parseArray(ordersInfo, Order.class);if (orders != null) {ArrayList<String> orderInfo = new ArrayList<>();ArrayList<String> productInfo = new ArrayList<>();for (Order order : orders) {Product product = productService.selectByKey(order.getProductNo());Integer productStock = product.getProductStock();Integer payAmount = order.getPayAmount();if (productStock >= payAmount) {Product newProduct = new Product();newProduct.setProductId(product.getProductId());int newStock = productStock - payAmount;newProduct.setProductStock(newStock);newProduct.setIsStockOut(newStock < product.getLowestStock());// 如果库存小于等于0,自动下架newProduct.setIsSale(newStock > 0);if (productService.updateById(newProduct) && orderService.insertData(order)) {orderInfo.add(order.getOrderNo());productInfo.add(order.getProductNo());}}}if (!orderInfo.isEmpty()) {String cartIdsInfo = StringUtils.join(cartIdList.toArray(), ",");String orderNoInfo = StringUtils.join(orderInfo, ",");String productNoInfo = StringUtils.join(productInfo, ",");redisTemplate.opsForValue().set(orderNo, orderNoInfo, 24, TimeUnit.HOURS);redisTemplate.opsForValue().set("cartId" + orderNo, cartIdsInfo, 24, TimeUnit.HOURS);return CommonResult.success("创建订单成功", productNoInfo);}return CommonResult.error("创建订单失败,请查看商品库存是否满足购买数量");} else {return CommonResult.error("订单数据不完整");}}@RequestMapping(value = "/order/update")public CommonResult updateOrder(Order order) {if (orderService.updateById(order)) {return CommonResult.success("修改订单成功", order);}return CommonResult.error("修改订单失败");}@RequestMapping(value = "/order/delete")public CommonResult deleteOrder(Integer orderId) {if (orderService.deleteById(orderId)) {return CommonResult.success("删除订单成功", "订单id:" + orderId);}return CommonResult.error("删除订单失败");}@RequestMapping(value = "/order/receipt")public CommonResult updateOrder(Integer orderId) {Order order = new Order();order.setOrderId(orderId);order.setOrderState(COLLECT_GOODS_STATE);if (orderService.updateById(order)) {return CommonResult.success("商品收货成功", order);}return CommonResult.error("商品收货失败");}@RequestMapping(value = "/orderDetail/orderInfo")public CommonResult orderInfo(String orderNo) {ArrayList<Object> resultList = new ArrayList<>();Order order = orderService.selectByKey(orderNo);Logistics logistics = logisticsService.selectOrderNo(orderNo);if (order != null) {resultList.add(order);}if (logistics != null) {resultList.add(logistics);}return CommonResult.success("订单详情查询成功", resultList);}/*** 处理会员订单** @param order 订单信息*/private CommonResult handleMemberOrders(Order order) {if (orderService.insertData(order)) {return CommonResult.success("创建订单成功", order);} else {return CommonResult.error("创建订单失败");}}/*** 处理商品订单** @param order 订单信息*/private CommonResult handleMerchandiseOrders(Order order) {Product product = productService.selectByKey(order.getProductNo());Integer productStock = product.getProductStock();Integer payAmount = order.getPayAmount();boolean isOk = productStock >= payAmount;if (isOk) {Product newProduct = new Product();newProduct.setProductId(product.getProductId());int newStock = productStock - payAmount;newProduct.setProductStock(newStock);newProduct.setIsStockOut(newStock < product.getLowestStock());// 如果库存小于等于0,自动下架newProduct.setIsSale(newStock > 0);if (productService.updateById(newProduct)) {if (orderService.insertData(order)) {redisTemplate.opsForValue().set(order.getOrderNo(), order.getOrderNo(), 24, TimeUnit.HOURS);return CommonResult.success("创建订单成功", order);} else {return CommonResult.error("创建订单失败");}} else {return CommonResult.error("创建订单失败");}} else {return CommonResult.error("商品库存不足");}}
}
五,项目总结
项目后台基于Springboot+MybatisPlus开发实现,前端使用VUE+Element开发实现,前后端分离开发,前端通过调用后台接口来进行相应的交互处理。
亮点技术:短信发送验证码、阿里云OSS云存储商品图片、邮箱自动发邮件验证操作权限,Shiro权限管理,数据加密处理,支付宝沙箱技术应用,Redis数据缓存处理。
项目功能完整,界面优雅大方,人机交互流畅,是一个难得的毕业设计作品。
基于Springboot+Vue实现前后端分离商城管理系统相关推荐
- 基于springboot+vue的前后端分离商城系统
springboot前后端分离商城 介绍 springboot前后端分离商城 本项目由本人根据教程实现的一个springboot项目,基本已实现项目,但是本人希望加入自己的小功能, 请期待下一次的更新 ...
- shiro+php,一套基于SpringBoot+Vue+Shiro 前后端分离 开发的代码生成器
一.前言 最近花了一个月时间完成了一套基于Spring Boot+Vue+Shiro前后端分离的代码生成器,目前项目代码已基本完成 止步传统CRUD,进阶代码优化: 该项目可根据数据库字段动态生成 c ...
- 基于Springboot+vue实现前后端分离二手图书交易
作者主页:编程指南针 作者简介:Java领域优质创作者.CSDN博客专家 .掘金特邀作者.多年架构师设计经验.腾讯课堂常驻讲师 主要内容:Java项目.毕业设计.简历模板.学习资料.面试题库.技术互助 ...
- 基于SpringBoot+Vue的前后端分离的博客管理系统
菜单 首页 写文章 内容管理 博客管理 相册管理 归档 登录.注册 (项目整合了shiro+jwt+redis,用户未登录不能发布博客.内容管理.相册.归档等功能) 文章末尾赋前后端代码 ...
- 社区团购|生鲜团购|基于Springboot+Vue实现前后端分离社区团购
作者主页:编程千纸鹤 作者简介:Java.前端.Python开发多年,做过高程,项目经理,架构师 主要内容:Java项目开发.毕业设计开发.面试技术整理.最新技术分享 收藏点赞不迷路 关注作者有好处 ...
- 在线租房|基于Springboot+Vue实现前后端分离的租房系统
作者简介:全栈开发工程,从事Java.Python.前端.小程序方面的开发和研究,对大数据应用与开发比较感兴趣, 主要内容:Java项目.前端项目.Python项目.小程序开发.大数据项目.单片机 收 ...
- 基于SpringBoot+Vue的前后端分离开发汽车之家资讯论坛系统设计与实现
演示地址:传送门 http://101.43.254.35/ (用户名:admin 密码:1) 废话不多说,直接上实际效果图 系统首页 系统首页桌面,顶部依次为系统Logo.全局搜索框(支持模糊查询动 ...
- 基于SpringBoot+vue的前后端分离学生成绩管理系统的设计与实现--毕业设计
开发环境 JAVA8.MySQL5.7.SpringBoot2.1.0.Vue.ElementUI.JPA 主要功能 学生信息:学号.姓名.性别.联系方式.班级. 成绩管理:学号.课程编号.成绩 班级 ...
- 基于SSM+SpringBoot+Vue+ElementUI前后端分离的校园岗位招聘就业管理系统
运行视频 基于SSM+SpringBoot+Vue+ElementUI前后端分离的校园岗位招聘就业管理系统 项目运行截图 学生管理 添加学生 学生信息 教师管理 教师信息 实习基地 公告信息 公司管理 ...
最新文章
- html5之通讯API
- python stringstrip方法详解_Python 的技巧和方法你了解多少?
- 【教程】瘦AP升级为胖AP的终极大法
- 支付开发填坑记之支付宝
- 在线旅游的2020:洗牌重组、直播自救、跨界面敌
- 18 个 jQuery Mobile 开发贴士和教程
- makefile运行_NVDIA TX2入门 系列之三:运行Yolov3
- LeetCode 1933. 判断字符串是否可分解为值均等的子串
- 计算机应用基础10000字论文,计算机应用毕业设计论文一万字.docx
- xpath下面的xpath_深入研究XPATH查询
- mysql dump h_mysqldump
- 浏览器加载渲染网页过程解析
- abb机器人焊接编程视频教程_【ABB】ABB机器人焊接指令介绍,内附视频
- 百度自然语言处理开放接口使用代码
- Windows10桌面优化 | 如何修改图标大小 | 如何把win10快捷方式小箭头去掉
- python 微信支付sdk_weixin-python
- 计算机应用的毕业论文论文,计算机应用本科毕业论文
- 【PE258】A lagged Fibonacci sequence
- 生态学经典:捕食者和被捕食者模型
- 国内首次!完成4K超高清电视5G网络传输测试
热门文章
- tushare使用教程(附代码)
- Oracle应用之merge合并更新函数
- autocad不能画图_说说基本的画图软件—AutoCAD(一)
- MATLAB 找到n阶方阵中对角线上的连续素数个数 不使用循环
- 二维码生成【前端,后端】
- 【深度之眼Python基础+数据科学入门训练营】第四章 组合数据类型
- 乡村爱情故事8 下载地址
- Python获取全部股票代码信息(A/B/H/美/英股)
- E0413: 不存在从 “std::string“ 到 “const char *“ 的适当转换函数
- Kafka的 ISR 概念和作用