mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 02:28:03 +08:00 
			
		
		
		
	钱包,转账 review 修改
This commit is contained in:
		| @ -9,7 +9,7 @@ CREATE TABLE `pay_transfer` | |||||||
|     `app_id`               bigint       NOT NULL COMMENT '应用编号', |     `app_id`               bigint       NOT NULL COMMENT '应用编号', | ||||||
|     `merchant_order_id`    varchar(64)  NOT NULL COMMENT '商户订单编号', |     `merchant_order_id`    varchar(64)  NOT NULL COMMENT '商户订单编号', | ||||||
|     `price`                int          NOT NULL COMMENT '转账金额,单位:分', |     `price`                int          NOT NULL COMMENT '转账金额,单位:分', | ||||||
|     `title`                varchar(512) NOT NULL COMMENT '转账标题', |     `subject`              varchar(512) NOT NULL COMMENT '转账标题', | ||||||
|     `payee_info`           varchar(512) NOT NULL COMMENT '收款人信息,不同类型和渠道不同', |     `payee_info`           varchar(512) NOT NULL COMMENT '收款人信息,不同类型和渠道不同', | ||||||
|     `status`               tinyint      NOT NULL COMMENT '转账状态', |     `status`               tinyint      NOT NULL COMMENT '转账状态', | ||||||
|     `success_time`         datetime     NULL COMMENT '转账成功时间', |     `success_time`         datetime     NULL COMMENT '转账成功时间', | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| package cn.iocoder.yudao.module.pay.api.transfer.dto; | package cn.iocoder.yudao.module.pay.api.transfer.dto; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.validation.InEnum; | ||||||
|  | import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| import javax.validation.constraints.Min; | import javax.validation.constraints.Min; | ||||||
| @ -23,7 +25,7 @@ public class PayTransferCreateReqDTO { | |||||||
|      * 类型 |      * 类型 | ||||||
|      */ |      */ | ||||||
|     @NotNull(message = "转账类型不能为空") |     @NotNull(message = "转账类型不能为空") | ||||||
|     // TODO @jason:枚举的校验 |     @InEnum(PayTransferTypeEnum.class) | ||||||
|     private Integer type; |     private Integer type; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @ -35,14 +37,14 @@ public class PayTransferCreateReqDTO { | |||||||
|     /** |     /** | ||||||
|      * 转账金额,单位:分 |      * 转账金额,单位:分 | ||||||
|      */ |      */ | ||||||
|     // TODO @jason:这个金额是不是非空哈 |  | ||||||
|     @Min(value = 1, message = "转账金额必须大于零") |     @Min(value = 1, message = "转账金额必须大于零") | ||||||
|  |     @NotNull(message = "转账金额不能为空") | ||||||
|     private Integer price; |     private Integer price; | ||||||
|  |  | ||||||
|     // TODO @jason:这个标题,是不是不允许空呀 |  | ||||||
|     /** |     /** | ||||||
|      * 转账标题 |      * 转账标题 | ||||||
|      */ |      */ | ||||||
|  |     @NotEmpty(message = "转账标题不能为空") | ||||||
|     private String title; |     private String title; | ||||||
|  |  | ||||||
|     @NotEmpty(message = "收款方信息不能为空") |     @NotEmpty(message = "收款方信息不能为空") | ||||||
|  | |||||||
| @ -62,6 +62,7 @@ public interface ErrorCodeConstants { | |||||||
|     ErrorCode WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY = new ErrorCode(1_007_008_011, "充值金额和充钱套餐不能同时为空"); |     ErrorCode WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY = new ErrorCode(1_007_008_011, "充值金额和充钱套餐不能同时为空"); | ||||||
|     ErrorCode WALLET_RECHARGE_PACKAGE_NOT_FOUND = new ErrorCode(1_007_008_012, "钱包充值套餐不存在"); |     ErrorCode WALLET_RECHARGE_PACKAGE_NOT_FOUND = new ErrorCode(1_007_008_012, "钱包充值套餐不存在"); | ||||||
|     ErrorCode WALLET_RECHARGE_PACKAGE_IS_DISABLE = new ErrorCode(1_007_008_013, "钱包充值套餐已禁用"); |     ErrorCode WALLET_RECHARGE_PACKAGE_IS_DISABLE = new ErrorCode(1_007_008_013, "钱包充值套餐已禁用"); | ||||||
|  |     ErrorCode WALLET_RECHARGE_PACKAGE_NAME_EXISTS = new ErrorCode(1_007_008_014, "钱包充值套餐名称已存在"); | ||||||
|  |  | ||||||
|     // ========== 转账模块 1-007-009-000 ========== |     // ========== 转账模块 1-007-009-000 ========== | ||||||
|     ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}"); |     ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}"); | ||||||
|  | |||||||
| @ -1,8 +1,11 @@ | |||||||
| package cn.iocoder.yudao.module.pay.enums.member; | package cn.iocoder.yudao.module.pay.enums.member; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 钱包交易业务分类 |  * 钱包交易业务分类 | ||||||
|  * |  * | ||||||
| @ -10,7 +13,7 @@ import lombok.Getter; | |||||||
|  */ |  */ | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
| @Getter | @Getter | ||||||
| public enum PayWalletBizTypeEnum { | public enum PayWalletBizTypeEnum implements IntArrayValuable { | ||||||
|  |  | ||||||
|     RECHARGE(1, "充值"), |     RECHARGE(1, "充值"), | ||||||
|     RECHARGE_REFUND(2, "充值退款"), |     RECHARGE_REFUND(2, "充值退款"), | ||||||
| @ -28,4 +31,10 @@ public enum PayWalletBizTypeEnum { | |||||||
|      */ |      */ | ||||||
|     private final String description; |     private final String description; | ||||||
|  |  | ||||||
|  |     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PayWalletBizTypeEnum::getType).toArray(); | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int[] array() { | ||||||
|  |          return ARRAYS; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,41 @@ | |||||||
|  | package cn.iocoder.yudao.module.pay.enums.transfer; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.util.ArrayUtil; | ||||||
|  | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Getter; | ||||||
|  |  | ||||||
|  | import java.util.Arrays; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 转账类型枚举 | ||||||
|  |  * | ||||||
|  |  * @author jason | ||||||
|  |  */ | ||||||
|  | @AllArgsConstructor | ||||||
|  | @Getter | ||||||
|  | public enum PayTransferTypeEnum implements IntArrayValuable { | ||||||
|  |  | ||||||
|  |     ALIPAY_BALANCE(1, "支付宝余额"), | ||||||
|  |     WX_BALANCE(2, "微信余额"), | ||||||
|  |     BANK_CARD(3, "银行卡"), | ||||||
|  |     WALLET_BALANCE(4, "钱包余额"); | ||||||
|  |  | ||||||
|  |     public static final String ALIPAY_LOGON_ID = "ALIPAY_LOGON_ID"; | ||||||
|  |     public static final String ALIPAY_ACCOUNT_NAME = "ALIPAY_ACCOUNT_NAME"; | ||||||
|  |  | ||||||
|  |     private final Integer type; | ||||||
|  |     private final String name; | ||||||
|  |  | ||||||
|  |     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PayTransferTypeEnum::getType).toArray(); | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int[] array() { | ||||||
|  |         return ARRAYS; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static PayTransferTypeEnum typeOf(Integer type) { | ||||||
|  |         return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -24,6 +24,11 @@ | |||||||
|             <version>${revision}</version> |             <version>${revision}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |  | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>cn.iocoder.boot</groupId> | ||||||
|  |             <artifactId>yudao-module-member-api</artifactId> | ||||||
|  |             <version>${revision}</version> | ||||||
|  |         </dependency> | ||||||
|         <!-- 业务组件 --> |         <!-- 业务组件 --> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>cn.iocoder.boot</groupId> |             <groupId>cn.iocoder.boot</groupId> | ||||||
|  | |||||||
| @ -1,9 +1,12 @@ | |||||||
| package cn.iocoder.yudao.module.pay.api.transfer; | package cn.iocoder.yudao.module.pay.api.transfer; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; | import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; | ||||||
|  | import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||||
|  |  | ||||||
|  | import javax.annotation.Resource; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 转账单 API 实现类 |  * 转账单 API 实现类 | ||||||
|  * |  * | ||||||
| @ -12,11 +15,11 @@ import org.springframework.validation.annotation.Validated; | |||||||
| @Service | @Service | ||||||
| @Validated | @Validated | ||||||
| public class PayTransferApiImpl implements PayTransferApi { | public class PayTransferApiImpl implements PayTransferApi { | ||||||
|  |     @Resource | ||||||
|  |     private PayTransferService payTransferService; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Long createTransfer(PayTransferCreateReqDTO reqDTO) { |     public Long createTransfer(PayTransferCreateReqDTO reqDTO) { | ||||||
|         // TODO @jason:貌似没实现噢 |         return payTransferService.createTransfer(reqDTO); | ||||||
|         return null; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @ -17,11 +17,10 @@ import java.util.Map; | |||||||
| @Data | @Data | ||||||
| public class PayDemoTransferCreateReqVO { | public class PayDemoTransferCreateReqVO { | ||||||
|  |  | ||||||
|     // TODO @jason:这个字段,是不是叫 type 就好了。 |  | ||||||
|     @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |     @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||||||
|     @NotNull(message = "转账类型不能为空") |     @NotNull(message = "转账类型不能为空") | ||||||
|     @InEnum(PayTransferTypeEnum.class) |     @InEnum(PayTransferTypeEnum.class) | ||||||
|     private Integer transferType; |     private Integer type; | ||||||
|  |  | ||||||
|     @NotNull(message = "转账金额不能为空") |     @NotNull(message = "转账金额不能为空") | ||||||
|     @Min(value = 1, message = "转账金额必须大于零") |     @Min(value = 1, message = "转账金额必须大于零") | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ public class PayTransferController { | |||||||
|  |  | ||||||
|     @PostMapping("/submit") |     @PostMapping("/submit") | ||||||
|     @Operation(summary = "提交转账订单") |     @Operation(summary = "提交转账订单") | ||||||
|     // TODO @jason:权限的设置 |     // TODO @jason:权限的设置, 管理后台页面加的时候加一下 | ||||||
|     public CommonResult<PayTransferSubmitRespVO> submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) { |     public CommonResult<PayTransferSubmitRespVO> submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) { | ||||||
|         PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP()); |         PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP()); | ||||||
|         return success(respVO); |         return success(respVO); | ||||||
|  | |||||||
| @ -1,7 +1,12 @@ | |||||||
| package cn.iocoder.yudao.module.pay.controller.admin.wallet; | package cn.iocoder.yudao.module.pay.controller.admin.wallet; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.collection.CollectionUtil; | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||||||
|  | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | ||||||
|  | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||||||
| import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO; | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletPageReqVO; | ||||||
| import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO; | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO; | ||||||
| import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletUserReqVO; | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletUserReqVO; | ||||||
| @ -19,8 +24,14 @@ import org.springframework.web.bind.annotation.RestController; | |||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
| import javax.validation.Valid; | import javax.validation.Valid; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.common.enums.UserTypeEnum.MEMBER; | ||||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||||||
|  |  | ||||||
| @Tag(name = "管理后台 - 用户钱包") | @Tag(name = "管理后台 - 用户钱包") | ||||||
| @RestController | @RestController | ||||||
| @ -31,21 +42,37 @@ public class PayWalletController { | |||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private PayWalletService payWalletService; |     private PayWalletService payWalletService; | ||||||
|  |     @Resource | ||||||
|  |     private MemberUserApi memberUserApi; | ||||||
|  |  | ||||||
|     @GetMapping("/get") |     @GetMapping("/get") | ||||||
|     @PreAuthorize("@ss.hasPermission('pay:wallet:query')") |     @PreAuthorize("@ss.hasPermission('pay:wallet:query')") | ||||||
|     @Operation(summary = "获得用户钱包明细") |     @Operation(summary = "获得用户钱包明细") | ||||||
|     public CommonResult<PayWalletRespVO> getWallet(PayWalletUserReqVO reqVO) { |     public CommonResult<PayWalletRespVO> getWallet(PayWalletUserReqVO reqVO) { | ||||||
|         PayWalletDO wallet = payWalletService.getOrCreateWallet(reqVO.getUserId(), reqVO.getUserType()); |         PayWalletDO wallet = payWalletService.getOrCreateWallet(reqVO.getUserId(), MEMBER.getValue()); | ||||||
|         return success(PayWalletConvert.INSTANCE.convert02(wallet)); |         MemberUserRespDTO memberUser = memberUserApi.getUser(reqVO.getUserId()); | ||||||
|  |         String nickname = memberUser == null ? "" : memberUser.getNickname(); | ||||||
|  |         String avatar = memberUser == null ? "" : memberUser.getAvatar(); | ||||||
|  |         return success(PayWalletConvert.INSTANCE.convert02(nickname, avatar, wallet)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @GetMapping("/page") |     @GetMapping("/page") | ||||||
|     @Operation(summary = "获得会员钱包分页") |     @Operation(summary = "获得会员钱包分页") | ||||||
|     @PreAuthorize("@ss.hasPermission('pay:wallet:query')") |     @PreAuthorize("@ss.hasPermission('pay:wallet:query')") | ||||||
|     public CommonResult<PageResult<PayWalletRespVO>> getWalletPage(@Valid PayWalletPageReqVO pageVO) { |     public CommonResult<PageResult<PayWalletRespVO>> getWalletPage(@Valid PayWalletPageReqVO pageVO) { | ||||||
|         PageResult<PayWalletDO> pageResult = payWalletService.getWalletPage(pageVO); |         if (StrUtil.isNotEmpty(pageVO.getNickname())) { | ||||||
|         return success(PayWalletConvert.INSTANCE.convertPage(pageResult)); |             Set<Long> userIds = CollectionUtils.convertSet(memberUserApi.getUserListByNickname(pageVO.getNickname()), | ||||||
|  |                     MemberUserRespDTO::getId); | ||||||
|  |             pageVO.setUserIds(userIds); | ||||||
|  |         } | ||||||
|  |         //  暂时支持查询 userType 会员类型。管理员类型还不知道使用场景 | ||||||
|  |         PageResult<PayWalletDO> pageResult = payWalletService.getWalletPage(MEMBER.getValue(),pageVO); | ||||||
|  |         if (CollectionUtil.isEmpty(pageResult.getList())) { | ||||||
|  |             return success(new PageResult<>(pageResult.getTotal())); | ||||||
|  |         } | ||||||
|  |         List<Long> userIds = convertList(pageResult.getList(), PayWalletDO::getUserId); | ||||||
|  |         Map<Long, MemberUserRespDTO> userMap = convertMap(memberUserApi.getUserList(userIds),MemberUserRespDTO::getId); | ||||||
|  |         return success(PayWalletConvert.INSTANCE.convertPage(pageResult, userMap)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService; | |||||||
| import io.swagger.v3.oas.annotations.Operation; | import io.swagger.v3.oas.annotations.Operation; | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; | import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.security.access.prepost.PreAuthorize; | ||||||
| import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||||
| import org.springframework.web.bind.annotation.GetMapping; | import org.springframework.web.bind.annotation.GetMapping; | ||||||
| import org.springframework.web.bind.annotation.RequestMapping; | import org.springframework.web.bind.annotation.RequestMapping; | ||||||
| @ -32,7 +33,7 @@ public class PayWalletTransactionController { | |||||||
|  |  | ||||||
|     @GetMapping("/page") |     @GetMapping("/page") | ||||||
|     @Operation(summary = "获得钱包流水分页") |     @Operation(summary = "获得钱包流水分页") | ||||||
|     // TODO @jason:权限校验,缺一个 |     @PreAuthorize("@ss.hasPermission('pay:wallet:query')") | ||||||
|     public CommonResult<PageResult<PayWalletTransactionRespVO>> getWalletTransactionPage( |     public CommonResult<PageResult<PayWalletTransactionRespVO>> getWalletTransactionPage( | ||||||
|             @Valid PayWalletTransactionPageReqVO pageReqVO) { |             @Valid PayWalletTransactionPageReqVO pageReqVO) { | ||||||
|         PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(pageReqVO); |         PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(pageReqVO); | ||||||
|  | |||||||
| @ -20,14 +20,6 @@ public class WalletRechargePackagePageReqVO extends PageParam { | |||||||
|     @Schema(description = "套餐名", example = "李四") |     @Schema(description = "套餐名", example = "李四") | ||||||
|     private String name; |     private String name; | ||||||
|  |  | ||||||
|     // TODO @jason:payPrice 和 bonusPrice 可以去掉。。。一般太少检索啦; |  | ||||||
|  |  | ||||||
|     @Schema(description = "支付金额", example = "16454") |  | ||||||
|     private Integer payPrice; |  | ||||||
|  |  | ||||||
|     @Schema(description = "赠送金额", example = "20887") |  | ||||||
|     private Integer bonusPrice; |  | ||||||
|  |  | ||||||
|     @Schema(description = "状态", example = "2") |     @Schema(description = "状态", example = "2") | ||||||
|     private Integer status; |     private Integer status; | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,12 +1,14 @@ | |||||||
| package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet; | package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |  | ||||||
| import cn.iocoder.yudao.framework.common.validation.InEnum; |  | ||||||
| import lombok.*; |  | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageParam; | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import lombok.Data; | ||||||
|  | import lombok.EqualsAndHashCode; | ||||||
|  | import lombok.ToString; | ||||||
| import org.springframework.format.annotation.DateTimeFormat; | import org.springframework.format.annotation.DateTimeFormat; | ||||||
|  |  | ||||||
| import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||||
|  | import java.util.Collection; | ||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||||||
|  |  | ||||||
| @ -16,12 +18,11 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | |||||||
| @ToString(callSuper = true) | @ToString(callSuper = true) | ||||||
| public class PayWalletPageReqVO extends PageParam { | public class PayWalletPageReqVO extends PageParam { | ||||||
|  |  | ||||||
|     @Schema(description = "用户编号", example = "14138") |     @Schema(description = "用户昵称", example = "李四") | ||||||
|     private Long userId; |     private String nickname; | ||||||
|  |  | ||||||
|     @Schema(description = "用户类型", example = "1") |     @Schema(description = "用户编号", example = "[1,2]") | ||||||
|     @InEnum(UserTypeEnum.class) |     private Collection<Long> userIds; | ||||||
|     private Integer userType; |  | ||||||
|  |  | ||||||
|     @Schema(description = "创建时间") |     @Schema(description = "创建时间") | ||||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||||
|  | |||||||
| @ -19,6 +19,10 @@ public class PayWalletRespVO extends PayWalletBaseVO { | |||||||
|     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|     private LocalDateTime createTime; |     private LocalDateTime createTime; | ||||||
|  |  | ||||||
|     // TODO @jason:要不把用户昵称 + avatar 也读取下? |     @Schema(description = "用户昵称") | ||||||
|  |     private String nickname; | ||||||
|  |  | ||||||
|  |     @Schema(description = "用户头像") | ||||||
|  |     private String avatar; | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,7 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet; | package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |  | ||||||
| import cn.iocoder.yudao.framework.common.validation.InEnum; |  | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| @ -14,10 +12,4 @@ public class PayWalletUserReqVO { | |||||||
|     @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |     @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||||||
|     @NotNull(message = "用户编号不能为空") |     @NotNull(message = "用户编号不能为空") | ||||||
|     private Long userId; |     private Long userId; | ||||||
|  |  | ||||||
|     @Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |  | ||||||
|     @NotNull(message = "用户类型不能为空") |  | ||||||
|     @InEnum(value = UserTypeEnum.class, message = "用户类型必须是 {value}") |  | ||||||
|     private Integer userType; |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ import javax.annotation.Resource; | |||||||
| import javax.validation.Valid; | import javax.validation.Valid; | ||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||||
|  | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; | ||||||
| import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; | import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; | ||||||
| import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; | import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType; | ||||||
|  |  | ||||||
| @ -37,7 +38,7 @@ public class AppPayWalletRechargeController { | |||||||
|     public CommonResult<AppPayWalletRechargeCreateRespVO> createWalletRecharge( |     public CommonResult<AppPayWalletRechargeCreateRespVO> createWalletRecharge( | ||||||
|             @Valid  @RequestBody  AppPayWalletRechargeCreateReqVO reqVO) { |             @Valid  @RequestBody  AppPayWalletRechargeCreateReqVO reqVO) { | ||||||
|         PayWalletRechargeDO walletRecharge = walletRechargeService.createWalletRecharge( |         PayWalletRechargeDO walletRecharge = walletRechargeService.createWalletRecharge( | ||||||
|                 getLoginUserId(), getLoginUserType(), reqVO); |                 getLoginUserId(), getLoginUserType(), getClientIP(), reqVO); | ||||||
|         return success(PayWalletRechargeConvert.INSTANCE.convert(walletRecharge)); |         return success(PayWalletRechargeConvert.INSTANCE.convert(walletRecharge)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,7 +3,9 @@ package cn.iocoder.yudao.module.pay.controller.app.wallet.vo.recharge; | |||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
|  | import javax.validation.constraints.AssertTrue; | ||||||
| import javax.validation.constraints.Min; | import javax.validation.constraints.Min; | ||||||
|  | import java.util.Objects; | ||||||
|  |  | ||||||
| @Schema(description = "用户 APP - 创建钱包充值 Request VO") | @Schema(description = "用户 APP - 创建钱包充值 Request VO") | ||||||
| @Data | @Data | ||||||
| @ -16,6 +18,8 @@ public class AppPayWalletRechargeCreateReqVO { | |||||||
|     @Schema(description = "充值套餐编号", example = "1024") |     @Schema(description = "充值套餐编号", example = "1024") | ||||||
|     private Long packageId; |     private Long packageId; | ||||||
|  |  | ||||||
|     // TODO @jaosn:写个 AssertTrue 的校验方法,payPrice 和 packageId 必须二选一 |     @AssertTrue(message = "充值金额和充钱套餐不能同时为空") | ||||||
|  |     public boolean validatePayPriceAndPackageId() { | ||||||
|  |         return Objects.nonNull(payPrice) || Objects.nonNull(packageId); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,9 +11,9 @@ import org.mapstruct.factory.Mappers; | |||||||
| public interface PayTransferConvert { | public interface PayTransferConvert { | ||||||
|  |  | ||||||
|     PayTransferConvert  INSTANCE = Mappers.getMapper(PayTransferConvert.class); |     PayTransferConvert  INSTANCE = Mappers.getMapper(PayTransferConvert.class); | ||||||
|  |     @Mapping(source = "title", target = "subject") | ||||||
|     PayTransferDO convert(PayTransferCreateReqDTO dto); |     PayTransferDO convert(PayTransferCreateReqDTO dto); | ||||||
|     @Mapping(source = "transferType", target = "type") |  | ||||||
|     PayTransferCreateReqDTO convert(PayDemoTransferCreateReqVO vo); |     PayTransferCreateReqDTO convert(PayDemoTransferCreateReqVO vo); | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,12 +1,16 @@ | |||||||
| package cn.iocoder.yudao.module.pay.convert.wallet; | package cn.iocoder.yudao.module.pay.convert.wallet; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | ||||||
|  | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||||||
| import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO; | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet.PayWalletRespVO; | ||||||
| import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; | import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.wallet.AppPayWalletRespVO; | ||||||
| import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | ||||||
| import org.mapstruct.Mapper; | import org.mapstruct.Mapper; | ||||||
| import org.mapstruct.factory.Mappers; | import org.mapstruct.factory.Mappers; | ||||||
|  |  | ||||||
|  | import java.util.Map; | ||||||
|  |  | ||||||
| @Mapper | @Mapper | ||||||
| public interface PayWalletConvert { | public interface PayWalletConvert { | ||||||
|  |  | ||||||
| @ -14,8 +18,18 @@ public interface PayWalletConvert { | |||||||
|  |  | ||||||
|     AppPayWalletRespVO convert(PayWalletDO bean); |     AppPayWalletRespVO convert(PayWalletDO bean); | ||||||
|  |  | ||||||
|     PayWalletRespVO convert02(PayWalletDO bean); |     PayWalletRespVO convert02(String nickname,String avatar, PayWalletDO bean); | ||||||
|  |  | ||||||
|     PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page); |     PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page); | ||||||
|  |  | ||||||
|  |     default PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page, Map<Long, MemberUserRespDTO> userMap){ | ||||||
|  |         PageResult<PayWalletRespVO> pageResult = convertPage(page); | ||||||
|  |         pageResult.getList().forEach( wallet -> MapUtils.findAndThen(userMap, wallet.getUserId(), | ||||||
|  |                 user -> { | ||||||
|  |                     wallet.setNickname(user.getNickname()); | ||||||
|  |                     wallet.setAvatar(user.getAvatar()); | ||||||
|  |                 })); | ||||||
|  |         return pageResult; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -64,11 +64,11 @@ public class PayTransferDO extends BaseDO { | |||||||
|      * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一 |      * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一 | ||||||
|      */ |      */ | ||||||
|     private String merchantOrderId; |     private String merchantOrderId; | ||||||
|     // TODO @jason:这个字段,要不要改成 subject。。。和 payorderdo 保持一致;哈哈哈,我也忘记为啥当时选了这个名字了。。。 |  | ||||||
|     /** |     /** | ||||||
|      * 转账标题 |      * 转账标题 | ||||||
|      */ |      */ | ||||||
|     private String title; |     private String subject; | ||||||
|  |  | ||||||
|     // ========== 转账相关字段 ========== |     // ========== 转账相关字段 ========== | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ import lombok.Data; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
|  |  | ||||||
| // TODO @jason:转账是不是类似 refund,不用拓展单呀?支付做拓展单的原因,是因为它存在不确定性,可以切换多种;转账和退款,都是明确方式的; | // TODO @jason:转账是不是类似 refund,不用拓展单呀?支付做拓展单的原因,是因为它存在不确定性,可以切换多种;转账和退款,都是明确方式的; | ||||||
|  | // @芋艿 转账是不是也存在多种方式。 例如转账到银行卡。 可以使用微信,也可以使用支付宝。 支付宝账号余额不够,可以切换到微信 | ||||||
| /** | /** | ||||||
|  * 转账拓展单 DO |  * 转账拓展单 DO | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -17,10 +17,10 @@ public interface PayWalletMapper extends BaseMapperX<PayWalletDO> { | |||||||
|                 PayWalletDO::getUserType, userType); |                 PayWalletDO::getUserType, userType); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     default PageResult<PayWalletDO> selectPage(PayWalletPageReqVO reqVO) { |     default PageResult<PayWalletDO> selectPage(Integer userType, PayWalletPageReqVO reqVO) { | ||||||
|         return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletDO>() |         return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletDO>() | ||||||
|                 .eqIfPresent(PayWalletDO::getUserId, reqVO.getUserId()) |                 .inIfPresent(PayWalletDO::getUserId, reqVO.getUserIds()) | ||||||
|                 .eqIfPresent(PayWalletDO::getUserType, reqVO.getUserType()) |                 .eqIfPresent(PayWalletDO::getUserType, userType) | ||||||
|                 .betweenIfPresent(PayWalletDO::getCreateTime, reqVO.getCreateTime()) |                 .betweenIfPresent(PayWalletDO::getCreateTime, reqVO.getCreateTime()) | ||||||
|                 .orderByDesc(PayWalletDO::getId)); |                 .orderByDesc(PayWalletDO::getId)); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -12,14 +12,14 @@ import org.apache.ibatis.annotations.Mapper; | |||||||
| public interface PayWalletRechargePackageMapper extends BaseMapperX<PayWalletRechargePackageDO> { | public interface PayWalletRechargePackageMapper extends BaseMapperX<PayWalletRechargePackageDO> { | ||||||
|  |  | ||||||
|     default PageResult<PayWalletRechargePackageDO> selectPage(WalletRechargePackagePageReqVO reqVO) { |     default PageResult<PayWalletRechargePackageDO> selectPage(WalletRechargePackagePageReqVO reqVO) { | ||||||
|         // TODO @jason:排序按照充值金额 |  | ||||||
|         return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletRechargePackageDO>() |         return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletRechargePackageDO>() | ||||||
|                 .likeIfPresent(PayWalletRechargePackageDO::getName, reqVO.getName()) |                 .likeIfPresent(PayWalletRechargePackageDO::getName, reqVO.getName()) | ||||||
|                 .eqIfPresent(PayWalletRechargePackageDO::getPayPrice, reqVO.getPayPrice()) |  | ||||||
|                 .eqIfPresent(PayWalletRechargePackageDO::getBonusPrice, reqVO.getBonusPrice()) |  | ||||||
|                 .eqIfPresent(PayWalletRechargePackageDO::getStatus, reqVO.getStatus()) |                 .eqIfPresent(PayWalletRechargePackageDO::getStatus, reqVO.getStatus()) | ||||||
|                 .betweenIfPresent(PayWalletRechargePackageDO::getCreateTime, reqVO.getCreateTime()) |                 .betweenIfPresent(PayWalletRechargePackageDO::getCreateTime, reqVO.getCreateTime()) | ||||||
|                 .orderByDesc(PayWalletRechargePackageDO::getId)); |                 .orderByDesc(PayWalletRechargePackageDO::getPayPrice)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     default PayWalletRechargePackageDO selectByName(String name){ | ||||||
|  |         return selectOne(PayWalletRechargePackageDO::getName, name); | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -46,10 +46,10 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { | |||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public Long createDemoTransfer(Long userId, @Valid PayDemoTransferCreateReqVO vo) { |     public Long createDemoTransfer(Long userId, @Valid PayDemoTransferCreateReqVO vo) { | ||||||
|         // 1 校验收款账号 |         // 1 校验收款账号 | ||||||
|         validatePayeeInfo(vo.getTransferType(), vo.getPayeeInfo()); |         validatePayeeInfo(vo.getType(), vo.getPayeeInfo()); | ||||||
|  |  | ||||||
|         // 2 保存示例转账业务表 |         // 2 保存示例转账业务表 | ||||||
|         PayDemoTransferDO demoTransfer = new PayDemoTransferDO().setUserId(userId).setType(vo.getTransferType()) |         PayDemoTransferDO demoTransfer = new PayDemoTransferDO().setUserId(userId).setType(vo.getType()) | ||||||
|                 .setPrice(vo.getPrice()).setPayeeInfo(vo.getPayeeInfo()) |                 .setPrice(vo.getPrice()).setPayeeInfo(vo.getPayeeInfo()) | ||||||
|                 .setTransferStatus(WAITING.getStatus()); |                 .setTransferStatus(WAITING.getStatus()); | ||||||
|         demoTransferMapper.insert(demoTransfer); |         demoTransferMapper.insert(demoTransfer); | ||||||
| @ -65,6 +65,7 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验 |     // TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验 | ||||||
|  |     // @jason payeeinfo 字段确定改一下 | ||||||
|     private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) { |     private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) { | ||||||
|         PayTransferTypeEnum transferTypeEnum = typeOf(transferType); |         PayTransferTypeEnum transferTypeEnum = typeOf(transferType); | ||||||
|         switch (transferTypeEnum) { |         switch (transferTypeEnum) { | ||||||
|  | |||||||
| @ -79,7 +79,7 @@ public class PayTransferServiceImpl implements PayTransferService { | |||||||
|         // 3. 调用三方渠道发起转账 |         // 3. 调用三方渠道发起转账 | ||||||
|         PayTransferUnifiedReqDTO transferUnifiedReq = new PayTransferUnifiedReqDTO() |         PayTransferUnifiedReqDTO transferUnifiedReq = new PayTransferUnifiedReqDTO() | ||||||
|                 .setOutTransferNo(transferExtension.getNo()).setPrice(transfer.getPrice()) |                 .setOutTransferNo(transferExtension.getNo()).setPrice(transfer.getPrice()) | ||||||
|                 .setType(transfer.getType()).setTitle(transfer.getTitle()) |                 .setType(transfer.getType()).setTitle(transfer.getSubject()) | ||||||
|                 .setPayeeInfo(transfer.getPayeeInfo()).setUserIp(userIp) |                 .setPayeeInfo(transfer.getPayeeInfo()).setUserIp(userIp) | ||||||
|                 .setChannelExtras(reqVO.getChannelExtras()); |                 .setChannelExtras(reqVO.getChannelExtras()); | ||||||
|         PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); |         PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| package cn.iocoder.yudao.module.pay.service.wallet; | package cn.iocoder.yudao.module.pay.service.wallet; | ||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.hutool.core.collection.ListUtil; |  | ||||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.rechargepackage.WalletRechargePackageCreateReqVO; | import cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.rechargepackage.WalletRechargePackageCreateReqVO; | ||||||
| @ -14,9 +13,6 @@ import org.springframework.stereotype.Service; | |||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
|  |  | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||||
| import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | ||||||
|  |  | ||||||
| @ -50,6 +46,8 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Long createWalletRechargePackage(WalletRechargePackageCreateReqVO createReqVO) { |     public Long createWalletRechargePackage(WalletRechargePackageCreateReqVO createReqVO) { | ||||||
|  |         // 校验套餐名是否唯一 | ||||||
|  |         validateRechargePackageNameUnique(null, createReqVO.getName()); | ||||||
|         // 插入 |         // 插入 | ||||||
|         PayWalletRechargePackageDO walletRechargePackage = WalletRechargePackageConvert.INSTANCE.convert(createReqVO); |         PayWalletRechargePackageDO walletRechargePackage = WalletRechargePackageConvert.INSTANCE.convert(createReqVO); | ||||||
|         walletRechargePackageMapper.insert(walletRechargePackage); |         walletRechargePackageMapper.insert(walletRechargePackage); | ||||||
| @ -57,16 +55,33 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac | |||||||
|         return walletRechargePackage.getId(); |         return walletRechargePackage.getId(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO @jason:校验下,套餐名唯一 |  | ||||||
|     @Override |     @Override | ||||||
|     public void updateWalletRechargePackage(WalletRechargePackageUpdateReqVO updateReqVO) { |     public void updateWalletRechargePackage(WalletRechargePackageUpdateReqVO updateReqVO) { | ||||||
|         // 校验存在 |         // 校验存在 | ||||||
|         validateWalletRechargePackageExists(updateReqVO.getId()); |         validateWalletRechargePackageExists(updateReqVO.getId()); | ||||||
|  |         // 校验套餐名是否唯一 | ||||||
|  |         validateRechargePackageNameUnique(updateReqVO.getId(), updateReqVO.getName()); | ||||||
|         // 更新 |         // 更新 | ||||||
|         PayWalletRechargePackageDO updateObj = WalletRechargePackageConvert.INSTANCE.convert(updateReqVO); |         PayWalletRechargePackageDO updateObj = WalletRechargePackageConvert.INSTANCE.convert(updateReqVO); | ||||||
|         walletRechargePackageMapper.updateById(updateObj); |         walletRechargePackageMapper.updateById(updateObj); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private void validateRechargePackageNameUnique(Long id, String name) { | ||||||
|  |         if (StrUtil.isBlank(name)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         PayWalletRechargePackageDO rechargePackage = walletRechargePackageMapper.selectByName(name); | ||||||
|  |         if (rechargePackage == null) { | ||||||
|  |             return ; | ||||||
|  |         } | ||||||
|  |         if (id == null) { | ||||||
|  |             throw exception(WALLET_RECHARGE_PACKAGE_NAME_EXISTS); | ||||||
|  |         } | ||||||
|  |         if (!id.equals(rechargePackage.getId())) { | ||||||
|  |             throw exception(WALLET_RECHARGE_PACKAGE_NAME_EXISTS); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void deleteWalletRechargePackage(Long id) { |     public void deleteWalletRechargePackage(Long id) { | ||||||
|         // 校验存在 |         // 校验存在 | ||||||
|  | |||||||
| @ -16,9 +16,10 @@ public interface PayWalletRechargeService { | |||||||
|      * @param userId      用户 id |      * @param userId      用户 id | ||||||
|      * @param userType    用户类型 |      * @param userType    用户类型 | ||||||
|      * @param createReqVO 钱包充值请求 VO |      * @param createReqVO 钱包充值请求 VO | ||||||
|  |      * @param userIp  用户Ip | ||||||
|      * @return 钱包充值记录 |      * @return 钱包充值记录 | ||||||
|      */ |      */ | ||||||
|     PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, |     PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, String userIp, | ||||||
|                                              AppPayWalletRechargeCreateReqVO createReqVO); |                                              AppPayWalletRechargeCreateReqVO createReqVO); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -29,7 +29,6 @@ import static cn.hutool.core.util.ObjectUtil.notEqual; | |||||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||||
| import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; | import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; | ||||||
| import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | ||||||
| import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |  | ||||||
| import static cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert.INSTANCE; | import static cn.iocoder.yudao.module.pay.convert.wallet.PayWalletRechargeConvert.INSTANCE; | ||||||
| import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | ||||||
| import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*; | import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*; | ||||||
| @ -63,13 +62,13 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, |     public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, String userIp, | ||||||
|                                                     AppPayWalletRechargeCreateReqVO reqVO) { |                                                     AppPayWalletRechargeCreateReqVO reqVO) { | ||||||
|         // 1.1 校验参数 TODO @jason:AppPayWalletRechargeCreateReqVO 看下校验; |  | ||||||
|         if (Objects.isNull(reqVO.getPayPrice()) && Objects.isNull(reqVO.getPackageId())) { |         if (Objects.isNull(reqVO.getPayPrice()) && Objects.isNull(reqVO.getPackageId())) { | ||||||
|  |             //  TODO @jason @AssertTrue 貌似没有效果。需要查下原因 | ||||||
|             throw exception(WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY); |             throw exception(WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 1.1 计算充值金额 |         // 1.1 计算充值金额 | ||||||
|         int payPrice; |         int payPrice; | ||||||
|         int bonusPrice = 0; |         int bonusPrice = 0; | ||||||
| @ -87,7 +86,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { | |||||||
|  |  | ||||||
|         // 2.1 创建支付单 |         // 2.1 创建支付单 | ||||||
|         Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() |         Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() | ||||||
|                 .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP()) // TODO @jason:clientIp 从 controller 传递进来噢 |                 .setAppId(WALLET_PAY_APP_ID).setUserIp(userIp) | ||||||
|                 .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号 |                 .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号 | ||||||
|                 .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("") |                 .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("") | ||||||
|                 .setPrice(recharge.getPayPrice()) |                 .setPrice(recharge.getPayPrice()) | ||||||
| @ -181,7 +180,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { | |||||||
|         // 退款失败 |         // 退款失败 | ||||||
|         if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) { |         if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) { | ||||||
|             // 2.2 解冻余额 |             // 2.2 解冻余额 | ||||||
|             payWalletService.unFreezePrice(walletRecharge.getWalletId(), walletRecharge.getTotalPrice()); |             payWalletService.unfreezePrice(walletRecharge.getWalletId(), walletRecharge.getTotalPrice()); | ||||||
|  |  | ||||||
|             updateObj.setRefundStatus(FAILURE.getStatus()); |             updateObj.setRefundStatus(FAILURE.getStatus()); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ public interface PayWalletService { | |||||||
|      * @param pageReqVO 分页查询 |      * @param pageReqVO 分页查询 | ||||||
|      * @return 会员钱包分页 |      * @return 会员钱包分页 | ||||||
|      */ |      */ | ||||||
|     PageResult<PayWalletDO> getWalletPage(PayWalletPageReqVO pageReqVO); |     PageResult<PayWalletDO> getWalletPage(Integer userType, PayWalletPageReqVO pageReqVO); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 钱包订单支付 |      * 钱包订单支付 | ||||||
| @ -90,13 +90,12 @@ public interface PayWalletService { | |||||||
|      */ |      */ | ||||||
|     void freezePrice(Long id, Integer price); |     void freezePrice(Long id, Integer price); | ||||||
|  |  | ||||||
|     // TODO @jason:unfreeze 是单词哈,f 不用大写 |  | ||||||
|     /** |     /** | ||||||
|      * 解冻钱包余额 |      * 解冻钱包余额 | ||||||
|      * |      * | ||||||
|      * @param id    钱包编号 |      * @param id    钱包编号 | ||||||
|      * @param price 解冻金额 |      * @param price 解冻金额 | ||||||
|      */ |      */ | ||||||
|     void unFreezePrice(Long id, Integer price); |     void unfreezePrice(Long id, Integer price); | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -63,8 +63,8 @@ public class PayWalletServiceImpl implements  PayWalletService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public PageResult<PayWalletDO> getWalletPage(PayWalletPageReqVO pageReqVO) { |     public PageResult<PayWalletDO> getWalletPage(Integer userType,PayWalletPageReqVO pageReqVO) { | ||||||
|         return walletMapper.selectPage(pageReqVO); |         return walletMapper.selectPage(userType, pageReqVO); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @ -196,7 +196,7 @@ public class PayWalletServiceImpl implements  PayWalletService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void unFreezePrice(Long id, Integer price) { |     public void unfreezePrice(Long id, Integer price) { | ||||||
|         int updateCounts = walletMapper.unFreezePrice(id, price); |         int updateCounts = walletMapper.unFreezePrice(id, price); | ||||||
|         if (updateCounts == 0) { |         if (updateCounts == 0) { | ||||||
|             throw exception(WALLET_FREEZE_PRICE_NOT_ENOUGH); |             throw exception(WALLET_FREEZE_PRICE_NOT_ENOUGH); | ||||||
|  | |||||||
| @ -12,6 +12,7 @@ import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | |||||||
| import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; | import cn.iocoder.yudao.module.pay.service.wallet.bo.WalletTransactionCreateReqBO; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.validation.annotation.Validated; | ||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
|  |  | ||||||
| @ -22,6 +23,7 @@ import javax.annotation.Resource; | |||||||
|  */ |  */ | ||||||
| @Service | @Service | ||||||
| @Slf4j | @Slf4j | ||||||
|  | @Validated | ||||||
| public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { | public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -1,8 +1,12 @@ | |||||||
| package cn.iocoder.yudao.module.pay.service.wallet.bo; | package cn.iocoder.yudao.module.pay.service.wallet.bo; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.validation.InEnum; | ||||||
| import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
|  | import javax.validation.constraints.NotEmpty; | ||||||
|  | import javax.validation.constraints.NotNull; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 创建钱包流水 BO |  * 创建钱包流水 BO | ||||||
|  * |  * | ||||||
| @ -11,12 +15,11 @@ import lombok.Data; | |||||||
| @Data | @Data | ||||||
| public class WalletTransactionCreateReqBO { | public class WalletTransactionCreateReqBO { | ||||||
|  |  | ||||||
|     // TODO @jason:bo 的话,最好加个参数校验哈; |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 钱包编号 |      * 钱包编号 | ||||||
|      * |      * | ||||||
|      */ |      */ | ||||||
|  |     @NotNull(message = "钱包编号不能为空") | ||||||
|     private Long walletId; |     private Long walletId; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @ -24,11 +27,13 @@ public class WalletTransactionCreateReqBO { | |||||||
|      * |      * | ||||||
|      * 正值表示余额增加,负值表示余额减少 |      * 正值表示余额增加,负值表示余额减少 | ||||||
|      */ |      */ | ||||||
|  |     @NotNull(message = "交易金额不能为空") | ||||||
|     private Integer price; |     private Integer price; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 交易后余额,单位分 |      * 交易后余额,单位分 | ||||||
|      */ |      */ | ||||||
|  |     @NotNull(message = "交易后余额不能为空") | ||||||
|     private Integer balance; |     private Integer balance; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @ -36,15 +41,19 @@ public class WalletTransactionCreateReqBO { | |||||||
|      * |      * | ||||||
|      * 枚举 {@link PayWalletBizTypeEnum#getType()} |      * 枚举 {@link PayWalletBizTypeEnum#getType()} | ||||||
|      */ |      */ | ||||||
|  |     @NotNull(message = "关联业务分类不能为空") | ||||||
|  |     @InEnum(PayWalletBizTypeEnum.class) | ||||||
|     private Integer bizType; |     private Integer bizType; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 关联业务编号 |      * 关联业务编号 | ||||||
|      */ |      */ | ||||||
|  |     @NotEmpty(message = "关联业务编号不能为空") | ||||||
|     private String bizId; |     private String bizId; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 流水说明 |      * 流水说明 | ||||||
|      */ |      */ | ||||||
|  |     @NotEmpty(message = "流水说明不能为空") | ||||||
|     private String title; |     private String title; | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 jason
					jason