From 51086db30ef517d2c042f7afc1192fecdcf561ab Mon Sep 17 00:00:00 2001 From: qingfeng1121 Date: Fri, 28 Nov 2025 14:14:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=9C=8D=E5=8A=A1=E5=8F=8AJWT=E8=AE=A4?= =?UTF-8?q?=E8=AF=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor: 重构实体类并添加Lombok注解 docs: 更新数据库表结构文档 style: 清理无用代码并优化格式 fix: 修复用户详情服务中的联系方式更新方法 build: 更新pom.xml配置并添加Lombok插件 test: 添加用户登录测试用例 chore: 添加开发和生产环境配置文件 --- build.log | 1 + doc/数据库表结构与关系文档.md | 37 +- pom.xml | 18 +- .../com/qf/backend/config/SecurityConfig.java | 57 +++ .../config/UsersDetailsServiceConfig.java | 43 ++ .../backend/controller/UsersController.java | 39 ++ .../java/com/qf/backend/dto/LoginUser.java | 30 ++ .../com/qf/backend/entity/OrderItems.java | 34 +- .../qf/backend/entity/OrderStatusHistory.java | 24 +- .../java/com/qf/backend/entity/Orders.java | 44 ++- .../java/com/qf/backend/entity/Payments.java | 28 +- .../com/qf/backend/entity/Permissions.java | 24 +- .../entity/ProductAttributeValues.java | 23 +- .../qf/backend/entity/ProductAttributes.java | 22 +- .../qf/backend/entity/ProductCategories.java | 30 +- .../com/qf/backend/entity/ProductImages.java | 22 +- .../qf/backend/entity/ProductInventories.java | 23 +- .../com/qf/backend/entity/ProductSkus.java | 27 +- .../java/com/qf/backend/entity/Products.java | 35 +- .../java/com/qf/backend/entity/Refunds.java | 41 +- .../qf/backend/entity/RolePermissions.java | 17 +- .../java/com/qf/backend/entity/Roles.java | 23 +- .../com/qf/backend/entity/ShopCategories.java | 23 +- .../com/qf/backend/entity/ShopRatings.java | 25 +- .../java/com/qf/backend/entity/Shops.java | 42 +- .../com/qf/backend/entity/UserDetails.java | 32 +- .../java/com/qf/backend/entity/UserRoles.java | 17 +- .../java/com/qf/backend/entity/Users.java | 28 +- .../com/qf/backend/exception/ErrorCode.java | 3 +- .../exception/GlobalExceptionHandler.java | 24 +- .../qf/backend/mapper/UserRolesMapper.java | 1 + .../com/qf/backend/mapper/UsersMapper.java | 1 - .../backend/service/PermissionsService.java | 19 +- .../com/qf/backend/service/RolesService.java | 17 +- .../backend/service/UserDetailsService.java | 8 - .../qf/backend/service/UserLoginService.java | 22 ++ .../service/impl/OrderItemsServiceImpl.java | 366 +++++++++++++++-- .../impl/OrderStatusHistoryServiceImpl.java | 166 ++++++++ .../service/impl/OrdersServiceImpl.java | 251 +++++++++++- .../service/impl/PaymentsServiceImpl.java | 215 ++++++++++ .../service/impl/PermissionsServiceImpl.java | 275 +++++++++++++ .../ProductAttributeValuesServiceImpl.java | 213 ++++++++++ .../impl/ProductAttributesServiceImpl.java | 200 ++++++++++ .../impl/ProductCategoriesServiceImpl.java | 240 +++++++++++ .../impl/ProductImagesServiceImpl.java | 319 +++++++++++++++ .../impl/ProductInventoriesServiceImpl.java | 371 +++++++++++++++++ .../service/impl/ProductSkusServiceImpl.java | 332 ++++++++++++++++ .../service/impl/ProductsServiceImpl.java | 248 ++++++++++++ .../service/impl/RefundsServiceImpl.java | 215 ++++++++++ .../impl/RolePermissionsServiceImpl.java | 212 ++++++++++ .../service/impl/RolesServiceImpl.java | 242 ++++++++++-- .../impl/ShopCategoriesServiceImpl.java | 282 +++++++++++++ .../service/impl/ShopRatingsServiceImpl.java | 373 ++++++++++++++++++ .../service/impl/ShopsServiceImpl.java | 335 ++++++++++++++++ .../service/impl/UserDetailsServiceImpl.java | 158 ++++++++ .../service/impl/UserLoginServiceImpl.java | 64 +++ .../service/impl/UsersRolesServiceImpl.java | 173 ++++++++ .../service/impl/UsersServiceImpl.java | 244 ++++++++---- .../java/com/qf/backend/util/JwtUtils.java | 120 ++++++ .../backend/util/RefundNumberFenerator.java | 21 + .../com/qf/backend/util/ValidateUtil.java | 183 +++++---- ...itional-spring-configuration-metadata.json | 5 + src/main/resources/application-dev.properties | 4 + .../resources/application-prod.properties | 4 + 64 files changed, 6168 insertions(+), 567 deletions(-) create mode 100644 build.log create mode 100644 src/main/java/com/qf/backend/config/SecurityConfig.java create mode 100644 src/main/java/com/qf/backend/config/UsersDetailsServiceConfig.java create mode 100644 src/main/java/com/qf/backend/controller/UsersController.java create mode 100644 src/main/java/com/qf/backend/dto/LoginUser.java create mode 100644 src/main/java/com/qf/backend/service/UserLoginService.java create mode 100644 src/main/java/com/qf/backend/service/impl/OrderStatusHistoryServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/PaymentsServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/PermissionsServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ProductAttributeValuesServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ProductAttributesServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ProductCategoriesServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ProductImagesServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ProductInventoriesServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ProductSkusServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ProductsServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/RefundsServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/RolePermissionsServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ShopCategoriesServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ShopRatingsServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/ShopsServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/UserDetailsServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/UserLoginServiceImpl.java create mode 100644 src/main/java/com/qf/backend/service/impl/UsersRolesServiceImpl.java create mode 100644 src/main/java/com/qf/backend/util/JwtUtils.java create mode 100644 src/main/java/com/qf/backend/util/RefundNumberFenerator.java create mode 100644 src/main/resources/META-INF/additional-spring-configuration-metadata.json create mode 100644 src/main/resources/application-dev.properties create mode 100644 src/main/resources/application-prod.properties diff --git a/build.log b/build.log new file mode 100644 index 0000000..f5ada36 --- /dev/null +++ b/build.log @@ -0,0 +1 @@ +[DEBUG] Shutting down 'noop' factory diff --git a/doc/数据库表结构与关系文档.md b/doc/数据库表结构与关系文档.md index fdddda9..12cc48f 100644 --- a/doc/数据库表结构与关系文档.md +++ b/doc/数据库表结构与关系文档.md @@ -36,12 +36,16 @@ | userId | BIGINT | 用户ID | 外键,关联users表 | | realName | VARCHAR | 真实姓名 | | | idCard | VARCHAR | 身份证号 | | -| gender | INTEGER | 性别 | | +| gender | VARCHAR | 性别 | 男、女、保密 | | birthday | DATE | 生日 | | | address | VARCHAR | 地址 | | +| province | VARCHAR | 省份 | | +| city | VARCHAR | 城市 | | +| district | VARCHAR | 区县 | | | createdAt | DATE | 创建时间 | | | updatedAt | DATE | 更新时间 | | + ## 权限相关表 ### roles表 @@ -97,10 +101,18 @@ | shopName | VARCHAR | 店铺名称 | | | userId | BIGINT | 店主用户ID | 外键,关联users表 | | categoryId | BIGINT | 店铺分类ID | 外键,关联shop_categories表 | -| logo | VARCHAR | 店铺Logo | | +| shopLogo | VARCHAR | 店铺Logo | | | coverImage | VARCHAR | 店铺封面图 | | | description | VARCHAR | 店铺描述 | | -| status | INTEGER | 状态 | 0:待审核, 1:正常, 2:封禁 | +| address | VARCHAR | 店铺地址 | | +| contactPhone | VARCHAR | 联系电话 | | +| contactPerson | VARCHAR | 联系人 | | +| rating | DECIMAL | 店铺评分 | | +| salesVolume | INTEGER | 销量 | | +| status | INTEGER | 状态 | 0: 未审核, 1: 已审核, 2: 已关闭, 3: 审核失败 | +| businessLicense | VARCHAR | 营业执照 | | +| businessStartTime | DATE | 营业时间开始 | | +| businessEndTime | DATE | 营业时间结束 | | | createdAt | DATE | 创建时间 | | | updatedAt | DATE | 更新时间 | | @@ -110,8 +122,9 @@ | :--- | :--- | :--- | :--- | | id | BIGINT | 分类ID | 主键,自增 | | categoryName | VARCHAR | 分类名称 | | -| parentId | BIGINT | 父分类ID | | +| parentId | BIGINT | 父分类ID | 顶级分类为0 | | level | INTEGER | 分类级别 | | +| icon | VARCHAR | 分类图标 | | | sort | INTEGER | 排序 | | | status | INTEGER | 状态 | 0:禁用, 1:启用 | | createdAt | DATE | 创建时间 | | @@ -127,14 +140,13 @@ | 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 | 销量 | | +| currentPrice | DECIMAL | 当前价格 | | +| salesVolume | INTEGER | 销量 | | | status | INTEGER | 状态 | 0:下架, 1:上架 | +| isDeleted | INTEGER | 是否删除 | 0: 未删除, 1: 已删除 | | createdAt | DATE | 创建时间 | | | updatedAt | DATE | 更新时间 | | @@ -144,8 +156,10 @@ | :--- | :--- | :--- | :--- | | id | BIGINT | 分类ID | 主键,自增 | | categoryName | VARCHAR | 分类名称 | | -| parentId | BIGINT | 父分类ID | | -| level | INTEGER | 分类级别 | | +| parentId | BIGINT | 父分类ID | 顶级分类为0 | +| level | INTEGER | 分类级别 | 1、2、3 | +| icon | VARCHAR | 分类图标 | | +| banner | VARCHAR | 分类横幅 | | | sort | INTEGER | 排序 | | | status | INTEGER | 状态 | 0:禁用, 1:启用 | | createdAt | DATE | 创建时间 | | @@ -158,9 +172,8 @@ | id | BIGINT | 属性ID | 主键,自增 | | attributeName | VARCHAR | 属性名称 | | | categoryId | BIGINT | 分类ID | 外键,关联product_categories表 | -| attributeType | INTEGER | 属性类型 | 0:普通属性, 1:规格属性 | +| attributeType | INTEGER | 属性类型 | 0: 规格属性, 1: 销售属性 | | sort | INTEGER | 排序 | | -| status | INTEGER | 状态 | 0:禁用, 1:启用 | | createdAt | DATE | 创建时间 | | | updatedAt | DATE | 更新时间 | | diff --git a/pom.xml b/pom.xml index 60c374b..a19e172 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,6 @@ org.projectlombok lombok - true @@ -181,6 +180,23 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + 3.14.1 + + ${java.version} + ${java.version} + UTF-8 + + + org.projectlombok + lombok + 1.18.42 + + + + diff --git a/src/main/java/com/qf/backend/config/SecurityConfig.java b/src/main/java/com/qf/backend/config/SecurityConfig.java new file mode 100644 index 0000000..5e57fa4 --- /dev/null +++ b/src/main/java/com/qf/backend/config/SecurityConfig.java @@ -0,0 +1,57 @@ +// /* +// * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license +// * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template +// */ +// package com.qf.backend.config; + +// import org.springframework.context.annotation.Bean; +// import org.springframework.context.annotation.Configuration; +// import org.springframework.security.config.annotation.web.builders.HttpSecurity; +// import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +// import org.springframework.security.provisioning.InMemoryUserDetailsManager; +// import org.springframework.security.web.SecurityFilterChain; + +// /** +// * 安全配置类(仅开发 禁用安全认证) +// * +// * @author 30803 +// */ +// @Configuration +// @EnableWebSecurity +// public class SecurityConfig { + +// @Bean +// public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { +// http +// .authorizeHttpRequests(auth -> auth +// .requestMatchers("/users/**").permitAll() // 公开路径 +// .requestMatchers("/admin/**").hasRole("ADMIN") // 需要 ADMIN 角色 +// .anyRequest().authenticated() // 其他请求需登录 +// ) +// .formLogin(form -> form +// .loginPage("/login") // 自定义登录页(可选) +// .permitAll() +// ) +// .logout(logout -> logout +// .permitAll() +// ); +// return http.build(); +// } + +// @Bean +// public UserDetailsService userDetailsService() { +// UserDetails user = User.withDefaultPasswordEncoder() +// .username("user") +// .password("123456") +// .roles("USER") +// .build(); + +// UserDetails admin = User.withDefaultPasswordEncoder() +// .username("admin") +// .password("admin123") +// .roles("USER", "ADMIN") +// .build(); + +// return new InMemoryUserDetailsManager(user, admin); +// } +// } diff --git a/src/main/java/com/qf/backend/config/UsersDetailsServiceConfig.java b/src/main/java/com/qf/backend/config/UsersDetailsServiceConfig.java new file mode 100644 index 0000000..56c3859 --- /dev/null +++ b/src/main/java/com/qf/backend/config/UsersDetailsServiceConfig.java @@ -0,0 +1,43 @@ +// /* +// * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license +// * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template +// */ + +// package com.qf.backend.config; + +// import org.springframework.beans.factory.annotation.Autowired; +// import org.springframework.security.core.userdetails.UserDetailsService; +// import org.springframework.stereotype.Component; +// import org.springframework.stereotype.Service; +// import org.springframework.security.core.userdetails.UserDetails; +// import org.springframework.security.core.userdetails.UsernameNotFoundException; +// import org.springframework.security.core.authority.AuthorityUtils; +// import com.qf.backend.mapper.UsersMapper; +// import com.qf.backend.entity.Users; +// import com.qf.backend.mapper.RolesMapper; + + + +// /** +// * 自定义UserDetailsService +// * 用于从数据库加载用户信息进行认证 +// * @author 30803 +// */ +// @Component +// public class UsersDetailsServiceConfig implements UserDetailsService { +// @Autowired +// private UsersMapper usersMapper; +// @Autowired +// private RolesMapper rolesMapper; + + +// @Override +// public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { +// Users users = usersMapper.selectByUsername(username); +// if (users == null) { +// throw new UsernameNotFoundException("用户不存在"+username); +// } +// int roleType = rolesMapper.selectById(users.getId()).getRoleType(); +// } + +// } diff --git a/src/main/java/com/qf/backend/controller/UsersController.java b/src/main/java/com/qf/backend/controller/UsersController.java new file mode 100644 index 0000000..6c47630 --- /dev/null +++ b/src/main/java/com/qf/backend/controller/UsersController.java @@ -0,0 +1,39 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ + +package com.qf.backend.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.qf.backend.common.Result; +import com.qf.backend.entity.Users; +import com.qf.backend.service.UsersService; + +/** + * + * @author 30803 + */ +@RestController +@RequestMapping("/api/users") +public class UsersController { + @Autowired + private UsersService usersService; + + @GetMapping("/list") + public Result> listAllUsers() { + return usersService.listAllUsers(); + } + @DeleteMapping("/delete/{id}") + public Result deleteUser(Long id) { + System.out.println(id); + return usersService.deleteUser(id); + } +} diff --git a/src/main/java/com/qf/backend/dto/LoginUser.java b/src/main/java/com/qf/backend/dto/LoginUser.java new file mode 100644 index 0000000..dd63d6e --- /dev/null +++ b/src/main/java/com/qf/backend/dto/LoginUser.java @@ -0,0 +1,30 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ + +package com.qf.backend.dto; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +/** + * 登录用户DTO(登录时使用) + * @param id 用户ID + * @param username 用户名 + * @param password 密码 + * @param roles 权限 + * @author 30803 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class LoginUser { + private Long id; + private String username; + private String password; + private List roles; +} diff --git a/src/main/java/com/qf/backend/entity/OrderItems.java b/src/main/java/com/qf/backend/entity/OrderItems.java index d7e6bdd..f011a73 100644 --- a/src/main/java/com/qf/backend/entity/OrderItems.java +++ b/src/main/java/com/qf/backend/entity/OrderItems.java @@ -7,30 +7,34 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 订单商品项表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("order_items") public class OrderItems { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 订单项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; + private Long orderId; // 订单ID,外键,关联orders表 + private Long productId; // 商品ID,外键,关联products表 + private Long skuId; // SKU ID,外键,关联product_skus表 + private String productName; // 商品名称 + private String skuSpecs; // SKU规格 + private String productImage; // 商品图片 + private BigDecimal price; // 价格 + private Integer quantity; // 数量 + private BigDecimal subtotal; // 小计 + private Integer itemStatus; // 商品状态:0:正常, 1:已退款, 2:退款中 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/OrderStatusHistory.java b/src/main/java/com/qf/backend/entity/OrderStatusHistory.java index 53ec60f..7f96b4c 100644 --- a/src/main/java/com/qf/backend/entity/OrderStatusHistory.java +++ b/src/main/java/com/qf/backend/entity/OrderStatusHistory.java @@ -6,25 +6,29 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 订单状态历史表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("order_status_history") public class OrderStatusHistory { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 历史ID,主键,自增 - private Long orderId; - private Integer previousStatus; - private Integer currentStatus; - private String changeReason; - private String operator; - private Date changeTime; - private Date createdAt; + private Long orderId; // 订单ID,外键,关联orders表 + private Integer previousStatus; // 之前状态 + private Integer currentStatus; // 当前状态 + private String changeReason; // 变更原因 + private String operator; // 操作人 + private Date changeTime; // 变更时间 + private Date createdAt; // 创建时间 } diff --git a/src/main/java/com/qf/backend/entity/Orders.java b/src/main/java/com/qf/backend/entity/Orders.java index f5a6311..5ca3666 100644 --- a/src/main/java/com/qf/backend/entity/Orders.java +++ b/src/main/java/com/qf/backend/entity/Orders.java @@ -7,36 +7,40 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 订单主表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("orders") public class Orders { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 订单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 orderNo; // 订单号 + private Long userId; // 用户ID,外键,关联users表 + private Long shopId; // 店铺ID,外键,关联shops表 + 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; + private Date paymentTime; // 支付时间 + private Date shippingTime; // 发货时间 + private Date deliveryTime; // 送达时间 + private Date completeTime; // 完成时间 + private String remark; // 备注 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/Payments.java b/src/main/java/com/qf/backend/entity/Payments.java index c936573..7049ff6 100644 --- a/src/main/java/com/qf/backend/entity/Payments.java +++ b/src/main/java/com/qf/backend/entity/Payments.java @@ -7,30 +7,34 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 支付信息表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("payments") public class Payments { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 支付ID,主键,自增 - private String paymentNo; - private Long orderId; - private Long userId; - private BigDecimal amount; + private String paymentNo; // 支付单号 + private Long orderId; // 订单ID,外键,关联orders表 + private Long userId; // 用户ID,外键,关联users表 + private BigDecimal amount; // 支付金额 private String paymentMethod; // 支付方式 private String transactionId; // 第三方交易流水号 - private Integer paymentStatus; // 0: 待支付, 1: 支付成功, 2: 支付失败, 3: 已退款 + private Integer paymentStatus; // 支付状态:0:待支付, 1:支付成功, 2:支付失败, 3:已退款 private String paymentUrl; // 支付链接 - private Date expireTime; - private Date paymentTime; - private Date createdAt; - private Date updatedAt; + private Date expireTime; // 过期时间 + private Date paymentTime; // 支付时间 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/Permissions.java b/src/main/java/com/qf/backend/entity/Permissions.java index af7f6b9..fc1050f 100644 --- a/src/main/java/com/qf/backend/entity/Permissions.java +++ b/src/main/java/com/qf/backend/entity/Permissions.java @@ -6,25 +6,29 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 权限信息表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("permissions") public class Permissions { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 权限ID,主键,自增 - private String permissionName; - private String permissionCode; - private String description; - private String module; - private Integer status; // 0: 禁用, 1: 启用 - private Date createdAt; - private Date updatedAt; + private String permissionName; // 权限名称 + private String permissionCode; // 权限编码 + private String description; // 权限描述 + private String module; // 所属模块 + private Integer status; // 状态:0:禁用, 1:启用 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/ProductAttributeValues.java b/src/main/java/com/qf/backend/entity/ProductAttributeValues.java index a2a85f6..ce7925e 100644 --- a/src/main/java/com/qf/backend/entity/ProductAttributeValues.java +++ b/src/main/java/com/qf/backend/entity/ProductAttributeValues.java @@ -6,25 +6,28 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 商品属性值表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("product_attribute_values") public class ProductAttributeValues { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 属性值ID,主键,自增 - private Long productId; - private Long attributeId; - private String attributeValue; - private Integer sort; - private Date createdAt; - private Date updatedAt; + private Long productId; // 商品ID,外键,关联products表 + private Long attributeId; // 属性ID,外键,关联product_attributes表 + private String attributeValue; // 属性值 + private Integer sort; // 排序 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/ProductAttributes.java b/src/main/java/com/qf/backend/entity/ProductAttributes.java index 97def85..1fb3a1a 100644 --- a/src/main/java/com/qf/backend/entity/ProductAttributes.java +++ b/src/main/java/com/qf/backend/entity/ProductAttributes.java @@ -6,24 +6,28 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 商品属性表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("product_attributes") public class ProductAttributes { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 属性ID,主键,自增 - private String attributeName; - private Long categoryId; - private Integer attributeType; // 0: 规格属性, 1: 销售属性 - private Integer sort; - private Date createdAt; - private Date updatedAt; + private String attributeName; // 属性名称 + private Long categoryId; // 分类ID,外键,关联product_categories表 + private Integer attributeType; // 属性类型:0: 规格属性, 1: 销售属性 + private Integer sort; // 排序 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/ProductCategories.java b/src/main/java/com/qf/backend/entity/ProductCategories.java index 9374e2e..a80c79c 100644 --- a/src/main/java/com/qf/backend/entity/ProductCategories.java +++ b/src/main/java/com/qf/backend/entity/ProductCategories.java @@ -1,32 +1,40 @@ package com.qf.backend.entity; +import java.util.Date; +import java.util.List; + import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -import java.util.Date; - +import lombok.NoArgsConstructor; /** * 商品分类表 */ @Data - @Builder +@AllArgsConstructor +@NoArgsConstructor @TableName("product_categories") public class ProductCategories { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 分类ID,主键,自增 - private String categoryName; + 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; + private String icon; // 分类图标 + private String banner; // 分类横幅 + private Integer sort; // 排序 + private Integer status; // 状态:0:禁用, 1:启用 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 + + @TableField(exist = false) // 非数据库字段,用于构建树形结构 + private List children; // 子分类列表 } diff --git a/src/main/java/com/qf/backend/entity/ProductImages.java b/src/main/java/com/qf/backend/entity/ProductImages.java index 3e0a1fc..6f9b0a8 100644 --- a/src/main/java/com/qf/backend/entity/ProductImages.java +++ b/src/main/java/com/qf/backend/entity/ProductImages.java @@ -4,25 +4,29 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; + import java.util.Date; /** * 商品图片表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("product_images") public class ProductImages { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 图片ID,主键,自增 - private Long productId; - private String imageUrl; - private Integer sort; - private Integer isMain; // 0: 非主图, 1: 主图 - private Date createdAt; + private Long productId; // 商品ID,外键,关联products表 + private String imageUrl; // 图片URL + private Integer sort; // 排序 + private Integer isMain; // 是否主图:0:非主图, 1:主图 + private Date createdAt; // 创建时间 } diff --git a/src/main/java/com/qf/backend/entity/ProductInventories.java b/src/main/java/com/qf/backend/entity/ProductInventories.java index b43d128..197dfd9 100644 --- a/src/main/java/com/qf/backend/entity/ProductInventories.java +++ b/src/main/java/com/qf/backend/entity/ProductInventories.java @@ -6,26 +6,29 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 库存信息表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("product_inventories") public class ProductInventories { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 库存ID,主键,自增 - private Long skuId; - private Integer currentStock; - private Integer safetyStock; + private Long skuId; // SKU ID,外键,关联product_skus表 + private Integer currentStock; // 当前库存 + private Integer safetyStock; // 安全库存 private Integer lockStock; // 锁定库存 - private Date lastUpdateTime; - private Date createdAt; - private Date updatedAt; + private Date lastUpdateTime; // 最后更新时间 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/ProductSkus.java b/src/main/java/com/qf/backend/entity/ProductSkus.java index 63d2b52..fd12959 100644 --- a/src/main/java/com/qf/backend/entity/ProductSkus.java +++ b/src/main/java/com/qf/backend/entity/ProductSkus.java @@ -7,28 +7,31 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 商品SKU表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("product_skus") public class ProductSkus { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // SKU ID,主键,自增 - private Long productId; - private String skuCode; + private Long productId; // 商品ID,外键,关联products表 + private String skuCode; // SKU编码 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; + private BigDecimal price; // 价格 + private Integer stock; // 库存 + private String image; // 图片 + private Integer status; // 状态:0:禁用, 1:启用 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/Products.java b/src/main/java/com/qf/backend/entity/Products.java index 48f8a0a..2e7f3b6 100644 --- a/src/main/java/com/qf/backend/entity/Products.java +++ b/src/main/java/com/qf/backend/entity/Products.java @@ -7,31 +7,34 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 商品基本信息表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("products") public class Products { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 商品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; + private String productName; // 商品名称 + private Long shopId; // 店铺ID,外键,关联shops表 + private Long categoryId; // 商品分类ID,外键,关联product_categories表 + private String description; // 商品描述 + private BigDecimal originalPrice; // 原价 不能为空 + private BigDecimal currentPrice; // 当前价格 为空时表示原价 ,否则表示折扣价 + private Integer salesVolume; // 销量 + private Integer status; // 状态:0:下架, 1:上架 + private String mainImage; // 主图URL + private Integer isDeleted; // 是否删除:0: 未删除, 1: 已删除 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/Refunds.java b/src/main/java/com/qf/backend/entity/Refunds.java index c5a59ef..2e229ad 100644 --- a/src/main/java/com/qf/backend/entity/Refunds.java +++ b/src/main/java/com/qf/backend/entity/Refunds.java @@ -7,35 +7,38 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 退款信息表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("refunds") public class Refunds { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 退款ID,主键,自增 - private String refundNo; - private Long orderId; - private Long orderItemId; - private Long userId; - private Long shopId; - private BigDecimal refundAmount; - private String refundReason; + private String refundNo; // 退款单号 + private Long orderId; // 订单ID,外键,关联orders表 + private Long orderItemId; // 订单项ID,外键,关联order_items表 + private Long userId; // 用户ID,外键,关联users表 + private Long shopId; // 店铺ID,外键,关联shops表 + 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; + private Integer refundStatus; // 退款状态:0:申请中, 1:退款成功, 2:退款失败, 3:已拒绝 + private String refundAccount; // 退款账户 + private String transactionId; // 交易ID + private Date applyTime; // 申请时间 + private Date processTime; // 处理时间 + private String processRemark; // 处理备注 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/RolePermissions.java b/src/main/java/com/qf/backend/entity/RolePermissions.java index c34a2ba..bf1f16a 100644 --- a/src/main/java/com/qf/backend/entity/RolePermissions.java +++ b/src/main/java/com/qf/backend/entity/RolePermissions.java @@ -6,22 +6,25 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 角色-权限关联表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("role_permissions") public class RolePermissions { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 关联ID,主键,自增 - private Long roleId; - private Long permissionId; - private Date createdAt; + private Long roleId; // 角色ID,外键,关联roles表 + private Long permissionId; // 权限ID,外键,关联permissions表 + private Date createdAt; // 创建时间 } diff --git a/src/main/java/com/qf/backend/entity/Roles.java b/src/main/java/com/qf/backend/entity/Roles.java index 2c10a64..8699a02 100644 --- a/src/main/java/com/qf/backend/entity/Roles.java +++ b/src/main/java/com/qf/backend/entity/Roles.java @@ -6,25 +6,28 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 角色信息表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("roles") public class Roles { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 角色ID,主键,自增 - private String roleName; - private String description; - private Integer roleType; // 0: 默认用户, 1: 店主, 2: 管理员 - private Integer status; // 0: 禁用, 1: 启用 - private Date createdAt; - private Date updatedAt; + private String roleName; // 角色名称 + private String description; // 角色描述 + private Integer roleType; // 角色类型:0:默认用户,1:店主,2:管理员 + private Integer status; // 状态:0:禁用, 1:启用 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/ShopCategories.java b/src/main/java/com/qf/backend/entity/ShopCategories.java index e23e972..e7e2b19 100644 --- a/src/main/java/com/qf/backend/entity/ShopCategories.java +++ b/src/main/java/com/qf/backend/entity/ShopCategories.java @@ -6,27 +6,30 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 店铺分类表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("shop_categories") public class ShopCategories { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 分类ID,主键,自增 - private String categoryName; + 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; + private String icon; // 分类图标 + private Integer sort; // 排序 + private Integer status; // 状态:0:禁用, 1:启用 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/ShopRatings.java b/src/main/java/com/qf/backend/entity/ShopRatings.java index 887761f..14b2019 100644 --- a/src/main/java/com/qf/backend/entity/ShopRatings.java +++ b/src/main/java/com/qf/backend/entity/ShopRatings.java @@ -6,28 +6,31 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 店铺评分表 */ -@Data - -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("shop_ratings") public class ShopRatings { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 评价ID,主键,自增 - private Long shopId; - private Long userId; - private Long orderId; + private Long shopId; // 店铺ID,外键,关联shops表 + private Long userId; // 用户ID,外键,关联users表 + private Long orderId; // 订单ID,外键,关联orders表 private Integer rating; // 评分:1-5星 - private String content; + private String content; // 评价内容 private String images; // 评价图片,JSON格式存储 - private Integer status; // 0: 待审核, 1: 已审核, 2: 已删除 - private Date createdAt; - private Date updatedAt; + private Integer status; // 状态:0:待审核, 1:已审核, 2:已删除 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/Shops.java b/src/main/java/com/qf/backend/entity/Shops.java index a2c1773..9f920af 100644 --- a/src/main/java/com/qf/backend/entity/Shops.java +++ b/src/main/java/com/qf/backend/entity/Shops.java @@ -7,35 +7,39 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 店铺信息表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("shops") public class Shops { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 店铺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 String shopName; // 店铺名称 + private Long userId; // 店主用户ID,外键,关联users表 + private Long categoryId; // 店铺分类ID,外键,关联shop_categories表 + private String shopLogo; // 店铺Logo + 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; + 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; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/UserDetails.java b/src/main/java/com/qf/backend/entity/UserDetails.java index 4110354..3a740ab 100644 --- a/src/main/java/com/qf/backend/entity/UserDetails.java +++ b/src/main/java/com/qf/backend/entity/UserDetails.java @@ -6,29 +6,33 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 用户详细信息表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("user_details") public class UserDetails { @TableId(type = IdType.AUTO) - private Long id; + private Long id; // 详情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; + private Long userId; // 用户ID,外键,关联users表 + 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; // 更新时间 } diff --git a/src/main/java/com/qf/backend/entity/UserRoles.java b/src/main/java/com/qf/backend/entity/UserRoles.java index 4fba0a8..0b24886 100644 --- a/src/main/java/com/qf/backend/entity/UserRoles.java +++ b/src/main/java/com/qf/backend/entity/UserRoles.java @@ -6,21 +6,24 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 用户-角色关联表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @TableName("user_roles") public class UserRoles { @TableId(type = IdType.AUTO) - private Long id; - - private Long userId; - private Long roleId; - private Date createdAt; + private Long id; // 关联ID,主键,自增 + private Long userId; // 用户ID,外键,关联users表 + private Long roleId; // 角色ID,外键,关联roles表 + private Date createdAt; // 创建时间 } diff --git a/src/main/java/com/qf/backend/entity/Users.java b/src/main/java/com/qf/backend/entity/Users.java index 6ff215e..4d0abf4 100644 --- a/src/main/java/com/qf/backend/entity/Users.java +++ b/src/main/java/com/qf/backend/entity/Users.java @@ -6,26 +6,30 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * 用户基本信息表 */ -@Data -@Builder +@Data // 自动生成getter、setter、toString、equals、hashCode方法 +@Builder // 自动生成builder模式的构造器 +@NoArgsConstructor // 自动生成无参构造器 +@AllArgsConstructor // 自动生成全参构造器 @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; + private Long id; // 用户ID,主键,自增 + private String username; // 用户名,唯一 + private String password; // 密码,加密存储 + private String email; // 邮箱,唯一 + private String phone; // 手机号,唯一 + private String avatar; // 头像URL + private Date lastLoginTime; // 最后登录时间 + private Integer status; // 状态:0:禁用, 1:启用 + private Date createdAt; // 创建时间 + private Date updatedAt; // 更新时间 } diff --git a/src/main/java/com/qf/backend/exception/ErrorCode.java b/src/main/java/com/qf/backend/exception/ErrorCode.java index a810e77..f9ae32f 100644 --- a/src/main/java/com/qf/backend/exception/ErrorCode.java +++ b/src/main/java/com/qf/backend/exception/ErrorCode.java @@ -38,7 +38,8 @@ public enum ErrorCode { PRODUCT_OFF_SHELF(4092, "商品已下架"), INSUFFICIENT_STOCK(4093, "库存不足"), ORDER_CANCELLED(4094, "订单已取消"), - + ROLE_NOT_FOUND(4095, "角色不存在"), + PASSWORD_ERROR(4096, "密码错误"), // 服务器错误 SYSTEM_ERROR(500, "服务器内部错误"), DATABASE_ERROR(5001, "数据库操作错误"), diff --git a/src/main/java/com/qf/backend/exception/GlobalExceptionHandler.java b/src/main/java/com/qf/backend/exception/GlobalExceptionHandler.java index 0ebda93..a92ccc5 100644 --- a/src/main/java/com/qf/backend/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/qf/backend/exception/GlobalExceptionHandler.java @@ -4,8 +4,6 @@ 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; @@ -17,7 +15,7 @@ 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.MissingPathVariableException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; @@ -28,6 +26,7 @@ import org.springframework.web.servlet.NoHandlerFoundException; import com.qf.backend.common.Result; import com.qf.backend.common.ResultUtils; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; /** @@ -46,24 +45,17 @@ public class GlobalExceptionHandler { log.warn("BusinessException: {} - Request: {}", e.getMessage(), request.getRequestURI()); return ResultUtils.fail(e.getCode(), e.getMessage()); } - /** - * 处理参数验证异常(@Valid) + * 处理缺少路径变量异常 */ - @ExceptionHandler(MethodArgumentNotValidException.class) + @ExceptionHandler(MissingPathVariableException.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()); + public Result handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) { + String errorMsg = "缺少路径变量: " + e.getVariableName(); + log.warn("MissingPathVariableException: {} - Request: {}", errorMsg, request.getRequestURI()); return ResultUtils.paramError(errorMsg); } - - /** + /** * 处理参数绑定异常(@RequestParam) */ @ExceptionHandler(BindException.class) diff --git a/src/main/java/com/qf/backend/mapper/UserRolesMapper.java b/src/main/java/com/qf/backend/mapper/UserRolesMapper.java index f5f9d35..c1ff125 100644 --- a/src/main/java/com/qf/backend/mapper/UserRolesMapper.java +++ b/src/main/java/com/qf/backend/mapper/UserRolesMapper.java @@ -9,6 +9,7 @@ import com.qf.backend.entity.UserRoles; * 用户角色关联表 Mapper 接口 */ public interface UserRolesMapper extends BaseMapper { + /** * 查询用户角色关联信息 * @param userRoles 用户角色关联对象 diff --git a/src/main/java/com/qf/backend/mapper/UsersMapper.java b/src/main/java/com/qf/backend/mapper/UsersMapper.java index a04f981..fac2744 100644 --- a/src/main/java/com/qf/backend/mapper/UsersMapper.java +++ b/src/main/java/com/qf/backend/mapper/UsersMapper.java @@ -40,7 +40,6 @@ public interface UsersMapper extends BaseMapper { * @return 用户对象 */ Users selectInfo(Users users, QueryWrapper queryWrapper); - /** * 更新用户信息 * @param users 用户信息 diff --git a/src/main/java/com/qf/backend/service/PermissionsService.java b/src/main/java/com/qf/backend/service/PermissionsService.java index 0e6b625..9e7676d 100644 --- a/src/main/java/com/qf/backend/service/PermissionsService.java +++ b/src/main/java/com/qf/backend/service/PermissionsService.java @@ -1,6 +1,7 @@ package com.qf.backend.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.qf.backend.common.Result; import com.qf.backend.entity.Permissions; import java.util.List; @@ -15,60 +16,60 @@ public interface PermissionsService extends IService { * @param permissionCode 权限编码 * @return 权限信息 */ - Permissions getPermissionByCode(String permissionCode); + Result getPermissionByCode(String permissionCode); /** * 创建权限 * @param permissions 权限信息 * @return 是否成功 */ - boolean createPermission(Permissions permissions); + Result createPermission(Permissions permissions); /** * 更新权限信息 * @param permissions 权限信息 * @return 是否成功 */ - boolean updatePermission(Permissions permissions); + Result updatePermission(Permissions permissions); /** * 删除权限 * @param id 权限ID * @return 是否成功 */ - boolean deletePermission(Long id); + Result deletePermission(Long id); /** * 查询所有权限 * @return 权限列表 */ - List listAllPermissions(); + Result> listAllPermissions(); /** * 根据权限ID查询权限 * @param id 权限ID * @return 权限信息 */ - Permissions getPermissionById(Long id); + Result getPermissionById(Long id); /** * 批量删除权限 * @param ids 权限ID列表 * @return 是否成功 */ - boolean batchDeletePermissions(List ids); + Result batchDeletePermissions(List ids); /** * 根据菜单ID查询权限 * @param menuId 菜单ID * @return 权限列表 */ - List listPermissionsByMenuId(Long menuId); + Result> listPermissionsByMenuId(Long menuId); /** * 根据权限类型查询权限 * @param permissionType 权限类型 * @return 权限列表 */ - List listPermissionsByType(String permissionType); + Result> listPermissionsByType(String permissionType); } diff --git a/src/main/java/com/qf/backend/service/RolesService.java b/src/main/java/com/qf/backend/service/RolesService.java index a1b441a..842a938 100644 --- a/src/main/java/com/qf/backend/service/RolesService.java +++ b/src/main/java/com/qf/backend/service/RolesService.java @@ -3,6 +3,7 @@ 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.Roles; /** @@ -15,53 +16,53 @@ public interface RolesService extends IService { * @param roleName 角色名称 * @return 角色信息 */ - Roles getRoleByName(String roleName); + Result getRoleByName(String roleName); /** * 创建角色 * @param roles 角色信息 * @return 是否成功 */ - boolean createRole(Roles roles); + Result createRole(Roles roles); /** * 更新角色信息 * @param roles 角色信息 * @return 是否成功 */ - boolean updateRole(Roles roles); + Result updateRole(Roles roles); /** * 删除角色 * @param id 角色ID * @return 是否成功 */ - boolean deleteRole(Long id); + Result deleteRole(Long id); /** * 查询所有角色 * @return 角色列表 */ - List listAllRoles(); + Result> listAllRoles(); /** * 根据角色ID查询角色 * @param id 角色ID * @return 角色信息 */ - Roles getRoleById(Long id); + Result getRoleById(Long id); /** * 批量删除角色 * @param ids 角色ID列表 * @return 是否成功 */ - boolean batchDeleteRoles(List ids); + Result batchDeleteRoles(List ids); /** * 根据用户ID查询其拥有的角色列表 * @param userId 用户ID * @return 角色列表 */ - List listRolesByUserId(Long userId); + Result> listRolesByUserId(Long userId); } diff --git a/src/main/java/com/qf/backend/service/UserDetailsService.java b/src/main/java/com/qf/backend/service/UserDetailsService.java index 3ae0cb7..a64c5c9 100644 --- a/src/main/java/com/qf/backend/service/UserDetailsService.java +++ b/src/main/java/com/qf/backend/service/UserDetailsService.java @@ -44,12 +44,4 @@ public interface UserDetailsService extends IService { */ Result getUserDetailsById(Long id); - /** - * 更新用户联系方式 - * @param userId 用户ID - * @param phone 手机号 - * @param email 邮箱 - * @return 是否成功 - */ - Result updateContactInfo(Long userId, String phone, String email); } diff --git a/src/main/java/com/qf/backend/service/UserLoginService.java b/src/main/java/com/qf/backend/service/UserLoginService.java new file mode 100644 index 0000000..c8e0d31 --- /dev/null +++ b/src/main/java/com/qf/backend/service/UserLoginService.java @@ -0,0 +1,22 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template + */ + +package com.qf.backend.service; + +import com.qf.backend.common.Result; +import com.qf.backend.dto.LoginUser; + +/** + * 用户登录服务接口 + */ +public interface UserLoginService { + /** + * 用户登录 + * @param username 用户名 + * @param password 密码 + * @return 登录结果 + */ + Result login(String username, String password); +} diff --git a/src/main/java/com/qf/backend/service/impl/OrderItemsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/OrderItemsServiceImpl.java index 9bd6a91..1474454 100644 --- a/src/main/java/com/qf/backend/service/impl/OrderItemsServiceImpl.java +++ b/src/main/java/com/qf/backend/service/impl/OrderItemsServiceImpl.java @@ -1,5 +1,6 @@ package com.qf.backend.service.impl; +import java.math.BigDecimal; import java.util.Collection; import java.util.List; import java.util.Map; @@ -10,10 +11,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.BusinessException; import com.qf.backend.exception.ErrorCode; import com.qf.backend.mapper.OrderItemsMapper; import com.qf.backend.service.OrderItemsService; @@ -26,117 +29,398 @@ public class OrderItemsServiceImpl implements OrderItemsService { @Override public Result> getOrderItemsByOrderId(Long orderId) { + // 参数校验 + if (orderId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { List orderItems = orderItemsMapper.selectByOrderId(orderId); if (orderItems == null || orderItems.isEmpty()) { - return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND); + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); } return ResultUtils.success(orderItems); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单商品失败: " + e.getMessage(), e); } } + @Override public Result> getOrderItemsByProductId(Long productId) { + // 参数校验 + if (productId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + try { List orderItems = orderItemsMapper.selectByProductId(productId); if (orderItems == null || orderItems.isEmpty()) { - return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND); + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); } return ResultUtils.success(orderItems); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单商品失败: " + e.getMessage(), e); } } @Override public BaseMapper getBaseMapper() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getBaseMapper'"); + return orderItemsMapper; } + @Override public Class getEntityClass() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getEntityClass'"); + return OrderItems.class; } + @Override public Map getMap(Wrapper queryWrapper) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getMap'"); + try { + return orderItemsMapper.selectMaps(queryWrapper).get(0); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "获取Map数据失败: " + e.getMessage(), e); + } } + @Override public V getObj(Wrapper queryWrapper, Function mapper) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getObj'"); + try { + OrderItems orderItem = orderItemsMapper.selectOne(queryWrapper); + if (orderItem == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); + } + return mapper.apply(orderItem); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "获取对象数据失败: " + e.getMessage(), e); + } } + @Override public OrderItems getOne(Wrapper queryWrapper, boolean throwEx) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getOne'"); + try { + OrderItems orderItem = orderItemsMapper.selectOne(queryWrapper); + if (orderItem == null && throwEx) { + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); + } + return orderItem; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "获取单个对象失败: " + e.getMessage(), e); + } } + @Override public Optional getOneOpt(Wrapper queryWrapper, boolean throwEx) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getOneOpt'"); + try { + OrderItems orderItem = orderItemsMapper.selectOne(queryWrapper); + if (orderItem == null && throwEx) { + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); + } + return Optional.ofNullable(orderItem); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "获取Optional对象失败: " + e.getMessage(), e); + } } + @Override public boolean saveBatch(Collection entityList, int batchSize) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'saveBatch'"); + try { + if (entityList == null || entityList.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "实体列表不能为空"); + } + if (batchSize <= 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "批处理大小必须大于0"); + } + + // 简单的批量保存实现 + for (OrderItems entity : entityList) { + orderItemsMapper.insert(entity); + } + return true; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量保存失败: " + e.getMessage(), e); + } } + @Override public boolean saveOrUpdate(OrderItems entity) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'saveOrUpdate'"); + try { + if (entity == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "实体不能为空"); + } + + if (entity.getId() == null) { + // 新增 + return orderItemsMapper.insert(entity) > 0; + } else { + // 更新 + return orderItemsMapper.updateById(entity) > 0; + } + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "保存或更新失败: " + e.getMessage(), e); + } } + @Override public boolean saveOrUpdateBatch(Collection entityList, int batchSize) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'saveOrUpdateBatch'"); + try { + if (entityList == null || entityList.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "实体列表不能为空"); + } + if (batchSize <= 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "批处理大小必须大于0"); + } + + for (OrderItems entity : entityList) { + saveOrUpdate(entity); + } + return true; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量保存或更新失败: " + e.getMessage(), e); + } } + @Override public boolean updateBatchById(Collection entityList, int batchSize) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'updateBatchById'"); + try { + if (entityList == null || entityList.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "实体列表不能为空"); + } + if (batchSize <= 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "批处理大小必须大于0"); + } + + for (OrderItems entity : entityList) { + if (entity.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "实体ID不能为空"); + } + orderItemsMapper.updateById(entity); + } + return true; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量更新失败: " + e.getMessage(), e); + } } @Override public Result createOrderItem(OrderItems orderItems) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'createOrderItem'"); + // 参数校验 + if (orderItems == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单商品信息不能为空"); + } + if (orderItems.getOrderId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + if (orderItems.getProductId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + if (orderItems.getQuantity() == null || orderItems.getQuantity() <= 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "商品数量必须大于0"); + } + if (orderItems.getPrice() == null || orderItems.getPrice().compareTo(BigDecimal.ZERO) < 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "商品价格不能为负数"); + } + + try { + int result = orderItemsMapper.insert(orderItems); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建订单商品失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建订单商品失败: " + e.getMessage(), e); + } } + @Override public Result updateOrderItem(OrderItems orderItems) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'updateOrderItem'"); + // 参数校验 + if (orderItems == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单商品信息不能为空"); + } + if (orderItems.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单商品ID不能为空"); + } + + try { + // 检查是否存在 + OrderItems existingItem = orderItemsMapper.selectById(orderItems.getId()); + if (existingItem == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); + } + + int result = orderItemsMapper.updateById(orderItems); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新订单商品失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新订单商品失败: " + e.getMessage(), e); + } } + @Override public Result deleteOrderItem(Long id) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'deleteOrderItem'"); + // 参数校验 + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单商品ID不能为空"); + } + + try { + // 检查是否存在 + OrderItems orderItem = orderItemsMapper.selectById(id); + if (orderItem == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); + } + + int result = orderItemsMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除订单商品失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除订单商品失败: " + e.getMessage(), e); + } } + @Override public Result getOrderItemById(Long id) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getOrderItemById'"); + // 参数校验 + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单商品ID不能为空"); + } + + try { + OrderItems orderItem = orderItemsMapper.selectById(id); + if (orderItem == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); + } + return ResultUtils.success(orderItem); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单商品失败: " + e.getMessage(), e); + } } + @Override public Result batchCreateOrderItems(List orderItemsList) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'batchCreateOrderItems'"); + // 参数校验 + if (orderItemsList == null || orderItemsList.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单商品列表不能为空"); + } + if (orderItemsList.size() > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "批量创建数量不能超过100个"); + } + + try { + // 逐个创建订单商品 + for (OrderItems orderItem : orderItemsList) { + // 验证每个订单商品 + if (orderItem.getOrderId() == null || orderItem.getProductId() == null || + orderItem.getQuantity() == null || orderItem.getQuantity() <= 0 || + orderItem.getPrice() == null || orderItem.getPrice().compareTo(BigDecimal.ZERO) < 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "订单商品信息不完整或无效"); + } + + int result = orderItemsMapper.insert(orderItem); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "批量创建订单商品失败"); + } + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量创建订单商品失败: " + e.getMessage(), e); + } } + @Override public Result deleteOrderItemsByOrderId(Long orderId) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'deleteOrderItemsByOrderId'"); + // 参数校验 + if (orderId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + + try { + int result = orderItemsMapper.delete( + new QueryWrapper().eq("order_id", orderId) + ); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除订单下所有商品失败: " + e.getMessage(), e); + } } + @Override public Result calculateOrderTotal(Long orderId) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'calculateOrderTotal'"); + // 参数校验 + if (orderId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + + try { + List orderItems = orderItemsMapper.selectByOrderId(orderId); + if (orderItems == null || orderItems.isEmpty()) { + throw new BusinessException(ErrorCode.NOT_FOUND, "订单商品不存在"); + } + + double totalAmount = 0.0; + for (OrderItems item : orderItems) { + totalAmount += item.getPrice().multiply(new BigDecimal(item.getQuantity())).doubleValue(); + } + return ResultUtils.success(totalAmount); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "计算订单总金额失败: " + e.getMessage(), e); + } } + @Override public Result> getOrderItemsBySkuId(Long skuId) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getOrderItemsBySkuId'"); + // 参数校验 + if (skuId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID不能为空"); + } + + try { + List orderItems = orderItemsMapper.selectList( + new QueryWrapper().eq("sku_id", skuId) + ); + if (orderItems == null || orderItems.isEmpty()) { + throw new BusinessException(ErrorCode.NOT_FOUND, "该SKU的订单商品不存在"); + } + return ResultUtils.success(orderItems); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询SKU订单商品失败: " + e.getMessage(), e); + } } -} +} \ No newline at end of file diff --git a/src/main/java/com/qf/backend/service/impl/OrderStatusHistoryServiceImpl.java b/src/main/java/com/qf/backend/service/impl/OrderStatusHistoryServiceImpl.java new file mode 100644 index 0000000..1150149 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/OrderStatusHistoryServiceImpl.java @@ -0,0 +1,166 @@ +package com.qf.backend.service.impl; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.qf.backend.common.Result; +import com.qf.backend.entity.OrderStatusHistory; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.OrderStatusHistoryMapper; +import com.qf.backend.service.OrderStatusHistoryService; +import com.qf.backend.util.ValidateUtil; + + +@Service +public class OrderStatusHistoryServiceImpl extends ServiceImpl implements OrderStatusHistoryService { + + private static final Logger logger = LoggerFactory.getLogger(OrderStatusHistoryServiceImpl.class); + + @Autowired + private OrderStatusHistoryMapper orderStatusHistoryMapper; + + @Override + public Result> getHistoryByOrderId(Long orderId) { + logger.info("根据订单ID查询订单状态历史记录,订单ID:{}", orderId); + if (ValidateUtil.isEmpty(orderId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { + List historyList = orderStatusHistoryMapper.selectList( new QueryWrapper().eq("order_id", orderId)); + return Result.success(historyList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单状态历史记录失败", e); + } + } + + @Override + public Result createStatusHistory(OrderStatusHistory orderStatusHistory) { + logger.info("创建订单状态历史记录,订单ID:{}", orderStatusHistory.getOrderId()); + if (ValidateUtil.isEmpty(orderStatusHistory.getOrderId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { + int result = orderStatusHistoryMapper.insert(orderStatusHistory); + if (result > 0) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建订单状态历史记录失败"); + } + return Result.success(true); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建订单状态历史记录失败", e); + } + } + + @Override + public Result updateStatusHistory(OrderStatusHistory orderStatusHistory) { + logger.info("更新订单状态历史记录,订单ID:{}", orderStatusHistory.getOrderId()); + if (ValidateUtil.isEmpty(orderStatusHistory.getOrderId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { + boolean result = orderStatusHistoryMapper.updateById(orderStatusHistory) > 0; + return Result.success(result); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新订单状态历史记录失败", e); + } + } + + @Override + public Result deleteStatusHistory(Long id) { + logger.info("删除订单状态历史记录,ID:{}", id); + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "ID不能为空"); + } + try { + boolean result = orderStatusHistoryMapper.deleteById(id) > 0; + return Result.success(result); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除订单状态历史记录失败", e); + } + } + + @Override + public Result getStatusHistoryById(Long id) { + logger.info("根据ID查询订单状态历史记录,ID:{}", id); + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "ID不能为空"); + } + try { + OrderStatusHistory history = orderStatusHistoryMapper.selectById(id); + return Result.success(history); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单状态历史记录失败", e); + } + } + + @Override + public Result batchCreateStatusHistory(List historyList) { + logger.info("批量创建订单状态历史记录,数量:{}", historyList.size()); + if (ValidateUtil.isEmpty(historyList)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单状态历史记录列表不能为空"); + } + try { + for (OrderStatusHistory history : historyList) { + int result = orderStatusHistoryMapper.insert(history); + if (result > 0) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量创建订单状态历史记录失败"); + } + } + return Result.success(true); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量创建订单状态历史记录失败", e); + } + } + + @Override + public Result> getHistoryByOrderIdAndStatus(Long orderId, Integer status) { + logger.info("根据订单ID和状态查询订单状态历史记录,订单ID:{},状态:{}", orderId, status); + if (ValidateUtil.isEmpty(orderId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { + List historyList = orderStatusHistoryMapper.selectList( new QueryWrapper().eq("order_id", orderId).eq("status", status)); + return Result.success(historyList); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单状态历史记录失败", e); + } + } + + @Override + public Result getLatestStatusHistory(Long orderId) { + logger.info("根据订单ID查询最新订单状态历史记录,订单ID:{}", orderId); + if (ValidateUtil.isEmpty(orderId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { + OrderStatusHistory history = orderStatusHistoryMapper.selectOne( new QueryWrapper().eq("order_id", orderId).orderByDesc("id").last("limit 1")); + return Result.success(history); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询最新订单状态历史记录失败", e); + } + } + + @Override + public Result deleteHistoryByOrderId(Long orderId) { + logger.info("根据订单ID删除订单状态历史记录,订单ID:{}", orderId); + if (ValidateUtil.isEmpty(orderId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { + boolean result = orderStatusHistoryMapper.delete( new QueryWrapper().eq("order_id", orderId)) > 0; + return Result.success(result); + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除订单状态历史记录失败", e); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/com/qf/backend/service/impl/OrdersServiceImpl.java b/src/main/java/com/qf/backend/service/impl/OrdersServiceImpl.java index fab49d8..229a474 100644 --- a/src/main/java/com/qf/backend/service/impl/OrdersServiceImpl.java +++ b/src/main/java/com/qf/backend/service/impl/OrdersServiceImpl.java @@ -1,5 +1,7 @@ package com.qf.backend.service.impl; +import java.math.BigDecimal; +import java.util.Date; import java.util.List; import org.slf4j.Logger; @@ -7,86 +9,293 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.BusinessException; import com.qf.backend.exception.ErrorCode; import com.qf.backend.mapper.OrdersMapper; import com.qf.backend.service.OrdersService; @Service public class OrdersServiceImpl extends ServiceImpl implements OrdersService { + private final Logger logger = LoggerFactory.getLogger(OrdersServiceImpl.class); @Autowired private OrdersMapper ordersMapper; - private Logger logger = LoggerFactory.getLogger(OrdersServiceImpl.class); @Override public Result getOrderByNumber(String orderNumber) { logger.info("根据订单号查询订单: {}", orderNumber); + // 参数校验 + if (orderNumber == null || orderNumber.trim().isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单编号不能为空"); + } + try { Orders orders = ordersMapper.selectByOrderNumber(orderNumber); if (orders == null) { logger.warn("订单号 {} 不存在", orderNumber); - return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND); + throw new BusinessException(ErrorCode.ORDER_NOT_FOUND, "订单不存在: " + orderNumber); } return ResultUtils.success(orders); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.ORDER_NOT_FOUND); + logger.error("查询订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单失败: " + e.getMessage(), e); } } @Override public Result> getOrdersByUserId(Long userId) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getOrdersByUserId'"); + // 参数校验 + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + + try { + List ordersList = ordersMapper.selectList( + new QueryWrapper().eq("user_id", userId).orderByDesc("create_time") + ); + return ResultUtils.success(ordersList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询用户订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户订单失败: " + e.getMessage(), e); + } } @Override public Result createOrder(Orders orders) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'createOrder'"); + // 参数校验 + if (orders == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单信息不能为空"); + } + if (orders.getUserId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + if (orders.getOrderNo() == null || orders.getOrderNo().trim().isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单编号不能为空"); + } + if (orders.getTotalAmount() == null || orders.getTotalAmount().compareTo(BigDecimal.ZERO) < 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "订单金额不能为负数"); + } + + try { + // 检查订单编号是否已存在 + Orders existingOrder = ordersMapper.selectByOrderNumber(orders.getOrderNo()); + if (existingOrder != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "订单编号已存在: " + orders.getOrderNo()); + } + + // 设置默认值 + if (orders.getOrderStatus() == null) { + orders.setOrderStatus(0); // 默认为待支付状态 + } + if (orders.getCreatedAt() == null) { + orders.setCreatedAt(new Date()); + } + + int result = ordersMapper.insert(orders); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建订单失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建订单失败: " + e.getMessage(), e); + } } @Override public Result updateOrder(Orders orders) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'updateOrder'"); + // 参数校验 + if (orders == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单信息不能为空"); + } + if (orders.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + + try { + // 检查订单是否存在 + Orders existingOrder = ordersMapper.selectById(orders.getId()); + if (existingOrder == null) { + throw new BusinessException(ErrorCode.ORDER_NOT_FOUND, "订单不存在"); + } + + // 更新时间戳 + orders.setUpdatedAt(new Date()); + + int result = ordersMapper.updateById(orders); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新订单失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新订单失败: " + e.getMessage(), e); + } } @Override public Result deleteOrder(Long id) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'deleteOrder'"); + // 参数校验 + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + + try { + // 检查订单是否存在 + Orders orders = ordersMapper.selectById(id); + if (orders == null) { + throw new BusinessException(ErrorCode.ORDER_NOT_FOUND, "订单不存在"); + } + + int result = ordersMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除订单失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除订单失败: " + e.getMessage(), e); + } } @Override public Result getOrderById(Long id) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getOrderById'"); + // 参数校验 + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + + try { + Orders orders = ordersMapper.selectById(id); + if (orders == null) { + throw new BusinessException(ErrorCode.ORDER_NOT_FOUND, "订单不存在"); + } + return ResultUtils.success(orders); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单失败: " + e.getMessage(), e); + } } @Override public Result> listOrdersByPage(int page, int size) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'listOrdersByPage'"); + // 参数校验 + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页大小必须在1-100之间"); + } + + try { + // 简单分页实现 + int offset = (page - 1) * size; + List ordersList = ordersMapper.selectList( + new QueryWrapper().last("LIMIT " + offset + ", " + size).orderByDesc("create_time") + ); + return ResultUtils.success(ordersList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("分页查询订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "分页查询订单失败: " + e.getMessage(), e); + } } @Override public Result> getOrdersByShopId(Long shopId) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getOrdersByShopId'"); + // 参数校验 + if (shopId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + + try { + List ordersList = ordersMapper.selectList( + new QueryWrapper().eq("shop_id", shopId).orderByDesc("create_time") + ); + return ResultUtils.success(ordersList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询店铺订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询店铺订单失败: " + e.getMessage(), e); + } } @Override public Result updateOrderStatus(Long orderId, Integer status) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'updateOrderStatus'"); + // 参数校验 + if (orderId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + if (status == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单状态不能为空"); + } + + try { + // 检查订单是否存在 + Orders orders = ordersMapper.selectById(orderId); + if (orders == null) { + throw new BusinessException(ErrorCode.ORDER_NOT_FOUND, "订单不存在"); + } + + // 检查状态是否合法(假设状态值为0-5) + if (status < 0 || status > 5) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "无效的订单状态值"); + } + + // 更新状态 + Orders updateOrder = new Orders(); + updateOrder.setId(orderId); + updateOrder.setOrderStatus(status); + updateOrder.setUpdatedAt(new Date()); + + int result = ordersMapper.updateById(updateOrder); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新订单状态失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新订单状态失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新订单状态失败: " + e.getMessage(), e); + } } @Override public Result> getOrdersByStatus(Integer status) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getOrdersByStatus'"); + // 参数校验 + if (status == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单状态不能为空"); + } + + try { + List ordersList = ordersMapper.selectList( + new QueryWrapper().eq("status", status).orderByDesc("create_time") + ); + return ResultUtils.success(ordersList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询订单失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询订单失败: " + e.getMessage(), e); + } } } diff --git a/src/main/java/com/qf/backend/service/impl/PaymentsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/PaymentsServiceImpl.java new file mode 100644 index 0000000..fb232cc --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/PaymentsServiceImpl.java @@ -0,0 +1,215 @@ +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.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.qf.backend.entity.Payments; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.PaymentsMapper; +import com.qf.backend.service.PaymentsService; +import com.qf.backend.util.ValidateUtil; + +/** + * 支付服务实现类 + */ +@Service +public class PaymentsServiceImpl extends ServiceImpl implements PaymentsService { + + @Autowired + private PaymentsMapper paymentsMapper; + + @Override + public Payments getPaymentByOrderId(Long orderId) { + if (ValidateUtil.isEmpty(orderId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { + return paymentsMapper.selectOne( + new QueryWrapper().eq("order_id", orderId)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询支付记录失败", e); + } + } + + @Override + public Payments getPaymentByTransactionId(String transactionId) { + if (ValidateUtil.isEmpty(transactionId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付流水号不能为空"); + } + try { + return paymentsMapper.selectOne( + new QueryWrapper().eq("transaction_id", transactionId)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询支付记录失败", e); + } + } + + @Override + public boolean createPayment(Payments payments) { + if (ValidateUtil.isEmpty(payments)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付信息不能为空"); + } + if (ValidateUtil.isEmpty(payments.getOrderId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + if (payments.getAmount() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付金额不能为空"); + } + if (ValidateUtil.isEmpty(payments.getPaymentMethod())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付方式不能为空"); + } + try { + int result = paymentsMapper.insert(payments); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建支付记录失败", e); + } + } + + @Override + public boolean updatePayment(Payments payments) { + if (ValidateUtil.isEmpty(payments)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付信息不能为空"); + } + if (ValidateUtil.isEmpty(payments.getId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付ID不能为空"); + } + try { + // 检查支付记录是否存在 + Payments existing = paymentsMapper.selectById(payments.getId()); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "支付记录不存在"); + } + int result = paymentsMapper.updateById(payments); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新支付记录失败", e); + } + } + + @Override + public boolean deletePayment(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付ID不能为空"); + } + try { + // 检查支付记录是否存在 + Payments existing = paymentsMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "支付记录不存在"); + } + int result = paymentsMapper.deleteById(id); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除支付记录失败", e); + } + } + + @Override + public Payments getPaymentById(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付ID不能为空"); + } + try { + Payments payment = paymentsMapper.selectById(id); + if (payment == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "支付记录不存在"); + } + return payment; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询支付记录失败", e); + } + } + + @Override + public List getPaymentsByUserId(Long userId) { + if (ValidateUtil.isEmpty(userId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + try { + return paymentsMapper.selectList( + new QueryWrapper().eq("user_id", userId)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询支付记录失败", e); + } + } + + @Override + public List getPaymentsByStatus(Integer status) { + if (ValidateUtil.isEmpty(status)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付状态不能为空"); + } + try { + return paymentsMapper.selectList( + new QueryWrapper().eq("status", status)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询支付记录失败", e); + } + } + + @Override + public boolean updatePaymentStatus(Long paymentId, Integer status) { + if (ValidateUtil.isEmpty(paymentId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付ID不能为空"); + } + if (ValidateUtil.isEmpty(status)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "支付状态不能为空"); + } + try { + // 检查支付记录是否存在 + Payments existing = paymentsMapper.selectById(paymentId); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "支付记录不存在"); + } + // 更新状态 + existing.setPaymentStatus(status); + int result = paymentsMapper.updateById(existing); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新支付状态失败", e); + } + } + + @Override + public List listPaymentsByPage(int page, int size) { + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页数量必须在1-100之间"); + } + try { + Page paymentPage = new Page<>(page, size); + Page resultPage = paymentsMapper.selectPage(paymentPage, null); + return resultPage.getRecords(); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "分页查询支付记录失败", e); + } + } +} diff --git a/src/main/java/com/qf/backend/service/impl/PermissionsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/PermissionsServiceImpl.java new file mode 100644 index 0000000..df6152b --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/PermissionsServiceImpl.java @@ -0,0 +1,275 @@ +package com.qf.backend.service.impl; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.Permissions; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.PermissionsMapper; +import com.qf.backend.service.PermissionsService; +import com.qf.backend.util.ValidateUtil; + +@Service +public class PermissionsServiceImpl extends ServiceImpl implements PermissionsService { + + private static final Logger logger = LoggerFactory.getLogger(PermissionsServiceImpl.class); + + @Autowired + private PermissionsMapper permissionsMapper; + + // 根据权限编码查询权限 + @Override + public Result getPermissionByCode(String permissionCode) { + logger.info("根据权限编码查询权限: {}", permissionCode); + + try { + if (ValidateUtil.isEmpty(permissionCode)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "权限编码不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper().eq("permission_code", permissionCode); + Permissions permission = permissionsMapper.selectOne(queryWrapper); + if (permission == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "权限不存在: " + permissionCode); + } + return ResultUtils.success(permission); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询权限失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询权限失败: " + e.getMessage(), e); + } + } + + // 创建权限 + @Override + public Result createPermission(Permissions permissions) { + logger.info("创建权限: 权限对象"); + + try { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(permissions, "permissionCode", "permissionName", "permissionType"); + + int result = permissionsMapper.insert(permissions); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建权限失败"); + } + + logger.info("权限创建成功"); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证权限信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证权限信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建权限失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建权限失败: " + e.getMessage(), e); + } + } + + // 更新权限信息 + @Override + public Result updatePermission(Permissions permissions) { + logger.info("更新权限信息: 权限ID = {}", permissions.getId()); + + try { + if (permissions == null || permissions.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限信息或权限ID不能为空"); + } + + // 检查权限是否存在 + Permissions existingPermission = getPermissionByIdAndCheckExist(permissions.getId()); + if (existingPermission == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "权限不存在"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(permissions, "permissionCode", "permissionName", "permissionType"); + + // 更新权限信息 + int result = permissionsMapper.updateById(permissions); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新权限信息失败"); + } + + logger.info("权限信息更新成功: 权限ID = {}", permissions.getId()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证权限信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证权限信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新权限信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新权限信息失败: " + e.getMessage(), e); + } + } + + // 删除权限 + @Override + public Result deletePermission(Long id) { + logger.info("删除权限: 权限ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID不能为空"); + } + // 检查权限是否存在 + Permissions permission = getPermissionByIdAndCheckExist(id); + if (permission == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "权限不存在"); + } + + int result = permissionsMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除权限失败"); + } + + logger.info("权限删除成功: 权限ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除权限失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除权限失败: " + e.getMessage(), e); + } + } + + // 查询所有权限 + @Override + public Result> listAllPermissions() { + logger.info("查询所有权限列表"); + + try { + List permissionsList = permissionsMapper.selectList(null); + logger.info("查询到 {} 个权限", permissionsList.size()); + return ResultUtils.success(permissionsList); + } catch (Exception e) { + logger.error("查询权限列表失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询权限列表失败: " + e.getMessage(), e); + } + } + + // 根据权限ID查询权限 + @Override + public Result getPermissionById(Long id) { + logger.info("根据ID查询权限: 权限ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID不能为空"); + } + + Permissions permission = getPermissionByIdAndCheckExist(id); + if (permission == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "权限不存在"); + } + + return ResultUtils.success(permission); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询权限失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询权限失败: " + e.getMessage(), e); + } + } + + // 批量删除权限 + @Override + public Result batchDeletePermissions(List ids) { + logger.info("批量删除权限: 权限ID列表 = {}", ids); + + try { + if (ids == null || ids.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID列表不能为空"); + } + + int result = permissionsMapper.deleteBatchIds(ids); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "批量删除权限失败"); + } + + logger.info("批量删除权限成功: 删除了 {} 个权限", result); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("批量删除权限失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量删除权限失败: " + e.getMessage(), e); + } + } + + // 根据菜单ID查询权限 + @Override + public Result> listPermissionsByMenuId(Long menuId) { + logger.info("根据菜单ID查询权限: 菜单ID = {}", menuId); + + try { + if (menuId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "菜单ID不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper().eq("menu_id", menuId); + List permissionsList = permissionsMapper.selectList(queryWrapper); + logger.info("查询到 {} 个权限", permissionsList.size()); + return ResultUtils.success(permissionsList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("根据菜单ID查询权限失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "根据菜单ID查询权限失败: " + e.getMessage(), e); + } + } + + // 根据权限类型查询权限 + @Override + public Result> listPermissionsByType(String permissionType) { + logger.info("根据权限类型查询权限: 权限类型 = {}", permissionType); + + try { + if (ValidateUtil.isEmpty(permissionType)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限类型不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper().eq("permission_type", permissionType); + List permissionsList = permissionsMapper.selectList(queryWrapper); + logger.info("查询到 {} 个权限", permissionsList.size()); + return ResultUtils.success(permissionsList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("根据权限类型查询权限失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "根据权限类型查询权限失败: " + e.getMessage(), e); + } + } + + /** + * 根据权限ID查询权限并检查是否存在 + * @param id 权限ID + * @return 权限对象,如果权限不存在则返回null + */ + private Permissions getPermissionByIdAndCheckExist(Long id) { + if (id == null) { + return null; + } + QueryWrapper queryWrapper = new QueryWrapper().eq("id", id); + return permissionsMapper.selectOne(queryWrapper); + } + +} diff --git a/src/main/java/com/qf/backend/service/impl/ProductAttributeValuesServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ProductAttributeValuesServiceImpl.java new file mode 100644 index 0000000..a2f77ff --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ProductAttributeValuesServiceImpl.java @@ -0,0 +1,213 @@ +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.core.conditions.query.QueryWrapper; +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.ProductAttributeValues; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ProductAttributeValuesMapper; +import com.qf.backend.service.ProductAttributeValuesService; +import com.qf.backend.util.ValidateUtil; + +/** + * 商品属性值服务实现类 + */ +@Service +public class ProductAttributeValuesServiceImpl extends ServiceImpl implements ProductAttributeValuesService { + + @Autowired + private ProductAttributeValuesMapper productAttributeValuesMapper; + + @Override + public Result> getAttributeValuesByProductId(Long productId) { + if (ValidateUtil.isEmpty(productId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + try { + List attributeValues = productAttributeValuesMapper.selectList( + new QueryWrapper().eq("product_id", productId)); + return ResultUtils.success(attributeValues); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品属性值失败", e); + } + } + + @Override + public Result> getAttributeValuesByAttributeId(Long attributeId) { + if (ValidateUtil.isEmpty(attributeId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性ID不能为空"); + } + try { + List attributeValues = productAttributeValuesMapper.selectList( + new QueryWrapper().eq("attribute_id", attributeId)); + return ResultUtils.success(attributeValues); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询属性值失败", e); + } + } + + @Override + public Result createAttributeValue(ProductAttributeValues productAttributeValues) { + if (ValidateUtil.isEmpty(productAttributeValues)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值信息不能为空"); + } + if (ValidateUtil.isEmpty(productAttributeValues.getProductId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + if (ValidateUtil.isEmpty(productAttributeValues.getAttributeId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性ID不能为空"); + } + if (ValidateUtil.isEmpty(productAttributeValues.getAttributeValue())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值不能为空"); + } + try { + int result = productAttributeValuesMapper.insert(productAttributeValues); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建属性值失败", e); + } + } + + @Override + public Result updateAttributeValue(ProductAttributeValues productAttributeValues) { + if (ValidateUtil.isEmpty(productAttributeValues)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值信息不能为空"); + } + if (ValidateUtil.isEmpty(productAttributeValues.getId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值ID不能为空"); + } + if (ValidateUtil.isEmpty(productAttributeValues.getAttributeValue())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值不能为空"); + } + try { + // 检查属性值是否存在 + ProductAttributeValues existing = productAttributeValuesMapper.selectById(productAttributeValues.getId()); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "属性值不存在"); + } + int result = productAttributeValuesMapper.updateById(productAttributeValues); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新属性值失败", e); + } + } + + @Override + public Result deleteAttributeValue(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值ID不能为空"); + } + try { + // 检查属性值是否存在 + ProductAttributeValues existing = productAttributeValuesMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "属性值不存在"); + } + int result = productAttributeValuesMapper.deleteById(id); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除属性值失败", e); + } + } + + @Override + public Result getAttributeValueById(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值ID不能为空"); + } + try { + ProductAttributeValues attributeValue = productAttributeValuesMapper.selectById(id); + if (attributeValue == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "属性值不存在"); + } + return ResultUtils.success(attributeValue); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询属性值失败", e); + } + } + + @Override + public Result batchCreateAttributeValues(List attributeValues) { + if (ValidateUtil.isEmpty(attributeValues)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值列表不能为空"); + } + if (attributeValues.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性值列表不能为空"); + } + try { + for (ProductAttributeValues attributeValue : attributeValues) { + if (ValidateUtil.isEmpty(attributeValue.getProductId())) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "属性值列表中存在商品ID为空的记录"); + } + if (ValidateUtil.isEmpty(attributeValue.getAttributeId())) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "属性值列表中存在属性ID为空的记录"); + } + if (ValidateUtil.isEmpty(attributeValue.getAttributeValue())) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "属性值列表中存在属性值为空的记录"); + } + productAttributeValuesMapper.insert(attributeValue); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量创建属性值失败", e); + } + } + + @Override + public Result getAttributeValueByProductAndAttribute(Long productId, Long attributeId) { + if (ValidateUtil.isEmpty(productId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + if (ValidateUtil.isEmpty(attributeId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性ID不能为空"); + } + try { + ProductAttributeValues attributeValue = productAttributeValuesMapper.selectOne( + new QueryWrapper() + .eq("product_id", productId) + .eq("attribute_id", attributeId)); + return ResultUtils.success(attributeValue); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品属性值失败", e); + } + } + + @Override + public Result deleteAttributeValuesByProductId(Long productId) { + if (ValidateUtil.isEmpty(productId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + try { + int result = productAttributeValuesMapper.delete( + new QueryWrapper().eq("product_id", productId)); + return ResultUtils.success(result >= 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除商品属性值失败", e); + } + } +} diff --git a/src/main/java/com/qf/backend/service/impl/ProductAttributesServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ProductAttributesServiceImpl.java new file mode 100644 index 0000000..b6598f8 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ProductAttributesServiceImpl.java @@ -0,0 +1,200 @@ +package com.qf.backend.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.ProductAttributes; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ProductAttributesMapper; +import com.qf.backend.service.ProductAttributesService; +import com.qf.backend.util.ValidateUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 商品属性服务实现类 + */ +@Service +public class ProductAttributesServiceImpl extends ServiceImpl implements ProductAttributesService { + + @Autowired + private ProductAttributesMapper productAttributesMapper; + + @Override + public Result> getAttributesByCategoryId(Long categoryId) { + if (ValidateUtil.isEmpty(categoryId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + try { + List attributes = productAttributesMapper.selectList( + new QueryWrapper().eq("category_id", categoryId)); + return ResultUtils.success(attributes); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品属性失败", e); + } + } + + @Override + public Result> getAttributesByName(String attributeName) { + if (ValidateUtil.isEmpty(attributeName)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性名称不能为空"); + } + try { + List attributes = productAttributesMapper.selectList( + new QueryWrapper().like("attribute_name", attributeName)); + return ResultUtils.success(attributes); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品属性失败", e); + } + } + + @Override + public Result createAttribute(ProductAttributes productAttributes) { + if (ValidateUtil.isEmpty(productAttributes)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性信息不能为空"); + } + if (ValidateUtil.isEmpty(productAttributes.getAttributeName())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性名称不能为空"); + } + if (ValidateUtil.isEmpty(productAttributes.getCategoryId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + try { + int result = productAttributesMapper.insert(productAttributes); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建商品属性失败", e); + } + } + + @Override + public Result updateAttribute(ProductAttributes productAttributes) { + if (ValidateUtil.isEmpty(productAttributes)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性信息不能为空"); + } + if (ValidateUtil.isEmpty(productAttributes.getId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性ID不能为空"); + } + if (ValidateUtil.isEmpty(productAttributes.getAttributeName())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性名称不能为空"); + } + try { + // 检查属性是否存在 + ProductAttributes existing = productAttributesMapper.selectById(productAttributes.getId()); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "属性不存在"); + } + int result = productAttributesMapper.updateById(productAttributes); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新商品属性失败", e); + } + } + + @Override + public Result deleteAttribute(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性ID不能为空"); + } + try { + // 检查属性是否存在 + ProductAttributes existing = productAttributesMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "属性不存在"); + } + int result = productAttributesMapper.deleteById(id); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除商品属性失败", e); + } + } + + @Override + public Result getAttributeById(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性ID不能为空"); + } + try { + ProductAttributes attribute = productAttributesMapper.selectById(id); + if (attribute == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "属性不存在"); + } + return ResultUtils.success(attribute); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品属性失败", e); + } + } + + @Override + public Result batchDeleteAttributes(List ids) { + if (ValidateUtil.isEmpty(ids)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性ID列表不能为空"); + } + if (ids.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性ID列表不能为空"); + } + try { + // 检查所有属性是否存在 + for (Long id : ids) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "属性ID列表中存在空值"); + } + ProductAttributes existing = productAttributesMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "属性ID为" + id + "的属性不存在"); + } + } + int result = productAttributesMapper.deleteBatchIds(ids); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量删除商品属性失败", e); + } + } + + @Override + public Result> getAttributesByType(String attributeType) { + if (ValidateUtil.isEmpty(attributeType)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "属性类型不能为空"); + } + try { + List attributes = productAttributesMapper.selectList( + new QueryWrapper().eq("attribute_type", attributeType)); + return ResultUtils.success(attributes); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品属性失败", e); + } + } + + @Override + public Result> getAttributesBySearchable(Boolean searchable) { + try { + List attributes = productAttributesMapper.selectList( + new QueryWrapper().eq("searchable", searchable)); + return ResultUtils.success(attributes); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品属性失败", e); + } + } +} diff --git a/src/main/java/com/qf/backend/service/impl/ProductCategoriesServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ProductCategoriesServiceImpl.java new file mode 100644 index 0000000..0b9c301 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ProductCategoriesServiceImpl.java @@ -0,0 +1,240 @@ +package com.qf.backend.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.ProductCategories; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ProductCategoriesMapper; +import com.qf.backend.service.ProductCategoriesService; +import com.qf.backend.util.ValidateUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * 商品分类服务实现类 + */ +@Service +public class ProductCategoriesServiceImpl extends ServiceImpl implements ProductCategoriesService { + + @Autowired + private ProductCategoriesMapper productCategoriesMapper; + + @Override + public Result getCategoryByName(String categoryName) { + if (ValidateUtil.isEmpty(categoryName)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类名称不能为空"); + } + try { + ProductCategories category = productCategoriesMapper.selectOne( + new QueryWrapper().eq("category_name", categoryName)); + return ResultUtils.success(category); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品分类失败", e); + } + } + + @Override + public Result> getSubCategoriesByParentId(Long parentId) { + try { + List categories = productCategoriesMapper.selectList( + new QueryWrapper().eq("parent_id", parentId)); + return ResultUtils.success(categories); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询子分类失败", e); + } + } + + @Override + public Result createCategory(ProductCategories productCategories) { + if (ValidateUtil.isEmpty(productCategories)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类信息不能为空"); + } + if (ValidateUtil.isEmpty(productCategories.getCategoryName())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类名称不能为空"); + } + try { + // 检查分类名称是否已存在 + ProductCategories existing = productCategoriesMapper.selectOne( + new QueryWrapper().eq("category_name", productCategories.getCategoryName())); + if (existing != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "分类名称已存在"); + } + int result = productCategoriesMapper.insert(productCategories); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建商品分类失败", e); + } + } + + @Override + public Result updateCategory(ProductCategories productCategories) { + if (ValidateUtil.isEmpty(productCategories)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类信息不能为空"); + } + if (ValidateUtil.isEmpty(productCategories.getId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + if (ValidateUtil.isEmpty(productCategories.getCategoryName())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类名称不能为空"); + } + try { + // 检查分类是否存在 + ProductCategories existing = productCategoriesMapper.selectById(productCategories.getId()); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类不存在"); + } + // 检查分类名称是否已存在(排除当前分类) + ProductCategories nameExists = productCategoriesMapper.selectOne( + new QueryWrapper() + .eq("category_name", productCategories.getCategoryName()) + .ne("id", productCategories.getId())); + if (nameExists != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "分类名称已存在"); + } + int result = productCategoriesMapper.updateById(productCategories); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新商品分类失败", e); + } + } + + @Override + public Result deleteCategory(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + try { + // 检查分类是否存在 + ProductCategories existing = productCategoriesMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类不存在"); + } + // 检查是否有子分类 + List subCategories = productCategoriesMapper.selectList( + new QueryWrapper().eq("parent_id", id)); + if (!subCategories.isEmpty()) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "该分类下存在子分类,无法删除"); + } + int result = productCategoriesMapper.deleteById(id); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除商品分类失败", e); + } + } + + @Override + public Result> listRootCategories() { + try { + List rootCategories = productCategoriesMapper.selectList( + new QueryWrapper().isNull("parent_id").or().eq("parent_id", 0)); + return ResultUtils.success(rootCategories); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询根分类失败", e); + } + } + + @Override + public Result getCategoryById(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + try { + ProductCategories category = productCategoriesMapper.selectById(id); + if (category == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类不存在"); + } + return ResultUtils.success(category); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品分类失败", e); + } + } + + @Override + public Result batchDeleteCategories(List ids) { + if (ValidateUtil.isEmpty(ids)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID列表不能为空"); + } + if (ids.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID列表不能为空"); + } + try { + // 检查所有分类是否存在以及是否有子分类 + for (Long id : ids) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "分类ID列表中存在空值"); + } + ProductCategories existing = productCategoriesMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类ID为" + id + "的分类不存在"); + } + // 检查是否有子分类 + List subCategories = productCategoriesMapper.selectList( + new QueryWrapper().eq("parent_id", id)); + if (!subCategories.isEmpty()) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "分类ID为" + id + "的分类下存在子分类,无法删除"); + } + } + int result = productCategoriesMapper.deleteBatchIds(ids); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量删除商品分类失败", e); + } + } + + @Override + public Result> listAllCategoriesWithTree() { + try { + // 查询所有分类 + List allCategories = productCategoriesMapper.selectList(null); + // 构建树形结构 + List treeCategories = buildCategoryTree(allCategories, null); + return ResultUtils.success(treeCategories); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品分类树失败", e); + } + } + + /** + * 构建分类树形结构 + * @param allCategories 所有分类列表 + * @param parentId 父分类ID + * @return 树形分类列表 + */ + private List buildCategoryTree(List allCategories, Long parentId) { + List tree = new ArrayList<>(); + for (ProductCategories category : allCategories) { + Long categoryParentId = category.getParentId(); + if ((parentId == null && (categoryParentId == null || categoryParentId == 0)) || (parentId != null && parentId.equals(categoryParentId))) { + // 递归查找子分类 + List children = buildCategoryTree(allCategories, category.getId()); + category.setChildren(children); + tree.add(category); + } + } + return tree; + } +} diff --git a/src/main/java/com/qf/backend/service/impl/ProductImagesServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ProductImagesServiceImpl.java new file mode 100644 index 0000000..f585376 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ProductImagesServiceImpl.java @@ -0,0 +1,319 @@ +package com.qf.backend.service.impl; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +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.ProductImages; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ProductImagesMapper; +import com.qf.backend.service.ProductImagesService; +import com.qf.backend.util.ValidateUtil; + +@Service +public class ProductImagesServiceImpl extends ServiceImpl implements ProductImagesService { + + private static final Logger logger = LoggerFactory.getLogger(ProductImagesServiceImpl.class); + + @Autowired + private ProductImagesMapper productImagesMapper; + + @Override + public Result> getImagesByProductId(Long productId) { + logger.info("根据商品ID查询图片: {}", productId); + + try { + if (productId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + + List images = productImagesMapper.selectList(new QueryWrapper().eq("product_id", productId).orderByAsc("sort")); + logger.info("查询到 {} 张图片", images.size()); + return ResultUtils.success(images); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询图片失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询图片失败: " + e.getMessage(), e); + } + } + + @Override + public Result getMainImageByProductId(Long productId) { + logger.info("根据商品ID查询主图: {}", productId); + + try { + if (productId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + + ProductImages mainImage = productImagesMapper.selectOne(new QueryWrapper().eq("product_id", productId).eq("is_main", 1)); + if (mainImage == null) { + logger.warn("商品 {} 没有设置主图", productId); + return ResultUtils.success(null); + } + return ResultUtils.success(mainImage); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询主图失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询主图失败: " + e.getMessage(), e); + } + } + + @Override + public Result createImage(ProductImages productImages) { + logger.info("创建商品图片: 商品ID = {}", productImages.getProductId()); + + try { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(productImages, "productId", "imageUrl"); + + // 检查是否设置了主图,如果设置了主图,则将其他图片设置为非主图 + if (productImages.getIsMain() != null && productImages.getIsMain() == 1) { + // 将该商品的所有图片设置为非主图 + productImagesMapper.update(null, new UpdateWrapper().eq("product_id", productImages.getProductId()).set("is_main", 0)); + } + + int result = productImagesMapper.insert(productImages); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建商品图片失败"); + } + + logger.info("商品图片创建成功"); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证图片信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证图片信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建商品图片失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建商品图片失败: " + e.getMessage(), e); + } + } + + @Override + public Result updateImage(ProductImages productImages) { + logger.info("更新图片信息: 图片ID = {}", productImages.getId()); + + try { + if (productImages == null || productImages.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "图片信息或图片ID不能为空"); + } + + // 检查图片是否存在 + ProductImages existingImage = getImageByIdAndCheckExist(productImages.getId()); + if (existingImage == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "图片不存在"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(productImages, "productId", "imageUrl"); + + // 检查是否设置了主图,如果设置了主图,则将其他图片设置为非主图 + if (productImages.getIsMain() != null && productImages.getIsMain() == 1) { + // 将该商品的所有图片设置为非主图 + productImagesMapper.update(null, new UpdateWrapper().eq("product_id", productImages.getProductId()).set("is_main", 0)); + } + + // 更新图片信息 + int result = productImagesMapper.updateById(productImages); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新图片信息失败"); + } + + logger.info("图片信息更新成功: 图片ID = {}", productImages.getId()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证图片信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证图片信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新图片信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新图片信息失败: " + e.getMessage(), e); + } + } + + @Override + public Result deleteImage(Long id) { + logger.info("删除图片: 图片ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "图片ID不能为空"); + } + // 检查图片是否存在 + ProductImages image = getImageByIdAndCheckExist(id); + if (image == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "图片不存在"); + } + + int result = productImagesMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除图片失败"); + } + + logger.info("图片删除成功: 图片ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除图片失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除图片失败: " + e.getMessage(), e); + } + } + + @Override + public Result getImageById(Long id) { + logger.info("根据ID查询图片: 图片ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "图片ID不能为空"); + } + + ProductImages image = getImageByIdAndCheckExist(id); + if (image == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "图片不存在"); + } + + return ResultUtils.success(image); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询图片失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询图片失败: " + e.getMessage(), e); + } + } + + @Override + public Result batchCreateImages(List images) { + logger.info("批量创建商品图片: 图片数量 = {}", images.size()); + + try { + if (images == null || images.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "图片列表不能为空"); + } + + // 批量创建图片 + for (ProductImages image : images) { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(image, "productId", "imageUrl"); + + // 检查是否设置了主图,如果设置了主图,则将其他图片设置为非主图 + if (image.getIsMain() != null && image.getIsMain() == 1) { + // 将该商品的所有图片设置为非主图 + productImagesMapper.update(null, new UpdateWrapper().eq("product_id", image.getProductId()).set("is_main", 0)); + } + + productImagesMapper.insert(image); + } + + logger.info("批量创建商品图片成功: 图片数量 = {}", images.size()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证图片信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证图片信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("批量创建商品图片失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量创建商品图片失败: " + e.getMessage(), e); + } + } + + @Override + public Result deleteImagesByProductId(Long productId) { + logger.info("根据商品ID删除所有图片: {}", productId); + + try { + if (productId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + + int result = productImagesMapper.delete(new QueryWrapper().eq("product_id", productId)); + logger.info("删除了 {} 张图片", result); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("根据商品ID删除所有图片失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "根据商品ID删除所有图片失败: " + e.getMessage(), e); + } + } + + @Override + public Result setMainImage(Long productId, Long imageId) { + logger.info("设置主图: 商品ID = {}, 图片ID = {}", productId, imageId); + + try { + if (productId == null || imageId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID和图片ID不能为空"); + } + + // 检查图片是否存在 + ProductImages image = getImageByIdAndCheckExist(imageId); + if (image == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "图片不存在"); + } + + // 检查图片是否属于该商品 + if (!image.getProductId().equals(productId)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "图片不属于该商品"); + } + + // 将该商品的所有图片设置为非主图 + productImagesMapper.update(null, new UpdateWrapper().eq("product_id", productId).set("is_main", 0)); + + // 将指定图片设置为主图 + ProductImages mainImage = new ProductImages(); + mainImage.setId(imageId); + mainImage.setIsMain(1); + int result = productImagesMapper.updateById(mainImage); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "设置主图失败"); + } + + logger.info("主图设置成功: 商品ID = {}, 图片ID = {}", productId, imageId); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("设置主图失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "设置主图失败: " + e.getMessage(), e); + } + } + + /** + * 根据图片ID查询图片并检查是否存在 + * @param id 图片ID + * @return 图片对象,如果图片不存在则返回null + */ + private ProductImages getImageByIdAndCheckExist(Long id) { + if (id == null) { + return null; + } + QueryWrapper queryWrapper = new QueryWrapper().eq("id", id); + return productImagesMapper.selectOne(queryWrapper); + } +} \ No newline at end of file diff --git a/src/main/java/com/qf/backend/service/impl/ProductInventoriesServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ProductInventoriesServiceImpl.java new file mode 100644 index 0000000..a22ae4c --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ProductInventoriesServiceImpl.java @@ -0,0 +1,371 @@ +package com.qf.backend.service.impl; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.ProductInventories; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ProductInventoriesMapper; +import com.qf.backend.service.ProductInventoriesService; +import com.qf.backend.util.ValidateUtil; + +@Service +public class ProductInventoriesServiceImpl extends ServiceImpl implements ProductInventoriesService { + + private static final Logger logger = LoggerFactory.getLogger(ProductInventoriesServiceImpl.class); + + @Autowired + private ProductInventoriesMapper productInventoriesMapper; + + @Override + public Result> getInventoriesByProductId(Long productId) { + logger.info("根据商品ID查询库存: {}", productId); + + try { + if (productId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + + List inventories = productInventoriesMapper.selectList(new QueryWrapper().eq("product_id", productId)); + logger.info("查询到 {} 条库存记录", inventories.size()); + return ResultUtils.success(inventories); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询库存失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询库存失败: " + e.getMessage(), e); + } + } + + @Override + public Result getInventoryBySkuId(Long skuId) { + logger.info("根据SKU ID查询库存: {}", skuId); + + try { + if (skuId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID不能为空"); + } + + ProductInventories inventory = productInventoriesMapper.selectOne(new QueryWrapper().eq("sku_id", skuId)); + if (inventory == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "库存不存在: SKU ID = " + skuId); + } + + return ResultUtils.success(inventory); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询库存失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询库存失败: " + e.getMessage(), e); + } + } + + @Override + public Result createInventory(ProductInventories productInventories) { + logger.info("创建库存记录: SKU ID = {}", productInventories.getSkuId()); + + try { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(productInventories, "skuId", "currentStock"); + + // 检查库存数量是否合法 + if (productInventories.getCurrentStock() < 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "库存数量不能为负数"); + } + + // 检查是否已存在该SKU的库存记录 + ProductInventories existingInventory = productInventoriesMapper.selectOne(new QueryWrapper().eq("sku_id", productInventories.getSkuId())); + if (existingInventory != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "该SKU的库存记录已存在"); + } + + int result = productInventoriesMapper.insert(productInventories); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建库存记录失败"); + } + + logger.info("库存记录创建成功"); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证库存信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证库存信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建库存记录失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建库存记录失败: " + e.getMessage(), e); + } + } + + @Override + public Result updateInventory(ProductInventories productInventories) { + logger.info("更新库存信息: 库存ID = {}", productInventories.getId()); + + try { + if (productInventories == null || productInventories.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "库存信息或库存ID不能为空"); + } + + // 检查库存是否存在 + ProductInventories existingInventory = getInventoryByIdAndCheckExist(productInventories.getId()); + if (existingInventory == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "库存不存在"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(productInventories, "skuId", "currentStock"); + + // 检查库存数量是否合法 + if (productInventories.getCurrentStock() < 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "库存数量不能为负数"); + } + + // 更新库存信息 + int result = productInventoriesMapper.updateById(productInventories); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新库存信息失败"); + } + + logger.info("库存信息更新成功: 库存ID = {}", productInventories.getId()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证库存信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证库存信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新库存信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新库存信息失败: " + e.getMessage(), e); + } + } + + @Override + public Result deleteInventory(Long id) { + logger.info("删除库存记录: 库存ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "库存ID不能为空"); + } + // 检查库存是否存在 + ProductInventories inventory = getInventoryByIdAndCheckExist(id); + if (inventory == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "库存不存在"); + } + + int result = productInventoriesMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除库存记录失败"); + } + + logger.info("库存记录删除成功: 库存ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除库存记录失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除库存记录失败: " + e.getMessage(), e); + } + } + + @Override + public Result getInventoryById(Long id) { + logger.info("根据ID查询库存: 库存ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "库存ID不能为空"); + } + + ProductInventories inventory = getInventoryByIdAndCheckExist(id); + if (inventory == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "库存不存在"); + } + + return ResultUtils.success(inventory); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询库存失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询库存失败: " + e.getMessage(), e); + } + } + + @Override + public Result increaseInventory(Long skuId, Integer quantity) { + logger.info("增加库存: SKU ID = {}, 数量 = {}", skuId, quantity); + + try { + if (skuId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID不能为空"); + } + if (quantity == null || quantity <= 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "增加数量必须大于0"); + } + + // 检查库存是否存在 + ProductInventories inventory = productInventoriesMapper.selectOne(new QueryWrapper().eq("sku_id", skuId)); + if (inventory == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "库存不存在: SKU ID = " + skuId); + } + + // 增加库存 + inventory.setCurrentStock(inventory.getCurrentStock() + quantity); + int result = productInventoriesMapper.updateById(inventory); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "增加库存失败"); + } + + logger.info("库存增加成功: SKU ID = {}, 新库存 = {}", skuId, inventory.getCurrentStock()); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("增加库存失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "增加库存失败: " + e.getMessage(), e); + } + } + + @Override + public Result decreaseInventory(Long skuId, Integer quantity) { + logger.info("减少库存: SKU ID = {}, 数量 = {}", skuId, quantity); + + try { + if (skuId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID不能为空"); + } + if (quantity == null || quantity <= 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "减少数量必须大于0"); + } + + // 检查库存是否存在 + ProductInventories inventory = productInventoriesMapper.selectOne(new QueryWrapper().eq("sku_id", skuId)); + if (inventory == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "库存不存在: SKU ID = " + skuId); + } + + // 检查库存是否充足 + if (inventory.getCurrentStock() < quantity) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "库存不足: 当前库存 = " + inventory.getCurrentStock() + ", 需要 = " + quantity); + } + + // 减少库存 + inventory.setCurrentStock(inventory.getCurrentStock() - quantity); + int result = productInventoriesMapper.updateById(inventory); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "减少库存失败"); + } + + logger.info("库存减少成功: SKU ID = {}, 新库存 = {}", skuId, inventory.getCurrentStock()); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("减少库存失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "减少库存失败: " + e.getMessage(), e); + } + } + + @Override + public Result checkInventorySufficient(Long skuId, Integer quantity) { + logger.info("检查库存是否充足: SKU ID = {}, 需要数量 = {}", skuId, quantity); + + try { + if (skuId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID不能为空"); + } + if (quantity == null || quantity <= 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "需要数量必须大于0"); + } + + // 检查库存是否存在 + ProductInventories inventory = productInventoriesMapper.selectOne(new QueryWrapper().eq("sku_id", skuId)); + if (inventory == null) { + logger.warn("库存不存在: SKU ID = {}", skuId); + return ResultUtils.success(false); + } + + boolean isSufficient = inventory.getCurrentStock() >= quantity; + logger.info("库存检查结果: SKU ID = {}, 当前库存 = {}, 需要数量 = {}, 是否充足 = {}", skuId, inventory.getCurrentStock(), quantity, isSufficient); + return ResultUtils.success(isSufficient); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("检查库存是否充足失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "检查库存是否充足失败: " + e.getMessage(), e); + } + } + + @Override + public Result batchUpdateInventory(List inventoryUpdates) { + logger.info("批量更新库存: 更新数量 = {}", inventoryUpdates.size()); + + try { + if (inventoryUpdates == null || inventoryUpdates.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "库存更新列表不能为空"); + } + + // 批量更新库存 + for (ProductInventories inventory : inventoryUpdates) { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(inventory, "id", "currentStock"); + + // 检查库存数量是否合法 + if (inventory.getCurrentStock() < 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "库存数量不能为负数"); + } + + // 检查库存是否存在 + ProductInventories existingInventory = getInventoryByIdAndCheckExist(inventory.getId()); + if (existingInventory == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "库存不存在: 库存ID = " + inventory.getId()); + } + + // 更新库存 + productInventoriesMapper.updateById(inventory); + } + + logger.info("批量更新库存成功: 更新数量 = {}", inventoryUpdates.size()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证库存信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证库存信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("批量更新库存失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量更新库存失败: " + e.getMessage(), e); + } + } + + /** + * 根据库存ID查询库存并检查是否存在 + * @param id 库存ID + * @return 库存对象,如果库存不存在则返回null + */ + private ProductInventories getInventoryByIdAndCheckExist(Long id) { + if (id == null) { + return null; + } + QueryWrapper queryWrapper = new QueryWrapper().eq("id", id); + return productInventoriesMapper.selectOne(queryWrapper); + } +} \ No newline at end of file diff --git a/src/main/java/com/qf/backend/service/impl/ProductSkusServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ProductSkusServiceImpl.java new file mode 100644 index 0000000..e59a158 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ProductSkusServiceImpl.java @@ -0,0 +1,332 @@ +package com.qf.backend.service.impl; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.ProductSkus; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ProductSkusMapper; +import com.qf.backend.service.ProductSkusService; +import com.qf.backend.util.ValidateUtil; + +@Service +public class ProductSkusServiceImpl extends ServiceImpl implements ProductSkusService { + + private static final Logger logger = LoggerFactory.getLogger(ProductSkusServiceImpl.class); + + @Autowired + private ProductSkusMapper productSkusMapper; + + @Override + public Result> getSkusByProductId(Long productId) { + logger.info("根据商品ID查询SKU: {}", productId); + + try { + if (productId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + + List skus = productSkusMapper.selectList(new QueryWrapper().eq("product_id", productId)); + logger.info("查询到 {} 个SKU", skus.size()); + return ResultUtils.success(skus); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询SKU失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询SKU失败: " + e.getMessage(), e); + } + } + + @Override + public Result getSkuByCode(String skuCode) { + logger.info("根据SKU编码查询SKU: {}", skuCode); + + try { + if (ValidateUtil.isEmpty(skuCode)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU编码不能为空"); + } + + ProductSkus sku = productSkusMapper.selectOne(new QueryWrapper().eq("sku_code", skuCode)); + if (sku == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "SKU不存在: " + skuCode); + } + return ResultUtils.success(sku); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询SKU失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询SKU失败: " + e.getMessage(), e); + } + } + + @Override + public Result createSku(ProductSkus productSkus) { + logger.info("创建SKU: SKU编码 = {}", productSkus.getSkuCode()); + + try { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(productSkus, "productId", "skuCode", "skuSpecs", "price", "stock"); + + // 检查SKU编码是否已存在 + ProductSkus existingSku = productSkusMapper.selectOne(new QueryWrapper().eq("sku_code", productSkus.getSkuCode())); + if (existingSku != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "SKU编码已存在"); + } + + int result = productSkusMapper.insert(productSkus); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建SKU失败"); + } + + logger.info("SKU创建成功"); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证SKU信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证SKU信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建SKU失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建SKU失败: " + e.getMessage(), e); + } + } + + @Override + public Result updateSku(ProductSkus productSkus) { + logger.info("更新SKU信息: SKU ID = {}", productSkus.getId()); + + try { + if (productSkus == null || productSkus.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU信息或SKU ID不能为空"); + } + + // 检查SKU是否存在 + ProductSkus existingSku = getSkuByIdAndCheckExist(productSkus.getId()); + if (existingSku == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "SKU不存在"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(productSkus, "productId", "skuCode", "skuSpecs", "price", "stock"); + + // 检查SKU编码是否已存在(排除当前SKU) + ProductSkus skuWithSameCode = productSkusMapper.selectOne(new QueryWrapper().eq("sku_code", productSkus.getSkuCode()).ne("id", productSkus.getId())); + if (skuWithSameCode != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "SKU编码已存在"); + } + + // 更新SKU信息 + int result = productSkusMapper.updateById(productSkus); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新SKU信息失败"); + } + + logger.info("SKU信息更新成功: SKU ID = {}", productSkus.getId()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证SKU信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证SKU信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新SKU信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新SKU信息失败: " + e.getMessage(), e); + } + } + + @Override + public Result deleteSku(Long id) { + logger.info("删除SKU: SKU ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID不能为空"); + } + // 检查SKU是否存在 + ProductSkus sku = getSkuByIdAndCheckExist(id); + if (sku == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "SKU不存在"); + } + + int result = productSkusMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除SKU失败"); + } + + logger.info("SKU删除成功: SKU ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除SKU失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除SKU失败: " + e.getMessage(), e); + } + } + + @Override + public Result getSkuById(Long id) { + logger.info("根据ID查询SKU: SKU ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID不能为空"); + } + + ProductSkus sku = getSkuByIdAndCheckExist(id); + if (sku == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "SKU不存在"); + } + + return ResultUtils.success(sku); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询SKU失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询SKU失败: " + e.getMessage(), e); + } + } + + @Override + public Result batchCreateSkus(List skus) { + logger.info("批量创建SKU: SKU数量 = {}", skus.size()); + + try { + if (skus == null || skus.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU列表不能为空"); + } + + // 批量创建SKU + for (ProductSkus sku : skus) { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(sku, "productId", "skuCode", "skuSpecs", "price", "stock"); + + // 检查SKU编码是否已存在 + ProductSkus existingSku = productSkusMapper.selectOne(new QueryWrapper().eq("sku_code", sku.getSkuCode())); + if (existingSku != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "SKU编码已存在: " + sku.getSkuCode()); + } + + productSkusMapper.insert(sku); + } + + logger.info("批量创建SKU成功: SKU数量 = {}", skus.size()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证SKU信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证SKU信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("批量创建SKU失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量创建SKU失败: " + e.getMessage(), e); + } + } + + @Override + public Result deleteSkusByProductId(Long productId) { + logger.info("根据商品ID删除所有SKU: {}", productId); + + try { + if (productId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + + int result = productSkusMapper.delete(new QueryWrapper().eq("product_id", productId)); + logger.info("删除了 {} 个SKU", result); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("根据商品ID删除所有SKU失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "根据商品ID删除所有SKU失败: " + e.getMessage(), e); + } + } + + @Override + public Result updateSkuStock(Long skuId, Integer quantity) { + logger.info("更新SKU库存: SKU ID = {}, 库存数量 = {}", skuId, quantity); + + try { + if (skuId == null || quantity == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID和库存数量不能为空"); + } + + // 检查库存数量是否合法 + if (quantity < 0) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "库存数量不能为负数"); + } + + // 检查SKU是否存在 + ProductSkus sku = getSkuByIdAndCheckExist(skuId); + if (sku == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "SKU不存在"); + } + + // 更新库存 + sku.setStock(quantity); + int result = productSkusMapper.updateById(sku); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新SKU库存失败"); + } + + logger.info("SKU库存更新成功: SKU ID = {}, 新库存 = {}", skuId, quantity); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新SKU库存失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新SKU库存失败: " + e.getMessage(), e); + } + } + + @Override + public Result> batchGetSkus(List skuIds) { + logger.info("批量查询SKU: SKU ID列表 = {}", skuIds); + + try { + if (skuIds == null || skuIds.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "SKU ID列表不能为空"); + } + + List skus = productSkusMapper.selectBatchIds(skuIds); + logger.info("查询到 {} 个SKU", skus.size()); + return ResultUtils.success(skus); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("批量查询SKU失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量查询SKU失败: " + e.getMessage(), e); + } + } + + /** + * 根据SKU ID查询SKU并检查是否存在 + * @param id SKU ID + * @return SKU对象,如果SKU不存在则返回null + */ + private ProductSkus getSkuByIdAndCheckExist(Long id) { + if (id == null) { + return null; + } + QueryWrapper queryWrapper = new QueryWrapper().eq("id", id); + return productSkusMapper.selectOne(queryWrapper); + } +} \ No newline at end of file diff --git a/src/main/java/com/qf/backend/service/impl/ProductsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ProductsServiceImpl.java new file mode 100644 index 0000000..fedbf64 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ProductsServiceImpl.java @@ -0,0 +1,248 @@ +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.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +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.Products; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ProductsMapper; +import com.qf.backend.service.ProductsService; +import com.qf.backend.util.ValidateUtil; + +/** + * 商品服务实现类 + */ +@Service +public class ProductsServiceImpl extends ServiceImpl implements ProductsService { + + @Autowired + private ProductsMapper productsMapper; + + @Override + public Result> getProductsByName(String productName) { + if (ValidateUtil.isEmpty(productName)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品名称不能为空"); + } + try { + List products = productsMapper.selectList( + new QueryWrapper().like("product_name", productName)); + return ResultUtils.success(products); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品失败", e); + } + } + + @Override + public Result> getProductsByCategoryId(Long categoryId) { + if (ValidateUtil.isEmpty(categoryId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + try { + List products = productsMapper.selectList( + new QueryWrapper().eq("category_id", categoryId)); + return ResultUtils.success(products); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品失败", e); + } + } + + @Override + public Result createProduct(Products products) { + if (ValidateUtil.isEmpty(products)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品信息不能为空"); + } + if (ValidateUtil.isEmpty(products.getProductName())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品名称不能为空"); + } + if (products.getShopId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + if (products.getCategoryId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + if (products.getOriginalPrice() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品原价不能为空"); + } + try { + int result = productsMapper.insert(products); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建商品失败", e); + } + } + + @Override + public Result updateProduct(Products products) { + if (ValidateUtil.isEmpty(products)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品信息不能为空"); + } + if (products.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + if (ValidateUtil.isEmpty(products.getProductName())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品名称不能为空"); + } + try { + // 检查商品是否存在 + Products existing = productsMapper.selectById(products.getId()); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "商品不存在"); + } + int result = productsMapper.updateById(products); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新商品失败", e); + } + } + + @Override + public Result deleteProduct(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + try { + // 检查商品是否存在 + Products existing = productsMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "商品不存在"); + } + int result = productsMapper.deleteById(id); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除商品失败", e); + } + } + + @Override + public Result getProductById(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID不能为空"); + } + try { + Products product = productsMapper.selectById(id); + if (product == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "商品不存在"); + } + return ResultUtils.success(product); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品失败", e); + } + } + + @Override + public Result> listProductsByPage(int page, int size) { + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页数量必须在1-100之间"); + } + try { + Page productPage = new Page<>(page, size); + Page resultPage = productsMapper.selectPage(productPage, null); + return ResultUtils.success(resultPage.getRecords()); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "分页查询商品失败", e); + } + } + + @Override + public Result> getProductsByShopId(Long shopId) { + if (ValidateUtil.isEmpty(shopId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + try { + List products = productsMapper.selectList( + new QueryWrapper().eq("shop_id", shopId)); + return ResultUtils.success(products); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询商品失败", e); + } + } + + @Override + public Result batchUpdateProductStatus(List ids, Integer status) { + if (ValidateUtil.isEmpty(ids)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID列表不能为空"); + } + if (ids.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品ID列表不能为空"); + } + if (ValidateUtil.isEmpty(status)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "商品状态不能为空"); + } + try { + // 检查所有商品是否存在 + for (Long id : ids) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "商品ID列表中存在空值"); + } + Products existing = productsMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "商品ID为" + id + "的商品不存在"); + } + } + // 批量更新状态 + for (Long id : ids) { + Products product = new Products(); + product.setId(id); + product.setStatus(status); + productsMapper.updateById(product); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量更新商品状态失败", e); + } + } + + @Override + public Result> searchProducts(String keyword, int page, int size) { + if (ValidateUtil.isEmpty(keyword)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "搜索关键词不能为空"); + } + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页数量必须在1-100之间"); + } + try { + Page productPage = new Page<>(page, size); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.like("product_name", keyword) + .or().like("description", keyword); + Page resultPage = productsMapper.selectPage(productPage, queryWrapper); + return ResultUtils.success(resultPage.getRecords()); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "搜索商品失败", e); + } + } +} diff --git a/src/main/java/com/qf/backend/service/impl/RefundsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/RefundsServiceImpl.java new file mode 100644 index 0000000..e4da75a --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/RefundsServiceImpl.java @@ -0,0 +1,215 @@ +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.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.qf.backend.entity.Refunds; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.RefundsMapper; +import com.qf.backend.service.RefundsService; +import com.qf.backend.util.RefundNumberFenerator; +import com.qf.backend.util.ValidateUtil; + +/** + * 退款服务实现类 + */ +@Service +public class RefundsServiceImpl extends ServiceImpl implements RefundsService { + + @Autowired + private RefundsMapper refundsMapper; + + @Override + public List getRefundsByOrderId(Long orderId) { + if (ValidateUtil.isEmpty(orderId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + try { + return refundsMapper.selectList( + new QueryWrapper().eq("order_id", orderId)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询退款记录失败", e); + } + } + + @Override + public Refunds getRefundByNumber(String refundNumber) { + if (ValidateUtil.isEmpty(refundNumber)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款单号不能为空"); + } + try { + return refundsMapper.selectOne( + new QueryWrapper().eq("refund_number", refundNumber)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询退款记录失败", e); + } + } + + @Override + public boolean createRefund(Refunds refunds) { + if (ValidateUtil.isEmpty(refunds)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款信息不能为空"); + } + if (ValidateUtil.isEmpty(refunds.getOrderId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "订单ID不能为空"); + } + if (refunds.getRefundAmount() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款金额不能为空"); + } + // 生成退款单号 基于时间戳 + 随机数 / 序列号(最常用) + refunds.setRefundNo(RefundNumberFenerator.generateRefundNumber()); + try { + int result = refundsMapper.insert(refunds); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建退款记录失败", e); + } + } + + @Override + public boolean updateRefund(Refunds refunds) { + if (ValidateUtil.isEmpty(refunds)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款信息不能为空"); + } + if (ValidateUtil.isEmpty(refunds.getId())) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款ID不能为空"); + } + try { + // 检查退款记录是否存在 + Refunds existing = refundsMapper.selectById(refunds.getId()); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "退款记录不存在"); + } + int result = refundsMapper.updateById(refunds); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新退款记录失败", e); + } + } + + @Override + public boolean deleteRefund(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款ID不能为空"); + } + try { + // 检查退款记录是否存在 + Refunds existing = refundsMapper.selectById(id); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "退款记录不存在"); + } + int result = refundsMapper.deleteById(id); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除退款记录失败", e); + } + } + + @Override + public Refunds getRefundById(Long id) { + if (ValidateUtil.isEmpty(id)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款ID不能为空"); + } + try { + Refunds refund = refundsMapper.selectById(id); + if (refund == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "退款记录不存在"); + } + return refund; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询退款记录失败", e); + } + } + + @Override + public List getRefundsByUserId(Long userId) { + if (ValidateUtil.isEmpty(userId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + try { + return refundsMapper.selectList( + new QueryWrapper().eq("user_id", userId)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询退款记录失败", e); + } + } + + @Override + public List getRefundsByStatus(Integer status) { + if (ValidateUtil.isEmpty(status)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款状态不能为空"); + } + try { + return refundsMapper.selectList( + new QueryWrapper().eq("status", status)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询退款记录失败", e); + } + } + + @Override + public boolean updateRefundStatus(Long refundId, Integer status) { + if (ValidateUtil.isEmpty(refundId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款ID不能为空"); + } + if (ValidateUtil.isEmpty(status)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "退款状态不能为空"); + } + try { + // 检查退款记录是否存在 + Refunds existing = refundsMapper.selectById(refundId); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "退款记录不存在"); + } + // 更新状态 + existing.setRefundStatus(status); + int result = refundsMapper.updateById(existing); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新退款状态失败", e); + } + } + + @Override + public List listRefundsByPage(int page, int size) { + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页数量必须在1-100之间"); + } + try { + Page refundPage = new Page<>(page, size); + Page resultPage = refundsMapper.selectPage(refundPage, null); + return resultPage.getRecords(); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "分页查询退款记录失败", e); + } + } +} diff --git a/src/main/java/com/qf/backend/service/impl/RolePermissionsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/RolePermissionsServiceImpl.java new file mode 100644 index 0000000..0e6514c --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/RolePermissionsServiceImpl.java @@ -0,0 +1,212 @@ +package com.qf.backend.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.qf.backend.entity.RolePermissions; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.RolePermissionsMapper; +import com.qf.backend.service.RolePermissionsService; +import com.qf.backend.util.ValidateUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * 角色权限关联服务实现类 + */ +@Service +public class RolePermissionsServiceImpl extends ServiceImpl implements RolePermissionsService { + + @Autowired + private RolePermissionsMapper rolePermissionsMapper; + + @Override + public List getRolePermissionsByRoleId(Long roleId) { + if (ValidateUtil.isEmpty(roleId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + try { + return rolePermissionsMapper.selectList( + new QueryWrapper().eq("role_id", roleId)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询角色权限关联失败", e); + } + } + + @Override + public List getRolePermissionsByPermissionId(Long permissionId) { + if (ValidateUtil.isEmpty(permissionId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID不能为空"); + } + try { + return rolePermissionsMapper.selectList( + new QueryWrapper().eq("permission_id", permissionId)); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询角色权限关联失败", e); + } + } + + @Override + public boolean addPermissionToRole(Long roleId, Long permissionId) { + if (ValidateUtil.isEmpty(roleId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + if (ValidateUtil.isEmpty(permissionId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID不能为空"); + } + try { + // 检查是否已经存在该关联关系 + RolePermissions existing = rolePermissionsMapper.selectOne( + new QueryWrapper() + .eq("role_id", roleId) + .eq("permission_id", permissionId)); + if (existing != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "该角色已拥有此权限"); + } + RolePermissions rolePermission = new RolePermissions(); + rolePermission.setRoleId(roleId); + rolePermission.setPermissionId(permissionId); + int result = rolePermissionsMapper.insert(rolePermission); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "添加角色权限关联失败", e); + } + } + + @Override + public boolean removePermissionFromRole(Long roleId, Long permissionId) { + if (ValidateUtil.isEmpty(roleId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + if (ValidateUtil.isEmpty(permissionId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID不能为空"); + } + try { + // 检查关联关系是否存在 + RolePermissions existing = rolePermissionsMapper.selectOne( + new QueryWrapper() + .eq("role_id", roleId) + .eq("permission_id", permissionId)); + if (existing == null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "角色与权限的关联关系不存在"); + } + int result = rolePermissionsMapper.delete( + new QueryWrapper() + .eq("role_id", roleId) + .eq("permission_id", permissionId)); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "移除角色权限关联失败", e); + } + } + + @Override + public boolean batchAddPermissionsToRole(Long roleId, List permissionIds) { + if (ValidateUtil.isEmpty(roleId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + if (ValidateUtil.isEmpty(permissionIds)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID列表不能为空"); + } + if (permissionIds.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID列表不能为空"); + } + try { + for (Long permissionId : permissionIds) { + if (ValidateUtil.isEmpty(permissionId)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "权限ID列表中存在空值"); + } + // 检查是否已经存在该关联关系 + RolePermissions existing = rolePermissionsMapper.selectOne( + new QueryWrapper() + .eq("role_id", roleId) + .eq("permission_id", permissionId)); + if (existing == null) { + RolePermissions rolePermission = new RolePermissions(); + rolePermission.setRoleId(roleId); + rolePermission.setPermissionId(permissionId); + rolePermissionsMapper.insert(rolePermission); + } + } + return true; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量添加角色权限关联失败", e); + } + } + + @Override + public boolean clearRolePermissions(Long roleId) { + if (ValidateUtil.isEmpty(roleId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + try { + // 检查角色是否有权限关联 + List existingPermissions = rolePermissionsMapper.selectList( + new QueryWrapper().eq("role_id", roleId)); + if (existingPermissions.isEmpty()) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "该角色没有关联的权限"); + } + int result = rolePermissionsMapper.delete( + new QueryWrapper().eq("role_id", roleId)); + return result > 0; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "清除角色权限关联失败", e); + } + } + + @Override + public boolean checkRoleHasPermission(Long roleId, Long permissionId) { + if (ValidateUtil.isEmpty(roleId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + if (ValidateUtil.isEmpty(permissionId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "权限ID不能为空"); + } + try { + RolePermissions rolePermission = rolePermissionsMapper.selectOne( + new QueryWrapper() + .eq("role_id", roleId) + .eq("permission_id", permissionId)); + return rolePermission != null; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "检查角色权限关系失败", e); + } + } + + @Override + public List listPermissionIdsByRoleId(Long roleId) { + if (ValidateUtil.isEmpty(roleId)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + try { + List rolePermissions = rolePermissionsMapper.selectList( + new QueryWrapper().eq("role_id", roleId)); + List permissionIds = new ArrayList<>(); + for (RolePermissions rp : rolePermissions) { + permissionIds.add(rp.getPermissionId()); + } + return permissionIds; + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询角色权限ID列表失败", e); + } + } +} diff --git a/src/main/java/com/qf/backend/service/impl/RolesServiceImpl.java b/src/main/java/com/qf/backend/service/impl/RolesServiceImpl.java index 1fec66a..0f28f33 100644 --- a/src/main/java/com/qf/backend/service/impl/RolesServiceImpl.java +++ b/src/main/java/com/qf/backend/service/impl/RolesServiceImpl.java @@ -7,14 +7,22 @@ package com.qf.backend.service.impl; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; 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.Roles; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; import com.qf.backend.mapper.RolesMapper; import com.qf.backend.service.RolesService; +import com.qf.backend.util.ValidateUtil; /** * @@ -23,66 +31,224 @@ import com.qf.backend.service.RolesService; @Service public class RolesServiceImpl extends ServiceImpl implements RolesService { + private static final Logger logger = LoggerFactory.getLogger(RolesServiceImpl.class); + @Autowired private RolesMapper rolesMapper; // 根据角色名称查询角色 @Override - public Roles getRoleByName(String roleName) { + public Result getRoleByName(String roleName) { + logger.info("根据角色名称查询角色: {}", roleName); + + // 参数校验 + if (ValidateUtil.isEmpty(roleName)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色名称不能为空"); + } + try { - if (roleName == null) { - return null; + Roles role = rolesMapper.selectOne(new QueryWrapper().eq("role_name", roleName)); + if (role == null) { + logger.warn("角色 {} 不存在", roleName); + throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在: " + roleName); } - Roles roles = rolesMapper.selectOne(new QueryWrapper().eq("role_name", roleName)); - if (roles == null) { - return null; - } - return roles; + return ResultUtils.success(role); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return null; + logger.error("查询角色失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询角色失败: " + e.getMessage(), e); } } - - // 查询所有角色 + @Override - public List listAllRoles() { - - throw new UnsupportedOperationException("Unimplemented method 'listAllRoles'"); + public Result createRole(Roles roles) { + logger.info("创建角色: {}", roles); + + try { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(roles, "roleName"); + + // 检查角色名称是否已存在 + Roles existingRole = rolesMapper.selectOne(new QueryWrapper().eq("role_name", roles.getRoleName())); + if (existingRole != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "角色名称已存在: " + roles.getRoleName()); + } + + int result = rolesMapper.insert(roles); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建角色失败"); + } + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证角色信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证角色信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建角色失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建角色失败: " + e.getMessage(), e); + } } - // 根据ID查询角色 + @Override - public Roles getRoleById(Long id) { - - throw new UnsupportedOperationException("Unimplemented method 'getRoleById'"); + public Result updateRole(Roles roles) { + logger.info("更新角色: {}", roles); + + try { + // 检查角色ID是否为空 + if (roles == null || roles.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色信息或角色ID不能为空"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(roles, "roleName"); + + // 检查角色是否存在 + Roles existingRole = rolesMapper.selectById(roles.getId()); + if (existingRole == null) { + throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在"); + } + + // 检查角色名称是否与其他角色重复 + Roles nameConflictRole = rolesMapper.selectOne( + new QueryWrapper().eq("role_name", roles.getRoleName()).ne("id", roles.getId()) + ); + if (nameConflictRole != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "角色名称已存在: " + roles.getRoleName()); + } + + rolesMapper.updateInfo(roles, new UpdateWrapper().eq("id", roles.getId())); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证角色信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证角色信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新角色失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新角色失败: " + e.getMessage(), e); + } } - // 根据用户ID查询角色 + @Override - public List listRolesByUserId(Long userId) { - - throw new UnsupportedOperationException("Unimplemented method 'listRolesByUserId'"); + public Result deleteRole(Long id) { + logger.info("删除角色: {}", id); + + // 参数校验 + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + + try { + // 检查角色是否存在 + Roles role = rolesMapper.selectById(id); + if (role == null) { + throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在"); + } + + // 删除角色 + int result = rolesMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除角色失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除角色失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除角色失败: " + e.getMessage(), e); + } } - // 创建角色 + @Override - public boolean createRole(Roles roles) { - - throw new UnsupportedOperationException("Unimplemented method 'createRole'"); + public Result> listAllRoles() { + logger.info("查询所有角色"); + + try { + List rolesList = rolesMapper.selectList(null); + return ResultUtils.success(rolesList); + } catch (Exception e) { + logger.error("查询所有角色失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询所有角色失败: " + e.getMessage(), e); + } } - // 更新角色 + @Override - public boolean updateRole(Roles roles) { - - throw new UnsupportedOperationException("Unimplemented method 'updateRole'"); + public Result getRoleById(Long id) { + logger.info("根据ID查询角色: {}", id); + + // 参数校验 + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + + try { + Roles role = rolesMapper.selectById(id); + if (role == null) { + throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在"); + } + return ResultUtils.success(role); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询角色失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询角色失败: " + e.getMessage(), e); + } } - // 批量删除角色 + @Override - public boolean batchDeleteRoles(List ids) { - - throw new UnsupportedOperationException("Unimplemented method 'batchDeleteRoles'"); + public Result batchDeleteRoles(List ids) { + logger.info("批量删除角色: {}", ids); + + // 参数校验 + if (ids == null || ids.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID列表不能为空"); + } + + try { + // 检查所有角色是否存在 + for (Long id : ids) { + Roles role = rolesMapper.selectById(id); + if (role == null) { + throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在: " + id); + } + } + + int result = rolesMapper.deleteBatchIds(ids); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "批量删除角色失败"); + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("批量删除角色失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量删除角色失败: " + e.getMessage(), e); + } } - // 删除角色 + @Override - public boolean deleteRole(Long id) { - - throw new UnsupportedOperationException("Unimplemented method 'deleteRole'"); + public Result> listRolesByUserId(Long userId) { + logger.info("查询用户角色: 用户ID = {}", userId); + + // 参数校验 + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + + try { + List rolesList = rolesMapper.selectList(new QueryWrapper().inSql("id", "select role_id from user_roles where user_id = " + userId)); + return ResultUtils.success(rolesList); + } catch (Exception e) { + logger.error("查询用户角色失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户角色失败: " + e.getMessage(), e); + } } } diff --git a/src/main/java/com/qf/backend/service/impl/ShopCategoriesServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ShopCategoriesServiceImpl.java new file mode 100644 index 0000000..f088abf --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ShopCategoriesServiceImpl.java @@ -0,0 +1,282 @@ +package com.qf.backend.service.impl; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.ShopCategories; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ShopCategoriesMapper; +import com.qf.backend.service.ShopCategoriesService; +import com.qf.backend.util.ValidateUtil; + +@Service +public class ShopCategoriesServiceImpl extends ServiceImpl implements ShopCategoriesService { + + private static final Logger logger = LoggerFactory.getLogger(ShopCategoriesServiceImpl.class); + + @Autowired + private ShopCategoriesMapper shopCategoriesMapper; + + @Override + public Result getCategoryByName(String categoryName) { + logger.info("根据分类名称查询分类: {}", categoryName); + + try { + if (ValidateUtil.isEmpty(categoryName)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "分类名称不能为空"); + } + + ShopCategories category = shopCategoriesMapper.selectOne(new QueryWrapper().eq("category_name", categoryName)); + if (category == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类不存在: " + categoryName); + } + return ResultUtils.success(category); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询分类失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询分类失败: " + e.getMessage(), e); + } + } + + @Override + public Result> getSubCategoriesByParentId(Long parentId) { + logger.info("根据父分类ID查询子分类: {}", parentId); + + try { + if (parentId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "父分类ID不能为空"); + } + + List subCategories = shopCategoriesMapper.selectList(new QueryWrapper().eq("parent_id", parentId)); + return ResultUtils.success(subCategories); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询子分类失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询子分类失败: " + e.getMessage(), e); + } + } + + @Override + public Result createCategory(ShopCategories shopCategories) { + logger.info("创建分类: 分类对象"); + + try { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(shopCategories, "categoryName"); + + int result = shopCategoriesMapper.insert(shopCategories); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建分类失败"); + } + + logger.info("分类创建成功"); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证分类信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证分类信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建分类失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建分类失败: " + e.getMessage(), e); + } + } + + @Override + public Result updateCategory(ShopCategories shopCategories) { + logger.info("更新分类信息: 分类ID = {}", shopCategories.getId()); + + try { + if (shopCategories == null || shopCategories.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类信息或分类ID不能为空"); + } + + // 检查分类是否存在 + ShopCategories existingCategory = getCategoryByIdAndCheckExist(shopCategories.getId()); + if (existingCategory == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类不存在"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(shopCategories, "categoryName"); + + // 更新分类信息 + int result = shopCategoriesMapper.updateById(shopCategories); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新分类信息失败"); + } + + logger.info("分类信息更新成功: 分类ID = {}", shopCategories.getId()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证分类信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证分类信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新分类信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新分类信息失败: " + e.getMessage(), e); + } + } + + @Override + public Result deleteCategory(Long id) { + logger.info("删除分类: 分类ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + // 检查分类是否存在 + ShopCategories category = getCategoryByIdAndCheckExist(id); + if (category == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类不存在"); + } + + // 检查是否有子分类 + List subCategories = shopCategoriesMapper.selectList(new QueryWrapper().eq("parent_id", id)); + if (subCategories != null && !subCategories.isEmpty()) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "该分类下存在子分类,无法删除"); + } + + int result = shopCategoriesMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除分类失败"); + } + + logger.info("分类删除成功: 分类ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除分类失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除分类失败: " + e.getMessage(), e); + } + } + + @Override + public Result> listRootCategories() { + logger.info("查询所有根分类"); + + try { + // 查询父分类ID为0或null的分类 + List rootCategories = shopCategoriesMapper.selectList(new QueryWrapper().isNull("parent_id").or().eq("parent_id", 0)); + logger.info("查询到 {} 个根分类", rootCategories.size()); + return ResultUtils.success(rootCategories); + } catch (Exception e) { + logger.error("查询根分类失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询根分类失败: " + e.getMessage(), e); + } + } + + @Override + public Result getCategoryById(Long id) { + logger.info("根据ID查询分类: 分类ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + + ShopCategories category = getCategoryByIdAndCheckExist(id); + if (category == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类不存在"); + } + + return ResultUtils.success(category); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询分类失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询分类失败: " + e.getMessage(), e); + } + } + + @Override + public Result batchDeleteCategories(List ids) { + logger.info("批量删除分类: 分类ID列表 = {}", ids); + + try { + if (ids == null || ids.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID列表不能为空"); + } + + // 检查所有分类是否存在且没有子分类 + for (Long id : ids) { + ShopCategories category = getCategoryByIdAndCheckExist(id); + if (category == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "分类不存在: " + id); + } + + // 检查是否有子分类 + List subCategories = shopCategoriesMapper.selectList(new QueryWrapper().eq("parent_id", id)); + if (subCategories != null && !subCategories.isEmpty()) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "分类 " + id + " 下存在子分类,无法删除"); + } + } + + int result = shopCategoriesMapper.deleteBatchIds(ids); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "批量删除分类失败"); + } + + logger.info("批量删除分类成功: 删除了 {} 个分类", result); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("批量删除分类失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量删除分类失败: " + e.getMessage(), e); + } + } + + @Override + public Result> listAllCategoriesWithTree() { + logger.info("查询所有分类(树形结构)"); + + try { + // 查询所有分类 + List allCategories = shopCategoriesMapper.selectList(null); + + // TODO: 实现树形结构转换逻辑 + // 这里简单返回所有分类,实际项目中需要将分类转换为树形结构 + + logger.info("查询到 {} 个分类", allCategories.size()); + return ResultUtils.success(allCategories); + } catch (Exception e) { + logger.error("查询分类树形结构失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询分类树形结构失败: " + e.getMessage(), e); + } + } + + /** + * 根据分类ID查询分类并检查是否存在 + * @param id 分类ID + * @return 分类对象,如果分类不存在则返回null + */ + private ShopCategories getCategoryByIdAndCheckExist(Long id) { + if (id == null) { + return null; + } + QueryWrapper queryWrapper = new QueryWrapper().eq("id", id); + return shopCategoriesMapper.selectOne(queryWrapper); + } + +} \ No newline at end of file diff --git a/src/main/java/com/qf/backend/service/impl/ShopRatingsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ShopRatingsServiceImpl.java new file mode 100644 index 0000000..36cf930 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ShopRatingsServiceImpl.java @@ -0,0 +1,373 @@ +package com.qf.backend.service.impl; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +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.ShopRatings; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ShopRatingsMapper; +import com.qf.backend.service.ShopRatingsService; +import com.qf.backend.util.ValidateUtil; + +@Service +public class ShopRatingsServiceImpl extends ServiceImpl implements ShopRatingsService { + + private static final Logger logger = LoggerFactory.getLogger(ShopRatingsServiceImpl.class); + + @Autowired + private ShopRatingsMapper shopRatingsMapper; + + // 根据店铺ID查询评分 + @Override + public Result> getRatingsByShopId(Long shopId) { + logger.info("根据店铺ID查询评分: {}", shopId); + + try { + if (shopId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper().eq("shop_id", shopId); + List ratingsList = shopRatingsMapper.selectList(queryWrapper); + logger.info("查询到 {} 个评分", ratingsList.size()); + return ResultUtils.success(ratingsList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询评分失败: " + e.getMessage(), e); + } + } + + // 根据用户ID查询评分 + @Override + public Result> getRatingsByUserId(Long userId) { + logger.info("根据用户ID查询评分: {}", userId); + + try { + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper().eq("user_id", userId); + List ratingsList = shopRatingsMapper.selectList(queryWrapper); + logger.info("查询到 {} 个评分", ratingsList.size()); + return ResultUtils.success(ratingsList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询评分失败: " + e.getMessage(), e); + } + } + + // 创建评分 + @Override + public Result createRating(ShopRatings shopRatings) { + logger.info("创建评分: 评分对象"); + + try { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(shopRatings, "shopId", "userId", "rating"); + + // 检查评分范围 + if (shopRatings.getRating() < 1 || shopRatings.getRating() > 5) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "评分必须在1-5之间"); + } + + int result = shopRatingsMapper.insert(shopRatings); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建评分失败"); + } + + logger.info("评分创建成功"); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证评分信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证评分信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建评分失败: " + e.getMessage(), e); + } + } + + // 更新评分信息 + @Override + public Result updateRating(ShopRatings shopRatings) { + logger.info("更新评分信息: 评分ID = {}", shopRatings.getId()); + + try { + if (shopRatings == null || shopRatings.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "评分信息或评分ID不能为空"); + } + + // 检查评分是否存在 + ShopRatings existingRating = getRatingByIdAndCheckExist(shopRatings.getId()); + if (existingRating == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "评分不存在"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(shopRatings, "shopId", "userId", "rating"); + + // 检查评分范围 + if (shopRatings.getRating() < 1 || shopRatings.getRating() > 5) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "评分必须在1-5之间"); + } + + // 更新评分信息 + int result = shopRatingsMapper.updateById(shopRatings); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新评分信息失败"); + } + + logger.info("评分信息更新成功: 评分ID = {}", shopRatings.getId()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证评分信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证评分信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新评分信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新评分信息失败: " + e.getMessage(), e); + } + } + + // 删除评分 + @Override + public Result deleteRating(Long id) { + logger.info("删除评分: 评分ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "评分ID不能为空"); + } + // 检查评分是否存在 + ShopRatings rating = getRatingByIdAndCheckExist(id); + if (rating == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "评分不存在"); + } + + int result = shopRatingsMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除评分失败"); + } + + logger.info("评分删除成功: 评分ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除评分失败: " + e.getMessage(), e); + } + } + + // 根据评分ID查询评分 + @Override + public Result getRatingById(Long id) { + logger.info("根据ID查询评分: 评分ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "评分ID不能为空"); + } + + ShopRatings rating = getRatingByIdAndCheckExist(id); + if (rating == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "评分不存在"); + } + + return ResultUtils.success(rating); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询评分失败: " + e.getMessage(), e); + } + } + + // 获取店铺平均评分 + @Override + public Result getAverageRatingByShopId(Long shopId) { + logger.info("获取店铺平均评分: 店铺ID = {}", shopId); + + try { + if (shopId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + + // 使用QueryWrapper查询所有评分 + QueryWrapper queryWrapper = new QueryWrapper().eq("shop_id", shopId); + List ratingsList = shopRatingsMapper.selectList(queryWrapper); + + // 计算平均评分 + Double averageRating = 0.0; + if (ratingsList != null && !ratingsList.isEmpty()) { + int totalRating = 0; + for (ShopRatings rating : ratingsList) { + totalRating += rating.getRating(); + } + averageRating = (double) totalRating / ratingsList.size(); + } + + logger.info("店铺平均评分: {}", averageRating); + return ResultUtils.success(averageRating); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("获取店铺平均评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "获取店铺平均评分失败: " + e.getMessage(), e); + } + } + + // 获取店铺评分数量 + @Override + public Result getRatingCountByShopId(Long shopId) { + logger.info("获取店铺评分数量: 店铺ID = {}", shopId); + + try { + if (shopId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + + // 使用QueryWrapper查询评分数量 + QueryWrapper queryWrapper = new QueryWrapper().eq("shop_id", shopId); + Long ratingCount = shopRatingsMapper.selectCount(queryWrapper); + + logger.info("店铺评分数量: {}", ratingCount); + return ResultUtils.success(ratingCount != null ? ratingCount.intValue() : 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("获取店铺评分数量失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "获取店铺评分数量失败: " + e.getMessage(), e); + } + } + + // 根据评分星级查询店铺评分 + @Override + public Result> getRatingsByShopIdAndRating(Long shopId, Integer rating) { + logger.info("根据评分星级查询店铺评分: 店铺ID = {}, 评分 = {}", shopId, rating); + + try { + if (shopId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + if (rating == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "评分不能为空"); + } + + // 检查评分范围 + if (rating < 1 || rating > 5) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "评分必须在1-5之间"); + } + + QueryWrapper queryWrapper = new QueryWrapper() + .eq("shop_id", shopId) + .eq("rating", rating); + List ratingsList = shopRatingsMapper.selectList(queryWrapper); + logger.info("查询到 {} 个评分", ratingsList.size()); + return ResultUtils.success(ratingsList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("根据评分星级查询店铺评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "根据评分星级查询店铺评分失败: " + e.getMessage(), e); + } + } + + // 检查用户是否已对店铺评分 + @Override + public Result checkUserHasRated(Long shopId, Long userId) { + logger.info("检查用户是否已对店铺评分: 店铺ID = {}, 用户ID = {}", shopId, userId); + + try { + if (shopId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper() + .eq("shop_id", shopId) + .eq("user_id", userId); + ShopRatings rating = shopRatingsMapper.selectOne(queryWrapper); + boolean hasRated = rating != null; + logger.info("用户是否已评分: {}", hasRated); + return ResultUtils.success(hasRated); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("检查用户是否已对店铺评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "检查用户是否已对店铺评分失败: " + e.getMessage(), e); + } + } + + // 分页查询店铺评分 + @Override + public Result> listRatingsByShopIdAndPage(Long shopId, int page, int size) { + logger.info("分页查询店铺评分: 店铺ID = {}, 页码 = {}, 每页大小 = {}", shopId, page, size); + + try { + if (shopId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + + // 参数校验 + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页大小必须在1-100之间"); + } + + // 使用MyBatis-Plus的分页功能 + Page ratingPage = new Page<>(page, size); + QueryWrapper queryWrapper = new QueryWrapper().eq("shop_id", shopId); + Page resultPage = shopRatingsMapper.selectPage(ratingPage, queryWrapper); + + logger.info("分页查询成功: 共 {} 条记录, 第 {} 页", resultPage.getTotal(), page); + return ResultUtils.success(resultPage.getRecords()); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("分页查询店铺评分失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "分页查询店铺评分失败: " + e.getMessage(), e); + } + } + + /** + * 根据评分ID查询评分并检查是否存在 + * @param id 评分ID + * @return 评分对象,如果评分不存在则返回null + */ + private ShopRatings getRatingByIdAndCheckExist(Long id) { + if (id == null) { + return null; + } + QueryWrapper queryWrapper = new QueryWrapper().eq("id", id); + return shopRatingsMapper.selectOne(queryWrapper); + } + +} diff --git a/src/main/java/com/qf/backend/service/impl/ShopsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/ShopsServiceImpl.java new file mode 100644 index 0000000..9344c9a --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/ShopsServiceImpl.java @@ -0,0 +1,335 @@ +package com.qf.backend.service.impl; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +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.Shops; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.ShopsMapper; +import com.qf.backend.service.ShopsService; +import com.qf.backend.util.ValidateUtil; + +@Service +public class ShopsServiceImpl extends ServiceImpl implements ShopsService { + + private static final Logger logger = LoggerFactory.getLogger(ShopsServiceImpl.class); + + @Autowired + private ShopsMapper shopsMapper; + + // 根据店铺名称查询店铺 + @Override + public Result> getShopsByName(String shopName) { + logger.info("根据店铺名称查询店铺: {}", shopName); + + try { + if (ValidateUtil.isEmpty(shopName)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "店铺名称不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper().like("shop_name", shopName); + List shopsList = shopsMapper.selectList(queryWrapper); + logger.info("查询到 {} 个店铺", shopsList.size()); + return ResultUtils.success(shopsList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询店铺失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询店铺失败: " + e.getMessage(), e); + } + } + + // 根据用户ID查询店铺 + @Override + public Result getShopByUserId(Long userId) { + logger.info("根据用户ID查询店铺: {}", userId); + + try { + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper().eq("user_id", userId); + Shops shop = shopsMapper.selectOne(queryWrapper); + if (shop == null) { + throw new BusinessException(ErrorCode.SHOP_NOT_FOUND, "店铺不存在: 用户ID = " + userId); + } + return ResultUtils.success(shop); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询店铺失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询店铺失败: " + e.getMessage(), e); + } + } + + // 创建店铺 + @Override + public Result createShop(Shops shops) { + logger.info("创建店铺: 店铺对象"); + + try { + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(shops, "shopName", "userId", "categoryId"); + + int result = shopsMapper.insert(shops); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建店铺失败"); + } + + logger.info("店铺创建成功"); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证店铺信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证店铺信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("创建店铺失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建店铺失败: " + e.getMessage(), e); + } + } + + // 更新店铺信息 + @Override + public Result updateShop(Shops shops) { + logger.info("更新店铺信息: 店铺ID = {}", shops.getId()); + + try { + if (shops == null || shops.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺信息或店铺ID不能为空"); + } + + // 检查店铺是否存在 + Shops existingShop = getShopByIdAndCheckExist(shops.getId()); + if (existingShop == null) { + throw new BusinessException(ErrorCode.SHOP_NOT_FOUND, "店铺不存在"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(shops, "shopName", "categoryId"); + + // 更新店铺信息 + int result = shopsMapper.updateById(shops); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新店铺信息失败"); + } + + logger.info("店铺信息更新成功: 店铺ID = {}", shops.getId()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证店铺信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证店铺信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新店铺信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新店铺信息失败: " + e.getMessage(), e); + } + } + + // 删除店铺 + @Override + public Result deleteShop(Long id) { + logger.info("删除店铺: 店铺ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + // 检查店铺是否存在 + Shops shop = getShopByIdAndCheckExist(id); + if (shop == null) { + throw new BusinessException(ErrorCode.SHOP_NOT_FOUND, "店铺不存在"); + } + + int result = shopsMapper.deleteById(id); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除店铺失败"); + } + + logger.info("店铺删除成功: 店铺ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("删除店铺失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除店铺失败: " + e.getMessage(), e); + } + } + + // 根据店铺ID查询店铺 + @Override + public Result getShopById(Long id) { + logger.info("根据ID查询店铺: 店铺ID = {}", id); + + try { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + + Shops shop = getShopByIdAndCheckExist(id); + if (shop == null) { + throw new BusinessException(ErrorCode.SHOP_NOT_FOUND, "店铺不存在"); + } + + return ResultUtils.success(shop); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("查询店铺失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询店铺失败: " + e.getMessage(), e); + } + } + + // 分页查询店铺 + @Override + public Result> listShopsByPage(int page, int size) { + logger.info("分页查询店铺: 页码 = {}, 每页大小 = {}", page, size); + + try { + // 参数校验 + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页大小必须在1-100之间"); + } + + // 使用MyBatis-Plus的分页功能 + Page shopPage = new Page<>(page, size); + Page resultPage = shopsMapper.selectPage(shopPage, null); + + logger.info("分页查询成功: 共 {} 条记录, 第 {} 页", resultPage.getTotal(), page); + return ResultUtils.success(resultPage.getRecords()); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("分页查询店铺失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "分页查询店铺失败: " + e.getMessage(), e); + } + } + + // 根据店铺分类ID查询店铺 + @Override + public Result> getShopsByCategoryId(Long categoryId) { + logger.info("根据店铺分类ID查询店铺: 分类ID = {}", categoryId); + + try { + if (categoryId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "分类ID不能为空"); + } + + QueryWrapper queryWrapper = new QueryWrapper().eq("category_id", categoryId); + List shopsList = shopsMapper.selectList(queryWrapper); + logger.info("查询到 {} 个店铺", shopsList.size()); + return ResultUtils.success(shopsList); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("根据分类ID查询店铺失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "根据分类ID查询店铺失败: " + e.getMessage(), e); + } + } + + // 更新店铺状态 + @Override + public Result updateShopStatus(Long shopId, Integer status) { + logger.info("更新店铺状态: 店铺ID = {}, 状态 = {}", shopId, status); + + try { + if (shopId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺ID不能为空"); + } + if (status == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "店铺状态不能为空"); + } + + // 检查店铺是否存在 + Shops shop = getShopByIdAndCheckExist(shopId); + if (shop == null) { + throw new BusinessException(ErrorCode.SHOP_NOT_FOUND, "店铺不存在"); + } + + // 更新店铺状态 + shop.setStatus(status); + int result = shopsMapper.updateById(shop); + if (result <= 0) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新店铺状态失败"); + } + + logger.info("店铺状态更新成功: 店铺ID = {}, 新状态 = {}", shopId, status); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("更新店铺状态失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新店铺状态失败: " + e.getMessage(), e); + } + } + + // 搜索店铺 + @Override + public Result> searchShops(String keyword, int page, int size) { + logger.info("搜索店铺: 关键词 = {}, 页码 = {}, 每页大小 = {}", keyword, page, size); + + try { + if (ValidateUtil.isEmpty(keyword)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "搜索关键词不能为空"); + } + + // 参数校验 + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页大小必须在1-100之间"); + } + + // 使用MyBatis-Plus的分页功能 + Page shopPage = new Page<>(page, size); + QueryWrapper queryWrapper = new QueryWrapper() + .like("shop_name", keyword) + .or().like("description", keyword); + Page resultPage = shopsMapper.selectPage(shopPage, queryWrapper); + + logger.info("搜索成功: 共 {} 条记录, 第 {} 页", resultPage.getTotal(), page); + return ResultUtils.success(resultPage.getRecords()); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("搜索店铺失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "搜索店铺失败: " + e.getMessage(), e); + } + } + + /** + * 根据店铺ID查询店铺并检查是否存在 + * @param id 店铺ID + * @return 店铺对象,如果店铺不存在则返回null + */ + private Shops getShopByIdAndCheckExist(Long id) { + if (id == null) { + return null; + } + QueryWrapper queryWrapper = new QueryWrapper().eq("id", id); + return shopsMapper.selectOne(queryWrapper); + } + +} diff --git a/src/main/java/com/qf/backend/service/impl/UserDetailsServiceImpl.java b/src/main/java/com/qf/backend/service/impl/UserDetailsServiceImpl.java new file mode 100644 index 0000000..b0d3251 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/UserDetailsServiceImpl.java @@ -0,0 +1,158 @@ +package com.qf.backend.service.impl; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.UserDetails; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.UserDetailsMapper; +import com.qf.backend.service.UserDetailsService; + +/** + * 用户详情服务实现类 + */ +@Service +public class UserDetailsServiceImpl extends ServiceImpl implements UserDetailsService { + + @Autowired + private UserDetailsMapper userDetailsMapper; + + @Override + public Result getUserDetailsByUserId(Long userId) { + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + try { + UserDetails userDetails = userDetailsMapper.selectOne( + new QueryWrapper().eq("user_id", userId)); + return ResultUtils.success(userDetails); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户详情失败", e); + } + } + + @Override + public Result createUserDetails(UserDetails userDetails) { + if (userDetails == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户详情信息不能为空"); + } + if (userDetails.getUserId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + try { + // 检查是否已存在该用户的详情 + UserDetails existing = userDetailsMapper.selectOne( + new QueryWrapper().eq("user_id", userDetails.getUserId())); + if (existing != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "该用户已存在详情信息"); + } + int result = userDetailsMapper.insert(userDetails); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建用户详情失败", e); + } + } + + @Override + public Result updateUserDetails(UserDetails userDetails) { + if (userDetails == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户详情信息不能为空"); + } + if (userDetails.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户详情ID不能为空"); + } + try { + // 检查用户详情是否存在 + UserDetails existing = userDetailsMapper.selectById(userDetails.getId()); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "用户详情不存在"); + } + int result = userDetailsMapper.updateById(userDetails); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新用户详情失败", e); + } + } + + @Override + public Result deleteUserDetailsByUserId(Long userId) { + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + try { + // 检查用户详情是否存在 + UserDetails existing = userDetailsMapper.selectOne( + new QueryWrapper().eq("user_id", userId)); + if (existing == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "用户详情不存在"); + } + int result = userDetailsMapper.delete( + new QueryWrapper().eq("user_id", userId)); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除用户详情失败", e); + } + } + + @Override + public Result getUserDetailsById(Long id) { + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户详情ID不能为空"); + } + try { + UserDetails userDetails = userDetailsMapper.selectById(id); + if (userDetails == null) { + throw new BusinessException(ErrorCode.NOT_FOUND, "用户详情不存在"); + } + return ResultUtils.success(userDetails); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户详情失败", e); + } + } + + // @Override + // public Result updateContactInfo(Long userId, String phone, String email) { + // if (userId == null) { + // throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + // } + // if (ValidateUtil.isEmpty(phone) && ValidateUtil.isEmpty(email)) { + // throw new BusinessException(ErrorCode.MISSING_PARAM, "手机号和邮箱不能同时为空"); + // } + // try { + // // 检查用户详情是否存在 + // UserDetails existing = userDetailsMapper.selectOne( + // new QueryWrapper().eq("user_id", userId)); + // if (existing == null) { + // throw new BusinessException(ErrorCode.NOT_FOUND, "用户详情不存在"); + // } + // // 更新联系方式 + // if (phone != null) { + // existing.setPhone(phone); + // } + // if (email != null) { + // existing.setEmail(email); + // } + // int result = userDetailsMapper.updateById(existing); + // return ResultUtils.success(result > 0); + // } catch (BusinessException e) { + // throw e; + // } catch (Exception e) { + // throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新用户联系方式失败", e); + // } + // } +} diff --git a/src/main/java/com/qf/backend/service/impl/UserLoginServiceImpl.java b/src/main/java/com/qf/backend/service/impl/UserLoginServiceImpl.java new file mode 100644 index 0000000..32cde08 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/UserLoginServiceImpl.java @@ -0,0 +1,64 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ + +package com.qf.backend.service.impl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.qf.backend.common.Result; +import com.qf.backend.common.ResultUtils; +import com.qf.backend.dto.LoginUser; +import com.qf.backend.entity.Users; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.service.UserLoginService; +import com.qf.backend.service.UsersService; +import com.qf.backend.util.ValidateUtil; + + +/** + * + * @author 30803 + */ +@Service +public class UserLoginServiceImpl implements UserLoginService { + private Logger logger = LoggerFactory.getLogger(UserLoginServiceImpl.class); + @Autowired + private UsersService usersServiceImpl; + + /** + * 用户登录 + * @param username 用户名 + * @param password 密码 + * @return 登录结果 + */ + @Override + public Result login(String username, String password) { + logger.info("用户登录,用户名:{}", username); + // 1. 校验用户名和密码是否为空 + if (ValidateUtil.isEmpty(username) || ValidateUtil.isEmpty(password)) { + return ResultUtils.fail(ErrorCode.PARAM_ERROR, "用户名或密码不能为空"); + } + // 2. 校验用户名是否存在 + Users user = usersServiceImpl.getUserByUsername(username).getData(); + if (user == null) { + return ResultUtils.fail(ErrorCode.USER_NOT_FOUND, "用户名不存在"); + } + // 3. 校验密码是否正确 + // 加密密码 + String encryptedPassword = ValidateUtil.encryptPassword(password); + if (!user.getPassword().equals(encryptedPassword)) { + return ResultUtils.fail(ErrorCode.PASSWORD_ERROR, "密码错误"); + } + // 4. 登录成功,返回登录用户信息 + LoginUser loginUser = new LoginUser(); + // loginUser.setUserId(user.getUserId()); + loginUser.setUsername(user.getUsername()); + // loginUser.setRoles(userRolesServiceImpl.findRolesByUserId(user.getUserId())); + return ResultUtils.success(loginUser); + } + +} diff --git a/src/main/java/com/qf/backend/service/impl/UsersRolesServiceImpl.java b/src/main/java/com/qf/backend/service/impl/UsersRolesServiceImpl.java new file mode 100644 index 0000000..3a1cdd4 --- /dev/null +++ b/src/main/java/com/qf/backend/service/impl/UsersRolesServiceImpl.java @@ -0,0 +1,173 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ + +package com.qf.backend.service.impl; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.UserRoles; +import com.qf.backend.exception.BusinessException; +import com.qf.backend.exception.ErrorCode; +import com.qf.backend.mapper.UserRolesMapper; +import com.qf.backend.service.UserRolesService; +import com.qf.backend.util.ValidateUtil; + + + + +/** + * + * @author 30803 + */ +public class UsersRolesServiceImpl extends ServiceImpl implements UserRolesService { + @Autowired + private UserRolesMapper userRolesMapper; + + @Override + public Result> getUserRolesByUserId(Long userId) { + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + try { + List userRoles = userRolesMapper.selectList(new QueryWrapper().eq("user_id", userId)); + return ResultUtils.success(userRoles); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户角色信息失败", e); + } + } + + @Override + public Result> getUserRolesByRoleId(Long roleId) { + if (roleId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID不能为空"); + } + try { + List userRoles = userRolesMapper.selectList(new QueryWrapper().eq("role_id", roleId)); + return ResultUtils.success(userRoles); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询角色用户信息失败", e); + } + } + + @Override + public Result addRoleToUser(Long userId, Long roleId) { + if (userId == null || roleId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID和角色ID不能为空"); + } + try { + // 检查是否已经存在该关联关系 + UserRoles existing = userRolesMapper.selectOne(new QueryWrapper().eq("user_id", userId).eq("role_id", roleId)); + if (existing != null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "用户已拥有该角色"); + } + UserRoles userRoles = new UserRoles(); + userRoles.setUserId(userId); + userRoles.setRoleId(roleId); + int result = userRolesMapper.insert(userRoles); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "添加用户角色关联失败", e); + } + } + + @Override + public Result removeRoleFromUser(Long userId, Long roleId) { + if (userId == null || roleId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID和角色ID不能为空"); + } + try { + // 检查关联关系是否存在 + UserRoles existing = userRolesMapper.selectOne(new QueryWrapper().eq("user_id", userId).eq("role_id", roleId)); + if (existing == null) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "用户与角色的关联关系不存在"); + } + int result = userRolesMapper.delete(new QueryWrapper().eq("user_id", userId).eq("role_id", roleId)); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "移除用户角色关联失败", e); + } + } + + @Override + public Result batchAddRolesToUser(Long userId, List roleIds) { + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + if (roleIds == null || roleIds.isEmpty()) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "角色ID列表不能为空"); + } + try { + for (Long roleId : roleIds) { + if (roleId == null) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "角色ID列表中存在空值"); + } + // 检查是否已经存在该关联关系 + UserRoles existing = userRolesMapper.selectOne(new QueryWrapper().eq("user_id", userId).eq("role_id", roleId)); + if (existing == null) { + UserRoles userRoles = new UserRoles(); + userRoles.setUserId(userId); + userRoles.setRoleId(roleId); + userRolesMapper.insert(userRoles); + } + } + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "批量添加用户角色关联失败", e); + } + } + + @Override + public Result clearUserRoles(Long userId) { + if (userId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); + } + try { + // 检查用户是否有角色关联 + List existingRoles = userRolesMapper.selectList(new QueryWrapper().eq("user_id", userId)); + if (existingRoles.isEmpty()) { + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "该用户没有关联的角色"); + } + int result = userRolesMapper.delete(new QueryWrapper().eq("user_id", userId)); + return ResultUtils.success(result > 0); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "清除用户角色关联失败", e); + } + } + + @Override + public Result checkUserHasRole(Long userId, Long roleId) { + if (userId == null || roleId == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID和角色ID不能为空"); + } + try { + // 修改selectInfo为selectOne,因为selectInfo方法可能不存在 + UserRoles userRoles = userRolesMapper.selectOne(new QueryWrapper().eq("user_id", userId).eq("role_id", roleId)); + return ResultUtils.success(userRoles != null); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + throw new BusinessException(ErrorCode.DATABASE_ERROR, "检查用户角色关系失败", e); + } + } + +} diff --git a/src/main/java/com/qf/backend/service/impl/UsersServiceImpl.java b/src/main/java/com/qf/backend/service/impl/UsersServiceImpl.java index 4f1560b..87c9274 100644 --- a/src/main/java/com/qf/backend/service/impl/UsersServiceImpl.java +++ b/src/main/java/com/qf/backend/service/impl/UsersServiceImpl.java @@ -2,190 +2,303 @@ package com.qf.backend.service.impl; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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.Users; +import com.qf.backend.exception.BusinessException; import com.qf.backend.exception.ErrorCode; import com.qf.backend.mapper.UsersMapper; import com.qf.backend.service.UsersService; +import com.qf.backend.util.ValidateUtil; @Service public class UsersServiceImpl extends ServiceImpl implements UsersService { + private static final Logger logger = LoggerFactory.getLogger(UsersServiceImpl.class); + @Autowired private UsersMapper usersMapper; // 根据用户名查询用户 @Override public Result getUserByUsername(String username) { + logger.info("根据用户名查询用户: {}", username); try { - if (username == null || username.isEmpty()) { - return ResultUtils.fail(ErrorCode.INVALID_PARAM); + if (ValidateUtil.isEmpty(username)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "用户名不能为空"); } + Users users = usersMapper.selectByUsername(username); if (users == null) { - return ResultUtils.fail(ErrorCode.USER_NOT_FOUND); + throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在: " + username); } return ResultUtils.success(users); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + logger.error("查询用户失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户失败: " + e.getMessage(), e); } } // 根据邮箱查询用户 @Override public Result getUserByEmail(String email) { + logger.info("根据邮箱查询用户: {}", email); try { - if (email == null || email.isEmpty()) { - return ResultUtils.fail(ErrorCode.INVALID_PARAM); + if (ValidateUtil.isEmpty(email)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "邮箱不能为空"); } + + // 使用ValidateUtil进行邮箱格式校验 + if (!ValidateUtil.isValidEmail(email)) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "邮箱格式不正确"); + } + Users users = usersMapper.selectByEmail(email); if (users == null) { - return ResultUtils.fail(ErrorCode.USER_NOT_FOUND); + throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在: " + email); } return ResultUtils.success(users); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + logger.error("查询用户失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户失败: " + e.getMessage(), e); } } //创建用户 @Override public Result createUser(Users users) { + logger.info("创建用户: 用户对象"); try { - // 调用封装的验证方法 - Result validationResult = validateUserBeforeCreate(users); - if (validationResult != null) { - return validationResult; - } + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(users, "username", "email", "password"); + // 加密密码 users.setPassword(new BCryptPasswordEncoder().encode(users.getPassword())); + int result = usersMapper.insert(users); if (result <= 0) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "创建用户失败"); } - return ResultUtils.success(); + + logger.info("用户创建成功"); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证用户信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证用户信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + logger.error("创建用户失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "创建用户失败: " + e.getMessage(), e); } } // 更新用户信息 @Override public Result updateUser(Users users) { - + logger.info("更新用户信息: 用户ID = {}", users.getId()); + try { - // 调用封装的验证方法 - Result validationResult = validateUserBeforeCreate(users); - if (validationResult != null) { - return validationResult; + if (users == null || users.getId() == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户信息或用户ID不能为空"); } - // 更新用户信息 - int result = usersMapper.updateInfo(users, new UpdateWrapper().set("username", users.getUsername()).set("email", users.getEmail()).set("phone", users.getPhone()).set("avatar", users.getAvatar()).eq("id", users.getId())); + + // 检查用户是否存在 + Users existingUser = getUserByIdAndCheckExist(users.getId()); + if (existingUser == null) { + throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在"); + } + + // 使用ValidateUtil进行实体验证 + ValidateUtil.validateEntity(users, "username", "email"); + + // 更新用户信息,不包含密码更新 + int result = usersMapper.updateInfo(users, new UpdateWrapper() + .set("username", users.getUsername()) + .set("email", users.getEmail()) + .set("phone", users.getPhone()) + .set("avatar", users.getAvatar()) + .eq("id", users.getId())); + if (result <= 0) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新用户信息失败"); } - return ResultUtils.success(); + + logger.info("用户信息更新成功: 用户ID = {}", users.getId()); + return ResultUtils.success(true); + } catch (IllegalArgumentException e) { + // 转换为业务异常 + throw new BusinessException(ErrorCode.INVALID_PARAM, e.getMessage()); + } catch (IllegalAccessException e) { + logger.error("验证用户信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "验证用户信息失败: " + e.getMessage(), e); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + logger.error("更新用户信息失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新用户信息失败: " + e.getMessage(), e); } } // 删除用户 @Override public Result deleteUser(Long id) { + logger.info("删除用户: 用户ID = {}", id); try { if (id == null) { - return ResultUtils.fail(ErrorCode.MISSING_PARAM); + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); } // 检查用户是否存在 Users users = getUserByIdAndCheckExist(id); if (users == null) { - return ResultUtils.fail(ErrorCode.USER_NOT_FOUND); + throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在"); } + int result = usersMapper.deleteById(id); if (result <= 0) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "删除用户失败"); } - return ResultUtils.success(); + + logger.info("用户删除成功: 用户ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + logger.error("删除用户失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "删除用户失败: " + e.getMessage(), e); } } // 查询所有用户 @Override public Result> listAllUsers() { + logger.info("查询所有用户列表"); try { List usersList = usersMapper.selectList(null); - if (usersList == null || usersList.isEmpty()) { - return ResultUtils.fail(ErrorCode.NOT_FOUND); - } + logger.info("查询到 {} 个用户", usersList.size()); return ResultUtils.success(usersList); } catch (Exception e) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + logger.error("查询用户列表失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户列表失败: " + e.getMessage(), e); } } // 分页查询用户 @Override public Result> listUsersByPage(int page, int size) { + logger.info("分页查询用户: 页码 = {}, 每页大小 = {}", page, size); - throw new UnsupportedOperationException("Unimplemented method 'listUsersByPage'"); + try { + // 参数校验 + if (page < 1) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "页码不能小于1"); + } + if (size < 1 || size > 100) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "每页大小必须在1-100之间"); + } + + // 使用MyBatis-Plus的分页功能 + Page userPage = new Page<>(page, size); + Page resultPage = usersMapper.selectPage(userPage, null); + + logger.info("分页查询成功: 共 {} 条记录, 第 {} 页", resultPage.getTotal(), page); + return ResultUtils.success(resultPage.getRecords()); + } catch (BusinessException e) { + throw e; + } catch (Exception e) { + logger.error("分页查询用户失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "分页查询用户失败: " + e.getMessage(), e); + } } // 根据ID查询用户 @Override public Result getUserById(Long id) { + logger.info("根据ID查询用户: 用户ID = {}", id); try { if (id == null) { - return ResultUtils.fail(ErrorCode.MISSING_PARAM); + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); } + Users users = getUserByIdAndCheckExist(id); if (users == null) { - return ResultUtils.fail(ErrorCode.USER_NOT_FOUND); + throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在"); } + return ResultUtils.success(users); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + logger.error("查询用户失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "查询用户失败: " + e.getMessage(), e); } } // 更新用户密码 @Override public Result updatePassword(Long id, String newPassword) { + logger.info("更新用户密码: 用户ID = {}", id); try { - if (id == null || newPassword == null || newPassword.isEmpty()) { - return ResultUtils.fail(ErrorCode.MISSING_PARAM); + if (id == null) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "用户ID不能为空"); } + if (ValidateUtil.isEmpty(newPassword)) { + throw new BusinessException(ErrorCode.MISSING_PARAM, "新密码不能为空"); + } + + // 密码强度校验 + if (newPassword.length() < 6) { + throw new BusinessException(ErrorCode.INVALID_PARAM, "密码长度不能少于6个字符"); + } + Users users = getUserByIdAndCheckExist(id); if (users == null) { - return ResultUtils.fail(ErrorCode.USER_NOT_FOUND); + throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在"); } + // 加密新密码 users.setPassword(new BCryptPasswordEncoder().encode(newPassword)); + // 更新密码 - int result = usersMapper.updateInfo(users, new UpdateWrapper().set("password", users.getPassword()).eq("id", id)); + int result = usersMapper.updateInfo(users, new UpdateWrapper() + .set("password", users.getPassword()) + .eq("id", id)); + if (result <= 0) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + throw new BusinessException(ErrorCode.BUSINESS_ERROR, "更新密码失败"); } - return ResultUtils.success(); + + logger.info("用户密码更新成功: 用户ID = {}", id); + return ResultUtils.success(true); + } catch (BusinessException e) { + throw e; } catch (Exception e) { - return ResultUtils.fail(ErrorCode.DATABASE_ERROR); + logger.error("更新用户密码失败: {}", e.getMessage(), e); + throw new BusinessException(ErrorCode.DATABASE_ERROR, "更新用户密码失败: " + e.getMessage(), e); } } @@ -202,43 +315,4 @@ public class UsersServiceImpl extends ServiceImpl implements return usersMapper.selectOne(queryWrapper); } - /** - * 验证用户信息是否合法且不存在重复 - * - * @param users 用户对象 - * @return 验证失败时返回错误Result,验证成功时返回null - */ - private Result validateUserBeforeCreate(Users users) { - // 检查用户对象是否为空 - if (users == null) { - return ResultUtils.fail(ErrorCode.MISSING_PARAM); - } - // 检查必要字段是否为空 - if (users.getUsername() == null || users.getUsername().isEmpty()) { - return ResultUtils.fail(ErrorCode.MISSING_PARAM); - } - if (users.getEmail() == null || users.getEmail().isEmpty()) { - return ResultUtils.fail(ErrorCode.MISSING_PARAM); - } - if (users.getPassword() == null || users.getPassword().isEmpty()) { - return ResultUtils.fail(ErrorCode.MISSING_PARAM); - } - // 检查用户名是否已存在 - Users existingUserByUsername = usersMapper.selectByUsername(users.getUsername()); - if (existingUserByUsername != null) { - return ResultUtils.fail(ErrorCode.USER_EXISTED); - } - // 检查邮箱是否已存在 - Users existingUserByEmail = usersMapper.selectByEmail(users.getEmail()); - if (existingUserByEmail != null) { - return ResultUtils.fail(ErrorCode.USER_EXISTED); - } - // 检查手机号是否已存在 - Users existingUserByPhone = usersMapper.selectByPhone(users.getPhone()); - if (existingUserByPhone != null) { - return ResultUtils.fail(ErrorCode.USER_EXISTED); - } - return null; // 验证通过 - } - } diff --git a/src/main/java/com/qf/backend/util/JwtUtils.java b/src/main/java/com/qf/backend/util/JwtUtils.java new file mode 100644 index 0000000..5b35185 --- /dev/null +++ b/src/main/java/com/qf/backend/util/JwtUtils.java @@ -0,0 +1,120 @@ +package com.qf.backend.util; + +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import javax.crypto.SecretKey; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; + +/** + * JWT工具类,用于生成和验证token(JJWT 0.12.x 版本) + * 支持 Java 17+ 和 Jakarta EE(Spring Boot 3.x) + */ +@Component +public class JwtUtils { + + @Value("${jwt.secret:default_secret_key_for_development}") + private String secret; + + @Value("${jwt.expiration:3600000}") + private long expiration; + + @Value("${jwt.token-prefix:Bearer}") + private String tokenPrefix; + + /** + * 获取签名密钥 + */ + private SecretKey getSignInKey() { + byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8); + return Keys.hmacShaKeyFor(keyBytes); + } + + /** + * 从token中获取用户名 + */ + public String getUsernameFromToken(String token) { + return getClaimFromToken(token, Claims::getSubject); + } + + /** + * 从token中获取过期时间 + */ + public Date getExpirationDateFromToken(String token) { + return getClaimFromToken(token, Claims::getExpiration); + } + + /** + * 从token中获取指定的claim + */ + public T getClaimFromToken(String token, Function claimsResolver) { + final Claims claims = getAllClaimsFromToken(token); + return claimsResolver.apply(claims); + } + + /** + * 获取token中的所有claims + */ + private Claims getAllClaimsFromToken(String token) { + return Jwts.parser() + .verifyWith(getSignInKey()) + .build() + .parseSignedClaims(token) + .getPayload(); + } + + /** + * 检查token是否过期 + */ + private Boolean isTokenExpired(String token) { + final Date expiration = getExpirationDateFromToken(token); + return expiration.before(new Date()); + } + + /** + * 生成token + */ + public String generateToken(UserDetails userDetails) { + Map claims = new HashMap<>(); + claims.put("authorities", userDetails.getAuthorities()); + return doGenerateToken(claims, userDetails.getUsername()); + } + + /** + * 生成token的核心方法 + */ + private String doGenerateToken(Map claims, String subject) { + return Jwts.builder() + .claims(claims) // 使用新的 claims() 方法 + .subject(subject) // 使用新的 subject() 方法 + .issuedAt(new Date(System.currentTimeMillis())) + .expiration(new Date(System.currentTimeMillis() + expiration)) // 使用新的 expiration() 方法 + .signWith(getSignInKey(), Jwts.SIG.HS256) // 使用新的签名方式 + .compact(); + } + + /** + * 验证token + */ + public Boolean validateToken(String token, UserDetails userDetails) { + final String username = getUsernameFromToken(token); + return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); + } + + /** + * 获取token前缀 + */ + public String getTokenPrefix() { + return tokenPrefix; + } +} \ No newline at end of file diff --git a/src/main/java/com/qf/backend/util/RefundNumberFenerator.java b/src/main/java/com/qf/backend/util/RefundNumberFenerator.java new file mode 100644 index 0000000..674de7b --- /dev/null +++ b/src/main/java/com/qf/backend/util/RefundNumberFenerator.java @@ -0,0 +1,21 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ + +package com.qf.backend.util; + +/** + * 退款单号生成器 + * @author 30803 + */ +public class RefundNumberFenerator { + /** + * 生成退款单号 + * @return 退款单号 + */ + public static String generateRefundNumber() { + // REF + 基于时间戳 + 随机数 / 序列号(最常用) + return "REF" + System.currentTimeMillis() + (int)(Math.random() * 10000); + } +} diff --git a/src/main/java/com/qf/backend/util/ValidateUtil.java b/src/main/java/com/qf/backend/util/ValidateUtil.java index 47182bb..8ee6560 100644 --- a/src/main/java/com/qf/backend/util/ValidateUtil.java +++ b/src/main/java/com/qf/backend/util/ValidateUtil.java @@ -3,10 +3,14 @@ package com.qf.backend.util; import java.lang.reflect.Field; import java.util.HashSet; import java.util.Set; +import java.util.regex.Pattern; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** * 参数验证工具类 * 用于验证字符串是否为空,以及实体类中指定关键字的属性是否为空 + * 还包括手机号和邮箱格式验证功能 */ public class ValidateUtil { @@ -22,7 +26,20 @@ public class ValidateUtil { public static boolean isEmpty(String str) { return str == null || str.trim().isEmpty(); } - + /** + * 验证数据是否为空 + * @param str 待验证的字符串 + * @return 如果字符串为null或空字符串或只包含空白字符,则返回true;否则返回false + */ + public static boolean isEmpty(Object obj) { + if (obj == null) { + return true; + } + if (obj instanceof String) { + return isEmpty((String) obj); + } + return false; + } /** * 检查字符串是否非空 * @param str 待检查的字符串 @@ -33,104 +50,124 @@ public class ValidateUtil { } /** - * 验证字符串非空 - * @param str 待验证的字符串 - * @param paramName 参数名,用于错误提示 - * @throws IllegalArgumentException 如果字符串为空,则抛出异常 + * 验证中国大陆手机号格式 + * @param phone 手机号 + * @return 如果手机号格式正确,则返回true;否则返回false + * @note 支持中国大陆11位手机号,以1开头 */ - public static void validateString(String str, String paramName) { - if (isEmpty(str)) { - throw new IllegalArgumentException(paramName + " cannot be empty or null"); + public static boolean isValidPhone(String phone) { + if (isEmpty(phone)) { + return false; } + // 中国大陆手机号正则表达式:1开头的11位数字 + String regex = "^1[3-9]\\d{9}$"; + return Pattern.matches(regex, phone); } /** - * 验证实体类中与关键字匹配的字符串属性是否为空 + * 验证邮箱格式 + * @param email 邮箱地址 + * @return 如果邮箱格式正确,则返回true;否则返回false + * @note 支持标准邮箱格式,如example@domain.com + */ + public static boolean isValidEmail(String email) { + if (isEmpty(email)) { + return false; + } + // 标准邮箱正则表达式 + String regex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"; + return Pattern.matches(regex, email); + } + + /** + * 验证实体类中与关键字匹配的字符串属性是否为空,以及特殊格式验证 * @param entity 实体对象 * @param keywords 关键字数组,用于匹配属性名 - * @throws IllegalArgumentException 如果实体对象为null,或者匹配的属性值为空,则抛出异常 + * @throws IllegalArgumentException 如果实体对象为null,或者匹配的属性值为空或格式不正确,则抛出异常 * @throws IllegalAccessException 如果反射访问属性失败 * @note 如果未提供关键字,则验证实体类中所有字符串属性都不为空 * @note 如果提供了关键字,则验证实体类中与关键字匹配的字符串属性都不为空 * @note 关键字匹配是不区分大小写的 - * @note 如果实体类中不存在与关键字匹配的字符串属性,则抛出异常 - * @note 如果实体类中存在多个与关键字匹配的字符串属性,只验证第一个匹配的属性 - * @note 如果实体类中存在与关键字匹配的非字符串属性,忽略该属性 + * @note 自动识别手机号相关字段(phone, tel, mobile)并验证格式 + * @note 自动识别邮箱相关字段(email)并验证格式 */ public static void validateEntity(Object entity, String... keywords) throws IllegalAccessException { if (entity == null) { throw new IllegalArgumentException("Entity cannot be null"); } - if (keywords == null || keywords.length == 0) { - // 如果没有提供关键字,则验证实体类中所有字符串属性都不为空 - for (Field field : entity.getClass().getDeclaredFields()) { - // 设置字段可访问 - field.setAccessible(true); - - // 检查字段是否为字符串类型 - if (field.getType() == String.class) { - String fieldValue = (String) field.get(entity); - if (isEmpty(fieldValue)) { - throw new IllegalArgumentException(field.getName() + " cannot be empty or null"); - } - } - } - return; - } - - // 将关键字转换为小写,用于不区分大小写的匹配 - Set keywordSet = new HashSet<>(); - for (String keyword : keywords) { - if (isNotEmpty(keyword)) { - keywordSet.add(keyword.toLowerCase()); - } - } - // 获取实体类的所有字段,包括私有字段 Class clazz = entity.getClass(); Field[] fields = clazz.getDeclaredFields(); - for (Field field : fields) { - // 设置字段可访问 - field.setAccessible(true); - - String fieldName = field.getName().toLowerCase(); - - // 检查字段名是否包含关键字 - for (String keyword : keywordSet) { - if (fieldName.contains(keyword)) { - // 如果是字符串类型,检查是否为空 - if (field.getType() == String.class) { - String fieldValue = (String) field.get(entity); - if (isEmpty(fieldValue)) { - throw new IllegalArgumentException(field.getName() + " cannot be empty or null"); - } - } - break; + // 将关键字转换为小写,用于不区分大小写的匹配 + Set keywordSet = new HashSet<>(); + if (keywords != null && keywords.length > 0) { + for (String keyword : keywords) { + if (isNotEmpty(keyword)) { + keywordSet.add(keyword.toLowerCase()); } } } - } - - /** - * 通用参数验证方法 - * 如果是String类型,直接验证是否为空 - * 如果是实体类,验证其与关键字匹配的属性 - * @param param 参数对象 - * @param keywords 关键字数组 - * @throws IllegalArgumentException 验证失败时抛出异常 - * @throws IllegalAccessException 反射访问失败时抛出异常 - */ - public static void validateParam(Object param, String... keywords) throws IllegalAccessException { - if (param == null) { - throw new IllegalArgumentException("Parameter cannot be null"); + + boolean hasMatchingField = false; + + for (Field field : fields) { + // 设置字段可访问 + field.setAccessible(true); + String fieldName = field.getName().toLowerCase(); + + // 检查是否需要验证此字段 + boolean shouldValidate = false; + if (keywords == null || keywords.length == 0) { + // 如果没有提供关键字,则验证所有字符串属性 + shouldValidate = field.getType() == String.class; + } else { + // 如果提供了关键字,则验证与关键字匹配的属性 + for (String keyword : keywordSet) { + if (fieldName.contains(keyword)) { + shouldValidate = true; + hasMatchingField = true; + break; + } + } + } + + if (shouldValidate && field.getType() == String.class) { + String fieldValue = (String) field.get(entity); + + // 检查是否为空 + if (isEmpty(fieldValue)) { + throw new IllegalArgumentException(field.getName() + " cannot be empty or null"); + } + + // 根据字段名进行特殊格式验证 + if (fieldName.contains("phone") || fieldName.contains("tel") || fieldName.contains("mobile")) { + // 验证手机号格式 + if (!isValidPhone(fieldValue)) { + throw new IllegalArgumentException(field.getName() + " has invalid phone format"); + } + } else if (fieldName.contains("email")) { + // 验证邮箱格式 + if (!isValidEmail(fieldValue)) { + throw new IllegalArgumentException(field.getName() + " has invalid email format"); + } + } + } } - if (param instanceof String) { - validateString((String) param, "parameter"); - } else { - validateEntity(param, keywords); + // 如果提供了关键字但没有匹配的字段,则抛出异常 + if (keywords != null && keywords.length > 0 && !hasMatchingField) { + throw new IllegalArgumentException("No matching fields found for the provided keywords"); + } + } + // 密码加密 + public static String encryptPassword(String password) { + try { + String newpasswrod = new BCryptPasswordEncoder().encode(password); + return newpasswrod; + } catch (Exception e) { + throw new RuntimeException("Password encryption failed", e); } } } diff --git a/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 0000000..44fd426 --- /dev/null +++ b/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,5 @@ +{"properties": [{ + "name": "jwt.expiration", + "type": "java.lang.String", + "description": "A description for 'jwt.expiration'" +}]} \ No newline at end of file diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties new file mode 100644 index 0000000..da43b5f --- /dev/null +++ b/src/main/resources/application-dev.properties @@ -0,0 +1,4 @@ +# JWT 配置 - 开发用(方便调试) +jwt.secret=your_very_strong_secret_key_that_is_at_least_32_characters_long! +jwt.expiration=3600000 +jwt.token-prefix=Bearer \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties new file mode 100644 index 0000000..c0fc115 --- /dev/null +++ b/src/main/resources/application-prod.properties @@ -0,0 +1,4 @@ +# JWT 配置 - 生产用(敏感信息从环境变量读取) +jwt.secret=${JWT_SECRET} +jwt.expiration=${JWT_EXPIRATION:3600000} +jwt.token-prefix=${JWT_TOKEN_PREFIX:Bearer} \ No newline at end of file