logo
2
0
WeChat Login

Shop 商城管理系统

基于 Spring Boot 3.5 + Spring Security + JWT + MyBatis Plus 的商城后端管理系统,实现了完整的用户认证授权、RBAC 权限管理功能。

技术栈

  • Java 17
  • Spring Boot 3.5.10
  • Spring Security 6.x - 安全框架
  • JWT (JJWT 0.12.6) - Token 认证
  • MyBatis Plus 3.5.5 - ORM 框架
  • MySQL 8.x - 数据库
  • Redis - 缓存与 Token 黑名单
  • Lombok - 简化开发
  • SpringDoc OpenAPI - API 文档(可选)

核心功能

1. 用户认证

  • 用户注册(自动分配默认角色)
  • 用户登录(JWT Token 生成)
  • 用户登出(Token 黑名单机制)
  • 密码加密存储(BCrypt)

2. 权限管理(RBAC)

  • 5 表设计:用户、角色、权限、用户-角色、角色-权限
  • 动态权限加载
  • 基于角色的访问控制
  • 注册时自动分配 USER 角色

3. 用户管理

  • 获取用户信息
  • 更新用户资料
  • 修改密码
  • 查询用户角色
  • 查询用户权限

4. 评论模块

  • 商品评价发布、分页查询(按商品 ID)
  • 评价详情(含回复列表、点赞数、当前用户是否已点赞)
  • 评价回复(用户回复、商家回复)
  • 评价点赞与取消点赞
  • 评价举报
  • 评价筛选(按评分 1–5、按时间/评分排序)

5. 支付模块

  • 创建支付订单(支持多种支付方式)
  • 查询支付详情
  • 查询支付记录列表(支持多条件筛选和分页)
  • 支付回调处理(模拟支付宝、微信支付回调)
  • 发起退款
  • 查询退款状态

5. 订单模块

  • 添加商品到购物车、修改购物项数量、删除购物项
  • 支持从购物车直接下单(选择项下单)
  • 用户收货地址的增删改查,支持设置默认地址(设置默认时会将该用户其他地址设为非默认)
  • 订单创建:支持从购物车(selected 项)创建或直接传商品项创建,生成订单、订单项与支付记录
  • 订单查询:按用户、按订单状态查询(支持分页)
  • 订单状态流转:待支付 -> 已支付 -> 已发货 -> 已完成;支持用户取消订单
  • 订单详情展示:提供订单基本信息(可扩展返回订单项、支付记录与状态历史)
  • 订单统计:按状态统计当前用户订单数量

数据库设计

表结构

users(用户表)

- id: 用户ID(主键,自增) - username: 用户名(唯一) - password: 密码(BCrypt 加密) - email: 邮箱 - status: 状态(1=启用,0=禁用) - created_at: 创建时间 - updated_at: 更新时间

roles(角色表)

