当前位置: 首页 > article >正文

springboot+vue实现在线书店(图书商城)系统

今天教大家如何设计一个图书商城 , 基于目前主流的技术:前端vue,后端springboot。

同时还带来的项目的部署教程

视频演示

在线书城

图片演示

一. 系统概述

商城是一款比较庞大的系统,需要有商品中心,库存中心,订单中心,收货地址和运费管理。先看下我们要实现的商城有哪些功能:

1. 商品分类管理。

2. 商品管理。

3.库存管理。

4.订单管理。 

5. 评价管理。

6.用户管理。

7.运费和运费模板管理。

8. 系统公告管理。

9.首页轮播图管理。

10. 用户购物车。

二. 核心功能实现思想

库存系统的设计

库存最大的问题就是超卖,也就是说有多个人同时并发下单,库存需要保持一致性,不会扣减到小于0的情况。普通的设计就是加一个全局锁。每个人下单都需要等待上一个人下单完成。

这样严重影响效率。这里我们库存的设计流程如下:

1. 首先我们将库存分为 数据库库存 和 销售库存。 数据库库存就是存储到数据库的商品库存值,销售库存就是用户下单,页面所在的库存值。

2. 后台管理上架商品时,会设置一个初始库存,我们将初始库存存储到数据库库存 和 销售库存 。

3.当用户下单时,不是直接扣减的数据库库存,而是通过redis的 decrement 方法,对销售库存进行扣减。但是redis的扣减操作这里还不是一个原子性操作,需要先从redis查出库存,然后进行decrment操作。这两步操作我们用reddsion的分布式锁来控制原子性,同时,我们将加锁的维度控制到了商品id。这样大大提高了并发效率。

3. 库存扣减后,我们又通过redis消费队列,实现了对数据库库存的同步。这样保持了redis库存和数据库库存的一致性。

4. 后台我们设计的是对商品只能加加库存,和减少库存的操作,而不是直接修改库存值。如果你直接修改库存值,就有可能会导致库存数据不一致,难以跟踪。

5. 我们还设计了库存的扣减,新增日志,方便对库存进行跟踪管理。

库存扣减的部分代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

