基于SpringBoot+Vue+Redis+Mybatis的商城购物系统 【系统实现+系统源码+答辩PPT】

简介: 这篇文章介绍了一个基于SpringBoot+Vue+Redis+Mybatis技术栈开发的商城购物系统,包括系统功能、页面展示、前后端项目结构和核心代码,以及如何获取系统源码和答辩PPT的方法。

前言

  该系统采用SpringBoot+Vue前后端分离开发,前端是一个单独的项目,后端是一个单独的项目。
  技术栈:SpringBoot+Vue+Mybatis+Redis+Mysql
  开发工具:IDEA、Vscode
  浏览器:Chrome
  开发环境:JDK1.8、Maven3.3.9、Node 16.6.0、MySql 5.7

一、功能划分

1、用户功能

在这里插入图片描述

2、管理员功能

在这里插入图片描述

二、页面展示部分

1、注册登录

在这里插入图片描述

在这里插入图片描述

2、系统首页

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

3、商品分类页面

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

4、购物车页面

在这里插入图片描述

5、订单页面

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

6、个人信息页面

在这里插入图片描述

7、后台页面

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

三、系统源码

1、前端

前端项目结构
在这里插入图片描述

部分核心代码

<!--
 * 前台首页 相关内容
 *
 * @Author: ShanZhu
 * @Date: 2023-11-11
-->
<template>
  <div>
    <search @search="handleSearch"></search>

    <div class="main-box">
      <div class="block" style="margin: 10px auto">

        <!--商品分类-->
        <div class="good-menu">
          <ul v-for="(item, index) in icons" :key="index">
            <li>

              <i class="iconfont" v-html="item.value"></i>

              <!--跳转到商品分类对应列表-->
              <span v-for="(category, index2) in item.categories" :key="index2">
                <router-link
                  :to="{
                    path: '/goodlist',
                    query: { categoryId: category.id },
                  }"
                >
                  <a href="/person"><span style="color: #3186cb">{
  
  { category.name }}</span></a>
                </router-link>

                <span v-if="index2 != item.categories.length - 1">/</span>

              </span>

            </li>
          </ul>
        </div>

        <!--轮播图-->
        <div>
          <el-carousel height="370px" style="border-radius: 20px; width: 600px">

            <el-carousel-item v-for="carousel in carousels" :key="carousel.id">
              <router-link :to="'/goodview/' + carousel.goodId">
                <img style="height: 370px; width: 600px"
                  :src="baseApi + carousel.img"
                />
              </router-link>
            </el-carousel-item>

          </el-carousel>
        </div>
      </div>

      <!--推荐商品-->
      <div style="margin-top: 30px">
        <span style="color: #e75c09">推荐商品</span>
      </div>

      <div style="margin: 20px auto">

        <el-row :gutter="20">

          <el-col
            :span="6"
            v-for="good in good"
            :key="good.id"
            style="margin-bottom: 20px"
          >

            <router-link :to="'goodview/' + good.id">

              <el-card :body-style="{ padding: '0px', background: '#3472a6' }">
                <img
                  :src="baseApi + good.imgs"
                  style="width: 100%; height: 300px"
                />
                <div style="padding: 5px 10px">
                  <!--商品名称-->
                  <span style="font-size: 18px; color: #ffffff">{
  
  { good.name }}</span><br/>
                  <!--商品价格-->
                  <span style="color: #ffffff; font-size: 15px">¥{
  
  { good.price }}</span>
                </div>
              </el-card>

            </router-link>

          </el-col>
        </el-row>

      </div>
    </div>
  </div>
</template>

