logo
3
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)。

About

No description, topics, or website provided.
Language
Java100%