/**

     * 扣减库存(使用Redisson分布式锁)

     * @param productId 商品ID

     * @param quantity 扣减数量

     * @return true-扣减成功,false-扣减失败(库存不足)

     */

    public boolean deductInventory(String productId, int quantity) {

        String lockKey = "lock:inventory:" + productId;

        String inventoryKey = "inventory:" + productId;

        RLock lock = redissonClient.getLock(lockKey);

        try {

            // 尝试加锁,最多等待10秒,锁过期时间30秒

            boolean locked = lock.tryLock(1030, TimeUnit.SECONDS);

            if (locked) {

                String stock = (String) redisTemplate.opsForValue().get(inventoryKey);

                if(StringUtils.isEmpty(stock)){

                    return false;

                }

                if (Integer.parseInt(stock) < quantity) {

                    return false;

                }

                // 扣减库存

                redisTemplate.opsForValue().decrement(inventoryKey, quantity);

                return true;

            }

            return false;

        catch (InterruptedException e) {

            Thread.currentThread().interrupt();

            return false;

        finally {

            // 释放锁

            if (lock.isHeldByCurrentThread()) {

                lock.unlock();

            }

        }

    }

    /**

     * 设置商品库存

     * @param productId 商品ID

     * @param quantity 库存数量

     */

    public void setInventory(String productId, int quantity) {

        String inventoryKey = "inventory:" + productId;

        redisTemplate.opsForValue().set(inventoryKey, quantity);

        System.out.println("库存设置: 商品id:" + productId + " , 数量:" + quantity);

    }

    /**

     * 获取商品库存

     * @param productId 商品ID

     * @return 当前库存数量

     */

    public int getInventory(String productId) {

        String inventoryKey = "inventory:" + productId;

        Object value = redisTemplate.opsForValue().get(inventoryKey);

        return value == null 0 : Integer.parseInt(value.toString());

    }

  

商品系统的设计

商品包含了很多属性,这里我设计的商品表如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

CREATE TABLE `product` (

  `product_id` int NOT NULL AUTO_INCREMENT COMMENT '商品id',

  `product_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '商品名称',

  `category_id` int NOT NULL COMMENT '类目id',

  `product_title` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '商品标题',

  `product_intro` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '商品详情',

  `product_picture` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '商品封面图',

  `product_price` double NOT NULL COMMENT '商品原价',

  `product_selling_price` double NOT NULL COMMENT '商品售卖价',

  `product_num` int NOT NULL COMMENT '商品库存',

  `product_sales` int NOT NULL COMMENT '销量',

  `state` tinyint DEFAULT '0' COMMENT '0-上架  1- 下架',

  `score` double DEFAULT NULL COMMENT '推荐评分,总共有5星',

  PRIMARY KEY (`product_id`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='商品';

 

商品还关联了多图

1

2

3

4

5

6

7

CREATE TABLE `product_picture` (

  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',

  `product_id` int NOT NULL COMMENT '商品id',

  `product_picture` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '商品图片',

  `intro` text CHARACTER SET utf8 COLLATE utf8_general_ci,

  PRIMARY KEY (`id`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=167 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='商品图片';

  

商品还有一个动态的字典属性

动态字典属性表设计

1

2

3

4

5

6

7

8

9

10

11

12

13

14

CREATE TABLE `product_attr` (

  `id` int NOT NULL AUTO_INCREMENT,

  `product_id` int NOT NULL,

  `product_attr_config_id` int NOT NULL COMMENT '商品属性字典id',

  `attr_val` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '属性值',

  PRIMARY KEY (`id`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=190 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='商品属性与字典关联';

CREATE TABLE `product_attr_config` (

  `id` int NOT NULL AUTO_INCREMENT,

  `attr_name` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '字典描述',

  `attr_key` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '字典key',

  PRIMARY KEY (`id`) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='商品属性字典';

  

订单系统的设计

我们将订单的状态设计成以下几种:0-待付款 1-待发货 2-待收货 3-待评价 4-已完成 5-退款中 6-已退款 7-已取消。

订单状态扭转流程:

1. 用户点击购买商品或从购物车点击,则商品进入待付款状态,此时,商品库存被锁,也就是实实在在的扣减了销售库存。

2. 当30分钟超过后,用户未支付上面的待付款订单,则订单状态扭转为已取消,库存回流,此笔订单结束。

3. 当用户30分钟内支付后,订单扭转为代发货。

4. 管理员登录管理后台,将待发货订单进行发货操作后,订单状态变成待收货。

5. 用户可以对待收获订单进行收获和退款操作,如果是退款,则变成退款中,管理员进行退款确认,确认后,订单变成已退款,退款成功后,库存回流。此订单结束。

6. 如果用户确认收获,则订单变成待评价,用户可以进行评价,评价完成后,订单变成已完成,此订单结束。

订单表设计如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

CREATE TABLE `orders` (

  `order_id` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,

  `user_id` int NOT NULL COMMENT '用户id',

  `product_id` int NOT NULL COMMENT '商品id',

  `product_num` int NOT NULL COMMENT '商品数量',

  `order_state` int NOT NULL COMMENT '订单状态 0-待付款 1-待发货 2-待收货 3-待评价 4-已完成 5-退款中 6-已退款 7-已取消',

  `product_price` double NOT NULL COMMENT '下单商品价格',

  `shipping_price` double NOT NULL COMMENT '下单运费价格',

  `refund_cause` varchar(2255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '退款原因',

  `order_remark` varchar(2000) COLLATE utf8mb4_bin NOT NULL COMMENT '订单备注',

  `pay_type` int DEFAULT NULL COMMENT '支付方式:0-支付宝 1-微信',

  `address` varchar(2000) COLLATE utf8mb4_bin NOT NULL COMMENT '收获地址',

  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',

  PRIMARY KEY (`order_id`) USING BTREE

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='订单';

  

三. 技术栈概述

后端技术栈:

JDK8 + springboot + mysql8

前端技术栈:

vue + Axios 等

四. 项目部署教程

前端部署

安装node , 版本:v22.15.0 , 安装完成后。

 进入到项目 hadluo-shop-webadmin 目录下,这个项目是vue的管理后台, 右键,运行cmd,运行下面命令:

npm run dev

由于我已经跟你npm install好了,所以你无需执行,直接run就可以了!!

运行项目

进入到项目 hadluo-shop-h5 目录下,这个项目是vue的前端, 右键,运行cmd,运行下面命令:

npm run dev

由于我已经跟你npm install好了,所以你无需执行,直接run就可以了!!

运行项目

到此前端项目部署完成。

执行sql

自己安装好数据库,注意,必须是mysql8 ,否则代码运行会出错。新建一个 wxhadluo-bookshop 数据库, 然后执行  “wxhadluo-bookshop.sql”

Redis安装

项目需要安装redis,直接下载一个windows版本的redis即可,没有的联系我。

启动后端项目

然后部署后端 , 打开idea, 导入maven工程 hadluo-bookshop。

打开resources目录, 修改 application.yml 配置文件,主要修改下面几个信息:

然后启动  main 启动类 : Application.class

五. 访问项目

管理后端:

http://localhost:3001/

账号:wx-hadluo,  密码: 123456

前端:

http://localhost:3000/

用户: 453423@qq.com / 123456

可以自己注册用户。

相关文章:

springboot+vue实现在线书店(图书商城)系统

今天教大家如何设计一个图书商城 , 基于目前主流的技术&#xff1a;前端vue&#xff0c;后端springboot。 同时还带来的项目的部署教程。 视频演示 在线书城 图片演示 一. 系统概述 商城是一款比较庞大的系统&#xff0c;需要有商品中心&#xff0c;库存中心&#xff0c;订单…...

C++二项式定理:原理、实现与应用

背景 鉴于复习&#xff0c;问了问清言二项式定理的应用…只好多找些资源…肝要死了… 一、引言 二项式定理是数学中一个基本定理&#xff0c;主要用于展开二项式的幂次。在C编程中&#xff0c;理解并实现二项式定理及其拓展具有重要意义&#xff0c;可以解决组合数学、概率论…...

使用GmSSL v3.1.1实现SM2证书认证

1、首先使用gmssl命令生成根证书、客户端公私钥&#xff0c;然后使用根证书签发客户端证书&#xff1b; 2、然后编写代码完成认证功能&#xff0c;使用根证书验证客户端证书是否由自己签发&#xff0c;然后使用客户端证书验证客户端私钥对随机数的签名是否正确。 第一部分生成根…...

远程实时控制安卓模拟器技术scrcpy

先运行模拟器 ~/Library/Android/sdk/emulator/emulator -avd Medium_Phone_API_25 再检查adb device /Users/xmkjsoft/Downloads/scrcpy-macos-x86_64-v3.2/adb devices 再开始实时获取模拟器画面 /Users/xmkjsoft/Downloads/scrcpy-macos-x86_64-v3.2/scrcpy --video-cod…...

Spring AI(6)——向量存储

向量数据库是一种特殊类型的数据库&#xff0c;在 AI 应用中发挥着至关重要的作用。 在向量数据库中&#xff0c;查询与传统关系型数据库不同。它们执行的是相似性搜索&#xff0c;而非精确匹配。当给定一个向量作为查询时&#xff0c;向量数据库会返回与该查询向量“相似”的…...

Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解

Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解 前言一、引入依赖二、配置 Elasticsearch三、创建模型类&#xff08;Entity&#xff09;四、使用 ElasticsearchOperations 进行 CRUD 操作1. 保存数据&#xff08;Create&#xff09;2. 获取数据&am…...

react-router基本写法

1. 创建项目并安装所有依赖 npx create-react-app react-router-pro npm i 2. 安装所有的 react router 包 npm i react-router-dom 3. 启动项目 npm run start router/index.js // 创建路由实例 绑定path elementimport Layout from "/pages/Layout"; import…...

【Matlab】最新版2025a发布,深色模式、Copilot编程助手上线!

文章目录 一、软件安装1.1 系统配置要求1.2 安装 二、新版功能探索2.1 界面图标和深色主题2.2 MATLAB Copilot AI助手2.3 绘图区升级2.4 simulink2.5 更多 延迟一个月&#xff0c;终于发布了&#x1f92d;。 一、软件安装 1.1 系统配置要求 现在的电脑都没问题&#xff0c;老…...

智能语音助手的未来:从交互到融合

摘要 随着人工智能技术的不断进步&#xff0c;智能语音助手已经成为我们生活中不可或缺的一部分。从简单的语音指令到复杂的多模态交互&#xff0c;语音助手正在经历一场深刻的变革。本文将探讨智能语音助手的发展历程、当前的技术瓶颈以及未来的发展方向&#xff0c;特别是其在…...

uniapp,小程序中实现文本“展开/收起“功能的最佳实践

文章目录 示例需求分析实现思路代码实现1. HTML结构2. 数据管理3. 展开/收起逻辑4. CSS样式 优化技巧1. 性能优化2. 防止事件冒泡3. 列表更新处理 实际效果总结 在移动端应用开发中&#xff0c;文本内容的"展开/收起"功能是提升用户体验的常见设计。当列表项中包含大…...

思维链框架:LLMChain,OpenAI,PromptTemplate

什么是思维链,怎么实现 目录 什么是思维链,怎么实现思维链(Chain of Thought)在代码中的实现方式1. 手动构建思维链提示2. 少样本思维链提示3. 自动思维链生成4. 思维链与工具使用结合5. 使用现有思维链框架:LLMChain,OpenAI,PromptTemplate思维链实现的关键要点思维链(C…...

HOT100 (哈希双指针)

哈希 1.两数之和(unordered_map) 给定一个整数数组 nums 和一个整数目标值 target,返回满足条件的数组下标 思路:用umap,一边遍历,一边装; class Solution {public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int> u…...

使用 QGIS 插件 OpenTopography DEM Downloader 下载高程数据(申请key教程)

使用 QGIS 插件 OpenTopography DEM Downloader 下载高程数据 目录 使用 QGIS 插件 OpenTopography DEM Downloader 下载高程数据&#x1f4cc; 简介&#x1f6e0; 插件安装方法&#x1f30d; 下载 DEM 数据步骤&#x1f511; 注册 OpenTopography 账号&#xff08;如使用 Cope…...

计算机组成与体系结构:替换策略(MRU LRU PLRU LFU)

目录 &#x1f3b2; MRU&#xff08;最近最常使用&#xff09; &#x1fa9c; 操作流程&#xff1a; &#x1f3b2; LRU&#xff08;最近最少使用&#xff09; &#x1fa9c; 操作流程&#xff1a; 示例 &#x1f50d; Age Bits&#xff08;年龄位&#xff09; 核心思想…...

websocket入门详解

入门websocket的基础应该掌握一下问题&#xff1a; 1、什么是握手&#xff1f; 2、什么是websocket&#xff1f; 3、websocket和http的区别&#xff0c;应用场景 4、html前端简单代码演示 5、springboot整合websocket使用 6、使用vueelementui打造简单聊天室 7、使用web…...

《数字藏品社交化破局:React Native与Flutter的创新实践指南》

NFT&#xff0c;这种非同质化代币&#xff0c;赋予了数字资产独一无二的身份标识&#xff0c;从数字艺术作品到限量版虚拟物品&#xff0c;每一件NFT数字藏品都承载着独特的价值与意义。当React Native和Flutter这两大跨平台开发框架遇上NFT数字藏品&#xff0c;一场技术与创意…...

(6)python开发经验

文章目录 1 QListWidget样式显示异常2 模块编码错误3 qtcreator开发pyqt编码错误 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;Qt开发 &#x1f448;&#x1f449;python开发 &#x1f448; 1 QListWidget样式显示异常 main.py import sys from PySide6.QtWi…...

HPC软件使用之ANSYS Fluent

目录 一、软件介绍 二、脚本编写 2.1 jou文件 2.2 slurm脚本文件 三、作业提交及查看 四、案例演示 4.1 网格模型 4.2 jou脚本 4.3 slurm脚本 4.4 计算 4.5 结果查看 从本文开始&#xff0c;我们将介绍如何在超级计算机上使用科学计算、工程仿真计算软件开展计算&am…...

YOLO11解决方案之距离计算探索

概述 Ultralytics提供了一系列的解决方案&#xff0c;利用YOLO11解决现实世界的问题&#xff0c;包括物体计数、模糊处理、热力图、安防系统、速度估计、物体追踪等多个方面的应用。 测量两个物体之间的间距被称为特定空间内的距离计算&#xff0c;YOLO11使用两个边界框的中心…...

论文学习_Precise and Accurate Patch Presence Test for Binaries

摘要&#xff1a;打补丁是应对软件漏洞的主要手段&#xff0c;及时将补丁应用到所有受影响的软件上至关重要&#xff0c;然而这一点在实际中常常难以做到&#xff0c;研究背景。因此&#xff0c;准确检测安全补丁是否已被集成进软件发行版本的能力&#xff0c;对于防御者和攻击…...

Ascend的aclgraph(九)AclConcreteGraph:e2e执行aclgraph

1回顾 前面的几章内容探讨了aclgraph运行过程中的涉及到的关键模块和技术。本章节将前面涉及到的模块串联起来&#xff0c;对aclgraph形成一个端到端的了解。 先给出端到端运行的代码&#xff0c;如下&#xff1a; import torch import torch_npu import torchair import log…...

JSX语法介绍

文章目录 JSX介绍JSX的引入JSX的全称babel转换工具 JSX的基本语法创建组件的第一种方式创建组件父组件传值给子组件 class 关键字的介绍class的基本用法&#xff1a;使用class创建对象使用 class 实现 JS 中的继承 创建组件的第二种方式&#xff1a;使用 class 关键字父组件传值…...

增强 HTNN 服务网格功能:基于 Istio 的BasicAuth 与 ACL 插件开发实战

目录 1.引言 什么是HTNN&#xff1f; 为什么开发 BasicAuth 和 ACL 插件&#xff1f; 2.技术背景 技术栈概览 Istio 与服务网格简述 HTNN 框架与插件机制概览 3.插件开发详解&#xff1a;BasicAuth 与 ACL 3.1 BasicAuth插件 功能点 实现细节 3.2 ACL插件 功能点 …...

c++从入门到精通(四)--动态内存,模板与泛型编程

文章目录 动态内存直接管理内存Shared_ptr类Unique_ptrWeak_ptr动态数组allocator类文本查询程序 模板与泛型编程定义模板函数模板类模板模板参数成员模板控制实例化 模板实参推断重载与模板可变参数模板模板特例化 动态内存 c中动态内存的管理是通过new和delete运算符来实现的…...

C盘清理秘籍:快速提升系统性能

C盘清理的重要性 C盘作为系统盘&#xff0c;存储着操作系统和关键程序文件。随着使用时间的增加&#xff0c;C盘空间会逐渐被占用&#xff0c;导致系统运行缓慢、程序启动延迟等问题。定期清理C盘可以有效提升系统性能&#xff0c;延长硬盘寿命。 清理临时文件 Windows系统在…...

从 Vue3 回望 Vue2:组件设计升级——Options API vs Composition API

文章目录 从 Vue3 回望 Vue2&#xff1a;组件设计升级——Options API vs Composition API1、组件范式&#xff1a;框架设计思想的投影2、Vue2&#xff1a;Options API 的结构与局限结构清晰&#xff1a;新手友好、职责分明核心痛点&#xff1a;逻辑分散&#xff0c;难以聚合复…...

寻找两个正序数组的中位数 - 困难

************* Python topic: 4. 寻找两个正序数组的中位数 - 力扣&#xff08;LeetCode&#xff09; ************* Give the topic an inspection. Do the old topic will give you some new sparks. Before that, I do some really good craetive things about my logo. …...

国产密码新时代!华测国密 SSL 证书解锁安全新高度

在数字安全被提升到国家战略高度的今天&#xff0c;国产密码算法成为筑牢网络安全防线的关键力量。华测国密SSL证书凭借其强大性能与贴心服务&#xff0c;为企业网络安全保驾护航&#xff0c;成为符合国家安全要求的不二之选&#xff01;​ 智能兼容&#xff0c;告别浏览器适配…...

【金仓数据库征文】从云计算到区块链:金仓数据库的颠覆性创新之路

目录 一、引言 二、金仓数据库概述 2.1 金仓数据库的背景 2.2 核心技术特点 2.3 行业应用案例 三、金仓数据库的产品优化提案 3.1 性能优化 3.1.1 查询优化 3.1.2 索引优化 3.1.3 缓存优化 3.2 可扩展性优化 3.2.1 水平扩展与分区设计 3.2.2 负载均衡与读写分离 …...

互联网大厂Java求职面试:AI与大模型集成的云原生架构设计

互联网大厂Java求职面试&#xff1a;AI与大模型集成的云原生架构设计 引言 在现代互联网企业中&#xff0c;AI与大模型技术的应用已经成为不可或缺的一部分。特别是在短视频平台、电商平台和金融科技等领域&#xff0c;如何高效地将大模型集成到现有的云原生架构中是一个巨大…...