<script>
import search from "../../components/Search";
export default {
  name: "TopView",
  //页面初始化数据
  data() {
    return {
      //轮播图
      carousels: [],
      //推荐商品
      good: [],
      baseApi: this.$store.state.baseApi,

      //分类icon,每个icon包含id、value、categories对象数组.category:id,name
      icons: [],
      //搜索内容
      searchText: "",
      baseApi: this.$store.state.baseApi,
    };
  },
  components: {
    search,
  },
  //页面创建
  created() {
    this.request.get("/api/good").then((res) => {
      if (res.code === "200") {
        this.good = res.data;
      } else {
        this.$message.error(res.msg);
      }
    });
    this.request.get("/api/icon").then((res) => {
      if (res.code === "200") {
        this.icons = res.data;
        if(this.icons.length > 6) {
          // 截取前六个分类
          this.icons = this.icons.slice(0, 6);
        }
      }
    });
    this.request.get("/api/carousel").then((res) => {
      if (res.code === "200") {
        this.carousels = res.data;
      }
    });
  },
  //方法
  methods: {
    //搜索按钮触发
    handleSearch(text) {
      this.searchText = text;
      this.$router.push({
        path: "/goodList",
        query: { searchText: this.searchText },
      });
    },

  },
};

</script>

<style scoped>
.main-box {
  background-color: white;
  border: white 2px solid;
  border-radius: 40px;
  padding: 20px 40px;
  margin: 5px auto;
}
.good-menu {
  float: left;
  height: 370px;
  margin-right: 130px;
}
.good-menu li {
  list-style: none;
  overflow: hidden;
  margin-bottom: 35px;
}
.good-menu li a,
span {
  font-size: 20px;
  color: #6c6969;
}
.good-menu a span:hover {
  color: #00b7ff;
}
</style>

2、后端

项目结构
在这里插入图片描述

核心代码

/**
 * 商品 控制层
 *
 * @author: ShanZhu
 * @date: 2023-11-10
 */
@RestController
@RequestMapping("/api/good")
@RequiredArgsConstructor
public class GoodController {

    private final GoodService goodService;

    private final StandardService standardService;

    /**
     * 查询商品
     *
     * @param id 商品id
     * @return 商品
     */
    @GetMapping("/{id}")
    public R<Good> findGood(@PathVariable Long id) {
        return R.success(goodService.getGoodById(id));
    }

    /**
     * 查询商品规格
     *
     * @param id 商品规格id
     * @return 商品规格
     */
    @GetMapping("/standard/{id}")
    public R<String> getStandard(@PathVariable Integer id) {
        return R.success(goodService.getStandard(id));
    }

    /**
     * 查询推荐商品,即recommend=1
     *
     * @return 商品
     */
    @GetMapping
    public R<GoodVo> findFrontGoods() {
        return R.success(goodService.findFrontGoods());
    }

    /**
     * 商品销售额排行
     *
     * @return 商品
     */
    @GetMapping("/rank")
    public R<List<Good>> getSaleRank(@RequestParam int num) {
        return R.success(goodService.getSaleRank(num));
    }

    /**
     * 保存商品
     *
     * @param good 商品信息
     * @return 商品id
     */
    @PostMapping
    public R<Long> save(@RequestBody Good good) {
        return R.success(goodService.saveOrUpdateGood(good));
    }

    /**
     * 更新商品
     *
     * @param good 商品信息
     */
    @PutMapping
    public R<Void> update(@RequestBody Good good) {
        goodService.update(good);
        return R.success();
    }

    /**
     * 删除商品
     *
     * @param id 商品id
     */
    @DeleteMapping("/{id}")
    public R<Void> delete(@PathVariable Long id) {
        goodService.loginDeleteGood(id);
        return R.success();
    }

    /**
     * 保存商品规格
     *
     * @param standards 商品规格列表
     * @param goodId    商品id
     */
    @PostMapping("/standard")
    public R<Void> saveStandard(
            @RequestBody List<Standard> standards,
            @RequestParam int goodId
    ) {
        //先删除全部旧记录
        standardService.deleteAll(goodId);

        //然后插入新记录
        for (Standard standard : standards) {
            standard.setGoodId(goodId);
            if (!standardService.save(standard)) {
                return R.error(Status.CODE_500, "商品id: " + goodId + " ,规格保存失败");
            }
        }

        return R.success();
    }

    /**
     * 删除商品规格
     *
     * @param standard 商品规格列表
     */
    @DeleteMapping("/standard")
    public R<Void> delStandard(@RequestBody Standard standard) {
        if (BooleanUtil.isTrue(standardService.delete(standard))) {
            return R.success();
        } else {
            return R.error(Status.CODE_500, "删除失败");
        }
    }

