基于 Spring Boot 3.5 + Spring Security + JWT + MyBatis Plus 的商城后端管理系统,实现了完整的用户认证授权、RBAC 权限管理功能。
- id: 用户ID(主键,自增)
- username: 用户名(唯一)
- password: 密码(BCrypt 加密)
- email: 邮箱
- status: 状态(1=启用,0=禁用)
- created_at: 创建时间
- updated_at: 更新时间
- role_id: 角色ID(主键,自增)
- role_name: 角色名称
- role_code: 角色代码(ADMIN/EDITOR/USER)
- description: 描述
- status: 状态
- create_at: 创建时间
- update_at: 更新时间
- permission_id: 权限ID(主键,自增)
- permission_name: 权限名称
- permission_code: 权限代码(如:product:view)
- resource: 资源类型
- action: 操作类型
- description: 描述
- id: 主键
- user_id: 用户ID(外键)
- role_id: 角色ID(外键)
- create_at: 创建时间
- id: 主键
- role_id: 角色ID(外键)
- permission_id: 权限ID(外键)
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. 创建数据库
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
编辑 src/main/resources/application.properties:
spring.datasource.username=your_username spring.datasource.password=your_password
spring.data.redis.host=localhost spring.data.redis.port=6379 spring.data.redis.password=
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
http://localhost:8080application/jsonBearer {token} (登录后需要)POST /user/registerUser Content-Type: application/json { "username": "test", "password": "123456" }
响应示例:
{
"code": 200,
"msg": "注册成功",
"data": null
}
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"
}
}
当 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 中保存的值匹配。
GET /auth/logout Authorization: Bearer {token}
响应示例:
{
"code": 200,
"msg": "操作成功",
"data": {
"message": "登出成功",
"logoutTime": "2026-01-25"
}
}
GET /auth/profile Authorization: Bearer {token}
响应示例:
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1,
"name": "test",
"email": "test@example.com",
"status": 1,
"nowTime": "2026-01-25"
}
}
POST /user/update Authorization: Bearer {token} Content-Type: application/json { "email": "newemail@example.com" }
POST /user/changePassword Authorization: Bearer {token} Content-Type: application/json { "oldPassword": "123456", "newPassword": "654321" }
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": "查看报表权限"
}
]
}
}
GET /user/roles Authorization: Bearer {token}
GET /user/permissions/list Authorization: Bearer {token}
商品模块提供标准的 CRUD 接口,支持分页查询与模糊搜索。
Base URL: http://localhost:8080
请求头(通用):
Content-Type: application/json(POST/PUT)Authorization: Bearer {token}(需要鉴权的接口)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。
写操作权限:需要 EDITOR 或 ADMIN 角色(后端根据 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"
}
}
GET /product/{id} Path param: id (Long) Headers: Authorization: Bearer {token}
GET /product?page=1&size=10&name=手机 Headers: Authorization: Bearer {token} Query params: - page: integer, 默认 1 - size: integer, 默认 10 - name: string, 可选,按 name 模糊匹配
PATCH /product/{id} Headers: Authorization: Bearer {token} Body: 与创建接口相同的 JSON 结构,但只需要包含要修改的字段(只会合并非 null 字段) 示例:只修改价格和库存 { "price": 1899.00, "stock": 100 }
说明:
PATCH /product/{id},后端可能同时支持 PATCH /product?id={id} 或在请求体中包含 id(兼容性由后端决定)。EDITOR 或 ADMIN 角色;查看需要登录(USER 及以上)。DELETE /product/{id} Headers: Authorization: Bearer {token}
PATCH /product/{id}/status?status=1 Headers: Authorization: Bearer {token} Query params: - status: integer, 必选,`1`=上架,`0`=下架
说明:写操作需要 EDITOR 或 ADMIN 角色。示例:把 id=101 的商品下架
curl -X PATCH "http://localhost:8080/product/101/status?status=0" \
-H "Authorization: Bearer ${TOKEN}"
成功响应示例:
{
"code":200,
"msg":"设置成功",
"data":null
}
评论模块提供商品评价的发布、查询、回复、点赞、举报及按评分/时间筛选。
Base URL: http://localhost:8080
请求头(通用):
Content-Type: application/json(POST/PUT)Authorization: Bearer {token}(发布、回复、点赞、举报、商家回复等需登录)POST /review Headers: Authorization: Bearer {token} Body (JSON): { "productId": 1, "rating": 5, "content": "非常不错,性价比高。", "images": "[\"https://example.com/1.jpg\"]" }
必填字段:productId。rating 为 1–5,默认 5;content、images 可选。
成功响应:返回完整评价对象(含 id、点赞数、回复列表等)。
GET /review/product/{productId}?page=1&size=10&rating=5&sortBy=time_desc
Query 参数:
page: 页码,默认 1size: 每页条数,默认 10rating: 可选,1–5,仅返回该评分的评价sortBy: 可选,time_desc(默认)| time_asc | rating_desc | rating_asc无需登录。响应为分页结果,每条包含评价信息、回复列表、点赞数、当前用户是否已点赞(未登录为 false)。
GET /review/{reviewId}
返回单条评价详情(含回复列表、点赞数、当前用户是否已点赞)。无需登录。
POST /review/reply Headers: Authorization: Bearer {token} Body (JSON): { "reviewId": 1, "content": "同意,确实很划算。" }
必填:reviewId、content。成功返回 "回复成功"。
PUT /review/{reviewId}/seller-reply Headers: Authorization: Bearer {token} Body (JSON): { "content": "感谢您的支持,欢迎再次购买。" }
将内容写入该评价的 reply 字段。成功返回 "回复成功"。
POST /review/{reviewId}/like Headers: Authorization: Bearer {token}
同一用户对同一评价再次请求即取消点赞。响应 data 为 true 表示当前为已点赞状态,false 表示已取消。
POST /review/report Headers: Authorization: Bearer {token} Body (JSON): { "reviewId": 1, "reason": "不当言论" }
必填:reviewId;reason 可选。成功返回 "举报已提交"。
对外提供多级分类管理接口,支持树形查询与 CRUD(写操作需要鉴权)。
POST /categories Headers: Authorization: Bearer {token} Body (JSON): { "parentId": 1, // 可选,顶级分类可为空 "name": "手机", "slug": "electronics-phones", "description": "手机分类", "sortOrder": 1, "status": 1 }
必填字段:name。
写操作权限:只有 EDITOR 或 ADMIN 可创建/更新/删除分类(后端通过 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}'
GET /categories/{id} Headers: Authorization: Bearer {token}
PATCH /categories/{id} Headers: Authorization: Bearer {token} Body: 只包含需要修改的字段,例如: { "name": "手机及配件", "sortOrder": 2 }
DELETE /categories/{id} Headers: Authorization: Bearer {token}
GET /categories/tree Headers: Authorization: Bearer {token}
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}。
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}
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 时,系统会将该用户其它地址设为非默认。
支持从购物车下单或直接传入商品项下单,支持分页查询、订单详情、状态流转和统计。
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)。