基于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

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

公众号:热爱技术的小郑

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

相关文章
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
929 7
|
11月前
|
NoSQL Java 网络安全
SpringBoot启动时连接Redis报错:ERR This instance has cluster support disabled - 如何解决?
通过以上步骤一般可以解决由于配置不匹配造成的连接错误。在调试问题时,一定要确保服务端和客户端的Redis配置保持同步一致。这能够确保SpringBoot应用顺利连接到正确配置的Redis服务,无论是单机模式还是集群模式。
793 5
|
12月前
|
前端开发 安全 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客户端
1575 4
基于springboot+vue开发的会议预约管理系统
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
962 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
前端开发 JavaScript Java
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
本系统基于SpringBoot与Vue3开发,实现校园食堂评价功能。前台支持用户注册登录、食堂浏览、菜品查看及评价发布;后台提供食堂、菜品与评价管理模块,支持权限控制与数据维护。技术栈涵盖SpringBoot、MyBatisPlus、Vue3、ElementUI等,适配响应式布局,提供完整源码与数据库脚本,可直接运行部署。
662 6
基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
|
供应链 JavaScript BI
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发
这是一款专为小微企业打造的 SaaS ERP 管理系统,基于 SpringBoot+Vue+ElementUI+UniAPP 技术栈开发,帮助企业轻松上云。系统覆盖进销存、采购、销售、生产、财务、品质、OA 办公及 CRM 等核心功能,业务流程清晰且操作简便。支持二次开发与商用,提供自定义界面、审批流配置及灵活报表设计,助力企业高效管理与数字化转型。
1031 2
ERP系统源码,基于SpringBoot+Vue+ElementUI+UniAPP开发
|
监控 数据可视化 JavaScript
springboot + vue的MES系统生产计划管理源码
MES系统(制造执行系统)的生产计划管理功能是其核心模块之一,涵盖生产计划制定与优化、调度排程、进度监控反馈、资源管理调配及可视化报告五大方面。系统基于SpringBoot + Vue-Element-Plus-Admin技术栈开发,支持多端应用(App、小程序、H5、后台)。通过实时数据采集与分析,MES助力企业优化生产流程,适用于现代化智能制造场景。
750 1
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
1015 0
|
存储 人工智能 NoSQL
SpringBoot整合Redis、ApacheSolr和SpringSession
本文介绍了如何使用SpringBoot整合Redis、ApacheSolr和SpringSession。SpringBoot以其便捷的配置方式受到开发者青睐,通过引入对应的starter依赖,可轻松实现功能整合。对于Redis,可通过配置RedisSentinel实现高可用;SpringSession则提供集群Session管理,支持多种存储方式如Redis;整合ApacheSolr时,借助Zookeeper搭建SolrCloud提高可用性。文中详细说明了各组件的配置步骤与代码示例,方便开发者快速上手。
291 11
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
1767 1
Spring boot 使用mybatis generator 自动生成代码插件