feat: 初始化后端项目基础架构
添加项目基础配置文件和目录结构 实现用户、角色、权限等核心模块的实体类、Mapper接口和服务层 配置数据库连接和MyBatis-Plus支持 添加统一响应格式和异常处理机制
This commit is contained in:
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/mvnw text eol=lf
|
||||
*.cmd text eol=crlf
|
||||
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
HELP.md
|
||||
target/
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
3
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
3
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
wrapperVersion=3.3.4
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
|
||||
81
Plain.text
Normal file
81
Plain.text
Normal file
@@ -0,0 +1,81 @@
|
||||
e:\TaoTaoWang\backend\
|
||||
├── pom.xml # Maven依赖配置
|
||||
├── src/main/java/com/taotaowang/
|
||||
│ ├── TaotaoWangApplication.java # 应用主启动类
|
||||
│ ├── config/ # 配置类
|
||||
│ │ ├── SecurityConfig.java # 安全配置
|
||||
│ │ ├── MyBatisPlusConfig.java # MyBatis-Plus配置
|
||||
│ │ ├── RedisConfig.java # Redis配置
|
||||
│ │ ├── SwaggerConfig.java # Swagger文档配置
|
||||
│ │ └── WebConfig.java # Web配置
|
||||
│ ├── controller/ # 控制器层
|
||||
│ │ ├── AuthController.java # 认证相关接口
|
||||
│ │ ├── UserController.java # 用户管理接口
|
||||
│ │ ├── RoleController.java # 角色管理接口
|
||||
│ │ ├── PermissionController.java # 权限管理接口
|
||||
│ │ ├── ProductController.java # 商品管理接口
|
||||
│ │ ├── OrderController.java # 订单管理接口
|
||||
│ │ ├── ShopController.java # 店铺管理接口
|
||||
│ │ └── MarketingController.java # 营销活动接口
|
||||
│ ├── service/ # 业务层
|
||||
│ │ ├── impl/ # 业务实现类
|
||||
│ │ │ ├── AuthServiceImpl.java
|
||||
│ │ │ ├── UserServiceImpl.java
|
||||
│ │ │ ├── RoleServiceImpl.java
|
||||
│ │ │ ├── PermissionServiceImpl.java
|
||||
│ │ │ ├── ProductServiceImpl.java
|
||||
│ │ │ ├── OrderServiceImpl.java
|
||||
│ │ │ ├── ShopServiceImpl.java
|
||||
│ │ │ └── MarketingServiceImpl.java
|
||||
│ │ ├── AuthService.java # 认证服务接口
|
||||
│ │ ├── UserService.java # 用户服务接口
|
||||
│ │ ├── RoleService.java # 角色服务接口
|
||||
│ │ ├── PermissionService.java # 权限服务接口
|
||||
│ │ ├── ProductService.java # 商品服务接口
|
||||
│ │ ├── OrderService.java # 订单服务接口
|
||||
│ │ ├── ShopService.java # 店铺服务接口
|
||||
│ │ └── MarketingService.java # 营销服务接口
|
||||
│ ├── mapper/ # 数据访问层
|
||||
│ │ ├── UserMapper.java
|
||||
│ │ ├── RoleMapper.java
|
||||
│ │ ├── PermissionMapper.java
|
||||
│ │ ├── ProductMapper.java
|
||||
│ │ ├── OrderMapper.java
|
||||
│ │ └── ShopMapper.java
|
||||
│ ├── entity/ # 实体层
|
||||
│ │ ├── User.java
|
||||
│ │ ├── Role.java
|
||||
│ │ ├── Permission.java
|
||||
│ │ ├── Product.java
|
||||
│ │ ├── Order.java
|
||||
│ │ ├── Shop.java
|
||||
│ │ └── Marketing.java
|
||||
│ ├── dto/ # 数据传输对象
|
||||
│ │ ├── request/ # 请求DTO
|
||||
│ │ │ ├── LoginRequest.java
|
||||
│ │ │ ├── RegisterRequest.java
|
||||
│ │ │ ├── ProductRequest.java
|
||||
│ │ │ └── OrderRequest.java
|
||||
│ │ └── response/ # 响应DTO
|
||||
│ │ ├── LoginResponse.java
|
||||
│ │ ├── UserResponse.java
|
||||
│ │ ├── ProductResponse.java
|
||||
│ │ └── OrderResponse.java
|
||||
│ ├── exception/ # 异常处理
|
||||
│ │ ├── GlobalExceptionHandler.java # 全局异常处理器
|
||||
│ │ ├── BusinessException.java # 业务异常
|
||||
│ │ └── ErrorCode.java # 错误码定义
|
||||
│ ├── util/ # 工具类
|
||||
│ │ ├── JwtUtil.java # JWT工具
|
||||
│ │ ├── SecurityUtil.java # 安全工具
|
||||
│ │ └── ResponseUtil.java # 响应工具
|
||||
│ └── interceptor/ # 拦截器
|
||||
│ ├── JwtInterceptor.java # JWT拦截器
|
||||
│ └── LogInterceptor.java # 日志拦截器
|
||||
└── src/main/resources/
|
||||
├── application.yml # 主配置文件
|
||||
├── application-dev.yml # 开发环境配置
|
||||
├── application-test.yml # 测试环境配置
|
||||
├── application-prod.yml # 生产环境配置
|
||||
├── mapper/ # MyBatis映射文件
|
||||
└── static/ # 静态资源
|
||||
268
doc/数据库关系图.md
Normal file
268
doc/数据库关系图.md
Normal file
@@ -0,0 +1,268 @@
|
||||
# 数据库关系图
|
||||
|
||||
下面使用Mermaid语法生成的数据库实体关系图(ER图),展示了系统中各个表之间的关联关系:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
%% 用户相关表
|
||||
users ||--o{ user_details : has
|
||||
users ||--o{ shops : owns
|
||||
users ||--o{ orders : places
|
||||
users ||--o{ payments : makes
|
||||
users ||--o{ refunds : requests
|
||||
users ||--o{ shop_ratings : writes
|
||||
users ||--o{ user_roles : assigned_to
|
||||
|
||||
%% 权限相关表
|
||||
roles ||--o{ user_roles : has
|
||||
roles ||--o{ role_permissions : contains
|
||||
permissions ||--o{ role_permissions : included_in
|
||||
|
||||
%% 店铺相关表
|
||||
shops ||--o{ products : sells
|
||||
shops ||--o{ orders : receives
|
||||
shops ||--o{ refunds : processes
|
||||
shops ||--o{ shop_ratings : receives
|
||||
shop_categories ||--o{ shops : categorizes
|
||||
shop_categories }o--|| shop_categories : parent
|
||||
|
||||
%% 商品相关表
|
||||
products ||--o{ product_images : has
|
||||
products ||--o{ product_skus : contains
|
||||
products ||--o{ product_attribute_values : has
|
||||
products ||--o{ order_items : included_in
|
||||
product_categories ||--o{ products : categorizes
|
||||
product_categories }o--|| product_categories : parent
|
||||
product_categories ||--o{ product_attributes : defines
|
||||
product_attributes ||--o{ product_attribute_values : has
|
||||
product_skus ||--o{ product_inventories : manages
|
||||
product_skus ||--o{ order_items : selected_in
|
||||
|
||||
%% 订单相关表
|
||||
orders ||--o{ order_items : contains
|
||||
orders ||--o{ order_status_history : tracks
|
||||
orders ||--o{ payments : related_to
|
||||
orders ||--o{ refunds : triggers
|
||||
orders ||--o{ shop_ratings : based_on
|
||||
|
||||
%% 支付与退款相关表
|
||||
payments ||--o{ refunds : reversed_by
|
||||
order_items ||--o{ refunds : includes
|
||||
|
||||
%% 表定义
|
||||
users {
|
||||
BIGINT id PK
|
||||
VARCHAR username
|
||||
VARCHAR password
|
||||
VARCHAR email
|
||||
VARCHAR phone
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
user_details {
|
||||
BIGINT id PK
|
||||
BIGINT userId FK
|
||||
VARCHAR realName
|
||||
VARCHAR idCard
|
||||
INTEGER gender
|
||||
}
|
||||
|
||||
roles {
|
||||
BIGINT id PK
|
||||
VARCHAR roleName
|
||||
INTEGER roleType
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
permissions {
|
||||
BIGINT id PK
|
||||
VARCHAR permissionName
|
||||
VARCHAR permissionCode
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
user_roles {
|
||||
BIGINT id PK
|
||||
BIGINT userId FK
|
||||
BIGINT roleId FK
|
||||
}
|
||||
|
||||
role_permissions {
|
||||
BIGINT id PK
|
||||
BIGINT roleId FK
|
||||
BIGINT permissionId FK
|
||||
}
|
||||
|
||||
shops {
|
||||
BIGINT id PK
|
||||
VARCHAR shopName
|
||||
BIGINT userId FK
|
||||
BIGINT categoryId FK
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
shop_categories {
|
||||
BIGINT id PK
|
||||
VARCHAR categoryName
|
||||
BIGINT parentId FK
|
||||
INTEGER level
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
products {
|
||||
BIGINT id PK
|
||||
VARCHAR productName
|
||||
BIGINT shopId FK
|
||||
BIGINT categoryId FK
|
||||
DECIMAL price
|
||||
INTEGER stock
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
product_categories {
|
||||
BIGINT id PK
|
||||
VARCHAR categoryName
|
||||
BIGINT parentId FK
|
||||
INTEGER level
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
product_attributes {
|
||||
BIGINT id PK
|
||||
VARCHAR attributeName
|
||||
BIGINT categoryId FK
|
||||
INTEGER attributeType
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
product_attribute_values {
|
||||
BIGINT id PK
|
||||
BIGINT productId FK
|
||||
BIGINT attributeId FK
|
||||
VARCHAR attributeValue
|
||||
}
|
||||
|
||||
product_images {
|
||||
BIGINT id PK
|
||||
BIGINT productId FK
|
||||
VARCHAR imageUrl
|
||||
INTEGER isMain
|
||||
}
|
||||
|
||||
product_skus {
|
||||
BIGINT id PK
|
||||
BIGINT productId FK
|
||||
VARCHAR skuCode
|
||||
DECIMAL price
|
||||
INTEGER stock
|
||||
INTEGER status
|
||||
}
|
||||
|
||||
product_inventories {
|
||||
BIGINT id PK
|
||||
BIGINT skuId FK
|
||||
INTEGER currentStock
|
||||
INTEGER safetyStock
|
||||
INTEGER lockStock
|
||||
}
|
||||
|
||||
orders {
|
||||
BIGINT id PK
|
||||
VARCHAR orderNo
|
||||
BIGINT userId FK
|
||||
BIGINT shopId FK
|
||||
DECIMAL totalAmount
|
||||
INTEGER orderStatus
|
||||
}
|
||||
|
||||
order_items {
|
||||
BIGINT id PK
|
||||
BIGINT orderId FK
|
||||
BIGINT productId FK
|
||||
BIGINT skuId FK
|
||||
DECIMAL price
|
||||
INTEGER quantity
|
||||
INTEGER itemStatus
|
||||
}
|
||||
|
||||
order_status_history {
|
||||
BIGINT id PK
|
||||
BIGINT orderId FK
|
||||
INTEGER previousStatus
|
||||
INTEGER currentStatus
|
||||
}
|
||||
|
||||
payments {
|
||||
BIGINT id PK
|
||||
VARCHAR paymentNo
|
||||
BIGINT orderId FK
|
||||
BIGINT userId FK
|
||||
DECIMAL amount
|
||||
INTEGER paymentStatus
|
||||
}
|
||||
|
||||
refunds {
|
||||
BIGINT id PK
|
||||
VARCHAR refundNo
|
||||
BIGINT orderId FK
|
||||
BIGINT orderItemId FK
|
||||
BIGINT userId FK
|
||||
BIGINT shopId FK
|
||||
DECIMAL refundAmount
|
||||
INTEGER refundStatus
|
||||
}
|
||||
|
||||
shop_ratings {
|
||||
BIGINT id PK
|
||||
BIGINT shopId FK
|
||||
BIGINT userId FK
|
||||
BIGINT orderId FK
|
||||
INTEGER rating
|
||||
INTEGER status
|
||||
}
|
||||
```
|
||||
|
||||
## 关系说明
|
||||
|
||||
### 一对一关系
|
||||
- **users 和 user_details**:每个用户只有一个详细信息记录
|
||||
|
||||
### 一对多关系
|
||||
- **users 和 shops**:一个用户可以创建多个店铺
|
||||
- **shops 和 products**:一个店铺可以有多个商品
|
||||
- **users 和 orders**:一个用户可以有多个订单
|
||||
- **shops 和 orders**:一个店铺可以有多个订单
|
||||
- **orders 和 order_items**:一个订单可以包含多个商品项
|
||||
- **products 和 product_images**:一个商品可以有多个图片
|
||||
- **products 和 product_skus**:一个商品可以有多个SKU
|
||||
- **product_skus 和 product_inventories**:一个SKU对应一个库存记录
|
||||
- **orders 和 order_status_history**:一个订单可以有多个状态历史记录
|
||||
- **orders 和 payments**:一个订单可以有多个支付记录
|
||||
- **orders 和 refunds**:一个订单可以有多个退款记录
|
||||
- **order_items 和 refunds**:一个订单项可以有多个退款记录
|
||||
- **shops 和 shop_ratings**:一个店铺可以有多个评价
|
||||
- **users 和 shop_ratings**:一个用户可以对多个店铺进行评价
|
||||
- **orders 和 shop_ratings**:一个订单对应一个店铺评价
|
||||
|
||||
### 多对多关系
|
||||
- **users 和 roles**:通过user_roles表关联
|
||||
- **roles 和 permissions**:通过role_permissions表关联
|
||||
|
||||
### 自关联关系
|
||||
- **shop_categories 和 shop_categories**:店铺分类的父子关系
|
||||
- **product_categories 和 product_categories**:商品分类的父子关系
|
||||
|
||||
## 查看方法
|
||||
|
||||
要查看此关系图,可以使用支持Mermaid语法的工具或编辑器,例如:
|
||||
|
||||
1. **在线工具**:
|
||||
- [Mermaid Live Editor](https://mermaid.live/)
|
||||
- [Markdown Preview Enhanced](https://shd101wyy.github.io/markdown-preview-enhanced/#/)
|
||||
|
||||
2. **IDE插件**:
|
||||
- VS Code的Markdown Preview Enhanced插件
|
||||
- IntelliJ IDEA的Mermaid插件
|
||||
|
||||
3. **版本控制系统**:
|
||||
- GitHub、GitLab等平台已支持Mermaid语法渲染
|
||||
95
doc/数据库关系图_简洁版.md
Normal file
95
doc/数据库关系图_简洁版.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# 数据库关系图(简洁版)
|
||||
|
||||
下面是使用Mermaid语法生成的简洁版数据库实体关系图,重点突出表之间的关联关系:
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
%% 用户与权限系统
|
||||
users ||--o{ user_details : has
|
||||
users }o--o{ roles : "多对多" via user_roles
|
||||
roles }o--o{ permissions : "多对多" via role_permissions
|
||||
|
||||
%% 店铺系统
|
||||
users ||--o{ shops : owns
|
||||
shops ||--o{ products : sells
|
||||
shop_categories ||--o{ shops : categorizes
|
||||
shop_categories }o--|| shop_categories : parent-child
|
||||
|
||||
%% 商品系统
|
||||
products ||--o{ product_images : has
|
||||
products ||--o{ product_skus : contains
|
||||
products ||--o{ product_attribute_values : has_attributes
|
||||
product_categories ||--o{ products : categorizes
|
||||
product_categories }o--|| product_categories : parent-child
|
||||
product_categories ||--o{ product_attributes : defines
|
||||
product_attributes ||--o{ product_attribute_values : values
|
||||
product_skus ||--o{ product_inventories : inventory
|
||||
|
||||
%% 订单系统
|
||||
users ||--o{ orders : places
|
||||
shops ||--o{ orders : receives
|
||||
orders ||--o{ order_items : contains
|
||||
orders ||--o{ order_status_history : status_history
|
||||
order_items ||--o{ products : product
|
||||
order_items ||--o{ product_skus : sku
|
||||
|
||||
%% 支付与退款
|
||||
orders ||--o{ payments : payment
|
||||
orders ||--o{ refunds : refund
|
||||
order_items ||--o{ refunds : item_refund
|
||||
payments ||--o{ refunds : reversed_by
|
||||
|
||||
%% 评价系统
|
||||
users ||--o{ shop_ratings : reviews
|
||||
shops ||--o{ shop_ratings : rated
|
||||
orders ||--o{ shop_ratings : based_on
|
||||
```
|
||||
|
||||
## 核心表关系说明
|
||||
|
||||
### 1. 用户与权限模块
|
||||
- **用户-详情**:一对一关系,用户信息和用户详细资料分离存储
|
||||
- **用户-角色**:多对多关系,通过user_roles关联表实现
|
||||
- **角色-权限**:多对多关系,通过role_permissions关联表实现
|
||||
|
||||
### 2. 店铺模块
|
||||
- **用户-店铺**:一对多关系,一个用户可以创建多个店铺
|
||||
- **店铺分类-店铺**:一对多关系,一个分类包含多个店铺
|
||||
- **店铺分类自身**:自关联,支持多级分类结构
|
||||
|
||||
### 3. 商品模块
|
||||
- **店铺-商品**:一对多关系,一个店铺可以销售多个商品
|
||||
- **商品-图片**:一对多关系,一个商品可以有多张图片
|
||||
- **商品-SKU**:一对多关系,一个商品可以有多个SKU(库存单元)
|
||||
- **SKU-库存**:一对一关系,每个SKU对应一个库存记录
|
||||
- **商品-属性值**:一对多关系,一个商品可以有多个属性值
|
||||
- **商品分类-商品**:一对多关系,一个分类包含多个商品
|
||||
- **商品分类-属性**:一对多关系,一个分类定义多个属性
|
||||
- **属性-属性值**:一对多关系,一个属性可以有多个值
|
||||
|
||||
### 4. 订单模块
|
||||
- **用户-订单**:一对多关系,一个用户可以下多个订单
|
||||
- **店铺-订单**:一对多关系,一个店铺可以接收多个订单
|
||||
- **订单-订单项**:一对多关系,一个订单包含多个商品项
|
||||
- **订单项-商品/SKU**:多对一关系,订单项关联到具体的商品和SKU
|
||||
- **订单-状态历史**:一对多关系,记录订单状态变更历史
|
||||
|
||||
### 5. 支付与退款模块
|
||||
- **订单-支付**:一对多关系,一个订单可以有多次支付记录
|
||||
- **订单-退款**:一对多关系,一个订单可以有多次退款
|
||||
- **订单项-退款**:一对多关系,一个订单项可以有多次退款
|
||||
- **支付-退款**:一对多关系,一笔支付可以对应多笔退款
|
||||
|
||||
### 6. 评价模块
|
||||
- **用户-评价**:一对多关系,用户可以对多个店铺评价
|
||||
- **店铺-评价**:一对多关系,店铺可以收到多个评价
|
||||
- **订单-评价**:一对一关系,一个订单对应一个评价
|
||||
|
||||
## 表关系符号说明
|
||||
|
||||
- `||--o{` : 一对一关系(1:1)
|
||||
- `||--o{` : 一对多关系(1:N)
|
||||
- `}o--o{` : 多对多关系(N:M)
|
||||
- `}o--||` : 自关联关系
|
||||
|
||||
此简洁版关系图重点突出了系统各模块之间的核心关联,有助于理解整个数据库的设计架构。
|
||||
467
doc/数据库表结构与关系文档.md
Normal file
467
doc/数据库表结构与关系文档.md
Normal file
@@ -0,0 +1,467 @@
|
||||
# 数据库表结构与关系文档
|
||||
|
||||
## 目录
|
||||
|
||||
1. [用户相关表](#用户相关表)
|
||||
2. [权限相关表](#权限相关表)
|
||||
3. [店铺相关表](#店铺相关表)
|
||||
4. [商品相关表](#商品相关表)
|
||||
5. [订单相关表](#订单相关表)
|
||||
6. [支付与退款相关表](#支付与退款相关表)
|
||||
7. [评价相关表](#评价相关表)
|
||||
8. [表与表之间的关系](#表与表之间的关系)
|
||||
|
||||
## 用户相关表
|
||||
|
||||
### users表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 用户ID | 主键,自增 |
|
||||
| username | VARCHAR | 用户名 | 唯一 |
|
||||
| password | VARCHAR | 密码 | 加密存储 |
|
||||
| email | VARCHAR | 邮箱 | 唯一 |
|
||||
| phone | VARCHAR | 手机号 | 唯一 |
|
||||
| avatar | VARCHAR | 头像URL | |
|
||||
| status | INTEGER | 状态 | 0:禁用, 1:启用 |
|
||||
| lastLoginTime | DATE | 最后登录时间 | |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### user_details表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 详情ID | 主键,自增 |
|
||||
| userId | BIGINT | 用户ID | 外键,关联users表 |
|
||||
| realName | VARCHAR | 真实姓名 | |
|
||||
| idCard | VARCHAR | 身份证号 | |
|
||||
| gender | INTEGER | 性别 | |
|
||||
| birthday | DATE | 生日 | |
|
||||
| address | VARCHAR | 地址 | |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
## 权限相关表
|
||||
|
||||
### roles表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 角色ID | 主键,自增 |
|
||||
| roleName | VARCHAR | 角色名称 | |
|
||||
| description | VARCHAR | 角色描述 | |
|
||||
| roleType | INTEGER | 角色类型 | 0:默认用户,1:店主,2:管理员 |
|
||||
| status | INTEGER | 状态 | 0:禁用, 1:启用 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### permissions表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 权限ID | 主键,自增 |
|
||||
| permissionName | VARCHAR | 权限名称 | |
|
||||
| permissionCode | VARCHAR | 权限编码 | |
|
||||
| description | VARCHAR | 权限描述 | |
|
||||
| module | VARCHAR | 所属模块 | |
|
||||
| status | INTEGER | 状态 | 0:禁用, 1:启用 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### user_roles表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 关联ID | 主键,自增 |
|
||||
| userId | BIGINT | 用户ID | 外键,关联users表 |
|
||||
| roleId | BIGINT | 角色ID | 外键,关联roles表 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
|
||||
### role_permissions表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 关联ID | 主键,自增 |
|
||||
| roleId | BIGINT | 角色ID | 外键,关联roles表 |
|
||||
| permissionId | BIGINT | 权限ID | 外键,关联permissions表 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
|
||||
## 店铺相关表
|
||||
|
||||
### shops表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 店铺ID | 主键,自增 |
|
||||
| shopName | VARCHAR | 店铺名称 | |
|
||||
| userId | BIGINT | 店主用户ID | 外键,关联users表 |
|
||||
| categoryId | BIGINT | 店铺分类ID | 外键,关联shop_categories表 |
|
||||
| logo | VARCHAR | 店铺Logo | |
|
||||
| coverImage | VARCHAR | 店铺封面图 | |
|
||||
| description | VARCHAR | 店铺描述 | |
|
||||
| status | INTEGER | 状态 | 0:待审核, 1:正常, 2:封禁 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### shop_categories表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 分类ID | 主键,自增 |
|
||||
| categoryName | VARCHAR | 分类名称 | |
|
||||
| parentId | BIGINT | 父分类ID | |
|
||||
| level | INTEGER | 分类级别 | |
|
||||
| sort | INTEGER | 排序 | |
|
||||
| status | INTEGER | 状态 | 0:禁用, 1:启用 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
## 商品相关表
|
||||
|
||||
### products表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 商品ID | 主键,自增 |
|
||||
| productName | VARCHAR | 商品名称 | |
|
||||
| shopId | BIGINT | 店铺ID | 外键,关联shops表 |
|
||||
| categoryId | BIGINT | 商品分类ID | 外键,关联product_categories表 |
|
||||
| brand | VARCHAR | 品牌 | |
|
||||
| description | VARCHAR | 商品描述 | |
|
||||
| mainImage | VARCHAR | 主图URL | |
|
||||
| price | DECIMAL | 价格 | |
|
||||
| originalPrice | DECIMAL | 原价 | |
|
||||
| stock | INTEGER | 库存 | |
|
||||
| sales | INTEGER | 销量 | |
|
||||
| status | INTEGER | 状态 | 0:下架, 1:上架 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### product_categories表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 分类ID | 主键,自增 |
|
||||
| categoryName | VARCHAR | 分类名称 | |
|
||||
| parentId | BIGINT | 父分类ID | |
|
||||
| level | INTEGER | 分类级别 | |
|
||||
| sort | INTEGER | 排序 | |
|
||||
| status | INTEGER | 状态 | 0:禁用, 1:启用 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### product_attributes表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 属性ID | 主键,自增 |
|
||||
| attributeName | VARCHAR | 属性名称 | |
|
||||
| categoryId | BIGINT | 分类ID | 外键,关联product_categories表 |
|
||||
| attributeType | INTEGER | 属性类型 | 0:普通属性, 1:规格属性 |
|
||||
| sort | INTEGER | 排序 | |
|
||||
| status | INTEGER | 状态 | 0:禁用, 1:启用 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### product_attribute_values表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 属性值ID | 主键,自增 |
|
||||
| productId | BIGINT | 商品ID | 外键,关联products表 |
|
||||
| attributeId | BIGINT | 属性ID | 外键,关联product_attributes表 |
|
||||
| attributeValue | VARCHAR | 属性值 | |
|
||||
| sort | INTEGER | 排序 | |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### product_images表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 图片ID | 主键,自增 |
|
||||
| productId | BIGINT | 商品ID | 外键,关联products表 |
|
||||
| imageUrl | VARCHAR | 图片URL | |
|
||||
| sort | INTEGER | 排序 | |
|
||||
| isMain | INTEGER | 是否主图 | 0:非主图, 1:主图 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
|
||||
### product_skus表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | SKU ID | 主键,自增 |
|
||||
| productId | BIGINT | 商品ID | 外键,关联products表 |
|
||||
| skuCode | VARCHAR | SKU编码 | |
|
||||
| skuSpecs | VARCHAR | SKU规格信息 | JSON格式存储 |
|
||||
| price | DECIMAL | 价格 | |
|
||||
| stock | INTEGER | 库存 | |
|
||||
| image | VARCHAR | 图片 | |
|
||||
| status | INTEGER | 状态 | 0:禁用, 1:启用 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### product_inventories表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 库存ID | 主键,自增 |
|
||||
| skuId | BIGINT | SKU ID | 外键,关联product_skus表 |
|
||||
| currentStock | INTEGER | 当前库存 | |
|
||||
| safetyStock | INTEGER | 安全库存 | |
|
||||
| lockStock | INTEGER | 锁定库存 | |
|
||||
| lastUpdateTime | DATE | 最后更新时间 | |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
## 订单相关表
|
||||
|
||||
### orders表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 订单ID | 主键,自增 |
|
||||
| orderNo | VARCHAR | 订单号 | |
|
||||
| userId | BIGINT | 用户ID | 外键,关联users表 |
|
||||
| shopId | BIGINT | 店铺ID | 外键,关联shops表 |
|
||||
| totalAmount | DECIMAL | 总金额 | |
|
||||
| actualAmount | DECIMAL | 实际支付金额 | |
|
||||
| shippingFee | DECIMAL | 运费 | |
|
||||
| orderStatus | INTEGER | 订单状态 | 0:待付款, 1:待发货, 2:待收货, 3:已完成, 4:已取消, 5:已退款 |
|
||||
| shippingAddress | VARCHAR | 收货地址 | |
|
||||
| receiverName | VARCHAR | 收件人姓名 | |
|
||||
| receiverPhone | VARCHAR | 收件人电话 | |
|
||||
| paymentMethod | VARCHAR | 支付方式 | |
|
||||
| paymentTime | DATE | 支付时间 | |
|
||||
| shippingTime | DATE | 发货时间 | |
|
||||
| deliveryTime | DATE | 送达时间 | |
|
||||
| completeTime | DATE | 完成时间 | |
|
||||
| remark | VARCHAR | 备注 | |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### order_items表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 订单项ID | 主键,自增 |
|
||||
| orderId | BIGINT | 订单ID | 外键,关联orders表 |
|
||||
| productId | BIGINT | 商品ID | 外键,关联products表 |
|
||||
| skuId | BIGINT | SKU ID | 外键,关联product_skus表 |
|
||||
| productName | VARCHAR | 商品名称 | |
|
||||
| skuSpecs | VARCHAR | SKU规格 | |
|
||||
| productImage | VARCHAR | 商品图片 | |
|
||||
| price | DECIMAL | 价格 | |
|
||||
| quantity | INTEGER | 数量 | |
|
||||
| subtotal | DECIMAL | 小计 | |
|
||||
| itemStatus | INTEGER | 商品状态 | 0:正常, 1:已退款, 2:退款中 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### order_status_history表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 历史ID | 主键,自增 |
|
||||
| orderId | BIGINT | 订单ID | 外键,关联orders表 |
|
||||
| previousStatus | INTEGER | 之前状态 | |
|
||||
| currentStatus | INTEGER | 当前状态 | |
|
||||
| changeReason | VARCHAR | 变更原因 | |
|
||||
| operator | VARCHAR | 操作人 | |
|
||||
| changeTime | DATE | 变更时间 | |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
|
||||
## 支付与退款相关表
|
||||
|
||||
### payments表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 支付ID | 主键,自增 |
|
||||
| paymentNo | VARCHAR | 支付单号 | |
|
||||
| orderId | BIGINT | 订单ID | 外键,关联orders表 |
|
||||
| userId | BIGINT | 用户ID | 外键,关联users表 |
|
||||
| amount | DECIMAL | 支付金额 | |
|
||||
| paymentMethod | VARCHAR | 支付方式 | |
|
||||
| transactionId | VARCHAR | 第三方交易流水号 | |
|
||||
| paymentStatus | INTEGER | 支付状态 | 0:待支付, 1:支付成功, 2:支付失败, 3:已退款 |
|
||||
| paymentUrl | VARCHAR | 支付链接 | |
|
||||
| expireTime | DATE | 过期时间 | |
|
||||
| paymentTime | DATE | 支付时间 | |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
### refunds表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 退款ID | 主键,自增 |
|
||||
| refundNo | VARCHAR | 退款单号 | |
|
||||
| orderId | BIGINT | 订单ID | 外键,关联orders表 |
|
||||
| orderItemId | BIGINT | 订单项ID | 外键,关联order_items表 |
|
||||
| userId | BIGINT | 用户ID | 外键,关联users表 |
|
||||
| shopId | BIGINT | 店铺ID | 外键,关联shops表 |
|
||||
| refundAmount | DECIMAL | 退款金额 | |
|
||||
| refundReason | VARCHAR | 退款原因 | |
|
||||
| refundType | VARCHAR | 退款类型 | |
|
||||
| refundStatus | INTEGER | 退款状态 | 0:申请中, 1:退款成功, 2:退款失败, 3:已拒绝 |
|
||||
| refundAccount | VARCHAR | 退款账户 | |
|
||||
| transactionId | VARCHAR | 交易ID | |
|
||||
| applyTime | DATE | 申请时间 | |
|
||||
| processTime | DATE | 处理时间 | |
|
||||
| processRemark | VARCHAR | 处理备注 | |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
## 评价相关表
|
||||
|
||||
### shop_ratings表
|
||||
|
||||
| 字段名 | 类型 | 描述 | 备注 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| id | BIGINT | 评价ID | 主键,自增 |
|
||||
| shopId | BIGINT | 店铺ID | 外键,关联shops表 |
|
||||
| userId | BIGINT | 用户ID | 外键,关联users表 |
|
||||
| orderId | BIGINT | 订单ID | 外键,关联orders表 |
|
||||
| rating | INTEGER | 评分 | 1-5星 |
|
||||
| content | VARCHAR | 评价内容 | |
|
||||
| images | VARCHAR | 评价图片 | JSON格式存储 |
|
||||
| status | INTEGER | 状态 | 0:待审核, 1:已审核, 2:已删除 |
|
||||
| createdAt | DATE | 创建时间 | |
|
||||
| updatedAt | DATE | 更新时间 | |
|
||||
|
||||
## 表与表之间的关系
|
||||
|
||||
### 一对一关系
|
||||
|
||||
1. **users 和 user_details**
|
||||
- 关系:一对一
|
||||
- 描述:每个用户只有一个详细信息记录
|
||||
- 外键:user_details.userId -> users.id
|
||||
|
||||
### 一对多关系
|
||||
|
||||
1. **users 和 shops**
|
||||
- 关系:一对多
|
||||
- 描述:一个用户可以创建多个店铺(店主)
|
||||
- 外键:shops.userId -> users.id
|
||||
|
||||
2. **shops 和 products**
|
||||
- 关系:一对多
|
||||
- 描述:一个店铺可以有多个商品
|
||||
- 外键:products.shopId -> shops.id
|
||||
|
||||
3. **users 和 orders**
|
||||
- 关系:一对多
|
||||
- 描述:一个用户可以有多个订单
|
||||
- 外键:orders.userId -> users.id
|
||||
|
||||
4. **shops 和 orders**
|
||||
- 关系:一对多
|
||||
- 描述:一个店铺可以有多个订单
|
||||
- 外键:orders.shopId -> shops.id
|
||||
|
||||
5. **orders 和 order_items**
|
||||
- 关系:一对多
|
||||
- 描述:一个订单可以包含多个商品项
|
||||
- 外键:order_items.orderId -> orders.id
|
||||
|
||||
6. **products 和 product_images**
|
||||
- 关系:一对多
|
||||
- 描述:一个商品可以有多个图片
|
||||
- 外键:product_images.productId -> products.id
|
||||
|
||||
7. **products 和 product_skus**
|
||||
- 关系:一对多
|
||||
- 描述:一个商品可以有多个SKU
|
||||
- 外键:product_skus.productId -> products.id
|
||||
|
||||
8. **product_skus 和 product_inventories**
|
||||
- 关系:一对一/一对多(实际为一对一)
|
||||
- 描述:一个SKU对应一个库存记录
|
||||
- 外键:product_inventories.skuId -> product_skus.id
|
||||
|
||||
9. **orders 和 order_status_history**
|
||||
- 关系:一对多
|
||||
- 描述:一个订单可以有多个状态历史记录
|
||||
- 外键:order_status_history.orderId -> orders.id
|
||||
|
||||
10. **orders 和 payments**
|
||||
- 关系:一对多
|
||||
- 描述:一个订单可以有多个支付记录(如多次支付尝试)
|
||||
- 外键:payments.orderId -> orders.id
|
||||
|
||||
11. **orders 和 refunds**
|
||||
- 关系:一对多
|
||||
- 描述:一个订单可以有多个退款记录
|
||||
- 外键:refunds.orderId -> orders.id
|
||||
|
||||
12. **order_items 和 refunds**
|
||||
- 关系:一对多
|
||||
- 描述:一个订单项可以有多个退款记录
|
||||
- 外键:refunds.orderItemId -> order_items.id
|
||||
|
||||
13. **shops 和 shop_ratings**
|
||||
- 关系:一对多
|
||||
- 描述:一个店铺可以有多个评价
|
||||
- 外键:shop_ratings.shopId -> shops.id
|
||||
|
||||
14. **users 和 shop_ratings**
|
||||
- 关系:一对多
|
||||
- 描述:一个用户可以对多个店铺进行评价
|
||||
- 外键:shop_ratings.userId -> users.id
|
||||
|
||||
15. **orders 和 shop_ratings**
|
||||
- 关系:一对一
|
||||
- 描述:一个订单对应一个店铺评价
|
||||
- 外键:shop_ratings.orderId -> orders.id
|
||||
|
||||
16. **product_categories 和 products**
|
||||
- 关系:一对多
|
||||
- 描述:一个商品分类可以包含多个商品
|
||||
- 外键:products.categoryId -> product_categories.id
|
||||
|
||||
17. **shop_categories 和 shops**
|
||||
- 关系:一对多
|
||||
- 描述:一个店铺分类可以包含多个店铺
|
||||
- 外键:shops.categoryId -> shop_categories.id
|
||||
|
||||
18. **product_categories 和 product_attributes**
|
||||
- 关系:一对多
|
||||
- 描述:一个商品分类可以有多个属性
|
||||
- 外键:product_attributes.categoryId -> product_categories.id
|
||||
|
||||
19. **products 和 product_attribute_values**
|
||||
- 关系:一对多
|
||||
- 描述:一个商品可以有多个属性值
|
||||
- 外键:product_attribute_values.productId -> products.id
|
||||
|
||||
20. **product_attributes 和 product_attribute_values**
|
||||
- 关系:一对多
|
||||
- 描述:一个属性可以有多个值
|
||||
- 外键:product_attribute_values.attributeId -> product_attributes.id
|
||||
|
||||
### 多对多关系
|
||||
|
||||
1. **users 和 roles**
|
||||
- 关系:多对多
|
||||
- 描述:一个用户可以有多个角色,一个角色可以分配给多个用户
|
||||
- 关联表:user_roles (userId, roleId)
|
||||
|
||||
2. **roles 和 permissions**
|
||||
- 关系:多对多
|
||||
- 描述:一个角色可以有多个权限,一个权限可以分配给多个角色
|
||||
- 关联表:role_permissions (roleId, permissionId)
|
||||
|
||||
### 自关联关系
|
||||
|
||||
1. **shop_categories 和 shop_categories**
|
||||
- 关系:自关联(一对多)
|
||||
- 描述:店铺分类的父子关系
|
||||
- 外键:shop_categories.parentId -> shop_categories.id
|
||||
|
||||
2. **product_categories 和 product_categories**
|
||||
- 关系:自关联(一对多)
|
||||
- 描述:商品分类的父子关系
|
||||
- 外键:product_categories.parentId -> product_categories.id
|
||||
295
mvnw
vendored
Normal file
295
mvnw
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.3.4
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
|
||||
# MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
set -euf
|
||||
[ "${MVNW_VERBOSE-}" != debug ] || set -x
|
||||
|
||||
# OS specific support.
|
||||
native_path() { printf %s\\n "$1"; }
|
||||
case "$(uname)" in
|
||||
CYGWIN* | MINGW*)
|
||||
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
|
||||
native_path() { cygpath --path --windows "$1"; }
|
||||
;;
|
||||
esac
|
||||
|
||||
# set JAVACMD and JAVACCMD
|
||||
set_java_home() {
|
||||
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
|
||||
if [ -n "${JAVA_HOME-}" ]; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACCMD="$JAVA_HOME/jre/sh/javac"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACCMD="$JAVA_HOME/bin/javac"
|
||||
|
||||
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
|
||||
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
|
||||
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(
|
||||
'set' +e
|
||||
'unset' -f command 2>/dev/null
|
||||
'command' -v java
|
||||
)" || :
|
||||
JAVACCMD="$(
|
||||
'set' +e
|
||||
'unset' -f command 2>/dev/null
|
||||
'command' -v javac
|
||||
)" || :
|
||||
|
||||
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
|
||||
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# hash string like Java String::hashCode
|
||||
hash_string() {
|
||||
str="${1:-}" h=0
|
||||
while [ -n "$str" ]; do
|
||||
char="${str%"${str#?}"}"
|
||||
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
|
||||
str="${str#?}"
|
||||
done
|
||||
printf %x\\n $h
|
||||
}
|
||||
|
||||
verbose() { :; }
|
||||
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
|
||||
|
||||
die() {
|
||||
printf %s\\n "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
trim() {
|
||||
# MWRAPPER-139:
|
||||
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
|
||||
# Needed for removing poorly interpreted newline sequences when running in more
|
||||
# exotic environments such as mingw bash on Windows.
|
||||
printf "%s" "${1}" | tr -d '[:space:]'
|
||||
}
|
||||
|
||||
scriptDir="$(dirname "$0")"
|
||||
scriptName="$(basename "$0")"
|
||||
|
||||
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
|
||||
while IFS="=" read -r key value; do
|
||||
case "${key-}" in
|
||||
distributionUrl) distributionUrl=$(trim "${value-}") ;;
|
||||
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
|
||||
esac
|
||||
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
|
||||
case "${distributionUrl##*/}" in
|
||||
maven-mvnd-*bin.*)
|
||||
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
|
||||
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
|
||||
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
|
||||
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
|
||||
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
|
||||
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
|
||||
*)
|
||||
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
|
||||
distributionPlatform=linux-amd64
|
||||
;;
|
||||
esac
|
||||
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
|
||||
;;
|
||||
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
|
||||
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
|
||||
esac
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
|
||||
distributionUrlName="${distributionUrl##*/}"
|
||||
distributionUrlNameMain="${distributionUrlName%.*}"
|
||||
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
|
||||
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
|
||||
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
|
||||
|
||||
exec_maven() {
|
||||
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
|
||||
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
|
||||
}
|
||||
|
||||
if [ -d "$MAVEN_HOME" ]; then
|
||||
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||
exec_maven "$@"
|
||||
fi
|
||||
|
||||
case "${distributionUrl-}" in
|
||||
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
|
||||
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
|
||||
esac
|
||||
|
||||
# prepare tmp dir
|
||||
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
|
||||
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
|
||||
trap clean HUP INT TERM EXIT
|
||||
else
|
||||
die "cannot create temp dir"
|
||||
fi
|
||||
|
||||
mkdir -p -- "${MAVEN_HOME%/*}"
|
||||
|
||||
# Download and Install Apache Maven
|
||||
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||
verbose "Downloading from: $distributionUrl"
|
||||
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
|
||||
# select .zip or .tar.gz
|
||||
if ! command -v unzip >/dev/null; then
|
||||
distributionUrl="${distributionUrl%.zip}.tar.gz"
|
||||
distributionUrlName="${distributionUrl##*/}"
|
||||
fi
|
||||
|
||||
# verbose opt
|
||||
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
|
||||
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
|
||||
|
||||
# normalize http auth
|
||||
case "${MVNW_PASSWORD:+has-password}" in
|
||||
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||
esac
|
||||
|
||||
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
|
||||
verbose "Found wget ... using wget"
|
||||
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
|
||||
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
|
||||
verbose "Found curl ... using curl"
|
||||
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
|
||||
elif set_java_home; then
|
||||
verbose "Falling back to use Java to download"
|
||||
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
|
||||
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
cat >"$javaSource" <<-END
|
||||
public class Downloader extends java.net.Authenticator
|
||||
{
|
||||
protected java.net.PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
|
||||
}
|
||||
public static void main( String[] args ) throws Exception
|
||||
{
|
||||
setDefault( new Downloader() );
|
||||
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
|
||||
}
|
||||
}
|
||||
END
|
||||
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
|
||||
verbose " - Compiling Downloader.java ..."
|
||||
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
|
||||
verbose " - Running Downloader.java ..."
|
||||
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
|
||||
fi
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||
if [ -n "${distributionSha256Sum-}" ]; then
|
||||
distributionSha256Result=false
|
||||
if [ "$MVN_CMD" = mvnd.sh ]; then
|
||||
echo "Checksum validation is not supported for maven-mvnd." >&2
|
||||
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
elif command -v sha256sum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
elif command -v shasum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
else
|
||||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
|
||||
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ $distributionSha256Result = false ]; then
|
||||
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
|
||||
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# unzip and move
|
||||
if command -v unzip >/dev/null; then
|
||||
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
|
||||
else
|
||||
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
|
||||
fi
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
actualDistributionDir=""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
|
||||
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$distributionUrlNameMain"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
# enable globbing to iterate over items
|
||||
set +f
|
||||
for dir in "$TMP_DOWNLOAD_DIR"/*; do
|
||||
if [ -d "$dir" ]; then
|
||||
if [ -f "$dir/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$(basename "$dir")"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
set -f
|
||||
fi
|
||||
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
verbose "Contents of $TMP_DOWNLOAD_DIR:"
|
||||
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
|
||||
die "Could not find Maven distribution directory in extracted archive"
|
||||
fi
|
||||
|
||||
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
|
||||
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||
|
||||
clean || :
|
||||
exec_maven "$@"
|
||||
189
mvnw.cmd
vendored
Normal file
189
mvnw.cmd
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
<# : batch portion
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.3.4
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
|
||||
@SET __MVNW_CMD__=
|
||||
@SET __MVNW_ERROR__=
|
||||
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
|
||||
@SET PSModulePath=
|
||||
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
|
||||
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
|
||||
)
|
||||
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
|
||||
@SET __MVNW_PSMODULEP_SAVE=
|
||||
@SET __MVNW_ARG0_NAME__=
|
||||
@SET MVNW_USERNAME=
|
||||
@SET MVNW_PASSWORD=
|
||||
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
|
||||
@echo Cannot start maven from wrapper >&2 && exit /b 1
|
||||
@GOTO :EOF
|
||||
: end batch / begin powershell #>
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
if ($env:MVNW_VERBOSE -eq "true") {
|
||||
$VerbosePreference = "Continue"
|
||||
}
|
||||
|
||||
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
|
||||
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
|
||||
if (!$distributionUrl) {
|
||||
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
}
|
||||
|
||||
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
|
||||
"maven-mvnd-*" {
|
||||
$USE_MVND = $true
|
||||
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
|
||||
$MVN_CMD = "mvnd.cmd"
|
||||
break
|
||||
}
|
||||
default {
|
||||
$USE_MVND = $false
|
||||
$MVN_CMD = $script -replace '^mvnw','mvn'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
if ($env:MVNW_REPOURL) {
|
||||
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
|
||||
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
|
||||
}
|
||||
$distributionUrlName = $distributionUrl -replace '^.*/',''
|
||||
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
|
||||
|
||||
$MAVEN_M2_PATH = "$HOME/.m2"
|
||||
if ($env:MAVEN_USER_HOME) {
|
||||
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
|
||||
}
|
||||
|
||||
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
|
||||
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
$MAVEN_WRAPPER_DISTS = $null
|
||||
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
|
||||
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
|
||||
} else {
|
||||
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
|
||||
}
|
||||
|
||||
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
|
||||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
|
||||
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
|
||||
|
||||
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
|
||||
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||
exit $?
|
||||
}
|
||||
|
||||
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
|
||||
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
|
||||
}
|
||||
|
||||
# prepare tmp dir
|
||||
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
|
||||
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
|
||||
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
|
||||
trap {
|
||||
if ($TMP_DOWNLOAD_DIR.Exists) {
|
||||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||
}
|
||||
}
|
||||
|
||||
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
|
||||
|
||||
# Download and Install Apache Maven
|
||||
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||
Write-Verbose "Downloading from: $distributionUrl"
|
||||
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
|
||||
$webclient = New-Object System.Net.WebClient
|
||||
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
|
||||
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
|
||||
}
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
|
||||
if ($distributionSha256Sum) {
|
||||
if ($USE_MVND) {
|
||||
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
|
||||
}
|
||||
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
|
||||
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
|
||||
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
|
||||
}
|
||||
}
|
||||
|
||||
# unzip and move
|
||||
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
$actualDistributionDir = ""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
|
||||
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
|
||||
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
|
||||
$actualDistributionDir = $distributionUrlNameMain
|
||||
}
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if (!$actualDistributionDir) {
|
||||
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
|
||||
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
|
||||
if (Test-Path -Path $testPath -PathType Leaf) {
|
||||
$actualDistributionDir = $_.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$actualDistributionDir) {
|
||||
Write-Error "Could not find Maven distribution directory in extracted archive"
|
||||
}
|
||||
|
||||
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
|
||||
try {
|
||||
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
|
||||
} catch {
|
||||
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
|
||||
Write-Error "fail to move MAVEN_HOME"
|
||||
}
|
||||
} finally {
|
||||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||
}
|
||||
|
||||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||
187
pom.xml
Normal file
187
pom.xml
Normal file
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.5.7</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.qf</groupId>
|
||||
<artifactId>backend</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>backend</name>
|
||||
<description>backend</description>
|
||||
<url/>
|
||||
<licenses>
|
||||
<license/>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer/>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection/>
|
||||
<developerConnection/>
|
||||
<tag/>
|
||||
<url/>
|
||||
</scm>
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<jjwt.version>0.12.5</jjwt.version>
|
||||
<mybatis-plus.version>3.5.6</mybatis-plus.version>
|
||||
<fastjson2.version>2.0.52</fastjson2.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>3.0.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter-test</artifactId>
|
||||
<version>3.0.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Log4j2 日志框架 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
<!-- JWT依赖 -->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
<version>${jjwt.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<version>${jjwt.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<version>${jjwt.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- MySQL驱动 -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis-Plus增强 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis-Plus代码生成器 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Redis缓存支持 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Redis连接池 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Lombok简化代码 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Fastjson JSON处理 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>${fastjson2.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Commons Lang3工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Commons IO工具类 -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.16.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 文件上传支持 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 邮件发送 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 验证码生成 -->
|
||||
<dependency>
|
||||
<groupId>com.github.penggle</groupId>
|
||||
<artifactId>kaptcha</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 日期时间处理 -->
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.12.7</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
15
src/main/java/com/qf/backend/BackendApplication.java
Normal file
15
src/main/java/com/qf/backend/BackendApplication.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package com.qf.backend;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.qf.backend.mapper")
|
||||
public class BackendApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(BackendApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
98
src/main/java/com/qf/backend/common/Result.java
Normal file
98
src/main/java/com/qf/backend/common/Result.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package com.qf.backend.common;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 统一响应格式
|
||||
* 根据项目文档6.2节统一响应格式定义
|
||||
*/
|
||||
@Data
|
||||
public class Result<T> {
|
||||
|
||||
/**
|
||||
* 状态码
|
||||
*/
|
||||
private int code;
|
||||
|
||||
/**
|
||||
* 状态信息
|
||||
*/
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
private T data;
|
||||
|
||||
/**
|
||||
* 构造私有方法
|
||||
*/
|
||||
private Result() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 成功响应(无数据)
|
||||
*/
|
||||
public static <T> Result<T> success() {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(200);
|
||||
result.setMessage("success");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功响应(有数据)
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(200);
|
||||
result.setMessage("success");
|
||||
result.setData(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败响应
|
||||
*/
|
||||
public static <T> Result<T> fail(int code, String message) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(code);
|
||||
result.setMessage(message);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败响应(带数据)
|
||||
*/
|
||||
public static <T> Result<T> fail(int code, String message, T data) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(code);
|
||||
result.setMessage(message);
|
||||
result.setData(data);
|
||||
return result;
|
||||
}
|
||||
// getters setters
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
87
src/main/java/com/qf/backend/common/ResultUtils.java
Normal file
87
src/main/java/com/qf/backend/common/ResultUtils.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package com.qf.backend.common;
|
||||
|
||||
import com.qf.backend.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* 响应结果工具类
|
||||
* 提供各种响应结果的快速创建方法
|
||||
*/
|
||||
public class ResultUtils {
|
||||
|
||||
/**
|
||||
* 成功响应(无数据)
|
||||
*/
|
||||
public static <T> Result<T> success() {
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功响应(有数据)
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败响应(使用错误码)
|
||||
*/
|
||||
public static <T> Result<T> fail(ErrorCode errorCode) {
|
||||
return Result.fail(errorCode.getCode(), errorCode.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败响应(使用错误码和自定义消息)
|
||||
*/
|
||||
public static <T> Result<T> fail(ErrorCode errorCode, String message) {
|
||||
return Result.fail(errorCode.getCode(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败响应(使用错误码和数据)
|
||||
*/
|
||||
public static <T> Result<T> fail(ErrorCode errorCode, T data) {
|
||||
return Result.fail(errorCode.getCode(), errorCode.getMessage(), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败响应(自定义状态码和消息)
|
||||
*/
|
||||
public static <T> Result<T> fail(int code, String message) {
|
||||
return Result.fail(code, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数错误响应
|
||||
*/
|
||||
public static <T> Result<T> paramError(String message) {
|
||||
return Result.fail(ErrorCode.PARAM_ERROR.getCode(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 未授权响应
|
||||
*/
|
||||
public static <T> Result<T> unauthorized() {
|
||||
return Result.fail(ErrorCode.UNAUTHORIZED.getCode(), ErrorCode.UNAUTHORIZED.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁止访问响应
|
||||
*/
|
||||
public static <T> Result<T> forbidden() {
|
||||
return Result.fail(ErrorCode.FORBIDDEN.getCode(), ErrorCode.FORBIDDEN.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 资源不存在响应
|
||||
*/
|
||||
public static <T> Result<T> notFound(String message) {
|
||||
return Result.fail(ErrorCode.NOT_FOUND.getCode(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务器错误响应
|
||||
*/
|
||||
public static <T> Result<T> serverError() {
|
||||
return Result.fail(ErrorCode.SYSTEM_ERROR.getCode(), ErrorCode.SYSTEM_ERROR.getMessage());
|
||||
}
|
||||
}
|
||||
34
src/main/java/com/qf/backend/entity/OrderItems.java
Normal file
34
src/main/java/com/qf/backend/entity/OrderItems.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 订单商品项表
|
||||
*/
|
||||
@Data
|
||||
@TableName("order_items")
|
||||
public class OrderItems {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long orderId;
|
||||
private Long productId;
|
||||
private Long skuId;
|
||||
private String productName;
|
||||
private String skuSpecs;
|
||||
private String productImage;
|
||||
private BigDecimal price;
|
||||
private Integer quantity;
|
||||
private BigDecimal subtotal;
|
||||
private Integer itemStatus; // 0: 正常, 1: 已退款, 2: 退款中
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
26
src/main/java/com/qf/backend/entity/OrderStatusHistory.java
Normal file
26
src/main/java/com/qf/backend/entity/OrderStatusHistory.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 订单状态历史表
|
||||
*/
|
||||
@Data
|
||||
@TableName("order_status_history")
|
||||
public class OrderStatusHistory {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long orderId;
|
||||
private Integer previousStatus;
|
||||
private Integer currentStatus;
|
||||
private String changeReason;
|
||||
private String operator;
|
||||
private Date changeTime;
|
||||
private Date createdAt;
|
||||
}
|
||||
40
src/main/java/com/qf/backend/entity/Orders.java
Normal file
40
src/main/java/com/qf/backend/entity/Orders.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 订单主表
|
||||
*/
|
||||
@Data
|
||||
@TableName("orders")
|
||||
public class Orders {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String orderNo;
|
||||
private Long userId;
|
||||
private Long shopId;
|
||||
private BigDecimal totalAmount;
|
||||
private BigDecimal actualAmount;
|
||||
private BigDecimal shippingFee;
|
||||
private Integer orderStatus; // 0: 待付款, 1: 待发货, 2: 待收货, 3: 已完成, 4: 已取消, 5: 已退款
|
||||
private String shippingAddress;
|
||||
private String receiverName;
|
||||
private String receiverPhone;
|
||||
private String paymentMethod; // 支付方式
|
||||
private Date paymentTime;
|
||||
private Date shippingTime;
|
||||
private Date deliveryTime;
|
||||
private Date completeTime;
|
||||
private String remark;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
32
src/main/java/com/qf/backend/entity/Payments.java
Normal file
32
src/main/java/com/qf/backend/entity/Payments.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 支付信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("payments")
|
||||
public class Payments {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String paymentNo;
|
||||
private Long orderId;
|
||||
private Long userId;
|
||||
private BigDecimal amount;
|
||||
private String paymentMethod; // 支付方式
|
||||
private String transactionId; // 第三方交易流水号
|
||||
private Integer paymentStatus; // 0: 待支付, 1: 支付成功, 2: 支付失败, 3: 已退款
|
||||
private String paymentUrl; // 支付链接
|
||||
private Date expireTime;
|
||||
private Date paymentTime;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
26
src/main/java/com/qf/backend/entity/Permissions.java
Normal file
26
src/main/java/com/qf/backend/entity/Permissions.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 权限信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("permissions")
|
||||
public class Permissions {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String permissionName;
|
||||
private String permissionCode;
|
||||
private String description;
|
||||
private String module;
|
||||
private Integer status; // 0: 禁用, 1: 启用
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 商品属性值表
|
||||
*/
|
||||
@Data
|
||||
@TableName("product_attribute_values")
|
||||
public class ProductAttributeValues {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long productId;
|
||||
private Long attributeId;
|
||||
private String attributeValue;
|
||||
private Integer sort;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
25
src/main/java/com/qf/backend/entity/ProductAttributes.java
Normal file
25
src/main/java/com/qf/backend/entity/ProductAttributes.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 商品属性表
|
||||
*/
|
||||
@Data
|
||||
@TableName("product_attributes")
|
||||
public class ProductAttributes {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String attributeName;
|
||||
private Long categoryId;
|
||||
private Integer attributeType; // 0: 规格属性, 1: 销售属性
|
||||
private Integer sort;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
28
src/main/java/com/qf/backend/entity/ProductCategories.java
Normal file
28
src/main/java/com/qf/backend/entity/ProductCategories.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 商品分类表
|
||||
*/
|
||||
@Data
|
||||
@TableName("product_categories")
|
||||
public class ProductCategories {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String categoryName;
|
||||
private Long parentId; // 父分类ID,顶级分类为0
|
||||
private Integer level; // 分类级别:1、2、3
|
||||
private String icon;
|
||||
private String banner;
|
||||
private Integer sort;
|
||||
private Integer status; // 0: 禁用, 1: 启用
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
24
src/main/java/com/qf/backend/entity/ProductImages.java
Normal file
24
src/main/java/com/qf/backend/entity/ProductImages.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 商品图片表
|
||||
*/
|
||||
@Data
|
||||
@TableName("product_images")
|
||||
public class ProductImages {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long productId;
|
||||
private String imageUrl;
|
||||
private Integer sort;
|
||||
private Integer isMain; // 0: 非主图, 1: 主图
|
||||
private Date createdAt;
|
||||
}
|
||||
28
src/main/java/com/qf/backend/entity/ProductInventories.java
Normal file
28
src/main/java/com/qf/backend/entity/ProductInventories.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 库存信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("product_inventories")
|
||||
public class ProductInventories {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long skuId;
|
||||
private Integer currentStock;
|
||||
private Integer safetyStock;
|
||||
private Integer lockStock; // 锁定库存
|
||||
private Date lastUpdateTime;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
31
src/main/java/com/qf/backend/entity/ProductSkus.java
Normal file
31
src/main/java/com/qf/backend/entity/ProductSkus.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 商品SKU表
|
||||
*/
|
||||
@Data
|
||||
@TableName("product_skus")
|
||||
public class ProductSkus {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long productId;
|
||||
private String skuCode;
|
||||
private String skuSpecs; // SKU规格信息,JSON格式存储
|
||||
private BigDecimal price;
|
||||
private Integer stock;
|
||||
private String image;
|
||||
private Integer status; // 0: 禁用, 1: 启用
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
32
src/main/java/com/qf/backend/entity/Products.java
Normal file
32
src/main/java/com/qf/backend/entity/Products.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 商品基本信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("products")
|
||||
public class Products {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String productName;
|
||||
private Long shopId;
|
||||
private Long categoryId;
|
||||
private String description;
|
||||
private BigDecimal originalPrice;
|
||||
private BigDecimal currentPrice;
|
||||
private Integer salesVolume;
|
||||
private Integer status; // 0: 下架, 1: 上架
|
||||
private String mainImage;
|
||||
private Integer isDeleted; // 0: 未删除, 1: 已删除
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
36
src/main/java/com/qf/backend/entity/Refunds.java
Normal file
36
src/main/java/com/qf/backend/entity/Refunds.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 退款信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("refunds")
|
||||
public class Refunds {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String refundNo;
|
||||
private Long orderId;
|
||||
private Long orderItemId;
|
||||
private Long userId;
|
||||
private Long shopId;
|
||||
private BigDecimal refundAmount;
|
||||
private String refundReason;
|
||||
private String refundType; // 退款类型
|
||||
private Integer refundStatus; // 0: 申请中, 1: 退款成功, 2: 退款失败, 3: 已拒绝
|
||||
private String refundAccount;
|
||||
private String transactionId;
|
||||
private Date applyTime;
|
||||
private Date processTime;
|
||||
private String processRemark;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
22
src/main/java/com/qf/backend/entity/RolePermissions.java
Normal file
22
src/main/java/com/qf/backend/entity/RolePermissions.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 角色-权限关联表
|
||||
*/
|
||||
@Data
|
||||
@TableName("role_permissions")
|
||||
public class RolePermissions {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long roleId;
|
||||
private Long permissionId;
|
||||
private Date createdAt;
|
||||
}
|
||||
25
src/main/java/com/qf/backend/entity/Roles.java
Normal file
25
src/main/java/com/qf/backend/entity/Roles.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 角色信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("roles")
|
||||
public class Roles {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String roleName;
|
||||
private String description;
|
||||
private Integer roleType; // 0: 默认用户, 1: 店主, 2: 管理员
|
||||
private Integer status; // 0: 禁用, 1: 启用
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
27
src/main/java/com/qf/backend/entity/ShopCategories.java
Normal file
27
src/main/java/com/qf/backend/entity/ShopCategories.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 店铺分类表
|
||||
*/
|
||||
@Data
|
||||
@TableName("shop_categories")
|
||||
public class ShopCategories {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String categoryName;
|
||||
private Long parentId; // 父分类ID,顶级分类为0
|
||||
private Integer level; // 分类级别
|
||||
private String icon;
|
||||
private Integer sort;
|
||||
private Integer status; // 0: 禁用, 1: 启用
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
28
src/main/java/com/qf/backend/entity/ShopRatings.java
Normal file
28
src/main/java/com/qf/backend/entity/ShopRatings.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 店铺评分表
|
||||
*/
|
||||
@Data
|
||||
@TableName("shop_ratings")
|
||||
public class ShopRatings {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long shopId;
|
||||
private Long userId;
|
||||
private Long orderId;
|
||||
private Integer rating; // 评分:1-5星
|
||||
private String content;
|
||||
private String images; // 评价图片,JSON格式存储
|
||||
private Integer status; // 0: 待审核, 1: 已审核, 2: 已删除
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
37
src/main/java/com/qf/backend/entity/Shops.java
Normal file
37
src/main/java/com/qf/backend/entity/Shops.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 店铺信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("shops")
|
||||
public class Shops {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String shopName;
|
||||
private Long userId; // 店主用户ID
|
||||
private Long categoryId;
|
||||
private String shopLogo;
|
||||
private String coverImage;
|
||||
private String description;
|
||||
private String address;
|
||||
private String contactPhone;
|
||||
private String contactPerson;
|
||||
private BigDecimal rating; // 店铺评分
|
||||
private Integer salesVolume;
|
||||
private Integer status; // 0: 未审核, 1: 已审核, 2: 已关闭, 3: 审核失败
|
||||
private String businessLicense;
|
||||
private Date businessStartTime;
|
||||
private Date businessEndTime;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
30
src/main/java/com/qf/backend/entity/UserDetails.java
Normal file
30
src/main/java/com/qf/backend/entity/UserDetails.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户详细信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("user_details")
|
||||
public class UserDetails {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long userId;
|
||||
private String realName;
|
||||
private String idCard;
|
||||
private String gender; //男、女、保密
|
||||
private Date birthday;
|
||||
private String address;
|
||||
private String province;
|
||||
private String city;
|
||||
private String district;
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
22
src/main/java/com/qf/backend/entity/UserRoles.java
Normal file
22
src/main/java/com/qf/backend/entity/UserRoles.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户-角色关联表
|
||||
*/
|
||||
@Data
|
||||
@TableName("user_roles")
|
||||
public class UserRoles {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long userId;
|
||||
private Long roleId;
|
||||
private Date createdAt;
|
||||
}
|
||||
29
src/main/java/com/qf/backend/entity/Users.java
Normal file
29
src/main/java/com/qf/backend/entity/Users.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.qf.backend.entity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用户基本信息表
|
||||
*/
|
||||
@Data
|
||||
@TableName("users")
|
||||
public class Users {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String username;
|
||||
private String password;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String nickname;
|
||||
private String avatar;
|
||||
private Integer status; // 0: 禁用, 1: 启用
|
||||
private Date createdAt;
|
||||
private Date updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.qf.backend.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 业务异常类 用于封装业务逻辑中产生的异常
|
||||
*/
|
||||
@Getter
|
||||
public class BusinessException extends RuntimeException {
|
||||
|
||||
private final int code;
|
||||
private final String message;
|
||||
private final Object data;
|
||||
|
||||
/**
|
||||
* 使用错误码构造业务异常
|
||||
*
|
||||
* @param errorCode 错误码枚举
|
||||
*/
|
||||
public BusinessException(ErrorCode errorCode) {
|
||||
super(errorCode.getMessage());
|
||||
this.code = errorCode.getCode();
|
||||
this.message = errorCode.getMessage();
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用错误码和自定义消息构造业务异常
|
||||
*
|
||||
* @param errorCode 错误码枚举
|
||||
* @param message 自定义错误消息
|
||||
*/
|
||||
public BusinessException(ErrorCode errorCode, String message) {
|
||||
super(message);
|
||||
this.code = errorCode.getCode();
|
||||
this.message = message;
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用错误码和附加数据构造业务异常
|
||||
*
|
||||
* @param errorCode 错误码枚举
|
||||
* @param data 附加数据
|
||||
*/
|
||||
public BusinessException(ErrorCode errorCode, Object data) {
|
||||
super(errorCode.getMessage());
|
||||
this.code = errorCode.getCode();
|
||||
this.message = errorCode.getMessage();
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用错误码、自定义消息和附加数据构造业务异常
|
||||
*
|
||||
* @param errorCode 错误码枚举
|
||||
* @param message 自定义错误消息
|
||||
* @param data 附加数据
|
||||
*/
|
||||
public BusinessException(ErrorCode errorCode, String message, Object data) {
|
||||
super(message);
|
||||
this.code = errorCode.getCode();
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用错误码、自定义消息和原始异常构造业务异常
|
||||
*
|
||||
* @param errorCode 错误码枚举
|
||||
* @param message 自定义错误消息
|
||||
* @param cause 原始异常
|
||||
*/
|
||||
public BusinessException(ErrorCode errorCode, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = errorCode.getCode();
|
||||
this.message = message;
|
||||
this.data = null;
|
||||
}
|
||||
|
||||
}
|
||||
55
src/main/java/com/qf/backend/exception/ErrorCode.java
Normal file
55
src/main/java/com/qf/backend/exception/ErrorCode.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.qf.backend.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 错误码定义
|
||||
* 根据项目文档6.3节状态码定义进行扩展
|
||||
*/
|
||||
@Getter
|
||||
public enum ErrorCode {
|
||||
// 成功状态码
|
||||
SUCCESS(200, "success"),
|
||||
|
||||
// 参数错误
|
||||
PARAM_ERROR(400, "请求参数错误"),
|
||||
MISSING_PARAM(4001, "缺少必要参数"),
|
||||
INVALID_PARAM(4002, "无效的参数值"),
|
||||
|
||||
// 认证授权错误
|
||||
UNAUTHORIZED(401, "未授权访问"),
|
||||
INVALID_TOKEN(4011, "无效的令牌"),
|
||||
TOKEN_EXPIRED(4012, "令牌已过期"),
|
||||
|
||||
// 权限错误
|
||||
FORBIDDEN(403, "禁止访问"),
|
||||
PERMISSION_DENIED(4031, "权限不足"),
|
||||
|
||||
// 资源错误
|
||||
NOT_FOUND(404, "资源不存在"),
|
||||
USER_NOT_FOUND(4041, "用户不存在"),
|
||||
PRODUCT_NOT_FOUND(4042, "商品不存在"),
|
||||
ORDER_NOT_FOUND(4043, "订单不存在"),
|
||||
SHOP_NOT_FOUND(4044, "店铺不存在"),
|
||||
|
||||
// 业务错误
|
||||
BUSINESS_ERROR(409, "业务逻辑错误"),
|
||||
USER_EXISTED(4091, "用户已存在"),
|
||||
PRODUCT_OFF_SHELF(4092, "商品已下架"),
|
||||
INSUFFICIENT_STOCK(4093, "库存不足"),
|
||||
ORDER_CANCELLED(4094, "订单已取消"),
|
||||
|
||||
// 服务器错误
|
||||
SYSTEM_ERROR(500, "服务器内部错误"),
|
||||
DATABASE_ERROR(5001, "数据库操作错误"),
|
||||
NETWORK_ERROR(5002, "网络请求错误"),
|
||||
UNKNOWN_ERROR(5003, "未知错误");
|
||||
|
||||
private final int code;
|
||||
private final String message;
|
||||
|
||||
ErrorCode(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.qf.backend.exception;
|
||||
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.common.ResultUtils;
|
||||
|
||||
/**
|
||||
* 异常处理使用示例
|
||||
* 演示如何在业务代码中使用异常处理相关类
|
||||
*/
|
||||
public class ExceptionUsageExample {
|
||||
|
||||
/**
|
||||
* 示例1:抛出业务异常
|
||||
*/
|
||||
public void throwBusinessExceptionExample(Long userId) {
|
||||
// 业务逻辑判断
|
||||
if (userId == null || userId <= 0) {
|
||||
// 使用预定义错误码抛出业务异常
|
||||
throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID无效");
|
||||
}
|
||||
|
||||
// 模拟用户不存在的场景
|
||||
boolean userExists = false; // 假设从数据库查询
|
||||
if (!userExists) {
|
||||
throw new BusinessException(ErrorCode.USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 抛出带附加数据的异常
|
||||
Object additionalData = new Object(); // 可以是任何附加信息
|
||||
throw new BusinessException(ErrorCode.BUSINESS_ERROR, "业务逻辑错误", additionalData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例2:返回统一响应格式
|
||||
*/
|
||||
public Result<String> returnResultExample(boolean success) {
|
||||
if (success) {
|
||||
// 返回成功响应
|
||||
return ResultUtils.success("操作成功");
|
||||
} else {
|
||||
// 返回失败响应
|
||||
return ResultUtils.fail(ErrorCode.BUSINESS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例3:使用不同类型的错误响应
|
||||
*/
|
||||
public Result<?> useDifferentErrorResponses() {
|
||||
// 参数错误
|
||||
Result<?> paramError = ResultUtils.paramError("参数校验失败");
|
||||
|
||||
// 未授权错误
|
||||
Result<?> unauthorizedError = ResultUtils.unauthorized();
|
||||
|
||||
// 禁止访问错误
|
||||
Result<?> forbiddenError = ResultUtils.forbidden();
|
||||
|
||||
// 资源不存在错误
|
||||
Result<?> notFoundError = ResultUtils.notFound("请求的资源不存在");
|
||||
|
||||
// 服务器错误
|
||||
Result<?> serverError = ResultUtils.serverError();
|
||||
|
||||
return paramError; // 示例返回
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例4:在Service层使用异常处理
|
||||
*/
|
||||
public void serviceLayerExample(Long productId, int quantity) {
|
||||
// 校验参数
|
||||
if (productId == null || productId <= 0) {
|
||||
throw new BusinessException(ErrorCode.PARAM_ERROR, "商品ID无效");
|
||||
}
|
||||
|
||||
if (quantity <= 0) {
|
||||
throw new BusinessException(ErrorCode.PARAM_ERROR, "购买数量必须大于0");
|
||||
}
|
||||
|
||||
// 模拟业务逻辑检查
|
||||
boolean productExists = true; // 假设从数据库查询
|
||||
if (!productExists) {
|
||||
throw new BusinessException(ErrorCode.PRODUCT_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 模拟库存检查
|
||||
boolean hasStock = false; // 假设从数据库查询
|
||||
if (!hasStock) {
|
||||
throw new BusinessException(ErrorCode.INSUFFICIENT_STOCK);
|
||||
}
|
||||
|
||||
// 正常业务逻辑处理...
|
||||
}
|
||||
|
||||
/**
|
||||
* 示例5:在Controller层使用统一响应
|
||||
*/
|
||||
public Result<?> controllerLayerExample(Long id) {
|
||||
try {
|
||||
// 调用业务逻辑
|
||||
Object result = new Object(); // 假设这是业务处理结果
|
||||
return ResultUtils.success(result);
|
||||
} catch (BusinessException e) {
|
||||
// 业务异常已经被GlobalExceptionHandler捕获,这里可以做额外处理
|
||||
// 例如记录日志等
|
||||
throw e; // 重新抛出,让全局异常处理器处理
|
||||
}
|
||||
// 系统异常也会被GlobalExceptionHandler自动捕获
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
package com.qf.backend.exception;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.InsufficientAuthenticationException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.common.ResultUtils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
* 处理系统中所有的异常,提供统一的错误响应格式
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理业务异常
|
||||
*/
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public Result<?> handleBusinessException(BusinessException e, HttpServletRequest request) {
|
||||
log.warn("BusinessException: {} - Request: {}", e.getMessage(), request.getRequestURI());
|
||||
return ResultUtils.fail(e.getCode(), e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理参数验证异常(@Valid)
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
|
||||
BindingResult bindingResult = e.getBindingResult();
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (FieldError fieldError : bindingResult.getFieldErrors()) {
|
||||
joiner.add(fieldError.getField() + ": " + fieldError.getDefaultMessage());
|
||||
}
|
||||
String errorMsg = joiner.toString();
|
||||
log.warn("MethodArgumentNotValidException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
return ResultUtils.paramError(errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理参数绑定异常(@RequestParam)
|
||||
*/
|
||||
@ExceptionHandler(BindException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public Result<?> handleBindException(BindException e, HttpServletRequest request) {
|
||||
BindingResult bindingResult = e.getBindingResult();
|
||||
StringJoiner joiner = new StringJoiner(", ");
|
||||
for (FieldError fieldError : bindingResult.getFieldErrors()) {
|
||||
joiner.add(fieldError.getField() + ": " + fieldError.getDefaultMessage());
|
||||
}
|
||||
String errorMsg = joiner.toString();
|
||||
log.warn("BindException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
return ResultUtils.paramError(errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理缺少请求参数异常
|
||||
*/
|
||||
@ExceptionHandler(MissingServletRequestParameterException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public Result<?> handleMissingServletRequestParameterException(MissingServletRequestParameterException e, HttpServletRequest request) {
|
||||
String errorMsg = "缺少必要参数: " + e.getParameterName();
|
||||
log.warn("MissingServletRequestParameterException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
return ResultUtils.paramError(errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理参数类型不匹配异常
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public Result<?> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {
|
||||
String errorMsg = "参数类型错误: " + e.getName() + " 应为 " + Objects.requireNonNull(e.getRequiredType()).getSimpleName();
|
||||
log.warn("MethodArgumentTypeMismatchException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
return ResultUtils.paramError(errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理HTTP消息不可读异常(如JSON格式错误)
|
||||
*/
|
||||
@ExceptionHandler(HttpMessageNotReadableException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public Result<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e, HttpServletRequest request) {
|
||||
String errorMsg = "请求体格式错误: " + e.getMostSpecificCause().getMessage();
|
||||
log.warn("HttpMessageNotReadableException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
return ResultUtils.paramError(errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理不支持的HTTP方法异常
|
||||
*/
|
||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
|
||||
public Result<?> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
|
||||
String errorMsg = "不支持的HTTP方法: " + e.getMethod();
|
||||
log.warn("HttpRequestMethodNotSupportedException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
return ResultUtils.fail(HttpStatus.METHOD_NOT_ALLOWED.value(), errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理不支持的媒体类型异常
|
||||
*/
|
||||
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
|
||||
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
|
||||
public Result<?> handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e, HttpServletRequest request) {
|
||||
String errorMsg = "不支持的媒体类型: " + e.getContentType();
|
||||
log.warn("HttpMediaTypeNotSupportedException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
return ResultUtils.fail(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(), errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理404异常
|
||||
*/
|
||||
@ExceptionHandler(NoHandlerFoundException.class)
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
public Result<?> handleNoHandlerFoundException(NoHandlerFoundException e, HttpServletRequest request) {
|
||||
String errorMsg = "请求路径不存在: " + request.getRequestURI();
|
||||
log.warn("NoHandlerFoundException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
return ResultUtils.notFound(errorMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据库异常
|
||||
*/
|
||||
@ExceptionHandler(SQLException.class)
|
||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public Result<?> handleSQLException(SQLException e, HttpServletRequest request) {
|
||||
log.error("SQLException: {} - Request: {}", e.getMessage(), request.getRequestURI(), e);
|
||||
return ResultUtils.fail(ErrorCode.DATABASE_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理认证异常
|
||||
*/
|
||||
@ExceptionHandler(AuthenticationException.class)
|
||||
@ResponseStatus(HttpStatus.UNAUTHORIZED)
|
||||
public Result<?> handleAuthenticationException(AuthenticationException e, HttpServletRequest request) {
|
||||
String errorMsg = "认证失败: " + e.getMessage();
|
||||
log.warn("AuthenticationException: {} - Request: {}", errorMsg, request.getRequestURI());
|
||||
|
||||
if (e instanceof BadCredentialsException) {
|
||||
return ResultUtils.fail(ErrorCode.UNAUTHORIZED, "用户名或密码错误");
|
||||
} else if (e instanceof InsufficientAuthenticationException) {
|
||||
return ResultUtils.fail(ErrorCode.UNAUTHORIZED, "缺少认证信息");
|
||||
}
|
||||
|
||||
return ResultUtils.unauthorized();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理权限不足异常
|
||||
*/
|
||||
@ExceptionHandler(AccessDeniedException.class)
|
||||
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||
public Result<?> handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
|
||||
log.warn("AccessDeniedException: {} - Request: {}", e.getMessage(), request.getRequestURI());
|
||||
return ResultUtils.fail(ErrorCode.PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理其他所有未捕获的异常
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public Result<?> handleException(Exception e, HttpServletRequest request) {
|
||||
log.error("Unhandled Exception: {} - Request: {}", e.getMessage(), request.getRequestURI(), e);
|
||||
return ResultUtils.serverError();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理运行时异常
|
||||
*/
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public Result<?> handleRuntimeException(RuntimeException e, HttpServletRequest request) {
|
||||
log.error("RuntimeException: {} - Request: {}", e.getMessage(), request.getRequestURI(), e);
|
||||
|
||||
// 可以根据具体的运行时异常类型进行特殊处理
|
||||
if (e instanceof NullPointerException) {
|
||||
log.warn("NullPointerException occurred: {}", e.getMessage());
|
||||
return ResultUtils.fail(ErrorCode.SYSTEM_ERROR, "系统内部错误:空指针异常");
|
||||
}
|
||||
|
||||
return ResultUtils.serverError();
|
||||
}
|
||||
}
|
||||
30
src/main/java/com/qf/backend/mapper/OrderItemsMapper.java
Normal file
30
src/main/java/com/qf/backend/mapper/OrderItemsMapper.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.OrderItems;
|
||||
|
||||
/**
|
||||
* 订单商品项表 Mapper 接口
|
||||
*/
|
||||
public interface OrderItemsMapper extends BaseMapper<OrderItems> {
|
||||
QueryWrapper<OrderItems> qw = new QueryWrapper<>();
|
||||
/**
|
||||
* 根据订单ID查询订单项
|
||||
* @param orderId 订单ID
|
||||
* @return 订单项列表
|
||||
*/
|
||||
@Select("select * from order_items where order_id = #{orderId}")
|
||||
List<OrderItems> selectByOrderId(Long orderId);
|
||||
/**
|
||||
* 根据商品ID查询订单项
|
||||
* @param productId 商品ID
|
||||
* @return 订单项列表
|
||||
*/
|
||||
@Select("select * from order_items where product_id = #{productId}")
|
||||
List<OrderItems> selectByProductId(Long productId);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.OrderStatusHistory;
|
||||
|
||||
/**
|
||||
* 订单状态历史表 Mapper 接口
|
||||
*/
|
||||
public interface OrderStatusHistoryMapper extends BaseMapper<OrderStatusHistory> {
|
||||
}
|
||||
16
src/main/java/com/qf/backend/mapper/OrdersMapper.java
Normal file
16
src/main/java/com/qf/backend/mapper/OrdersMapper.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.Orders;
|
||||
|
||||
/**
|
||||
* 订单主表 Mapper 接口
|
||||
*/
|
||||
public interface OrdersMapper extends BaseMapper<Orders> {
|
||||
/**
|
||||
* 根据订单号查询订单
|
||||
* @param orderNumber 订单号
|
||||
* @return 订单信息
|
||||
*/
|
||||
Orders selectByOrderNumber(String orderNumber);
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/PaymentsMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/PaymentsMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.Payments;
|
||||
|
||||
/**
|
||||
* 支付信息表 Mapper 接口
|
||||
*/
|
||||
public interface PaymentsMapper extends BaseMapper<Payments> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/PermissionsMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/PermissionsMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.Permissions;
|
||||
|
||||
/**
|
||||
* 权限信息表 Mapper 接口
|
||||
*/
|
||||
public interface PermissionsMapper extends BaseMapper<Permissions> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.ProductAttributeValues;
|
||||
|
||||
/**
|
||||
* 商品属性值表 Mapper 接口
|
||||
*/
|
||||
public interface ProductAttributeValuesMapper extends BaseMapper<ProductAttributeValues> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.ProductAttributes;
|
||||
|
||||
/**
|
||||
* 商品属性表 Mapper 接口
|
||||
*/
|
||||
public interface ProductAttributesMapper extends BaseMapper<ProductAttributes> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.ProductCategories;
|
||||
|
||||
/**
|
||||
* 商品分类表 Mapper 接口
|
||||
*/
|
||||
public interface ProductCategoriesMapper extends BaseMapper<ProductCategories> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/ProductImagesMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/ProductImagesMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.ProductImages;
|
||||
|
||||
/**
|
||||
* 商品图片表 Mapper 接口
|
||||
*/
|
||||
public interface ProductImagesMapper extends BaseMapper<ProductImages> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.ProductInventories;
|
||||
|
||||
/**
|
||||
* 库存信息表 Mapper 接口
|
||||
*/
|
||||
public interface ProductInventoriesMapper extends BaseMapper<ProductInventories> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/ProductSkusMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/ProductSkusMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.ProductSkus;
|
||||
|
||||
/**
|
||||
* 商品SKU表 Mapper 接口
|
||||
*/
|
||||
public interface ProductSkusMapper extends BaseMapper<ProductSkus> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/ProductsMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/ProductsMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.Products;
|
||||
|
||||
/**
|
||||
* 商品基本信息表 Mapper 接口
|
||||
*/
|
||||
public interface ProductsMapper extends BaseMapper<Products> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/RefundsMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/RefundsMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.Refunds;
|
||||
|
||||
/**
|
||||
* 退款信息表 Mapper 接口
|
||||
*/
|
||||
public interface RefundsMapper extends BaseMapper<Refunds> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.RolePermissions;
|
||||
|
||||
/**
|
||||
* 角色-权限关联表 Mapper 接口
|
||||
*/
|
||||
public interface RolePermissionsMapper extends BaseMapper<RolePermissions> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/RolesMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/RolesMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.Roles;
|
||||
|
||||
/**
|
||||
* 角色信息表 Mapper 接口
|
||||
*/
|
||||
public interface RolesMapper extends BaseMapper<Roles> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.ShopCategories;
|
||||
|
||||
/**
|
||||
* 店铺分类表 Mapper 接口
|
||||
*/
|
||||
public interface ShopCategoriesMapper extends BaseMapper<ShopCategories> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/ShopRatingsMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/ShopRatingsMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.ShopRatings;
|
||||
|
||||
/**
|
||||
* 店铺评分表 Mapper 接口
|
||||
*/
|
||||
public interface ShopRatingsMapper extends BaseMapper<ShopRatings> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/ShopsMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/ShopsMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.Shops;
|
||||
|
||||
/**
|
||||
* 店铺信息表 Mapper 接口
|
||||
*/
|
||||
public interface ShopsMapper extends BaseMapper<Shops> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/UserDetailsMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/UserDetailsMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.UserDetails;
|
||||
|
||||
/**
|
||||
* 用户详细信息表 Mapper 接口
|
||||
*/
|
||||
public interface UserDetailsMapper extends BaseMapper<UserDetails> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/UserRolesMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/UserRolesMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.UserRoles;
|
||||
|
||||
/**
|
||||
* 用户-角色关联表 Mapper 接口
|
||||
*/
|
||||
public interface UserRolesMapper extends BaseMapper<UserRoles> {
|
||||
}
|
||||
10
src/main/java/com/qf/backend/mapper/UsersMapper.java
Normal file
10
src/main/java/com/qf/backend/mapper/UsersMapper.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.qf.backend.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.entity.Users;
|
||||
|
||||
/**
|
||||
* 用户基本信息表 Mapper 接口
|
||||
*/
|
||||
public interface UsersMapper extends BaseMapper<Users> {
|
||||
}
|
||||
83
src/main/java/com/qf/backend/service/OrderItemsService.java
Normal file
83
src/main/java/com/qf/backend/service/OrderItemsService.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.OrderItems;
|
||||
|
||||
/**
|
||||
* 订单项服务接口
|
||||
*/
|
||||
public interface OrderItemsService extends IService<OrderItems> {
|
||||
|
||||
/**
|
||||
* 根据订单ID查询订单项
|
||||
* @param orderId 订单ID
|
||||
* @return 订单项列表
|
||||
*/
|
||||
Result<List<OrderItems>> getOrderItemsByOrderId(Long orderId);
|
||||
|
||||
/**
|
||||
* 根据商品ID查询订单项
|
||||
* @param productId 商品ID
|
||||
* @return 订单项列表
|
||||
*/
|
||||
Result<List<OrderItems>> getOrderItemsByProductId(Long productId);
|
||||
|
||||
/**
|
||||
* 创建订单项
|
||||
* @param orderItems 订单项信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createOrderItem(OrderItems orderItems);
|
||||
|
||||
/**
|
||||
* 更新订单项信息
|
||||
* @param orderItems 订单项信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateOrderItem(OrderItems orderItems);
|
||||
|
||||
/**
|
||||
* 删除订单项
|
||||
* @param id 订单项ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteOrderItem(Long id);
|
||||
|
||||
/**
|
||||
* 根据订单项ID查询订单项
|
||||
* @param id 订单项ID
|
||||
* @return 订单项信息
|
||||
*/
|
||||
Result<OrderItems> getOrderItemById(Long id);
|
||||
|
||||
/**
|
||||
* 批量创建订单项
|
||||
* @param orderItemsList 订单项列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchCreateOrderItems(List<OrderItems> orderItemsList);
|
||||
|
||||
/**
|
||||
* 根据订单ID删除所有订单项
|
||||
* @param orderId 订单ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteOrderItemsByOrderId(Long orderId);
|
||||
|
||||
/**
|
||||
* 计算订单总金额
|
||||
* @param orderId 订单ID
|
||||
* @return 订单总金额
|
||||
*/
|
||||
Result<Double> calculateOrderTotal(Long orderId);
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询订单项
|
||||
* @param skuId SKU ID
|
||||
* @return 订单项列表
|
||||
*/
|
||||
Result<List<OrderItems>> getOrderItemsBySkuId(Long skuId);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.OrderStatusHistory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单状态历史服务接口
|
||||
*/
|
||||
public interface OrderStatusHistoryService extends IService<OrderStatusHistory> {
|
||||
|
||||
/**
|
||||
* 根据订单ID查询状态历史
|
||||
* @param orderId 订单ID
|
||||
* @return 订单状态历史列表
|
||||
*/
|
||||
Result<List<OrderStatusHistory>> getHistoryByOrderId(Long orderId);
|
||||
|
||||
/**
|
||||
* 创建订单状态历史记录
|
||||
* @param orderStatusHistory 订单状态历史信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createStatusHistory(OrderStatusHistory orderStatusHistory);
|
||||
|
||||
/**
|
||||
* 更新订单状态历史信息
|
||||
* @param orderStatusHistory 订单状态历史信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateStatusHistory(OrderStatusHistory orderStatusHistory);
|
||||
|
||||
/**
|
||||
* 删除订单状态历史记录
|
||||
* @param id 记录ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteStatusHistory(Long id);
|
||||
|
||||
/**
|
||||
* 根据记录ID查询订单状态历史
|
||||
* @param id 记录ID
|
||||
* @return 订单状态历史信息
|
||||
*/
|
||||
Result<OrderStatusHistory> getStatusHistoryById(Long id);
|
||||
|
||||
/**
|
||||
* 批量创建订单状态历史记录
|
||||
* @param historyList 订单状态历史列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchCreateStatusHistory(List<OrderStatusHistory> historyList);
|
||||
|
||||
/**
|
||||
* 根据订单ID和状态查询历史记录
|
||||
* @param orderId 订单ID
|
||||
* @param status 订单状态
|
||||
* @return 订单状态历史列表
|
||||
*/
|
||||
Result<List<OrderStatusHistory>> getHistoryByOrderIdAndStatus(Long orderId, Integer status);
|
||||
|
||||
/**
|
||||
* 获取订单最新状态
|
||||
* @param orderId 订单ID
|
||||
* @return 最新订单状态历史信息
|
||||
*/
|
||||
Result<OrderStatusHistory> getLatestStatusHistory(Long orderId);
|
||||
|
||||
/**
|
||||
* 根据订单ID删除所有状态历史
|
||||
* @param orderId 订单ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteHistoryByOrderId(Long orderId);
|
||||
}
|
||||
85
src/main/java/com/qf/backend/service/OrdersService.java
Normal file
85
src/main/java/com/qf/backend/service/OrdersService.java
Normal file
@@ -0,0 +1,85 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.Orders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订单服务接口
|
||||
*/
|
||||
public interface OrdersService extends IService<Orders> {
|
||||
|
||||
/**
|
||||
* 根据订单号查询订单
|
||||
* @param orderNumber 订单号
|
||||
* @return 订单信息
|
||||
*/
|
||||
Result<Orders> getOrderByNumber(String orderNumber);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询订单列表
|
||||
* @param userId 用户ID
|
||||
* @return 订单列表
|
||||
*/
|
||||
Result<List<Orders>> getOrdersByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 创建订单
|
||||
* @param orders 订单信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createOrder(Orders orders);
|
||||
|
||||
/**
|
||||
* 更新订单信息
|
||||
* @param orders 订单信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateOrder(Orders orders);
|
||||
|
||||
/**
|
||||
* 删除订单
|
||||
* @param id 订单ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteOrder(Long id);
|
||||
|
||||
/**
|
||||
* 根据订单ID查询订单
|
||||
* @param id 订单ID
|
||||
* @return 订单信息
|
||||
*/
|
||||
Result<Orders> getOrderById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询订单
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 订单列表
|
||||
*/
|
||||
Result<List<Orders>> listOrdersByPage(int page, int size);
|
||||
|
||||
/**
|
||||
* 根据店铺ID查询订单
|
||||
* @param shopId 店铺ID
|
||||
* @return 订单列表
|
||||
*/
|
||||
Result<List<Orders>> getOrdersByShopId(Long shopId);
|
||||
|
||||
/**
|
||||
* 更新订单状态
|
||||
* @param orderId 订单ID
|
||||
* @param status 订单状态
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateOrderStatus(Long orderId, Integer status);
|
||||
|
||||
/**
|
||||
* 根据订单状态查询订单
|
||||
* @param status 订单状态
|
||||
* @return 订单列表
|
||||
*/
|
||||
Result<List<Orders>> getOrdersByStatus(Integer status);
|
||||
}
|
||||
84
src/main/java/com/qf/backend/service/PaymentsService.java
Normal file
84
src/main/java/com/qf/backend/service/PaymentsService.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.entity.Payments;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支付服务接口
|
||||
*/
|
||||
public interface PaymentsService extends IService<Payments> {
|
||||
|
||||
/**
|
||||
* 根据订单ID查询支付记录
|
||||
* @param orderId 订单ID
|
||||
* @return 支付记录
|
||||
*/
|
||||
Payments getPaymentByOrderId(Long orderId);
|
||||
|
||||
/**
|
||||
* 根据支付流水号查询支付记录
|
||||
* @param transactionId 支付流水号
|
||||
* @return 支付记录
|
||||
*/
|
||||
Payments getPaymentByTransactionId(String transactionId);
|
||||
|
||||
/**
|
||||
* 创建支付记录
|
||||
* @param payments 支付信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean createPayment(Payments payments);
|
||||
|
||||
/**
|
||||
* 更新支付信息
|
||||
* @param payments 支付信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updatePayment(Payments payments);
|
||||
|
||||
/**
|
||||
* 删除支付记录
|
||||
* @param id 支付ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean deletePayment(Long id);
|
||||
|
||||
/**
|
||||
* 根据支付ID查询支付记录
|
||||
* @param id 支付ID
|
||||
* @return 支付记录
|
||||
*/
|
||||
Payments getPaymentById(Long id);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询支付记录
|
||||
* @param userId 用户ID
|
||||
* @return 支付记录列表
|
||||
*/
|
||||
List<Payments> getPaymentsByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据支付状态查询支付记录
|
||||
* @param status 支付状态
|
||||
* @return 支付记录列表
|
||||
*/
|
||||
List<Payments> getPaymentsByStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 更新支付状态
|
||||
* @param paymentId 支付ID
|
||||
* @param status 支付状态
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updatePaymentStatus(Long paymentId, Integer status);
|
||||
|
||||
/**
|
||||
* 分页查询支付记录
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 支付记录列表
|
||||
*/
|
||||
List<Payments> listPaymentsByPage(int page, int size);
|
||||
}
|
||||
74
src/main/java/com/qf/backend/service/PermissionsService.java
Normal file
74
src/main/java/com/qf/backend/service/PermissionsService.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.entity.Permissions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 权限服务接口
|
||||
*/
|
||||
public interface PermissionsService extends IService<Permissions> {
|
||||
|
||||
/**
|
||||
* 根据权限编码查询权限
|
||||
* @param permissionCode 权限编码
|
||||
* @return 权限信息
|
||||
*/
|
||||
Permissions getPermissionByCode(String permissionCode);
|
||||
|
||||
/**
|
||||
* 创建权限
|
||||
* @param permissions 权限信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean createPermission(Permissions permissions);
|
||||
|
||||
/**
|
||||
* 更新权限信息
|
||||
* @param permissions 权限信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updatePermission(Permissions permissions);
|
||||
|
||||
/**
|
||||
* 删除权限
|
||||
* @param id 权限ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean deletePermission(Long id);
|
||||
|
||||
/**
|
||||
* 查询所有权限
|
||||
* @return 权限列表
|
||||
*/
|
||||
List<Permissions> listAllPermissions();
|
||||
|
||||
/**
|
||||
* 根据权限ID查询权限
|
||||
* @param id 权限ID
|
||||
* @return 权限信息
|
||||
*/
|
||||
Permissions getPermissionById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除权限
|
||||
* @param ids 权限ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean batchDeletePermissions(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据菜单ID查询权限
|
||||
* @param menuId 菜单ID
|
||||
* @return 权限列表
|
||||
*/
|
||||
List<Permissions> listPermissionsByMenuId(Long menuId);
|
||||
|
||||
/**
|
||||
* 根据权限类型查询权限
|
||||
* @param permissionType 权限类型
|
||||
* @return 权限列表
|
||||
*/
|
||||
List<Permissions> listPermissionsByType(String permissionType);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.ProductAttributeValues;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品属性值服务接口
|
||||
*/
|
||||
public interface ProductAttributeValuesService extends IService<ProductAttributeValues> {
|
||||
|
||||
/**
|
||||
* 根据商品ID查询属性值
|
||||
* @param productId 商品ID
|
||||
* @return 属性值列表
|
||||
*/
|
||||
Result<List<ProductAttributeValues>> getAttributeValuesByProductId(Long productId);
|
||||
|
||||
/**
|
||||
* 根据属性ID查询属性值
|
||||
* @param attributeId 属性ID
|
||||
* @return 属性值列表
|
||||
*/
|
||||
Result<List<ProductAttributeValues>> getAttributeValuesByAttributeId(Long attributeId);
|
||||
|
||||
/**
|
||||
* 创建属性值
|
||||
* @param productAttributeValues 属性值信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createAttributeValue(ProductAttributeValues productAttributeValues);
|
||||
|
||||
/**
|
||||
* 更新属性值信息
|
||||
* @param productAttributeValues 属性值信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateAttributeValue(ProductAttributeValues productAttributeValues);
|
||||
|
||||
/**
|
||||
* 删除属性值
|
||||
* @param id 属性值ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteAttributeValue(Long id);
|
||||
|
||||
/**
|
||||
* 根据属性值ID查询属性值
|
||||
* @param id 属性值ID
|
||||
* @return 属性值信息
|
||||
*/
|
||||
Result<ProductAttributeValues> getAttributeValueById(Long id);
|
||||
|
||||
/**
|
||||
* 批量创建商品属性值
|
||||
* @param attributeValues 属性值列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchCreateAttributeValues(List<ProductAttributeValues> attributeValues);
|
||||
|
||||
/**
|
||||
* 根据商品ID和属性ID查询属性值
|
||||
* @param productId 商品ID
|
||||
* @param attributeId 属性ID
|
||||
* @return 属性值信息
|
||||
*/
|
||||
Result<ProductAttributeValues> getAttributeValueByProductAndAttribute(Long productId, Long attributeId);
|
||||
|
||||
/**
|
||||
* 根据商品ID删除所有属性值
|
||||
* @param productId 商品ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteAttributeValuesByProductId(Long productId);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.ProductAttributes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品属性服务接口
|
||||
*/
|
||||
public interface ProductAttributesService extends IService<ProductAttributes> {
|
||||
|
||||
/**
|
||||
* 根据分类ID查询属性
|
||||
* @param categoryId 分类ID
|
||||
* @return 属性列表
|
||||
*/
|
||||
Result<List<ProductAttributes>> getAttributesByCategoryId(Long categoryId);
|
||||
|
||||
/**
|
||||
* 根据属性名称查询属性
|
||||
* @param attributeName 属性名称
|
||||
* @return 属性列表
|
||||
*/
|
||||
Result<List<ProductAttributes>> getAttributesByName(String attributeName);
|
||||
|
||||
/**
|
||||
* 创建属性
|
||||
* @param productAttributes 属性信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createAttribute(ProductAttributes productAttributes);
|
||||
|
||||
/**
|
||||
* 更新属性信息
|
||||
* @param productAttributes 属性信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateAttribute(ProductAttributes productAttributes);
|
||||
|
||||
/**
|
||||
* 删除属性
|
||||
* @param id 属性ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteAttribute(Long id);
|
||||
|
||||
/**
|
||||
* 根据属性ID查询属性
|
||||
* @param id 属性ID
|
||||
* @return 属性信息
|
||||
*/
|
||||
Result<ProductAttributes> getAttributeById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除属性
|
||||
* @param ids 属性ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchDeleteAttributes(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据属性类型查询属性
|
||||
* @param attributeType 属性类型
|
||||
* @return 属性列表
|
||||
*/
|
||||
Result<List<ProductAttributes>> getAttributesByType(String attributeType);
|
||||
|
||||
/**
|
||||
* 查询是否可搜索的属性
|
||||
* @param searchable 是否可搜索
|
||||
* @return 属性列表
|
||||
*/
|
||||
Result<List<ProductAttributes>> getAttributesBySearchable(Boolean searchable);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.ProductCategories;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品分类服务接口
|
||||
*/
|
||||
public interface ProductCategoriesService extends IService<ProductCategories> {
|
||||
|
||||
/**
|
||||
* 根据分类名称查询分类
|
||||
* @param categoryName 分类名称
|
||||
* @return 分类信息
|
||||
*/
|
||||
Result<ProductCategories> getCategoryByName(String categoryName);
|
||||
|
||||
/**
|
||||
* 根据父分类ID查询子分类
|
||||
* @param parentId 父分类ID
|
||||
* @return 子分类列表
|
||||
*/
|
||||
Result<List<ProductCategories>> getSubCategoriesByParentId(Long parentId);
|
||||
|
||||
/**
|
||||
* 创建分类
|
||||
* @param productCategories 分类信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createCategory(ProductCategories productCategories);
|
||||
|
||||
/**
|
||||
* 更新分类信息
|
||||
* @param productCategories 分类信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateCategory(ProductCategories productCategories);
|
||||
|
||||
/**
|
||||
* 删除分类
|
||||
* @param id 分类ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteCategory(Long id);
|
||||
|
||||
/**
|
||||
* 查询所有根分类(父分类ID为0或null的分类)
|
||||
* @return 根分类列表
|
||||
*/
|
||||
Result<List<ProductCategories>> listRootCategories();
|
||||
|
||||
/**
|
||||
* 根据分类ID查询分类
|
||||
* @param id 分类ID
|
||||
* @return 分类信息
|
||||
*/
|
||||
Result<ProductCategories> getCategoryById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除分类
|
||||
* @param ids 分类ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchDeleteCategories(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 查询所有分类(树形结构)
|
||||
* @return 分类树形列表
|
||||
*/
|
||||
Result<List<ProductCategories>> listAllCategoriesWithTree();
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.ProductImages;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品图片服务接口
|
||||
*/
|
||||
public interface ProductImagesService extends IService<ProductImages> {
|
||||
|
||||
/**
|
||||
* 根据商品ID查询图片
|
||||
* @param productId 商品ID
|
||||
* @return 图片列表
|
||||
*/
|
||||
Result<List<ProductImages>> getImagesByProductId(Long productId);
|
||||
|
||||
/**
|
||||
* 根据商品ID查询主图
|
||||
* @param productId 商品ID
|
||||
* @return 主图信息
|
||||
*/
|
||||
Result<ProductImages> getMainImageByProductId(Long productId);
|
||||
|
||||
/**
|
||||
* 创建商品图片
|
||||
* @param productImages 图片信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createImage(ProductImages productImages);
|
||||
|
||||
/**
|
||||
* 更新图片信息
|
||||
* @param productImages 图片信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateImage(ProductImages productImages);
|
||||
|
||||
/**
|
||||
* 删除图片
|
||||
* @param id 图片ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteImage(Long id);
|
||||
|
||||
/**
|
||||
* 根据图片ID查询图片
|
||||
* @param id 图片ID
|
||||
* @return 图片信息
|
||||
*/
|
||||
Result<ProductImages> getImageById(Long id);
|
||||
|
||||
/**
|
||||
* 批量创建商品图片
|
||||
* @param images 图片列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchCreateImages(List<ProductImages> images);
|
||||
|
||||
/**
|
||||
* 根据商品ID删除所有图片
|
||||
* @param productId 商品ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteImagesByProductId(Long productId);
|
||||
|
||||
/**
|
||||
* 设置主图
|
||||
* @param productId 商品ID
|
||||
* @param imageId 图片ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> setMainImage(Long productId, Long imageId);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.ProductInventories;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品库存服务接口
|
||||
*/
|
||||
public interface ProductInventoriesService extends IService<ProductInventories> {
|
||||
|
||||
/**
|
||||
* 根据商品ID查询库存
|
||||
* @param productId 商品ID
|
||||
* @return 库存列表
|
||||
*/
|
||||
Result<List<ProductInventories>> getInventoriesByProductId(Long productId);
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询库存
|
||||
* @param skuId SKU ID
|
||||
* @return 库存信息
|
||||
*/
|
||||
Result<ProductInventories> getInventoryBySkuId(Long skuId);
|
||||
|
||||
/**
|
||||
* 创建库存记录
|
||||
* @param productInventories 库存信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createInventory(ProductInventories productInventories);
|
||||
|
||||
/**
|
||||
* 更新库存信息
|
||||
* @param productInventories 库存信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateInventory(ProductInventories productInventories);
|
||||
|
||||
/**
|
||||
* 删除库存记录
|
||||
* @param id 库存ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteInventory(Long id);
|
||||
|
||||
/**
|
||||
* 根据库存ID查询库存
|
||||
* @param id 库存ID
|
||||
* @return 库存信息
|
||||
*/
|
||||
Result<ProductInventories> getInventoryById(Long id);
|
||||
|
||||
/**
|
||||
* 增加库存
|
||||
* @param skuId SKU ID
|
||||
* @param quantity 增加数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> increaseInventory(Long skuId, Integer quantity);
|
||||
|
||||
/**
|
||||
* 减少库存
|
||||
* @param skuId SKU ID
|
||||
* @param quantity 减少数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> decreaseInventory(Long skuId, Integer quantity);
|
||||
|
||||
/**
|
||||
* 检查库存是否充足
|
||||
* @param skuId SKU ID
|
||||
* @param quantity 需要的数量
|
||||
* @return 是否充足
|
||||
*/
|
||||
Result<Boolean> checkInventorySufficient(Long skuId, Integer quantity);
|
||||
|
||||
/**
|
||||
* 批量更新库存
|
||||
* @param inventoryUpdates 库存更新列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchUpdateInventory(List<ProductInventories> inventoryUpdates);
|
||||
}
|
||||
84
src/main/java/com/qf/backend/service/ProductSkusService.java
Normal file
84
src/main/java/com/qf/backend/service/ProductSkusService.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.ProductSkus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品SKU服务接口
|
||||
*/
|
||||
public interface ProductSkusService extends IService<ProductSkus> {
|
||||
|
||||
/**
|
||||
* 根据商品ID查询SKU
|
||||
* @param productId 商品ID
|
||||
* @return SKU列表
|
||||
*/
|
||||
Result<List<ProductSkus>> getSkusByProductId(Long productId);
|
||||
|
||||
/**
|
||||
* 根据SKU编码查询SKU
|
||||
* @param skuCode SKU编码
|
||||
* @return SKU信息
|
||||
*/
|
||||
Result<ProductSkus> getSkuByCode(String skuCode);
|
||||
|
||||
/**
|
||||
* 创建SKU
|
||||
* @param productSkus SKU信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createSku(ProductSkus productSkus);
|
||||
|
||||
/**
|
||||
* 更新SKU信息
|
||||
* @param productSkus SKU信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateSku(ProductSkus productSkus);
|
||||
|
||||
/**
|
||||
* 删除SKU
|
||||
* @param id SKU ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteSku(Long id);
|
||||
|
||||
/**
|
||||
* 根据SKU ID查询SKU
|
||||
* @param id SKU ID
|
||||
* @return SKU信息
|
||||
*/
|
||||
Result<ProductSkus> getSkuById(Long id);
|
||||
|
||||
/**
|
||||
* 批量创建SKU
|
||||
* @param skus SKU列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchCreateSkus(List<ProductSkus> skus);
|
||||
|
||||
/**
|
||||
* 根据商品ID删除所有SKU
|
||||
* @param productId 商品ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteSkusByProductId(Long productId);
|
||||
|
||||
/**
|
||||
* 更新SKU库存
|
||||
* @param skuId SKU ID
|
||||
* @param quantity 库存数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateSkuStock(Long skuId, Integer quantity);
|
||||
|
||||
/**
|
||||
* 批量查询SKU
|
||||
* @param skuIds SKU ID列表
|
||||
* @return SKU列表
|
||||
*/
|
||||
Result<List<ProductSkus>> batchGetSkus(List<Long> skuIds);
|
||||
}
|
||||
87
src/main/java/com/qf/backend/service/ProductsService.java
Normal file
87
src/main/java/com/qf/backend/service/ProductsService.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.Products;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品服务接口
|
||||
*/
|
||||
public interface ProductsService extends IService<Products> {
|
||||
|
||||
/**
|
||||
* 根据商品名称查询商品
|
||||
* @param productName 商品名称
|
||||
* @return 商品列表
|
||||
*/
|
||||
Result<List<Products>> getProductsByName(String productName);
|
||||
|
||||
/**
|
||||
* 根据分类ID查询商品
|
||||
* @param categoryId 分类ID
|
||||
* @return 商品列表
|
||||
*/
|
||||
Result<List<Products>> getProductsByCategoryId(Long categoryId);
|
||||
|
||||
/**
|
||||
* 创建商品
|
||||
* @param products 商品信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createProduct(Products products);
|
||||
|
||||
/**
|
||||
* 更新商品信息
|
||||
* @param products 商品信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateProduct(Products products);
|
||||
|
||||
/**
|
||||
* 删除商品
|
||||
* @param id 商品ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteProduct(Long id);
|
||||
|
||||
/**
|
||||
* 根据商品ID查询商品
|
||||
* @param id 商品ID
|
||||
* @return 商品信息
|
||||
*/
|
||||
Result<Products> getProductById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询商品
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 商品列表
|
||||
*/
|
||||
Result<List<Products>> listProductsByPage(int page, int size);
|
||||
|
||||
/**
|
||||
* 根据店铺ID查询商品
|
||||
* @param shopId 店铺ID
|
||||
* @return 商品列表
|
||||
*/
|
||||
Result<List<Products>> getProductsByShopId(Long shopId);
|
||||
|
||||
/**
|
||||
* 批量上下架商品
|
||||
* @param ids 商品ID列表
|
||||
* @param status 状态(上架/下架)
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchUpdateProductStatus(List<Long> ids, Integer status);
|
||||
|
||||
/**
|
||||
* 搜索商品
|
||||
* @param keyword 关键词
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 商品列表
|
||||
*/
|
||||
Result<List<Products>> searchProducts(String keyword, int page, int size);
|
||||
}
|
||||
84
src/main/java/com/qf/backend/service/RefundsService.java
Normal file
84
src/main/java/com/qf/backend/service/RefundsService.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.entity.Refunds;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 退款服务接口
|
||||
*/
|
||||
public interface RefundsService extends IService<Refunds> {
|
||||
|
||||
/**
|
||||
* 根据订单ID查询退款记录
|
||||
* @param orderId 订单ID
|
||||
* @return 退款记录列表
|
||||
*/
|
||||
List<Refunds> getRefundsByOrderId(Long orderId);
|
||||
|
||||
/**
|
||||
* 根据退款单号查询退款记录
|
||||
* @param refundNumber 退款单号
|
||||
* @return 退款记录
|
||||
*/
|
||||
Refunds getRefundByNumber(String refundNumber);
|
||||
|
||||
/**
|
||||
* 创建退款记录
|
||||
* @param refunds 退款信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean createRefund(Refunds refunds);
|
||||
|
||||
/**
|
||||
* 更新退款信息
|
||||
* @param refunds 退款信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateRefund(Refunds refunds);
|
||||
|
||||
/**
|
||||
* 删除退款记录
|
||||
* @param id 退款ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean deleteRefund(Long id);
|
||||
|
||||
/**
|
||||
* 根据退款ID查询退款记录
|
||||
* @param id 退款ID
|
||||
* @return 退款记录
|
||||
*/
|
||||
Refunds getRefundById(Long id);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询退款记录
|
||||
* @param userId 用户ID
|
||||
* @return 退款记录列表
|
||||
*/
|
||||
List<Refunds> getRefundsByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据退款状态查询退款记录
|
||||
* @param status 退款状态
|
||||
* @return 退款记录列表
|
||||
*/
|
||||
List<Refunds> getRefundsByStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 更新退款状态
|
||||
* @param refundId 退款ID
|
||||
* @param status 退款状态
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateRefundStatus(Long refundId, Integer status);
|
||||
|
||||
/**
|
||||
* 分页查询退款记录
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 退款记录列表
|
||||
*/
|
||||
List<Refunds> listRefundsByPage(int page, int size);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.entity.RolePermissions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色权限关联服务接口
|
||||
*/
|
||||
public interface RolePermissionsService extends IService<RolePermissions> {
|
||||
|
||||
/**
|
||||
* 根据角色ID查询角色权限关联
|
||||
* @param roleId 角色ID
|
||||
* @return 角色权限关联列表
|
||||
*/
|
||||
List<RolePermissions> getRolePermissionsByRoleId(Long roleId);
|
||||
|
||||
/**
|
||||
* 根据权限ID查询角色权限关联
|
||||
* @param permissionId 权限ID
|
||||
* @return 角色权限关联列表
|
||||
*/
|
||||
List<RolePermissions> getRolePermissionsByPermissionId(Long permissionId);
|
||||
|
||||
/**
|
||||
* 为角色添加权限
|
||||
* @param roleId 角色ID
|
||||
* @param permissionId 权限ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean addPermissionToRole(Long roleId, Long permissionId);
|
||||
|
||||
/**
|
||||
* 从角色移除权限
|
||||
* @param roleId 角色ID
|
||||
* @param permissionId 权限ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean removePermissionFromRole(Long roleId, Long permissionId);
|
||||
|
||||
/**
|
||||
* 批量为角色添加权限
|
||||
* @param roleId 角色ID
|
||||
* @param permissionIds 权限ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean batchAddPermissionsToRole(Long roleId, List<Long> permissionIds);
|
||||
|
||||
/**
|
||||
* 清空角色的所有权限
|
||||
* @param roleId 角色ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean clearRolePermissions(Long roleId);
|
||||
|
||||
/**
|
||||
* 检查角色是否拥有指定权限
|
||||
* @param roleId 角色ID
|
||||
* @param permissionId 权限ID
|
||||
* @return 是否拥有
|
||||
*/
|
||||
boolean checkRoleHasPermission(Long roleId, Long permissionId);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询其拥有的权限ID列表
|
||||
* @param roleId 角色ID
|
||||
* @return 权限ID列表
|
||||
*/
|
||||
List<Long> listPermissionIdsByRoleId(Long roleId);
|
||||
}
|
||||
67
src/main/java/com/qf/backend/service/RolesService.java
Normal file
67
src/main/java/com/qf/backend/service/RolesService.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.entity.Roles;
|
||||
|
||||
/**
|
||||
* 角色服务接口
|
||||
*/
|
||||
public interface RolesService extends IService<Roles> {
|
||||
|
||||
/**
|
||||
* 根据角色名称查询角色
|
||||
* @param roleName 角色名称
|
||||
* @return 角色信息
|
||||
*/
|
||||
Roles getRoleByName(String roleName);
|
||||
|
||||
/**
|
||||
* 创建角色
|
||||
* @param roles 角色信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean createRole(Roles roles);
|
||||
|
||||
/**
|
||||
* 更新角色信息
|
||||
* @param roles 角色信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean updateRole(Roles roles);
|
||||
|
||||
/**
|
||||
* 删除角色
|
||||
* @param id 角色ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean deleteRole(Long id);
|
||||
|
||||
/**
|
||||
* 查询所有角色
|
||||
* @return 角色列表
|
||||
*/
|
||||
List<Roles> listAllRoles();
|
||||
|
||||
/**
|
||||
* 根据角色ID查询角色
|
||||
* @param id 角色ID
|
||||
* @return 角色信息
|
||||
*/
|
||||
Roles getRoleById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除角色
|
||||
* @param ids 角色ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean batchDeleteRoles(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询其拥有的角色列表
|
||||
* @param userId 用户ID
|
||||
* @return 角色列表
|
||||
*/
|
||||
List<Roles> listRolesByUserId(Long userId);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.ShopCategories;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 店铺分类服务接口
|
||||
*/
|
||||
public interface ShopCategoriesService extends IService<ShopCategories> {
|
||||
|
||||
/**
|
||||
* 根据分类名称查询分类
|
||||
* @param categoryName 分类名称
|
||||
* @return 分类信息
|
||||
*/
|
||||
Result<ShopCategories> getCategoryByName(String categoryName);
|
||||
|
||||
/**
|
||||
* 根据父分类ID查询子分类
|
||||
* @param parentId 父分类ID
|
||||
* @return 子分类列表
|
||||
*/
|
||||
Result<List<ShopCategories>> getSubCategoriesByParentId(Long parentId);
|
||||
|
||||
/**
|
||||
* 创建分类
|
||||
* @param shopCategories 分类信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createCategory(ShopCategories shopCategories);
|
||||
|
||||
/**
|
||||
* 更新分类信息
|
||||
* @param shopCategories 分类信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateCategory(ShopCategories shopCategories);
|
||||
|
||||
/**
|
||||
* 删除分类
|
||||
* @param id 分类ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteCategory(Long id);
|
||||
|
||||
/**
|
||||
* 查询所有根分类(父分类ID为0或null的分类)
|
||||
* @return 根分类列表
|
||||
*/
|
||||
Result<List<ShopCategories>> listRootCategories();
|
||||
|
||||
/**
|
||||
* 根据分类ID查询分类
|
||||
* @param id 分类ID
|
||||
* @return 分类信息
|
||||
*/
|
||||
Result<ShopCategories> getCategoryById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除分类
|
||||
* @param ids 分类ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchDeleteCategories(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 查询所有分类(树形结构)
|
||||
* @return 分类树形列表
|
||||
*/
|
||||
Result<List<ShopCategories>> listAllCategoriesWithTree();
|
||||
}
|
||||
94
src/main/java/com/qf/backend/service/ShopRatingsService.java
Normal file
94
src/main/java/com/qf/backend/service/ShopRatingsService.java
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.ShopRatings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 店铺评分服务接口
|
||||
*/
|
||||
public interface ShopRatingsService extends IService<ShopRatings> {
|
||||
|
||||
/**
|
||||
* 根据店铺ID查询评分
|
||||
* @param shopId 店铺ID
|
||||
* @return 评分列表
|
||||
*/
|
||||
Result<List<ShopRatings>> getRatingsByShopId(Long shopId);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询评分
|
||||
* @param userId 用户ID
|
||||
* @return 评分列表
|
||||
*/
|
||||
Result<List<ShopRatings>> getRatingsByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 创建评分
|
||||
* @param shopRatings 评分信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createRating(ShopRatings shopRatings);
|
||||
|
||||
/**
|
||||
* 更新评分信息
|
||||
* @param shopRatings 评分信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateRating(ShopRatings shopRatings);
|
||||
|
||||
/**
|
||||
* 删除评分
|
||||
* @param id 评分ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteRating(Long id);
|
||||
|
||||
/**
|
||||
* 根据评分ID查询评分
|
||||
* @param id 评分ID
|
||||
* @return 评分信息
|
||||
*/
|
||||
Result<ShopRatings> getRatingById(Long id);
|
||||
|
||||
/**
|
||||
* 获取店铺平均评分
|
||||
* @param shopId 店铺ID
|
||||
* @return 平均评分
|
||||
*/
|
||||
Result<Double> getAverageRatingByShopId(Long shopId);
|
||||
|
||||
/**
|
||||
* 获取店铺评分数量
|
||||
* @param shopId 店铺ID
|
||||
* @return 评分数量
|
||||
*/
|
||||
Result<Integer> getRatingCountByShopId(Long shopId);
|
||||
|
||||
/**
|
||||
* 根据评分星级查询店铺评分
|
||||
* @param shopId 店铺ID
|
||||
* @param rating 评分星级
|
||||
* @return 评分列表
|
||||
*/
|
||||
Result<List<ShopRatings>> getRatingsByShopIdAndRating(Long shopId, Integer rating);
|
||||
|
||||
/**
|
||||
* 检查用户是否已对店铺评分
|
||||
* @param shopId 店铺ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否已评分
|
||||
*/
|
||||
Result<Boolean> checkUserHasRated(Long shopId, Long userId);
|
||||
|
||||
/**
|
||||
* 分页查询店铺评分
|
||||
* @param shopId 店铺ID
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 评分列表
|
||||
*/
|
||||
Result<List<ShopRatings>> listRatingsByShopIdAndPage(Long shopId, int page, int size);
|
||||
}
|
||||
87
src/main/java/com/qf/backend/service/ShopsService.java
Normal file
87
src/main/java/com/qf/backend/service/ShopsService.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.Shops;
|
||||
|
||||
/**
|
||||
* 店铺服务接口
|
||||
*/
|
||||
public interface ShopsService extends IService<Shops> {
|
||||
|
||||
/**
|
||||
* 根据店铺名称查询店铺
|
||||
* @param shopName 店铺名称
|
||||
* @return 店铺列表
|
||||
*/
|
||||
Result<List<Shops>> getShopsByName(String shopName);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询店铺
|
||||
* @param userId 用户ID
|
||||
* @return 店铺信息
|
||||
*/
|
||||
Result<Shops> getShopByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 创建店铺
|
||||
* @param shops 店铺信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createShop(Shops shops);
|
||||
|
||||
/**
|
||||
* 更新店铺信息
|
||||
* @param shops 店铺信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateShop(Shops shops);
|
||||
|
||||
/**
|
||||
* 删除店铺
|
||||
* @param id 店铺ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteShop(Long id);
|
||||
|
||||
/**
|
||||
* 根据店铺ID查询店铺
|
||||
* @param id 店铺ID
|
||||
* @return 店铺信息
|
||||
*/
|
||||
Result<Shops> getShopById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询店铺
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 店铺列表
|
||||
*/
|
||||
Result<List<Shops>> listShopsByPage(int page, int size);
|
||||
|
||||
/**
|
||||
* 根据店铺分类ID查询店铺
|
||||
* @param categoryId 分类ID
|
||||
* @return 店铺列表
|
||||
*/
|
||||
Result<List<Shops>> getShopsByCategoryId(Long categoryId);
|
||||
|
||||
/**
|
||||
* 更新店铺状态
|
||||
* @param shopId 店铺ID
|
||||
* @param status 店铺状态
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateShopStatus(Long shopId, Integer status);
|
||||
|
||||
/**
|
||||
* 搜索店铺
|
||||
* @param keyword 关键词
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 店铺列表
|
||||
*/
|
||||
Result<List<Shops>> searchShops(String keyword, int page, int size);
|
||||
}
|
||||
55
src/main/java/com/qf/backend/service/UserDetailsService.java
Normal file
55
src/main/java/com/qf/backend/service/UserDetailsService.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.UserDetails;
|
||||
|
||||
/**
|
||||
* 用户详情服务接口
|
||||
*/
|
||||
public interface UserDetailsService extends IService<UserDetails> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查询用户详情
|
||||
* @param userId 用户ID
|
||||
* @return 用户详情信息
|
||||
*/
|
||||
Result<UserDetails> getUserDetailsByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 创建用户详情
|
||||
* @param userDetails 用户详情信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createUserDetails(UserDetails userDetails);
|
||||
|
||||
/**
|
||||
* 更新用户详情
|
||||
* @param userDetails 用户详情信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateUserDetails(UserDetails userDetails);
|
||||
|
||||
/**
|
||||
* 根据用户ID删除用户详情
|
||||
* @param userId 用户ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteUserDetailsByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据用户详情ID查询
|
||||
* @param id 用户详情ID
|
||||
* @return 用户详情信息
|
||||
*/
|
||||
Result<UserDetails> getUserDetailsById(Long id);
|
||||
|
||||
/**
|
||||
* 更新用户联系方式
|
||||
* @param userId 用户ID
|
||||
* @param phone 手机号
|
||||
* @param email 邮箱
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateContactInfo(Long userId, String phone, String email);
|
||||
}
|
||||
66
src/main/java/com/qf/backend/service/UserRolesService.java
Normal file
66
src/main/java/com/qf/backend/service/UserRolesService.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.UserRoles;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户角色关联服务接口
|
||||
*/
|
||||
public interface UserRolesService extends IService<UserRoles> {
|
||||
|
||||
/**
|
||||
* 根据用户ID查询用户角色关联
|
||||
* @param userId 用户ID
|
||||
* @return 用户角色关联列表
|
||||
*/
|
||||
Result<List<UserRoles>> getUserRolesByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色ID查询用户角色关联
|
||||
* @param roleId 角色ID
|
||||
* @return 用户角色关联列表
|
||||
*/
|
||||
Result<List<UserRoles>> getUserRolesByRoleId(Long roleId);
|
||||
|
||||
/**
|
||||
* 为用户添加角色
|
||||
* @param userId 用户ID
|
||||
* @param roleId 角色ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> addRoleToUser(Long userId, Long roleId);
|
||||
|
||||
/**
|
||||
* 从用户移除角色
|
||||
* @param userId 用户ID
|
||||
* @param roleId 角色ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> removeRoleFromUser(Long userId, Long roleId);
|
||||
|
||||
/**
|
||||
* 批量为用户添加角色
|
||||
* @param userId 用户ID
|
||||
* @param roleIds 角色ID列表
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> batchAddRolesToUser(Long userId, List<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 清空用户的所有角色
|
||||
* @param userId 用户ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> clearUserRoles(Long userId);
|
||||
|
||||
/**
|
||||
* 检查用户是否拥有指定角色
|
||||
* @param userId 用户ID
|
||||
* @param roleId 角色ID
|
||||
* @return 是否拥有
|
||||
*/
|
||||
Result<Boolean> checkUserHasRole(Long userId, Long roleId);
|
||||
}
|
||||
77
src/main/java/com/qf/backend/service/UsersService.java
Normal file
77
src/main/java/com/qf/backend/service/UsersService.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package com.qf.backend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.entity.Users;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户服务接口
|
||||
*/
|
||||
public interface UsersService extends IService<Users> {
|
||||
|
||||
/**
|
||||
* 根据用户名查询用户
|
||||
* @param username 用户名
|
||||
* @return 用户信息
|
||||
*/
|
||||
Result<Users> getUserByUsername(String username);
|
||||
|
||||
/**
|
||||
* 根据邮箱查询用户
|
||||
* @param email 邮箱
|
||||
* @return 用户信息
|
||||
*/
|
||||
Result<Users> getUserByEmail(String email);
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
* @param users 用户信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> createUser(Users users);
|
||||
|
||||
/**
|
||||
* 更新用户信息
|
||||
* @param users 用户信息
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updateUser(Users users);
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @param id 用户ID
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> deleteUser(Long id);
|
||||
|
||||
/**
|
||||
* 查询所有用户
|
||||
* @return 用户列表
|
||||
*/
|
||||
Result<List<Users>> listAllUsers();
|
||||
|
||||
/**
|
||||
* 分页查询用户
|
||||
* @param page 当前页码
|
||||
* @param size 每页数量
|
||||
* @return 用户列表
|
||||
*/
|
||||
Result<List<Users>> listUsersByPage(int page, int size);
|
||||
|
||||
/**
|
||||
* 根据用户ID查询用户
|
||||
* @param id 用户ID
|
||||
* @return 用户信息
|
||||
*/
|
||||
Result<Users> getUserById(Long id);
|
||||
|
||||
/**
|
||||
* 更新用户密码
|
||||
* @param id 用户ID
|
||||
* @param newPassword 新密码
|
||||
* @return 是否成功
|
||||
*/
|
||||
Result<Boolean> updatePassword(Long id, String newPassword);
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.qf.backend.service.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.common.ResultUtils;
|
||||
import com.qf.backend.entity.OrderItems;
|
||||
import com.qf.backend.exception.ErrorCode;
|
||||
import com.qf.backend.mapper.OrderItemsMapper;
|
||||
import com.qf.backend.service.OrderItemsService;
|
||||
|
||||
@Service
|
||||
public class OrderItemsServiceImpl implements OrderItemsService {
|
||||
|
||||
@Autowired
|
||||
private OrderItemsMapper orderItemsMapper;
|
||||
|
||||
@Override
|
||||
public Result<List<OrderItems>> getOrderItemsByOrderId(Long orderId) {
|
||||
try {
|
||||
List<OrderItems> orderItems = orderItemsMapper.selectByOrderId(orderId);
|
||||
if (orderItems == null || orderItems.isEmpty()) {
|
||||
return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND);
|
||||
}
|
||||
return ResultUtils.success(orderItems);
|
||||
} catch (Exception e) {
|
||||
return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Result<List<OrderItems>> getOrderItemsByProductId(Long productId) {
|
||||
try {
|
||||
List<OrderItems> orderItems = orderItemsMapper.selectByProductId(productId);
|
||||
if (orderItems == null || orderItems.isEmpty()) {
|
||||
return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND);
|
||||
}
|
||||
return ResultUtils.success(orderItems);
|
||||
} catch (Exception e) {
|
||||
return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public BaseMapper<OrderItems> getBaseMapper() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getBaseMapper'");
|
||||
}
|
||||
@Override
|
||||
public Class<OrderItems> getEntityClass() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getEntityClass'");
|
||||
}
|
||||
@Override
|
||||
public Map<String, Object> getMap(Wrapper<OrderItems> queryWrapper) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getMap'");
|
||||
}
|
||||
@Override
|
||||
public <V> V getObj(Wrapper<OrderItems> queryWrapper, Function<? super Object, V> mapper) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getObj'");
|
||||
}
|
||||
@Override
|
||||
public OrderItems getOne(Wrapper<OrderItems> queryWrapper, boolean throwEx) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOne'");
|
||||
}
|
||||
@Override
|
||||
public Optional<OrderItems> getOneOpt(Wrapper<OrderItems> queryWrapper, boolean throwEx) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOneOpt'");
|
||||
}
|
||||
@Override
|
||||
public boolean saveBatch(Collection<OrderItems> entityList, int batchSize) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'saveBatch'");
|
||||
}
|
||||
@Override
|
||||
public boolean saveOrUpdate(OrderItems entity) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'saveOrUpdate'");
|
||||
}
|
||||
@Override
|
||||
public boolean saveOrUpdateBatch(Collection<OrderItems> entityList, int batchSize) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'saveOrUpdateBatch'");
|
||||
}
|
||||
@Override
|
||||
public boolean updateBatchById(Collection<OrderItems> entityList, int batchSize) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'updateBatchById'");
|
||||
}
|
||||
@Override
|
||||
public Result<Boolean> createOrderItem(OrderItems orderItems) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'createOrderItem'");
|
||||
}
|
||||
@Override
|
||||
public Result<Boolean> updateOrderItem(OrderItems orderItems) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'updateOrderItem'");
|
||||
}
|
||||
@Override
|
||||
public Result<Boolean> deleteOrderItem(Long id) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'deleteOrderItem'");
|
||||
}
|
||||
@Override
|
||||
public Result<OrderItems> getOrderItemById(Long id) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOrderItemById'");
|
||||
}
|
||||
@Override
|
||||
public Result<Boolean> batchCreateOrderItems(List<OrderItems> orderItemsList) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'batchCreateOrderItems'");
|
||||
}
|
||||
@Override
|
||||
public Result<Boolean> deleteOrderItemsByOrderId(Long orderId) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'deleteOrderItemsByOrderId'");
|
||||
}
|
||||
@Override
|
||||
public Result<Double> calculateOrderTotal(Long orderId) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'calculateOrderTotal'");
|
||||
}
|
||||
@Override
|
||||
public Result<List<OrderItems>> getOrderItemsBySkuId(Long skuId) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOrderItemsBySkuId'");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.qf.backend.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.qf.backend.common.Result;
|
||||
import com.qf.backend.common.ResultUtils;
|
||||
import com.qf.backend.entity.Orders;
|
||||
import com.qf.backend.exception.ErrorCode;
|
||||
import com.qf.backend.mapper.OrdersMapper;
|
||||
import com.qf.backend.service.OrdersService;
|
||||
|
||||
import ch.qos.logback.classic.Logger;
|
||||
|
||||
@Service
|
||||
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {
|
||||
@Autowired
|
||||
private OrdersMapper ordersMapper;
|
||||
@Autowired
|
||||
private Logger logger;
|
||||
|
||||
@Override
|
||||
public Result<Orders> getOrderByNumber(String orderNumber) {
|
||||
logger.info("根据订单号查询订单: {}", orderNumber);
|
||||
try {
|
||||
Orders orders = ordersMapper.selectByOrderNumber(orderNumber);
|
||||
if (orders == null) {
|
||||
logger.warn("订单号 {} 不存在", orderNumber);
|
||||
return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND);
|
||||
}
|
||||
return ResultUtils.success(orders);
|
||||
} catch (Exception e) {
|
||||
return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<Orders>> getOrdersByUserId(Long userId) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOrdersByUserId'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> createOrder(Orders orders) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'createOrder'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> updateOrder(Orders orders) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'updateOrder'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> deleteOrder(Long id) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'deleteOrder'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Orders> getOrderById(Long id) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOrderById'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<Orders>> listOrdersByPage(int page, int size) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'listOrdersByPage'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<Orders>> getOrdersByShopId(Long shopId) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOrdersByShopId'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> updateOrderStatus(Long orderId, Integer status) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'updateOrderStatus'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<List<Orders>> getOrdersByStatus(Integer status) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOrdersByStatus'");
|
||||
}
|
||||
}
|
||||
7
src/main/resources/application.properties
Normal file
7
src/main/resources/application.properties
Normal file
@@ -0,0 +1,7 @@
|
||||
spring.application.name=backend
|
||||
|
||||
# 数据库连接配置
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/TaoTaoWang?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=123456
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
13
src/test/java/com/qf/backend/BackendApplicationTests.java
Normal file
13
src/test/java/com/qf/backend/BackendApplicationTests.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.qf.backend;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class BackendApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user