    /**
     * 修改商品推荐
     *
     * @param id          商品id
     * @param isRecommend 是否推荐
     * @return 结果
     */
    @GetMapping("/recommend")
    public R<Void> setRecommend(
            @RequestParam Long id,
            @RequestParam Boolean isRecommend
    ) {
        return R.success(goodService.setRecommend(id, isRecommend));
    }

    /**
     * 分页查询商品 - 带查询条件
     *
     * @param pageNum    页数
     * @param pageSize   分页大学
     * @param searchText 查询文本
     * @param categoryId 分类id
     * @return 商品列表
     */
    @GetMapping("/page")
    public R<IPage<GoodVo>> findGoodPage(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false, defaultValue = "") String searchText,
            @RequestParam(required = false) Integer categoryId
    ) {
        return R.success(
                goodService.findPage(pageNum, pageSize, searchText, categoryId)
        );
    }

    /**
     * 分页查询全部商品
     *
     * @param pageNum    页数
     * @param pageSize   分页大学
     * @param searchText 查询文本
     * @param categoryId 分类id
     * @return 商品列表
     */
    @GetMapping("/fullPage")
    public R<IPage<GoodVo>> findGoodFullPage(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false, defaultValue = "") String searchText,
            @RequestParam(required = false) Integer categoryId) {

        return R.success(goodService.findFullPage(pageNum, pageSize, searchText, categoryId));
    }

}

四、系统源码+答辩PPT

系统源码链接地址:仅供参考学习。

公众号:热爱技术的小郑

回复:商城系统,即可获取到系统源码。

相关文章
|
7月前
|
NoSQL Java 网络安全
SpringBoot启动时连接Redis报错:ERR This instance has cluster support disabled - 如何解决?
通过以上步骤一般可以解决由于配置不匹配造成的连接错误。在调试问题时,一定要确保服务端和客户端的Redis配置保持同步一致。这能够确保SpringBoot应用顺利连接到正确配置的Redis服务,无论是单机模式还是集群模式。
657 5
|
8月前
|
前端开发 安全 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客户端
1154 4
基于springboot+vue开发的会议预约管理系统
|
9月前
|
前端开发 JavaScript Java
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
本系统基于SpringBoot与Vue3开发,实现校园食堂评价功能。前台支持用户注册登录、食堂浏览、菜品查看及评价发布;后台提供食堂、菜品与评价管理模块,支持权限控制与数据维护。技术栈涵盖SpringBoot、MyBatisPlus、Vue3、ElementUI等,适配响应式布局,提供完整源码与数据库脚本,可直接运行部署。
529 6
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
|
8月前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
771 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
11月前
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
812 0
|
前端开发 druid Java
SpringBoot 整合 MyBatis
文本是基于MVC前后端分离模式的一个SpringBoot整合MyBatis的项目,不过没有用到前端页面,使用了更方便的Apifox请求工具。SpringBoot+MyBatis使用起来更方便,更舒服。掌握SpingBoot整合MyBatis,要比Spring整合简单的多,少了很多繁琐的配置。......
385 0
SpringBoot 整合 MyBatis
|
XML 存储 SQL
SpringBoot整合MyBatis
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
1533 1
SpringBoot整合MyBatis
|
XML 数据可视化 Java
Springboot整合mybatis(注解而且能看明白版本)
这篇文章主要讲解Springboot整合Mybatis实现一个最基本的增删改查功能,整合的方式有两种一种是注解形式的,也就是没有Mapper.xml文件,还有一种是XML形式的,我推荐的是使用注解形式,为什么呢?因为更加的简介,减少不必要的错误。
818 0
Springboot整合mybatis(注解而且能看明白版本)
|
XML SQL Java
SpringBoot整合MyBatis(七)下
SpringBoot整合MyBatis(七)
207 0
SpringBoot整合MyBatis(七)下
|
XML Java 数据库连接
SpringBoot整合MyBatis(七)中
SpringBoot整合MyBatis(七)
247 0
SpringBoot整合MyBatis(七)中

热门文章

最新文章