From c985272d5894c109912294313c7382ec36576612 Mon Sep 17 00:00:00 2001 From: gaoqr <13665037151@163.com> Date: Tue, 12 Aug 2025 16:44:07 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E4=BA=A7=E5=93=81=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E3=80=81=E5=AE=9A=E4=BB=B7=E8=A7=84=E5=88=99=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=AE=8C=E5=96=84=EF=BC=9B2=E3=80=81=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/Assert/AssertUtils.java | 13 ++ .../common/validation/NumberValidator.java | 10 +- .../config/ChenfengPayAutoConfiguration.java | 2 +- .../pay/config/ChenfengPayConfig.java | 19 ++ .../system/enums/ErrorCodeConstants.java | 15 +- .../funds/products/ProductsController.java | 23 +-- .../products/ProductsDetailController.java | 8 +- .../products/vo/product/ProductPageReqVO.java | 18 +- .../products/vo/product/ProductSaveReqVO.java | 2 + .../ProductDetailsPageReqVO.java | 21 +- .../ProductDetailsSaveReqVO.java | 25 ++- .../controller/admin/pay/PayController.java | 20 +- .../pay/vo/PayProductOrderUnifiedReqVO.java | 30 +++ .../admin/pay/vo/PayRechargeOrderReqVO.java | 35 ++++ .../funds/products/ProductsDetailDO.java | 14 +- .../funds/products/ProductsDetailMapper.java | 9 +- .../enums/pay/PayProductChannelCodeEnum.java | 53 +++++ .../funds/products/ProductsDetailService.java | 15 ++ .../products/ProductsDetailServiceImpl.java | 187 +++++++----------- .../funds/products/ProductsServiceImpl.java | 68 ++++--- .../system/service/pay/PayOrderService.java | 19 +- .../service/pay/PayOrderServiceImpl.java | 69 +++++-- .../impl/alipay/AlipayPcPayHandler.java | 8 + .../validation/pay/PayChannelCodeValid.java | 2 +- .../pay/PayProductChannelCodeValid.java | 31 +++ .../pay/PayProductChannelCodeValidator.java | 27 +++ .../validation/products/ProductType.java | 2 +- .../validation/products/TimeUnitValid.java | 32 +++ .../products/TimeUnitValidator.java | 30 +++ 29 files changed, 563 insertions(+), 244 deletions(-) create mode 100644 cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengPayConfig.java create mode 100644 cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductOrderUnifiedReqVO.java create mode 100644 cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayRechargeOrderReqVO.java create mode 100644 cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/PayProductChannelCodeEnum.java create mode 100644 cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayProductChannelCodeValid.java create mode 100644 cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayProductChannelCodeValidator.java create mode 100644 cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/TimeUnitValid.java create mode 100644 cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/TimeUnitValidator.java diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/Assert/AssertUtils.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/Assert/AssertUtils.java index a034cfda2..5c0111c20 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/Assert/AssertUtils.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/util/Assert/AssertUtils.java @@ -1,7 +1,9 @@ package com.cf.imes.framework.common.util.Assert; +import cn.hutool.core.util.ObjectUtil; import com.cf.imes.framework.common.exception.ErrorCode; +import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil; import org.springframework.util.ObjectUtils; import java.util.List; @@ -38,6 +40,12 @@ public class AssertUtils { } } + public static void empty(List array, ErrorCode errorCode, Object... params) { + if (!ObjectUtils.isEmpty(array)) { + throw ServiceExceptionUtil.exception(errorCode, params); + } + } + public static void empty(Object object, ErrorCode errorCode) { if (object != null) { throw exception(errorCode); @@ -64,4 +72,9 @@ public class AssertUtils { } } + public static void notEquals(Object obj1, Object obj2, ErrorCode errorCode) { + if (ObjectUtil.notEqual(obj1, obj2)) { + throw exception(errorCode); + } + } } diff --git a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValidator.java b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValidator.java index da2eb4354..73ea026d3 100644 --- a/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValidator.java +++ b/cf-framework/cf-common/src/main/java/com/cf/imes/framework/common/validation/NumberValidator.java @@ -17,7 +17,7 @@ public class NumberValidator implements ConstraintValidator private static final String GREATER_THAN_ZERO_NOTIFICATION = "%s必须大于0"; - private static final String FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION = "%s长度不合法,总长度不超过8位,小数点后不超过3位"; + private static final String FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION = "%s长度不合法,总长度不超过%d位,小数点后不超过%d位"; private String name; @@ -104,13 +104,13 @@ public class NumberValidator implements ConstraintValidator int integerPartLength = split[0].length(); // 获取小数点后的位数 int fractionalPartLength = 0; - if (split.length > 2) { + if (split.length == 2) { fractionalPartLength = split[1].length(); } // 总位数不超过 8 位,小数点后位数不超过 3 位 if (integerPartLength > integer || fractionalPartLength > fraction) { - return String.format(FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION, name); + return String.format(FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION, name, integer, fraction); } return null; } @@ -131,13 +131,13 @@ public class NumberValidator implements ConstraintValidator int integerPartLength = split[0].length(); // 获取小数点后的位数 int fractionalPartLength = 0; - if (split.length > 2) { + if (split.length == 2) { fractionalPartLength = split[1].length(); } // 总位数不超过 8 位,小数点后位数不超过 3 位 if (integerPartLength > integer || fractionalPartLength > fraction) { - return String.format(FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION, name); + return String.format(FLOAT_NUMBER_LENGTH_ERROR_NOTIFICATION, name, integer, fraction); } return null; } diff --git a/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengPayAutoConfiguration.java b/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengPayAutoConfiguration.java index b769364f3..058fd3d0c 100644 --- a/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengPayAutoConfiguration.java +++ b/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengPayAutoConfiguration.java @@ -12,7 +12,7 @@ import org.springframework.context.annotation.Bean; * @author 晨丰科技 */ @AutoConfiguration -@EnableConfigurationProperties({ChenfengAlipayConfig.class, ChenfengWechatPayConfig.class}) +@EnableConfigurationProperties({ChenfengAlipayConfig.class, ChenfengWechatPayConfig.class, ChenfengPayConfig.class}) public class ChenfengPayAutoConfiguration { @Bean diff --git a/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengPayConfig.java b/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengPayConfig.java new file mode 100644 index 000000000..988734a83 --- /dev/null +++ b/cf-framework/cf-spring-boot-starter-biz-pay/src/main/java/com/cf/imes/framework/pay/config/ChenfengPayConfig.java @@ -0,0 +1,19 @@ +package com.cf.imes.framework.pay.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.time.Duration; + +/** + * @author Gqr + * @since 2025/8/12 15:55 + */ +@ConfigurationProperties(prefix = "chenfeng.pay") +@Data +public class ChenfengPayConfig { + /** + * 支付超时时间 + */ + private Duration payExpireTime = Duration.ofMinutes(5); +} diff --git a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java index adcbfdcc4..b80d160f5 100644 --- a/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java +++ b/cf-module-system/cf-module-system-api/src/main/java/com/cf/imes/module/system/enums/ErrorCodeConstants.java @@ -422,9 +422,9 @@ public class ErrorCodeConstants { public static final ErrorCode INVOICE_TITLE_NO_EXIST = new ErrorCode(1_002_043_009, "发票抬头信息有误,请进行查看"); public static final ErrorCode THIS_INVOICE_IS_FAIL = new ErrorCode(1_002_043_010, "当前发票以开票,无法再次进行开票"); public static final ErrorCode THIS_INVOICE_IS_SUCCESS = new ErrorCode(1_002_043_011, "当前发票已经开票,无法再次进行开票"); - public static final ErrorCode PRODUCTS_IS_EXIST = new ErrorCode(1_002_043_012, "当前名称的产品已存在,无法新增产品"); - public static final ErrorCode PRODUCTS_NO_DELETE = new ErrorCode(1_002_043_013, "当前产品以上架,无法删除,请下架后再删除"); - public static final ErrorCode PRODUCTS_NO_UPDATE = new ErrorCode(1_002_043_014, "当前产品以上架,无法进行修改"); + public static final ErrorCode PRODUCTS_IS_EXIST = new ErrorCode(1_002_043_012, "产品【{}】已存在,请修改产品名称后再次操作"); + public static final ErrorCode PRODUCTS_NO_DELETE = new ErrorCode(1_002_043_013, "当前产品已上架,无法删除,请下架后再删除"); + public static final ErrorCode PRODUCTS_NO_UPDATE = new ErrorCode(1_002_043_014, "当前产品已上架,无法进行修改"); public static final ErrorCode PRODUCTS_DETAIL_NO_UPDATE = new ErrorCode(1_002_043_016, "定价规则对应的产品已上架,无法进行修改"); public static final ErrorCode ADVERTISEMENT_START_TIME_ERROR = new ErrorCode(1_002_043_017, "广告开始时间选择有误,应等于或大于当日"); public static final ErrorCode ADVERTISEMENT_TIME_ERROR = new ErrorCode(1_002_043_018, "时间选择有误,结束时间应大于或等于开始时间"); @@ -441,17 +441,18 @@ public class ErrorCodeConstants { public static final ErrorCode PAY_ORDER_NOTIFY_DATA_PARSE_ERROR = new ErrorCode(1_002_048_003, "解析支付回调数据异常"); public static final ErrorCode PAY_ORDER_STATUS_IS_NOT_WAITING = new ErrorCode(1_002_048_004, "支付订单不处于待支付"); public static final ErrorCode PAY_ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_002_048_005, "发起渠道支付异常,请联系客服"); + public static final ErrorCode PAY_RECHARGE_ORDER_ORGANID_CHECK_ERROR = new ErrorCode(1_002_048_006, "充值目标组织和当前操作人组织不同,发起充值支付失败"); //=========== 产品相关 1-002-045-000 ============ public static final ErrorCode PRODUCTS_NO_EXIST = new ErrorCode(1_002_045_001, "当前产品不存在"); public static final ErrorCode PRODUCTS_DETAIL_NO_EXIST = new ErrorCode(1_002_045_002, "当前产品的规则不存在"); - public static final ErrorCode PRODUCTS_DURATION_NOT_NULL = new ErrorCode(1_002_045_003, "购买方式为时长时,需确定产品时长"); + public static final ErrorCode PRODUCTS_DURATION_NOT_NULL = new ErrorCode(1_002_045_003, "当前购买方式为【时长】,请填写产品时长"); public static final ErrorCode PRODUCTS_OUTPUT_NOT_NULL = new ErrorCode(1_002_045_004, "购买方式为产量时,需确定产量数量"); - public static final ErrorCode PRODUCTS_DETAIL_DURATION_EXIST = new ErrorCode(1_002_045_005, "存在当前时长的产品定价规则"); + public static final ErrorCode PRODUCTS_DETAIL_DURATION_EXIST = new ErrorCode(1_002_045_005, "当前产品下已存在产品时长:【{}】、单位:【{}】的定价规则,请修改后重新操作"); public static final ErrorCode PRODUCTS_DETAIL_OUTPUT_EXIST = new ErrorCode(1_002_045_006, "存在当前产量的产品定价规则"); - public static final ErrorCode PRODUCTS_DURATION_NUM_ERR = new ErrorCode(1_002_045_007, "产品定价规则,时长数据设置有误"); + public static final ErrorCode PRODUCTS_DETAIL_CURRENTPRICE_CALCULATE_ERROR = new ErrorCode(1_002_045_007, "产品现价计算错误,期望价格【{}】"); public static final ErrorCode PRODUCTS_DURATION_INT_ERR = new ErrorCode(1_002_045_008, "产品定价规则:时长必须为整数且大于 0"); - public static final ErrorCode PRODUCTS_DURATION_UNIT_ERR = new ErrorCode(1_002_045_009, "产品定价规则,时长单位设置有误"); + public static final ErrorCode PRODUCTS_OUTPUT_NOT_SUPPORT = new ErrorCode(1_002_045_009, "暂不支持创建购买方式为【产量】的定价规则"); public static final ErrorCode RECHARGE_ACTIVE_NO_EXIST = new ErrorCode(1_002_045_010, "当前赠送金活动不存在"); //=========== 广告相关 1-002-046-000 ============ diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/ProductsController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/ProductsController.java index 9c00ffe4d..afca9b7bd 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/ProductsController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/ProductsController.java @@ -7,6 +7,7 @@ import com.cf.imes.module.system.controller.admin.funds.products.vo.product.Prod import com.cf.imes.module.system.controller.admin.funds.products.vo.product.ProductRespVO; import com.cf.imes.module.system.controller.admin.funds.products.vo.product.ProductSaveReqVO; import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO; +import com.cf.imes.module.system.enums.products.ProductStatusEnum; import com.cf.imes.module.system.service.funds.products.ProductsService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -30,36 +31,36 @@ public class ProductsController { @Resource private ProductsService productsService; - @PostMapping("") + @PutMapping("") @Operation(summary = "新建产品") -// @PreAuthorize("@ss.hasPermission('base:products:create')") + @PreAuthorize("@ss.hasPermission('base:products:create')") public CommonResult createProducts(@RequestParam("productName") String productName) { return success(productsService.create(productName)); } - @PutMapping("") + @PostMapping("") @Operation(summary = "更新产品") -// @PreAuthorize("@ss.hasPermission('base:products:update')") + @PreAuthorize("@ss.hasPermission('base:products:update')") public CommonResult updateProducts(@Valid @RequestBody ProductSaveReqVO updateReqVO) { ProductsDO productsDO = BeanUtils.toBean(updateReqVO, ProductsDO.class); productsService.update(productsDO); return success(true); } - @PutMapping("/freeze") + @PostMapping("/freeze") @Operation(summary = "下架产品") -// @PreAuthorize("@ss.hasPermission('base:products:freeze')") + @PreAuthorize("@ss.hasPermission('base:products:freeze')") public CommonResult freezeProducts(@Valid Long id) { - ProductsDO productsDO = new ProductsDO().setId(id).setStatus(3); + ProductsDO productsDO = new ProductsDO().setId(id).setStatus(ProductStatusEnum.PRODUCT_DELIS.getStatus()); productsService.update(productsDO); return success(true); } - @PutMapping("/melt") + @PostMapping("/melt") @Operation(summary = "上架产品") @PreAuthorize("@ss.hasPermission('base:products:melt')") public CommonResult meltProducts(@Valid Long id) { - ProductsDO productsDO = new ProductsDO().setId(id).setStatus(2); + ProductsDO productsDO = new ProductsDO().setId(id).setStatus(ProductStatusEnum.PRODUCT_UPDATES.getStatus()); productsService.update(productsDO); return success(true); } @@ -75,7 +76,7 @@ public class ProductsController { } @GetMapping("/{id}") - @Operation(summary = "获得产品") + @Operation(summary = "查询产品") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('base:products:query')") public CommonResult getProducts(@PathVariable("id") Long id) { @@ -84,7 +85,7 @@ public class ProductsController { } @GetMapping("/page") - @Operation(summary = "获得产品分页") + @Operation(summary = "查询产品分页") @PreAuthorize("@ss.hasPermission('base:products:query')") public CommonResult> getProductsPage(@Valid ProductPageReqVO pageReqVO) { PageResult pageResult = productsService.getPage(pageReqVO); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/ProductsDetailController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/ProductsDetailController.java index 7151ada69..58455c5c0 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/ProductsDetailController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/ProductsDetailController.java @@ -30,14 +30,14 @@ public class ProductsDetailController { @Resource private ProductsDetailService productDetailsService; - @PostMapping("") + @PutMapping("") @Operation(summary = "新建产品明细") @PreAuthorize("@ss.hasPermission('base:productDetails:create')") public CommonResult createProducts(@Valid @RequestBody ProductDetailsSaveReqVO createReqVO) { return success(productDetailsService.create(createReqVO)); } - @PutMapping("") + @PostMapping("") @Operation(summary = "更新产品明细") @PreAuthorize("@ss.hasPermission('base:productDetails:update')") public CommonResult updateProducts(@Valid @RequestBody ProductDetailsSaveReqVO updateReqVO) { @@ -55,7 +55,7 @@ public class ProductsDetailController { } @GetMapping("/{id}") - @Operation(summary = "获得产品明细") + @Operation(summary = "查询产品明细") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('base:productDetails:query')") public CommonResult> getProducts(@PathVariable("id") Long id) { @@ -64,7 +64,7 @@ public class ProductsDetailController { } @GetMapping("/page") - @Operation(summary = "获得产品明细分页") + @Operation(summary = "查询产品明细分页") @PreAuthorize("@ss.hasPermission('base:productDetails:query')") public CommonResult> getProductsPage(@Valid ProductDetailsPageReqVO pageReqVO) { PageResult pageResult = productDetailsService.getPage(pageReqVO); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductPageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductPageReqVO.java index 798b5ed98..ce375b047 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductPageReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductPageReqVO.java @@ -6,11 +6,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @Schema(description = "管理后台 - 产品表 products Request VO") @Data @@ -24,18 +19,7 @@ public class ProductPageReqVO extends PageParam { @Schema(description = "产品名称", example = "赵六") private String productName; - @Schema(description = "产品状态", example = "0待上架 1已上架 2已下架") + @Schema(description = "产品状态", example = "0") @ProductStatus private Integer status; - - @Schema(description = "软件id", example = "1") - private Long softwareId; - - @Schema(description = "操作时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] updateTime; - - @Schema(description = "是否删除") - private Integer deleted; - } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductSaveReqVO.java index 8208536e4..d4d4fa158 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/product/ProductSaveReqVO.java @@ -1,5 +1,6 @@ package com.cf.imes.module.system.controller.admin.funds.products.vo.product; +import com.cf.imes.module.system.validation.products.ProductStatus; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -17,6 +18,7 @@ public class ProductSaveReqVO { private String productName; @Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED) + @ProductStatus private Integer status; @Schema(description = "软件id", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsPageReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsPageReqVO.java index 53a1d214e..46c834f80 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsPageReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsPageReqVO.java @@ -6,12 +6,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; -import java.time.LocalDateTime; - -import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @Schema(description = "管理后台 - 产品详情表 productDetails Request VO") @Data @@ -23,19 +19,19 @@ public class ProductDetailsPageReqVO extends PageParam { private Long id; @Schema(description = "产品ID", example = "1") - private String productId; + private Long productId; - @Schema(description = "购买方式", example = "购买方式:0时长;1产量") + @Schema(description = "购买方式", example = "0") @ProductType private Integer purchaseType; - @Schema(description = "正常时间", example = "半个月") + @Schema(description = "产品时长", example = "1") private String duration; @Schema(description = "正常产量", example = "") private BigDecimal output; - @Schema(description = "赠送时间", example = "半个月") + @Schema(description = "赠送市场", example = "1") private String giftDuration; @Schema(description = "赠送产量", example = "") @@ -50,14 +46,7 @@ public class ProductDetailsPageReqVO extends PageParam { @Schema(description = "产品现价", example = "80") private BigDecimal currentPrice; - @Schema(description = "是否特惠", example = "是") + @Schema(description = "是否特惠", example = "0") private Boolean isDiscounted; - @Schema(description = "操作时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] updateTime; - - @Schema(description = "是否删除") - private Integer deleted; - } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsSaveReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsSaveReqVO.java index fab847166..b99db46e4 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsSaveReqVO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/funds/products/vo/productDetails/ProductDetailsSaveReqVO.java @@ -1,6 +1,8 @@ package com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails; +import com.cf.imes.framework.common.validation.NumberValid; import com.cf.imes.module.system.validation.products.ProductType; +import com.cf.imes.module.system.validation.products.TimeUnitValid; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -18,35 +20,46 @@ public class ProductDetailsSaveReqVO { @NotNull(message = "产品名称不能为空") private Long productId; - @Schema(description = "购买方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "购买方式:0时长;1产量") + @Schema(description = "购买方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") @NotNull(message = "购买方式不能为空") @ProductType private Integer purchaseType; - @Schema(description = "产品时间,格式:时长值 - 时间单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "1month") + @Schema(description = "产品时间,格式:时长值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private String duration; + @Schema(description = "产品时长单位,0:年、1:月、2:日", example = "1") + @TimeUnitValid + private Integer durationUnit; + @Schema(description = "产品产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "") private BigDecimal output; // - @Schema(description = "赠送时间,格式:时长值 - 时间单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "半个月") + @Schema(description = "赠送时间,格式:时长值 - 时间单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private String giftDuration; + @Schema(description = "赠送时长单位,0:年、1:月、2:日", example = "1") + @TimeUnitValid + private Integer giftDurationUnit; + @Schema(description = "赠送产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "") private BigDecimal giftOutput; @Schema(description = "产品原价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - @NotNull(message = "产品时间不能为空") + @NotNull(message = "产品原价不能为空") + @NumberValid(name = "产品原价") private BigDecimal originalPrice; @Schema(description = "折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.8") + @NumberValid(name = "折扣", integer = 4, fraction = 2) private BigDecimal discount; @Schema(description = "产品现价", requiredMode = Schema.RequiredMode.REQUIRED, example = "80") - @NotNull(message = "产品时间不能为空") + @NotNull(message = "产品现价不能为空") + @NumberValid(name = "产品现价") private BigDecimal currentPrice; - @Schema(description = "是否特惠", requiredMode = Schema.RequiredMode.REQUIRED, example = "是") + @Schema(description = "是否特惠", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") private Boolean isDiscounted; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/PayController.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/PayController.java index f7a3d6c60..277d18a1d 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/PayController.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/PayController.java @@ -2,7 +2,8 @@ package com.cf.imes.module.system.controller.admin.pay; import com.cf.imes.framework.common.pojo.CommonResult; import com.cf.imes.framework.pay.core.client.dto.order.PayOrderRespDTO; -import com.cf.imes.module.system.controller.admin.pay.vo.PayOrderUnifiedReqVO; +import com.cf.imes.module.system.controller.admin.pay.vo.PayProductOrderUnifiedReqVO; +import com.cf.imes.module.system.controller.admin.pay.vo.PayRechargeOrderReqVO; import com.cf.imes.module.system.service.pay.PayOrderService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -36,13 +37,20 @@ public class PayController { @Resource private PayOrderService payOrderService; - @PostMapping() - @Operation(summary = "创建支付订单") - public CommonResult initiatePay(@RequestBody PayOrderUnifiedReqVO payOrderUnifiedReqVO) throws Throwable { - PayOrderRespDTO payOrderRespDTO = payOrderService.initiatePay(payOrderUnifiedReqVO); + @PostMapping("/recharge") + @Operation(summary = "创建充值支付订单") + public CommonResult initiatePay(@RequestBody PayRechargeOrderReqVO payRechargeOrderReqVO) { + PayOrderRespDTO payOrderRespDTO = payOrderService.rechargePay(payRechargeOrderReqVO); return success(payOrderRespDTO); } + @PostMapping("/product") + @Operation(summary = "创建产品支付订单") + public CommonResult initiatePay(@RequestBody PayProductOrderUnifiedReqVO payProductOrderUnifiedReqVO) { + payOrderService.productPay(payProductOrderUnifiedReqVO); + return success(null); + } + @GetMapping("/order/{channelCode}/{outTradeNo}") @Operation(summary = "查询支付订单") public CommonResult queryPayOrder(@PathVariable("outTradeNo") String outTradeNo, @PathVariable("channelCode") int channelCode) { @@ -57,7 +65,7 @@ public class PayController { public String notifyOrder(@PathVariable("channelCode") Integer channelCode, @RequestParam(required = false) Map params, @RequestBody(required = false) String body) { - log.debug("[notifyOrder][channelCode({}) 回调数据({}/{})]", channelCode, params, body); + log.info("[notifyOrder][channelCode({}) 回调数据({}/{})]", channelCode, params, body); payOrderService.doOrderNotify(channelCode, params, body); // 支付接口回调相应必须是"success" return "success"; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductOrderUnifiedReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductOrderUnifiedReqVO.java new file mode 100644 index 000000000..cd9e49a2a --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayProductOrderUnifiedReqVO.java @@ -0,0 +1,30 @@ +package com.cf.imes.module.system.controller.admin.pay.vo; + +import com.cf.imes.module.system.validation.pay.PayProductChannelCodeValid; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 产品支付vo + * + * @author Gqr + * @since 2025/4/15 14:30 + */ +@Data +@Valid +public class PayProductOrderUnifiedReqVO { + /** + * 产品定价规则编号 + */ + @Schema(description = "产品定价规则编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotEmpty(message = "产品定价规则编号不能为空") + private Long productDetailsId; + + @Schema(description = "支付渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @PayProductChannelCodeValid + @NotNull(message = "支付渠道编码不能为空") + private Integer channelCode; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayRechargeOrderReqVO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayRechargeOrderReqVO.java new file mode 100644 index 000000000..20ef60ff5 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/controller/admin/pay/vo/PayRechargeOrderReqVO.java @@ -0,0 +1,35 @@ +package com.cf.imes.module.system.controller.admin.pay.vo; + +import com.cf.imes.module.system.validation.pay.PayChannelCodeValid; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 充值支付vo + * + * @author Gqr + * @since 2025/4/15 14:30 + */ +@Data +@Valid +public class PayRechargeOrderReqVO { + + @Schema(description = "组织编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "组织编号不能为空") + private Long organId; + + @Schema(description = "支付金额,单位:元", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") + @NotNull(message = "支付金额不能为空") + @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") + private BigDecimal price; + + @Schema(description = "支付渠道编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @PayChannelCodeValid + @NotNull(message = "支付渠道编码不能为空") + private Integer channelCode; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/dataobject/funds/products/ProductsDetailDO.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/dataobject/funds/products/ProductsDetailDO.java index f98431cb1..6568d421e 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/dataobject/funds/products/ProductsDetailDO.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/dataobject/funds/products/ProductsDetailDO.java @@ -14,8 +14,8 @@ import java.math.BigDecimal; * * @author 晨丰科技 */ -@TableName("products_detail") -@KeySequence("products_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@TableName("products_details") +@KeySequence("products_details_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -45,6 +45,11 @@ public class ProductsDetailDO extends BaseDO { */ private String duration; + /** + * 产品时长单位 + */ + private Integer durationUnit; + /** * 正常产量,不加赠送产量 */ @@ -56,6 +61,11 @@ public class ProductsDetailDO extends BaseDO { */ private String giftDuration; + /** + * 赠送时间单位 + */ + private Integer giftDurationUnit; + /** * 赠送产量 */ diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/products/ProductsDetailMapper.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/products/ProductsDetailMapper.java index 2e0c40c84..ca0c42019 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/products/ProductsDetailMapper.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/dal/mysql/funds/products/ProductsDetailMapper.java @@ -34,13 +34,14 @@ public interface ProductsDetailMapper extends BaseMapperX { // 时长查重,添加productId为查询条件 - default int selectCountByDuration(String duration, Long productId) { + default int selectCountByDuration(Long productId, Long productDetailId, String duration, Integer durationUnit) { LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX<>(); queryWrapper.eq(ProductsDetailDO::getProductId, productId) - .eq(ProductsDetailDO::getDeleted, false) - .eq(ProductsDetailDO::getDuration, duration); + .eq(ProductsDetailDO::getDeleted, false) + .eq(ProductsDetailDO::getDuration, duration) + .eq(ProductsDetailDO::getDurationUnit, durationUnit) + .neIfPresent(ProductsDetailDO::getId, productDetailId); return Math.toIntExact(selectCount(queryWrapper)); - } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/PayProductChannelCodeEnum.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/PayProductChannelCodeEnum.java new file mode 100644 index 000000000..753a0a7df --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/enums/pay/PayProductChannelCodeEnum.java @@ -0,0 +1,53 @@ +package com.cf.imes.module.system.enums.pay; + +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonCreator; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 产品支付渠道编码 + * + * @author Gqr + * @since 2024/7/5 9:25 + */ +@Getter +@AllArgsConstructor +public enum PayProductChannelCodeEnum { + /** + * 支付宝 + */ + ALIPAY_PC(0), + /** + * 微信 + */ + WECHAT_NATIVE(1), + + /** + * 账户余额 + */ + BALANCE_ONLY(2), + + /** + * 账户余额+支付宝 + */ + BALANCE_AND_ALIPAY(3), + + /** + * 账户余额+微信 + */ + BALANCE_AND_WECHAT(4); + + @EnumValue + private final Integer code; + + @JsonCreator + public static PayProductChannelCodeEnum fromType(Integer type) { + for (PayProductChannelCodeEnum value : values()) { + if (value.getCode().equals(type)) { + return value; + } + } + return null; + } +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsDetailService.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsDetailService.java index 89f1d3750..64f091af7 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsDetailService.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsDetailService.java @@ -6,6 +6,7 @@ import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetai import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO; import jakarta.validation.Valid; + import java.util.List; /** @@ -51,4 +52,18 @@ public interface ProductsDetailService { */ PageResult getPage(ProductDetailsPageReqVO pageReqVO); + /** + * 校验产品明细是否存在 + * + * @param id + * @return + */ + ProductsDetailDO validateProductDetailsExists(Long id); + + /** + * 校验产品是否存在和时效性 + * + * @param productId + */ + void validateProductExist(Long productId); } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsDetailServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsDetailServiceImpl.java index f5eb54dc8..aa94b24a4 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsDetailServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsDetailServiceImpl.java @@ -1,7 +1,7 @@ package com.cf.imes.module.system.service.funds.products; -import cn.hutool.core.util.ObjectUtil; import com.alibaba.nacos.common.utils.StringUtils; +import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil; import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.common.util.Assert.AssertUtils; import com.cf.imes.framework.common.util.object.BeanUtils; @@ -12,15 +12,14 @@ import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO; import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO; import com.cf.imes.module.system.dal.mysql.funds.products.ProductsDetailMapper; import com.cf.imes.module.system.dal.mysql.funds.products.ProductsMapper; -import com.cf.imes.module.system.enums.products.DurationUnitEnum; import com.cf.imes.module.system.enums.products.ProductStatusEnum; import com.cf.imes.module.system.enums.products.ProductsPurchaseTypeEnum; -import com.cf.imes.module.system.util.SnowflakeIdWorker3rd; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import jakarta.annotation.Resource; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.List; import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -41,57 +40,37 @@ public class ProductsDetailServiceImpl implements ProductsDetailService { @Resource private ProductsMapper productsMapper; - @Resource - private SnowflakeIdWorker3rd idWorker; - - - - @Override public Long create(ProductDetailsSaveReqVO createReqVO) { // 校验是否有这个产品 validateProductExist(createReqVO.getProductId()); - if (createReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.DURATION.getStatus())) { - - String duration = createReqVO.getDuration(); - - AssertUtils.notEmpty(duration,PRODUCTS_DURATION_NOT_NULL); - + if (ProductsPurchaseTypeEnum.DURATION.getStatus().equals(createReqVO.getPurchaseType())) { // 校验时长 - duration = checkDuration(duration); - - String giftDuration = null; - if (createReqVO.getGiftDuration() != null) { - giftDuration = checkDuration(createReqVO.getGiftDuration()); + checkDuration(createReqVO.getDuration(), createReqVO.getDurationUnit()); + // 校验赠送时长 + String giftDuration = createReqVO.getGiftDuration(); + if (StringUtils.isNotEmpty(giftDuration)) { + checkDuration(giftDuration, createReqVO.getGiftDurationUnit()); } - createReqVO.setDuration(duration) - .setGiftDuration(giftDuration); - + // 校验现价计算是否正确 + calculateDiscount(createReqVO.getOriginalPrice(), createReqVO.getCurrentPrice(), createReqVO.getDiscount()); // 查询是否有重复的定价 checkProductDetails(createReqVO); } else if (createReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.OUTPUT.getStatus())) { - if (StringUtils.isBlank(createReqVO.getDuration())) { - throw exception(PRODUCTS_OUTPUT_NOT_NULL); - } + // todo 暂不支持产量 + throw exception(PRODUCTS_OUTPUT_NOT_SUPPORT); } - Long id = idWorker.nextId(); - createReqVO.setId(id); - ProductsDetailDO productDetailsDO = BeanUtils.toBean(createReqVO, ProductsDetailDO.class).setId(id); + ProductsDetailDO productDetailsDO = BeanUtils.toBean(createReqVO, ProductsDetailDO.class); productDetailsMapper.insert(productDetailsDO); - return id; - + return productDetailsDO.getId(); } - - - - @Override public void update(ProductDetailsSaveReqVO updateReqVO) { @@ -100,45 +79,25 @@ public class ProductsDetailServiceImpl implements ProductsDetailService { validateProductDetailsExists(updateReqVO.getId()); if (updateReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.DURATION.getStatus())) { - - if (StringUtils.isBlank(updateReqVO.getDuration())) { - throw exception(PRODUCTS_DURATION_NOT_NULL); - } // 校验时长 - String duration = checkDuration(updateReqVO.getDuration()); - String giftDuration = null; - if (updateReqVO.getGiftDuration() != null) { - giftDuration = checkDuration(updateReqVO.getGiftDuration()); + checkDuration(updateReqVO.getDuration(), updateReqVO.getDurationUnit()); + // 校验赠送时长 + String giftDuration = updateReqVO.getGiftDuration(); + if (StringUtils.isNotEmpty(giftDuration)) { + checkDuration(giftDuration, updateReqVO.getGiftDurationUnit()); } - updateReqVO.setDuration(duration).setGiftDuration(giftDuration); + // 校验现价计算是否正确 + calculateDiscount(updateReqVO.getOriginalPrice(), updateReqVO.getCurrentPrice(), updateReqVO.getDiscount()); // 校验同时长是否还有其他的定价规则 checkProductDetails(updateReqVO); - } else if (updateReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.OUTPUT.getStatus())) { - if (StringUtils.isBlank(updateReqVO.getDuration())) { - throw exception(PRODUCTS_OUTPUT_NOT_NULL); - } + // todo 暂不支持产量 + throw exception(PRODUCTS_OUTPUT_NOT_SUPPORT); } - ProductsDetailDO productDetailsDO = BeanUtils.toBean(updateReqVO, ProductsDetailDO.class) - .setDiscount(getZeroBigDecimal(updateReqVO.getDiscount())) - .setOriginalPrice(getZeroBigDecimal(updateReqVO.getOriginalPrice())) - .setIsDiscounted(updateReqVO.getIsDiscounted()); - productDetailsMapper.updateById(productDetailsDO); - } - - - - /** - * value为空返回0.0 - * - * @param value - * @return - */ - private BigDecimal getZeroBigDecimal(BigDecimal value) { - return ObjectUtil.defaultIfNull(value, BigDecimal.ZERO); + productDetailsMapper.updateById(BeanUtils.toBean(updateReqVO, ProductsDetailDO.class)); } @Override @@ -160,12 +119,12 @@ public class ProductsDetailServiceImpl implements ProductsDetailService { @Override public PageResult getPage(ProductDetailsPageReqVO pageReqVO) { - return productDetailsMapper.selectPage(pageReqVO.setDeleted(0)); + return productDetailsMapper.selectPage(pageReqVO); } - - private ProductsDetailDO validateProductDetailsExists(Long id) { + @Override + public ProductsDetailDO validateProductDetailsExists(Long id) { if (id == null) { throw exception(PRODUCTS_DETAIL_NO_EXIST); } @@ -182,75 +141,64 @@ public class ProductsDetailServiceImpl implements ProductsDetailService { } - - - - // 时长校验 - private String checkDuration(String duration){ - - if (duration == null || !duration.contains("-")) { - throw new IllegalArgumentException("格式错误,格式为:时长值-单位,例如 10-月"); - } - - String[] parts = duration.split("-", 2); - String valueStr = parts[0].trim(); - String timeUnit = parts[1].trim(); + /** + * 校验时长 + * + * @param duration + * @param timeUnit + * @return + */ + private void checkDuration(String duration, Integer timeUnit) { + AssertUtils.notEmpty(duration, PRODUCTS_DURATION_NOT_NULL); + AssertUtils.notEmpty(timeUnit, PRODUCTS_DURATION_NOT_NULL); // 校验时长值 - if (valueStr.isEmpty() || !valueStr.matches("^\\d+$")) { + if (!duration.matches("^\\d+$")) { throw exception(PRODUCTS_DURATION_INT_ERR); } - // 去除前导 0 - valueStr = valueStr.replaceFirst("^0+(?!$)", ""); - - int timeValue = Integer.parseInt(valueStr); + int timeValue = Integer.parseInt(duration); if (timeValue <= 0) { throw exception(PRODUCTS_DURATION_INT_ERR); } - - // 校验时间单位 - if (timeUnit.isEmpty() - || !(timeUnit.equals(DurationUnitEnum.YEAR.getName()) - || timeUnit.equals(DurationUnitEnum.MONTH.getName()) - || timeUnit.equals(DurationUnitEnum.DAY.getName()))) { - - throw exception(PRODUCTS_DURATION_UNIT_ERR); - } - - return timeValue + timeUnit; - } - - // 产品存在性校验 - private void validateProductExist(Long productId){ + /** + * 产品是否存在和时效性校验 + * + * @param productId + */ + @Override + public void validateProductExist(Long productId) { ProductsDO productsDO = productsMapper.selectOne(new LambdaQueryWrapperX() .eq(ProductsDO::getId, productId) .eq(ProductsDO::getDeleted, false)); - AssertUtils.notEmpty(productsDO,PRODUCTS_NO_EXIST); + AssertUtils.notEmpty(productsDO, PRODUCTS_NO_EXIST); - if(productsDO.getStatus().equals(ProductStatusEnum.PRODUCT_UPDATES.getStatus())){ + if (productsDO.getStatus().equals(ProductStatusEnum.PRODUCT_UPDATES.getStatus())) { throw exception(PRODUCTS_DETAIL_NO_UPDATE); } - } - - - // 时长/产量去重 - private void checkProductDetails(ProductDetailsSaveReqVO createReqVO){ + /** + * 检查产品下是否有相同时长的规则 + * + * @param createReqVO + */ + private void checkProductDetails(ProductDetailsSaveReqVO createReqVO) { int count; - if (createReqVO.getPurchaseType() == 0){ + if (createReqVO.getPurchaseType() == 0) { + String duration = createReqVO.getDuration(); + Integer durationUnit = createReqVO.getDurationUnit(); // 时长去重 - count = productDetailsMapper.selectCountByDuration(createReqVO.getDuration(), createReqVO.getProductId()); + count = productDetailsMapper.selectCountByDuration(createReqVO.getProductId(), createReqVO.getId(), duration, durationUnit); if (count > 0) { - throw exception(PRODUCTS_DETAIL_DURATION_EXIST); + throw ServiceExceptionUtil.exception(PRODUCTS_DETAIL_DURATION_EXIST, duration, durationUnit); } - }else if (createReqVO.getPurchaseType() == 1){ + } else if (createReqVO.getPurchaseType() == 1) { //产量去重 count = productDetailsMapper.selectCountByOutput(createReqVO.getOutput(), createReqVO.getProductId()); if (count > 0) { @@ -260,6 +208,21 @@ public class ProductsDetailServiceImpl implements ProductsDetailService { } + /** + * 计算折扣是否正确 + * + * @param originalPrice 原价 + * @param currentPrice 当前价格 + * @param discount 折扣(百分比) + */ + private void calculateDiscount(BigDecimal originalPrice, BigDecimal currentPrice, BigDecimal discount) { + // 校验当前价格是否正确 + // 计算期望现价(保留2位小数,四舍五入) + BigDecimal expectedPrice = originalPrice.multiply(discount).setScale(2, RoundingMode.HALF_UP); + if (currentPrice.compareTo(expectedPrice) != 0) { + throw ServiceExceptionUtil.exception(PRODUCTS_DETAIL_CURRENTPRICE_CALCULATE_ERROR, expectedPrice); + } + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsServiceImpl.java index dabfc4062..ae411a861 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/funds/products/ProductsServiceImpl.java @@ -1,6 +1,5 @@ package com.cf.imes.module.system.service.funds.products; - import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.common.util.Assert.AssertUtils; @@ -9,7 +8,7 @@ import com.cf.imes.module.system.controller.admin.funds.products.vo.product.Prod import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO; import com.cf.imes.module.system.dal.mysql.funds.products.ProductsMapper; import com.cf.imes.module.system.enums.products.ProductStatusEnum; -import com.cf.imes.module.system.util.SnowflakeIdWorker3rd; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -27,44 +26,42 @@ import static com.cf.imes.module.system.enums.ErrorCodeConstants.*; */ @Service @Validated -public class ProductsServiceImpl implements ProductsService{ +public class ProductsServiceImpl implements ProductsService { @Resource private ProductsMapper productsMapper; - @Resource - private SnowflakeIdWorker3rd idWorker; - @Override public Long create(String productName) { + // 校验产品名称唯一 + validateProductNameUnique(null, productName); - List productsDOS = productsMapper.selectList(new LambdaQueryWrapperX() - .eq(ProductsDO::getDeleted, false) - .eq(ProductsDO::getProductName, productName) - .select(ProductsDO::getId)); - - AssertUtils.empty(productsDOS,PRODUCTS_IS_EXIST); - - Long id = idWorker.nextId(); - productsMapper.insert( - new ProductsDO() - .setId(id) - .setProductName(productName) - .setStatus(ProductStatusEnum.PRODUCT_WAITING_UPDATES.getStatus()) - .setSoftwareId(0) - ); - return id; + ProductsDO productsDO = new ProductsDO() + .setProductName(productName) + .setStatus(ProductStatusEnum.PRODUCT_WAITING_UPDATES.getStatus()) + .setSoftwareId(0); + productsMapper.insert(productsDO); + return productsDO.getId(); } @Override public void update(ProductsDO updateReqVO) { - Integer status = validateProductPlateExists(updateReqVO.getId()).getStatus(); + Long updateReqVOId = updateReqVO.getId(); + String productName = updateReqVO.getProductName(); + // 目标状态 + Integer updateReqVOStatus = updateReqVO.getStatus(); + // 校验产品是否存在 + Integer status = validateProductPlateExists(updateReqVOId).getStatus(); + // 校验产品名称唯一 + if (StringUtils.isNotEmpty(productName)) { + validateProductNameUnique(updateReqVOId, productName); + } - if(status.equals(ProductStatusEnum.PRODUCT_UPDATES.getStatus())){ + // 当前状态是上架状态 && 目标状态不是下架 的操作提示已上架 + if (ProductStatusEnum.PRODUCT_UPDATES.getStatus().equals(status) && !ProductStatusEnum.isProductDelis(updateReqVOStatus)) { throw exception(PRODUCTS_NO_UPDATE); - } productsMapper.updateById(updateReqVO); @@ -99,8 +96,12 @@ public class ProductsServiceImpl implements ProductsService{ } - - + /** + * 校验产品id是否存在 + * + * @param id + * @return + */ private ProductsDO validateProductPlateExists(Long id) { ProductsDO productsDO = productsMapper.selectOne(new LambdaQueryWrapperX() .eq(ProductsDO::getId, id) @@ -112,6 +113,19 @@ public class ProductsServiceImpl implements ProductsService{ return productsDO; } + /** + * 校验产品名称是否存在 + * + * @param productName + */ + private void validateProductNameUnique(Long productId, String productName) { + List productsDOS = productsMapper.selectList(new LambdaQueryWrapperX() + .eq(ProductsDO::getDeleted, false) + .eq(ProductsDO::getProductName, productName) + .neIfPresent(ProductsDO::getId, productId) + .select(ProductsDO::getId)); + AssertUtils.empty(productsDOS, PRODUCTS_IS_EXIST, productName); + } } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderService.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderService.java index dd0baf224..0bbf8ce29 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderService.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderService.java @@ -1,8 +1,8 @@ package com.cf.imes.module.system.service.pay; -import com.alipay.api.AlipayApiException; import com.cf.imes.framework.pay.core.client.dto.order.PayOrderRespDTO; -import com.cf.imes.module.system.controller.admin.pay.vo.PayOrderUnifiedReqVO; +import com.cf.imes.module.system.controller.admin.pay.vo.PayProductOrderUnifiedReqVO; +import com.cf.imes.module.system.controller.admin.pay.vo.PayRechargeOrderReqVO; import java.util.Map; @@ -14,13 +14,18 @@ import java.util.Map; */ public interface PayOrderService { /** - * 发起支付 + * 产品支付 * - * @param payOrderUnifiedReqVO - * @return - * @throws AlipayApiException + * @param payProductOrderUnifiedReqVO */ - PayOrderRespDTO initiatePay(PayOrderUnifiedReqVO payOrderUnifiedReqVO); + void productPay(PayProductOrderUnifiedReqVO payProductOrderUnifiedReqVO); + + /** + * 账户充值支付 + * + * @param payRechargeOrderReqVO + */ + PayOrderRespDTO rechargePay(PayRechargeOrderReqVO payRechargeOrderReqVO); /** * 查询支付订单支付状态 diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java index ddc77d2e9..afb535953 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/PayOrderServiceImpl.java @@ -10,18 +10,26 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.cf.imes.framework.common.exception.ServiceException; import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants; +import com.cf.imes.framework.common.util.Assert.AssertUtils; import com.cf.imes.framework.common.util.json.JsonUtils; import com.cf.imes.framework.common.util.validation.ValidationUtils; import com.cf.imes.framework.organ.core.context.OrganContextHolder; import com.cf.imes.framework.pay.config.ChenfengAlipayConfig; +import com.cf.imes.framework.pay.config.ChenfengPayConfig; import com.cf.imes.framework.pay.core.client.dto.order.PayOrderRespDTO; import com.cf.imes.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import com.cf.imes.framework.common.exception.PayException; import com.cf.imes.framework.pay.core.enums.order.PayOrderStatusRespEnum; +import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; +import com.cf.imes.module.system.controller.admin.funds.organamount.vo.OrganAmountRespVO; +import com.cf.imes.module.system.controller.admin.pay.vo.PayProductOrderUnifiedReqVO; +import com.cf.imes.module.system.controller.admin.pay.vo.PayRechargeOrderReqVO; +import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO; import com.cf.imes.module.system.enums.pay.PayChannelCodeEnum; +import com.cf.imes.module.system.service.funds.organamount.OrganAmountService; +import com.cf.imes.module.system.service.funds.products.ProductsDetailService; import com.cf.imes.module.system.service.pay.factory.impl.AbstractPayHandler; import com.cf.imes.module.system.service.pay.factory.PayHandlerFactory; -import com.cf.imes.module.system.controller.admin.pay.vo.PayOrderUnifiedReqVO; import com.cf.imes.module.system.dal.dataobject.pay.PayOrderDO; import com.cf.imes.module.system.dal.mysql.pay.PayOrderMapper; import com.cf.imes.module.system.enums.pay.PayOrderStatusEnum; @@ -32,6 +40,8 @@ import org.springframework.validation.annotation.Validated; import jakarta.annotation.Resource; import jakarta.validation.Validator; + +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Map; import java.util.regex.Matcher; @@ -43,6 +53,7 @@ import static com.cf.imes.module.system.enums.ErrorCodeConstants.PAY_ORDER_NOTIF import static com.cf.imes.module.system.enums.ErrorCodeConstants.PAY_ORDER_NOT_EXIST; import static com.cf.imes.module.system.enums.ErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_WAITING; import static com.cf.imes.module.system.enums.ErrorCodeConstants.PAY_ORDER_SUBMIT_CHANNEL_ERROR; +import static com.cf.imes.module.system.enums.ErrorCodeConstants.PAY_RECHARGE_ORDER_ORGANID_CHECK_ERROR; /** * 支付订单接口 实现类 @@ -69,18 +80,43 @@ public class PayOrderServiceImpl implements PayOrderService { @Resource private ChenfengAlipayConfig alipayConfig; - @Override - @Transactional(rollbackFor = Exception.class) - public PayOrderRespDTO initiatePay(PayOrderUnifiedReqVO payOrderUnifiedReqVO) { - // 主动校验一次入参 - ValidationUtils.validate(validator, payOrderUnifiedReqVO); + @Resource + private ChenfengPayConfig payConfig; - Integer channelCode = payOrderUnifiedReqVO.getChannelCode(); + @Resource + private ProductsDetailService productsDetailService; + + @Resource + private OrganAmountService organAmountService; + + @Override + public void productPay(PayProductOrderUnifiedReqVO payProductOrderUnifiedReqVO) { + // 主动校验一次入参 + ValidationUtils.validate(validator, payProductOrderUnifiedReqVO); + + // 校验产品和产品明细 + ProductsDetailDO productsDetailDO = productsDetailService.validateProductDetailsExists(payProductOrderUnifiedReqVO.getProductDetailsId()); + productsDetailService.validateProductExist(productsDetailDO.getProductId()); + + // 查询组织余额信息 + OrganAmountRespVO organAmount = organAmountService.getOrganAmount(SecurityFrameworkUtils.getUserOrganId()); + + } + + @Override + public PayOrderRespDTO rechargePay(PayRechargeOrderReqVO payRechargeOrderReqVO) { + // 主动校验一次入参 + ValidationUtils.validate(validator, payRechargeOrderReqVO); + + // 校验组织名称 + AssertUtils.notEquals(payRechargeOrderReqVO.getOrganId(), SecurityFrameworkUtils.getUserOrganId(), PAY_RECHARGE_ORDER_ORGANID_CHECK_ERROR); + + Integer channelCode = payRechargeOrderReqVO.getChannelCode(); // 获取渠道方处理器 AbstractPayHandler payHandler = payHandlerFactory.getPayHandler(channelCode); // 创建支付订单 - PayOrderDO payOrder = createPayOrder(payOrderUnifiedReqVO); + PayOrderDO payOrder = createPayOrder(payRechargeOrderReqVO.getPrice(), "imes充值", channelCode); payOrderMapper.insert(payOrder); // 发起渠道方支付 @@ -99,23 +135,22 @@ public class PayOrderServiceImpl implements PayOrderService { /** * 创建支付订单 * - * @param payOrderUnifiedReqVO + * @param * @return */ - private PayOrderDO createPayOrder(PayOrderUnifiedReqVO payOrderUnifiedReqVO) { + private PayOrderDO createPayOrder(BigDecimal price, String subject, Integer channelCode) { PayOrderDO payOrderDO = new PayOrderDO(); - // 校验获取组织id - Long organId = validOrganId(); - Long payOrderId = IdUtil.getSnowflake(0, 0).nextId(); + Long organId = SecurityFrameworkUtils.getUserOrganId(); + payOrderDO.setId(payOrderId); payOrderDO.setPayNo(String.format(PAY_ORDER_PREFIX_FORMAT, organId, payOrderId, DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN))); payOrderDO.setStatus(PayOrderStatusEnum.WAITING); - payOrderDO.setExpireTime(payOrderUnifiedReqVO.getExpireTime()); - payOrderDO.setPrice(payOrderUnifiedReqVO.getPrice()); - payOrderDO.setSubject(payOrderUnifiedReqVO.getSubject()); - payOrderDO.setChannelCode(PayChannelCodeEnum.fromType(payOrderUnifiedReqVO.getChannelCode())); + payOrderDO.setExpireTime(LocalDateTime.now().plus(payConfig.getPayExpireTime())); + payOrderDO.setPrice(price); + payOrderDO.setSubject(subject); + payOrderDO.setChannelCode(PayChannelCodeEnum.fromType(channelCode)); payOrderDO.setOrganId(organId); return payOrderDO; } diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/alipay/AlipayPcPayHandler.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/alipay/AlipayPcPayHandler.java index c79a9be8d..04dc6c622 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/alipay/AlipayPcPayHandler.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/service/pay/factory/impl/alipay/AlipayPcPayHandler.java @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.http.HttpUtil; import cn.hutool.http.Method; +import com.alibaba.fastjson.JSON; import com.alipay.api.AlipayApiException; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.domain.AlipayTradePagePayModel; @@ -27,6 +28,7 @@ import jakarta.annotation.Resource; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; +import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.function.Supplier; @@ -60,6 +62,12 @@ public class AlipayPcPayHandler extends AbstractPayHandler { model.setProductCode(alipayConfig.getProductCode()); model.setQrPayMode(alipayConfig.getQrPayMode()); + Map passbackMap = new HashMap<>(); + passbackMap.put("test1", "1"); + passbackMap.put("test2", "2"); + passbackMap.put("test3", outTradeNo); + model.setPassbackParams(JSON.toJSONString(passbackMap)); + // 1.2 构建 AlipayTradePagePayRequest 请求 AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); request.setBizModel(model); diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayChannelCodeValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayChannelCodeValid.java index ebbea1319..fa81325a6 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayChannelCodeValid.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayChannelCodeValid.java @@ -22,7 +22,7 @@ import java.lang.annotation.Target; validatedBy = {PayChannelCodeValidator.class} ) public @interface PayChannelCodeValid { - String message() default "不支持的支付渠道,0:支付宝、1:微信"; + String message() default "不支持的支付渠道"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayProductChannelCodeValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayProductChannelCodeValid.java new file mode 100644 index 000000000..190d7c8c3 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayProductChannelCodeValid.java @@ -0,0 +1,31 @@ +package com.cf.imes.module.system.validation.pay; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 产品支付渠道编码校验注解 + * @author Gqr + * @since 2025/4/18 10:21 + */ +@Target({ + ElementType.FIELD, +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint( + validatedBy = {PayProductChannelCodeValidator.class} +) +public @interface PayProductChannelCodeValid { + String message() default "不支持的支付渠道"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayProductChannelCodeValidator.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayProductChannelCodeValidator.java new file mode 100644 index 000000000..84cf09864 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/pay/PayProductChannelCodeValidator.java @@ -0,0 +1,27 @@ +package com.cf.imes.module.system.validation.pay; + +import cn.hutool.core.util.ObjectUtil; +import com.cf.imes.module.system.enums.pay.PayProductChannelCodeEnum; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +/** + * 产品支付渠道编码校验器 + * + * @author Gqr + * @since 2025/4/18 10:22 + */ +public class PayProductChannelCodeValidator implements ConstraintValidator { + @Override + public boolean isValid(Integer value, ConstraintValidatorContext context) { + if (ObjectUtil.isNull(value)) { + return true; + } + for (PayProductChannelCodeEnum codeEnum : PayProductChannelCodeEnum.values()) { + if (ObjectUtil.equal(codeEnum.getCode(), value)) { + return true; + } + } + return false; + } +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductType.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductType.java index 2e2cf3541..9d9e46bfe 100644 --- a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductType.java +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/ProductType.java @@ -17,7 +17,7 @@ import java.lang.annotation.*; ) public @interface ProductType { - String message() default "购买方式:0 时长;1 产量"; + String message() default "购买方式不合法:0 时长;1 产量"; Class[] groups() default {}; diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/TimeUnitValid.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/TimeUnitValid.java new file mode 100644 index 000000000..26f1fb324 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/TimeUnitValid.java @@ -0,0 +1,32 @@ +package com.cf.imes.module.system.validation.products; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 时长单位校验注解 + * + * @author Gqr + * @since 2025/8/11 14:18 + */ +@Target({ + ElementType.FIELD, +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint( + validatedBy = {TimeUnitValidator.class} +) +public @interface TimeUnitValid { + String message() default "时长单位不合法"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/TimeUnitValidator.java b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/TimeUnitValidator.java new file mode 100644 index 000000000..966dad672 --- /dev/null +++ b/cf-module-system/cf-module-system-biz/src/main/java/com/cf/imes/module/system/validation/products/TimeUnitValidator.java @@ -0,0 +1,30 @@ +package com.cf.imes.module.system.validation.products; + +import cn.hutool.core.util.ObjectUtil; +import com.cf.imes.module.system.enums.products.DurationUnitEnum; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.util.Objects; + +/** + * 时长单位校验器 + * + * @author Gqr + * @since 2025/8/11 14:19 + */ +public class TimeUnitValidator implements ConstraintValidator { + + @Override + public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) { + if (ObjectUtil.isNull(value)) { + return true; + } + for (DurationUnitEnum unitEnum : DurationUnitEnum.values()) { + if (Objects.equals(unitEnum.getStatus(), value)) { + return true; + } + } + return false; + } +}