- role_id: 角色ID(主键,自增) - role_name: 角色名称 - role_code: 角色代码(ADMIN/EDITOR/USER- description: 描述 - status: 状态 - create_at: 创建时间 - update_at: 更新时间

permissions(权限表)

- permission_id: 权限ID(主键,自增) - permission_name: 权限名称 - permission_code: 权限代码(如:product:view- resource: 资源类型 - action: 操作类型 - description: 描述

user_role(用户-角色关联表)

- id: 主键 - user_id: 用户ID(外键) - role_id: 角色ID(外键) - create_at: 创建时间

role_permission(角色-权限关联表)

- id: 主键 - role_id: 角色ID(外键) - permission_id: 权限ID(外键)

评论相关表(依赖 product_schema 与 users)

product_reviews(商品评价表,见 product_schema.sql)

- id: 主键 - product_id: 商品ID(外键) - user_id: 用户ID - order_item_id: 订单项ID(可选) - rating: 评分 1-5 - content: 评价内容 - images: 图片 JSON - reply: 商家回复内容 - status: 1=显示, 0=隐藏 - created_at: 创建时间

review_replies(评价回复表)

- id: 主键 - review_id: 评价ID(外键) - user_id: 用户ID - content: 回复内容 - created_at: 创建时间

review_likes(评价点赞表)

- id: 主键 - review_id: 评价ID(外键) - user_id: 用户ID - created_at: 创建时间 - 唯一约束: (review_id, user_id)

review_reports(评价举报表)

- id: 主键 - review_id: 评价ID(外键) - user_id: 用户ID - reason: 举报原因 - status: 0=待处理, 1=已处理, 2=已驳回 - created_at: 创建时间

订单与购物相关表(新增)

addresses(地址表)

- id: 主键 - user_id: 用户ID(外键) - receiver_name: 收件人姓名 - phone: 联系电话 - province, city, district, detail: 地址字段 - is_default: 是否默认(0/1- created_at, updated_at: 时间戳

cart(购物车表)

- id: 主键 - user_id: 用户ID(外键) - product_id: 商品ID(外键) - quantity: 商品数量 - selected: 是否选中用于下单(0/1- created_at, updated_at: 时间戳

orders(订单表)

- id: 主键 - order_no: 订单号(唯一) - user_id: 用户ID(外键) - address_id: 收货地址ID - total_amount: 订单总金额 - status: 订单状态(PENDING_PAYMENT/PAID/SHIPPED/COMPLETED/CANCELLED) - payment_status: 支付状态(UNPAID/PAID/CANCELLED) - remark: 备注 - created_at, updated_at: 时间戳

order_items(订单明细表)

- id: 主键 - order_id: 订单ID(外键) - product_id: 商品ID - product_name: 商品名称(冗余) - sku_info: 规格信息 - price: 单价 - quantity: 数量 - total_amount: 小计金额

payments(支付记录)

- id: 主键 - order_id: 订单ID(外键) - amount: 支付金额 - method: 支付方式 - status: 支付状态(PENDING/SUCCESS/FAILED) - transaction_id: 第三方交易号 - paid_at: 支付时间

order_status_history(订单状态历史)

- id: 主键 - order_id: 订单ID(外键) - status: 状态 - remark: 备注 - created_at: 时间戳

payments(支付记录表,见 payment_schema.sql)

- id: 主键 - order_id: 订单ID(外键) - user_id: 用户ID(外键) - payment_method: 支付方式(alipay/wechat/bank_card) - payment_amount: 支付金额 - payment_status: 支付状态(pending/success/failed/refunded) - transaction_id: 第三方交易ID - payment_time: 支付时间 - refund_amount: 退款金额 - refund_time: 退款时间 - refund_reason: 退款原因 - callback_data: 回调数据(JSON) - created_at: 创建时间 - updated_at: 更新时间

默认角色权限

角色角色代码权限
系统管理员ADMIN所有权限(编辑报表、编辑商品、查看报表、查看商品、删除商品)
编辑EDITOR查看、编辑商品和报表权限
普通用户USER查看商品和报表权限

快速开始

1. 环境要求

  • JDK 17+
  • Maven 3.6+
  • MySQL 8.0+
  • Redis 6.0+

2. 数据库初始化

# 1. 创建数据库 CREATE DATABASE shop DEFAULT CHARACTER SET utf8mb4; # 2. 执行初始化脚本 mysql -u root -p shop < sql/rbac_init.sql # 3. 若使用商品与评论模块,再执行(需先有 products、users 等表) mysql -u root -p shop < sql/product_schema.sql mysql -u root -p shop < sql/review_schema.sql # 4. 若使用支付模块,再执行 mysql -u root -p shop < sql/payment_schema.sql

3. 配置文件

编辑 src/main/resources/application.properties

spring.datasource.username=your_username spring.datasource.password=your_password

Redis 配置

spring.data.redis.host=localhost spring.data.redis.port=6379 spring.data.redis.password=

JWT 配置

jwt.secret=your-secret-key-change-this-in-production-environment-minimum-256-bits jwt.access-token-expiration=7200 jwt.refresh-token-expiration=604800

服务器端口


server.port=8080

### 4. 运行项目 ```bash # 使用 Maven 运行 mvn spring-boot:run # 或打包后运行 mvn clean package java -jar target/demo1-0.0.1-SNAPSHOT.jar

5. 访问地址

API 接口文档

基础配置

  • Base URL: http://localhost:8080
  • Content-Type: application/json
  • Authorization: Bearer {token} (登录后需要)

用户认证接口

1. 用户注册

POST /user/registerUser Content-Type: application/json { "username": "test", "password": "123456" }

响应示例

{ "code": 200, "msg": "注册成功", "data": null }

2. 用户登录

POST /auth/login Content-Type: application/json { "username": "test", "password": "123456" }

响应示例

{ "code": 200, "msg": "操作成功", "data": { "id": 1, "username": "test", "token": "eyJhbGciOiJIUzI1NiJ9...", "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "loginTime": "2026-01-25" } }

2.1 刷新 Access Token

当 Access Token 过期时,可以使用 Refresh Token 换取新的 Access Token,Refresh Token 的有效期默认为 7 天(可通过 jwt.refresh-token-expiration 配置调整)。

POST /auth/refresh Content-Type: application/x-www-form-urlencoded refreshToken=<refreshToken>

响应示例

{ "code": 200, "msg": "操作成功", "data": { "accessToken": "eyJhbGciOiJIUzI1NiJ9...", "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "tokenType": "Bearer", "expiresIn": 7200 } }

注意:刷新接口允许匿名访问(/auth/refresh 已加入安全白名单),但 refresh token 本身必须有效且与服务器在 Redis 中保存的值匹配。

3. 用户登出

GET /auth/logout Authorization: Bearer {token}

响应示例

{ "code": 200, "msg": "操作成功", "data": { "message": "登出成功", "logoutTime": "2026-01-25" } }

用户管理接口

4. 获取用户信息

GET /auth/profile Authorization: Bearer {token}

响应示例

{ "code": 200, "msg": "操作成功", "data": { "id": 1, "name": "test", "email": "test@example.com", "status": 1, "nowTime": "2026-01-25" } }

5. 更新用户资料

POST /user/update Authorization: Bearer {token} Content-Type: application/json { "email": "newemail@example.com" }

6. 修改密码

POST /user/changePassword Authorization: Bearer {token} Content-Type: application/json { "oldPassword": "123456", "newPassword": "654321" }

权限管理接口

7. 获取用户权限(完整信息)

GET /user/permissions Authorization: Bearer {token}

响应示例

{ "code": 200, "msg": "操作成功", "data": { "userId": 1, "username": "test", "email": null, "roles": [ { "roleId": 2, "roleName": "普通用户", "roleCode": "USER", "description": "普通用户", "status": 1 } ], "permissions": [ { "permissionId": 1, "permissionName": "查看商品", "permissionCode": "product:view", "resource": "product", "action": "view", "description": "查看商品权限" }, { "permissionId": 4, "permissionName": "查看报表", "permissionCode": "report:view", "resource": "report", "action": "view", "description": "查看报表权限" } ] } }

8. 获取用户角色列表

GET /user/roles Authorization: Bearer {token}

9. 获取用户权限列表

GET /user/permissions/list Authorization: Bearer {token}

商品模块 API(Product)

商品模块提供标准的 CRUD 接口,支持分页查询与模糊搜索。

Base URL: http://localhost:8080

请求头(通用):

  • Content-Type: application/json(POST/PUT)
  • Authorization: Bearer {token}(需要鉴权的接口)
  1. 创建商品
POST /product Headers: Authorization: Bearer {token} Body (JSON): { "categoryId": 1, "sku": "PHN-0001", "name": "示例手机 A1", "subtitle": "全面屏 / 128GB", "description": "示例手机 A1,性能均衡。", "price": 1999.00, "originalPrice": 2499.00, "stock": 120, "status": 1, "isFeatured": 1, "coverUrl": "https://example.com/images/phone_a1.jpg", "weight": 0.18 }

必填字段:name, categoryId, price, stock

写操作权限:需要 EDITORADMIN 角色(后端根据 RBAC 检查 product:create/product:edit 权限)。

示例 curl:

curl -X POST "http://localhost:8080/product" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"categoryId":1,"sku":"PHN-0001","name":"示例手机 A1","price":1999.00,"stock":120}'

成功响应示例:

{ "code":200, "msg":"操作成功", "data":{ "id":101, "name":"示例手机 A1" } }
  1. 获取单个商品
GET /product/{id} Path param: id (Long) Headers: Authorization: Bearer {token}
  1. 分页查询商品
GET /product?page=1&size=10&name=手机 Headers: Authorization: Bearer {token} Query params: - page: integer, 默认 1 - size: integer, 默认 10 - name: string, 可选,按 name 模糊匹配
  1. 更新商品(部分更新,PATCH)
PATCH /product/{id} Headers: Authorization: Bearer {token} Body: 与创建接口相同的 JSON 结构,但只需要包含要修改的字段(只会合并非 null 字段) 示例:只修改价格和库存 { "price": 1899.00, "stock": 100 }

说明:

  • 如果客户端无法发送 PATCH /product/{id},后端可能同时支持 PATCH /product?id={id} 或在请求体中包含 id(兼容性由后端决定)。
  • 部分更新不会把未包含的字段设为 null;仅覆盖非 null 字段。
  • 写操作需要 EDITORADMIN 角色;查看需要登录(USER 及以上)。
  1. 删除商品
DELETE /product/{id} Headers: Authorization: Bearer {token}
  1. 设置商品上下架
PATCH /product/{id}/status?status=1 Headers: Authorization: Bearer {token} Query params: - status: integer, 必选,`1`=上架,`0`=下架

说明:写操作需要 EDITORADMIN 角色。示例:把 id=101 的商品下架

curl -X PATCH "http://localhost:8080/product/101/status?status=0" \ -H "Authorization: Bearer ${TOKEN}"

成功响应示例:

{ "code":200, "msg":"设置成功", "data":null }

评论模块 API(Review)

评论模块提供商品评价的发布、查询、回复、点赞、举报及按评分/时间筛选。

Base URL: http://localhost:8080

请求头(通用):

  • Content-Type: application/json(POST/PUT)
  • Authorization: Bearer {token}(发布、回复、点赞、举报、商家回复等需登录)
  1. 发布商品评价
POST /review Headers: Authorization: Bearer {token} Body (JSON): { "productId": 1, "rating": 5, "content": "非常不错,性价比高。", "images": "[\"https://example.com/1.jpg\"]" }

必填字段:productIdrating 为 1–5,默认 5;contentimages 可选。

成功响应:返回完整评价对象(含 id、点赞数、回复列表等)。

  1. 分页查询商品评价(支持按评分、时间排序)
GET /review/product/{productId}?page=1&size=10&rating=5&sortBy=time_desc

Query 参数:

  • page: 页码,默认 1
  • size: 每页条数,默认 10
  • rating: 可选,1–5,仅返回该评分的评价
  • sortBy: 可选,time_desc(默认)| time_asc | rating_desc | rating_asc

无需登录。响应为分页结果,每条包含评价信息、回复列表、点赞数、当前用户是否已点赞(未登录为 false)。

  1. 查询评价详情
GET /review/{reviewId}

返回单条评价详情(含回复列表、点赞数、当前用户是否已点赞)。无需登录。

  1. 回复评价
POST /review/reply Headers: Authorization: Bearer {token} Body (JSON): { "reviewId": 1, "content": "同意,确实很划算。" }

必填:reviewIdcontent。成功返回 "回复成功"

  1. 商家回复(更新评价主表的商家回复)
PUT /review/{reviewId}/seller-reply Headers: Authorization: Bearer {token} Body (JSON): { "content": "感谢您的支持,欢迎再次购买。" }

将内容写入该评价的 reply 字段。成功返回 "回复成功"

  1. 点赞 / 取消点赞
POST /review/{reviewId}/like Headers: Authorization: Bearer {token}

同一用户对同一评价再次请求即取消点赞。响应 datatrue 表示当前为已点赞状态,false 表示已取消。

  1. 举报评价
POST /review/report Headers: Authorization: Bearer {token} Body (JSON): { "reviewId": 1, "reason": "不当言论" }

必填:reviewIdreason 可选。成功返回 "举报已提交"

商品分类管理(Categories)

对外提供多级分类管理接口,支持树形查询与 CRUD(写操作需要鉴权)。

  1. 创建分类
POST /categories Headers: Authorization: Bearer {token} Body (JSON): { "parentId": 1, // 可选,顶级分类可为空 "name": "手机", "slug": "electronics-phones", "description": "手机分类", "sortOrder": 1, "status": 1 }

必填字段:name

写操作权限:只有 EDITORADMIN 可创建/更新/删除分类(后端通过 role/permission 控制)。

重要约束:

  • slug 应保持在同一层级唯一(后端应做唯一性检查)。
  • 删除分类前会校验是否存在子分类,存在子分类时禁止删除。

示例 curl:

curl -X POST "http://localhost:8080/categories" \ -H "Authorization: Bearer ${TOKEN}" \ -H "Content-Type: application/json" \ -d '{"parentId":0,"name":"电子产品","slug":"electronics","sortOrder":1}'
  1. 获取单个分类
GET /categories/{id} Headers: Authorization: Bearer {token}
  1. 更新分类(部分更新)
PATCH /categories/{id} Headers: Authorization: Bearer {token} Body: 只包含需要修改的字段,例如: { "name": "手机及配件", "sortOrder": 2 }
  1. 删除分类(若存在子分类将禁止删除)
DELETE /categories/{id} Headers: Authorization: Bearer {token}
  1. 获取分类树(多级)
GET /categories/tree Headers: Authorization: Bearer {token}
  1. 平铺查询(可按 parentId 查询子分类)
GET /categories?parentId=1 Headers: Authorization: Bearer {token}

说明:返回的分类对象包含 children 字段(数组)表示下级分类。

示例响应片段:

{ "code":200, "msg":"操作成功", "data":[ { "id":1, "name":"电子产品", "children":[ {"id":2,"name":"手机"}, {"id":3,"name":"笔记本"} ] } ] }

购物车、地址与订单接口(新增)

下面列出项目中已实现的购物车、地址与订单相关接口、请求示例与说明。

注意:需要登录的接口请在请求头中带上 Authorization: Bearer {token}

购物车(Cart)

  • 添加商品到购物车
POST /cart/add Content-Type: application/json Authorization: Bearer {token} { "productId": 1, "quantity": 2 }
  • 修改购物项数量
POST /cart/update Content-Type: application/json Authorization: Bearer {token} { "id": 10, "quantity": 3 }
  • 删除购物项
DELETE /cart/{id} Authorization: Bearer {token}
  • 获取当前用户购物车列表
GET /cart/list Authorization: Bearer {token}

地址管理(Address)

  • 添加收货地址
POST /address/add Content-Type: application/json Authorization: Bearer {token} { "receiverName": "张三", "phone": "13800000000", "province": "广东省", "city": "深圳市", "district": "南山区", "detail": "科技园路100号", "isDefault": 1 }
  • 更新收货地址
POST /address/update Content-Type: application/json Authorization: Bearer {token} { "id": 1, "receiverName": "张三", "phone": "13800000000", "province": "广东省", "city": "深圳市", "district": "南山区", "detail": "科技园路101号", "isDefault": 1 }
  • 删除地址
DELETE /address/{id} Authorization: Bearer {token}
  • 列表
GET /address/list Authorization: Bearer {token}

当添加或更新地址并设置 isDefault=1 时,系统会将该用户其它地址设为非默认。

订单(Order)

支持从购物车下单或直接传入商品项下单,支持分页查询、订单详情、状态流转和统计。

  • 创建订单(从购物车或传入 items)
POST /order/create Content-Type: application/json Authorization: Bearer {token} { "items": [ { "productId": 1, "quantity": 2 } ], // 可选,若为空则使用购物车 selected=1 的项 "addressId": 1, "remark": "请尽快发货" }

返回:创建的 Order 实体(包含 orderNo, totalAmount, status 等)。

  • 查询(按用户、按状态,支持分页)
GET /order/list?pageNum=1&pageSize=10&status=PAID Authorization: Bearer {token}
  • 订单详情(当前返回 Order 实体)
GET /order/{id} Authorization: Bearer {token}
  • 订单状态流转(示例)
POST /order/{id}/pay // 标记为已支付 POST /order/{id}/ship // 标记为已发货 POST /order/{id}/complete // 标记为已完成 POST /order/{id}/cancel // 取消订单
  • 订单统计
GET /order/stats Authorization: Bearer {token}

返回当前用户各状态订单数量(PENDING_PAYMENT、PAID、SHIPPED、COMPLETED、CANCELLED)。