diff --git a/db/800pjcloudx_wallet.sql b/db/800pjcloudx_wallet.sql index 0493737ae..e32f569cb 100644 --- a/db/800pjcloudx_wallet.sql +++ b/db/800pjcloudx_wallet.sql @@ -212,6 +212,7 @@ CREATE TABLE wallet_rule_transaction after_balance int DEFAULT 0 NOT NULL COMMENT '转换后的金额', balance_multiple int DEFAULT 0 NOT NULL COMMENT '钱包转换百分比', is_refund VARCHAR(64) default '0' not null comment '是否退回', + refund_time datetime default NULL comment '退回时间', create_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', create_time datetime DEFAULT NULL COMMENT '创建时间', update_by varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '修改人', diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletBizEnum.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletBizEnum.java index ba36fb2d7..cb1cad37f 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletBizEnum.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/constant/WalletBizEnum.java @@ -16,6 +16,7 @@ public enum WalletBizEnum { PAYMENT("4", "支付"), REFUND("5", "退款"), TRANSFER_ACCOUNTS("6", "转账"), + TRANSFER_ACCOUNTS_REFUND("7", "转账退款"), ; private final String code; diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/rule/WalletRuleTransactionDto.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/rule/WalletRuleTransactionDto.java index 237859dce..a9f5e9603 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/rule/WalletRuleTransactionDto.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/rule/WalletRuleTransactionDto.java @@ -4,6 +4,8 @@ import com.bsd.pjcloud.admin.api.vo.base.BaseIsIncludeTreeInterface; import com.bsd.pjcloud.wallet.api.entity.rule.WalletRuleTransactionEntity; import lombok.Data; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; @Data @@ -12,9 +14,14 @@ public class WalletRuleTransactionDto extends WalletRuleTransactionEntity implem /** * 树状结构搜索 */ - private List deptIds; private Boolean isInclude = false; + private Long userId; + + private LocalDate[] createTimeList; + + private LocalDate[] refundTimeList; + } diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/rule/WalletRuleTransferAccountsDto.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/rule/WalletRuleTransferAccountsDto.java new file mode 100644 index 000000000..a9f83662c --- /dev/null +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/dto/rule/WalletRuleTransferAccountsDto.java @@ -0,0 +1,25 @@ +package com.bsd.pjcloud.wallet.api.dto.rule; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Data +public class WalletRuleTransferAccountsDto { + + @Schema(description = "用户id") + @NotNull(message = "用户id不能为空") + private Long userId; + + @Schema(description = "源钱包id") + @NotNull(message = "源钱包类型id不能为空") + private Long sourceWalletTypeId; + + @Schema(description = "目标钱包id") + @NotNull(message = "目标钱包类型id不能为空") + private Long targetWalletTypeId; + + @Schema(description = "转换金额") + @NotNull(message = "转换金额不能为空") + private Integer balance; +} diff --git a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/rule/WalletRuleTransactionEntity.java b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/rule/WalletRuleTransactionEntity.java index 8f673add6..3f4f83dbf 100644 --- a/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/rule/WalletRuleTransactionEntity.java +++ b/pjcloud-wallet/pjcloud-wallet-api/src/main/java/com/bsd/pjcloud/wallet/api/entity/rule/WalletRuleTransactionEntity.java @@ -75,6 +75,12 @@ public class WalletRuleTransactionEntity extends Model wrapper = Wrappers.lambdaQuery(); return R.ok(walletRuleTransactionService.page(page, wrapper)); } @Operation(summary = "分页复杂查询", description = "分页复杂查询") - @GetMapping("/page-join") + @PostMapping("/page-join") @PreAuthorize("@pms.hasPermission('wallet_walletRuleTransaction_view')") - public R pageJoin(@ParameterObject Page page, @ParameterObject WalletRuleTransactionDto dto) { + public R pageJoin(@ParameterObject Page page, @RequestBody WalletRuleTransactionDto dto) { DataScope dataScope = DataScope.of().func(DataScopeFuncEnum.ALL); return R.ok(walletRuleTransactionService.scopePageList(page, dto, dataScope)); } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRuleTransactionService.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRuleTransactionService.java index 78b4acc8d..354858a87 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRuleTransactionService.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/WalletRuleTransactionService.java @@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.bsd.pjcloud.common.data.datascope.DataScope; import com.bsd.pjcloud.wallet.api.dto.rule.WalletRuleTransactionDto; +import com.bsd.pjcloud.wallet.api.dto.rule.WalletRuleTransferAccountsDto; import com.bsd.pjcloud.wallet.api.entity.rule.WalletRuleTransactionEntity; import com.bsd.pjcloud.wallet.api.vo.rule.WalletRuleTransactionVo; +import jakarta.validation.Valid; public interface WalletRuleTransactionService extends IService { @@ -14,4 +16,13 @@ public interface WalletRuleTransactionService extends IService scopePageList(Page page, WalletRuleTransactionDto dto, DataScope dataScope); + /** + * 转账 + */ + void transferAccounts(@Valid WalletRuleTransferAccountsDto body); + + /** + * 退回 + */ + void refund(Long id); } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java index 6cdd965c3..aa3417573 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/WalletTransactionServiceImpl.java @@ -120,11 +120,11 @@ public class WalletTransactionServiceImpl extends ServiceImpl() .eq(WalletRuleJoinEntity::getSourceWalletTypeId, sourceWallet.getWalletTypeId()) .eq(WalletRuleJoinEntity::getTargetWalletTypeId, targetWallet.getWalletTypeId()) @@ -181,6 +178,15 @@ public class WalletRuleJoinServiceImpl extends ServiceImpl未配置钱包规则"); } + if (ObjectUtil.equals(walletRuleJoin.getStatus(), YesNoEnum.NO.getCode())) { + // 查询部门 + SysDept sysDept = remoteDeptService.getDeptByDeptId(userInfo.getSysUser().getDeptId()).getData(); + throw new RuntimeException("该用户所属的部门<" + sysDept.getName() + ">未配置未打开"); + } + configVo.setBalanceMultiple(walletRuleJoin.getBalanceMultiple()); + // 计算最大可以转过去的金额 + Long maxTransferBalance = BigDecimal.valueOf(sourceWallet.getTotalRecharge()).multiply(BigDecimal.valueOf(walletRuleJoin.getBalanceMultiple())).divide(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).longValue(); + configVo.setMaxTransferBalance(maxTransferBalance); return configVo; } diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/rule/WalletRuleTransactionServiceImpl.java b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/rule/WalletRuleTransactionServiceImpl.java index 1b67229fd..f12c13945 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/rule/WalletRuleTransactionServiceImpl.java +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/java/com/bsd/pjcloud/wallet/service/impl/rule/WalletRuleTransactionServiceImpl.java @@ -1,18 +1,37 @@ package com.bsd.pjcloud.wallet.service.impl.rule; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bsd.pjcloud.admin.api.feign.RemoteUserService; +import com.bsd.pjcloud.admin.api.utils.DataUtil; +import com.bsd.pjcloud.admin.api.vo.UserVO; +import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum; +import com.bsd.pjcloud.common.core.util.CollectionUtils; import com.bsd.pjcloud.common.data.datascope.DataScope; +import com.bsd.pjcloud.wallet.api.constant.WalletBizEnum; +import com.bsd.pjcloud.wallet.api.constant.WalletTypeEnum; import com.bsd.pjcloud.wallet.api.dto.rule.WalletRuleTransactionDto; +import com.bsd.pjcloud.wallet.api.dto.rule.WalletRuleTransferAccountsDto; import com.bsd.pjcloud.wallet.api.entity.rule.WalletRuleTransactionEntity; +import com.bsd.pjcloud.wallet.api.vo.WalletManageVo; +import com.bsd.pjcloud.wallet.api.vo.rule.WalletRuleJoinUserConfigVo; import com.bsd.pjcloud.wallet.api.vo.rule.WalletRuleTransactionVo; import com.bsd.pjcloud.wallet.mapper.rule.WalletRuleTransactionMapper; +import com.bsd.pjcloud.wallet.service.WalletManageService; +import com.bsd.pjcloud.wallet.service.WalletRuleJoinService; import com.bsd.pjcloud.wallet.service.WalletRuleTransactionService; +import com.bsd.pjcloud.wallet.service.WalletTransactionService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + /** * 钱包转账记录 */ @@ -22,11 +41,95 @@ import org.springframework.validation.annotation.Validated; @Service public class WalletRuleTransactionServiceImpl extends ServiceImpl implements WalletRuleTransactionService { + private final WalletRuleJoinService walletRuleJoinService; + private final WalletManageService walletManageService; + private final WalletTransactionService walletTransactionService; + + private final RemoteUserService userService; + /** * 分页复杂查询 */ @Override public Page scopePageList(Page page, WalletRuleTransactionDto dto, DataScope dataScope) { - return baseMapper.scopePageList(page, dto, dataScope); + Page pageList = baseMapper.scopePageList(page, dto, dataScope); + disposeList(pageList.getRecords(), dto); + return pageList; + } + + /** + * 转账 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void transferAccounts(WalletRuleTransferAccountsDto body) { + // 查询配置 + WalletRuleJoinUserConfigVo userConfig = walletRuleJoinService.userConfig(body.getUserId(), body.getSourceWalletTypeId(), body.getTargetWalletTypeId()); + if (ObjectUtil.isEmpty(userConfig)) return; + WalletRuleTransactionEntity entity = new WalletRuleTransactionEntity(); + int price = userConfig.getSourceWalletBalance() - body.getBalance(); + if (price < 0) { + throw new RuntimeException("源钱包" + userConfig.getSourceWalletTypeName() + "余额不足"); + } + // 查询源饭卡 + if (ObjectUtil.equals(userConfig.getSourceWalletUniqueCode(), WalletTypeEnum.EAT.getCode())) { + if (price < 4000) { + throw new RuntimeException(WalletTypeEnum.EAT.getDesc() + "余额必须留40元用于公午餐"); + } + } + entity.setSourceWalletId(userConfig.getSourceWalletId()); + entity.setTargetWalletId(userConfig.getTargetWalletId()); + entity.setSourceWalletBalance(userConfig.getSourceWalletBalance()); + entity.setTargetWalletBalance(userConfig.getTargetWalletBalance()); + entity.setBalance(body.getBalance()); + entity.setAfterBalance(userConfig.getTargetWalletBalance() + body.getBalance()); + entity.setBalanceMultiple(userConfig.getBalanceMultiple()); + entity.setIsRefund(YesNoEnum.NO.getCode()); + baseMapper.insert(entity); + // 源头钱包扣减 + walletTransactionService.reduceWalletBalance(userConfig.getSourceWalletId(), body.getBalance(), String.valueOf(entity.getId()), WalletBizEnum.TRANSFER_ACCOUNTS); + // 目标钱包增加 + walletTransactionService.addWalletBalance(userConfig.getTargetWalletId(), body.getBalance(), String.valueOf(entity.getId()), WalletBizEnum.TRANSFER_ACCOUNTS); + } + + /** + * 退回 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void refund(Long id) { + // 判断是否已退回 + WalletRuleTransactionEntity detail = baseMapper.selectById(id); + if (ObjectUtil.isEmpty(detail)) throw new RuntimeException("查询不到转账记录"); + if (ObjectUtil.equals(detail.getIsRefund(), YesNoEnum.YES.getCode())) { + throw new RuntimeException("已退回请勿重复操作"); + } + // 判断源钱包余额是否够 + WalletManageVo tragetWallet = walletManageService.join(detail.getTargetWalletId()); + int price = tragetWallet.getBalance() - detail.getBalance(); + if (price < 0) { + throw new RuntimeException("源钱包" + tragetWallet.getWalletTypeName() + "余额不足,无法退回"); + } + // 源头钱包增加 + walletTransactionService.addWalletBalance(detail.getSourceWalletId(), detail.getBalance(), String.valueOf(detail.getId()), WalletBizEnum.TRANSFER_ACCOUNTS_REFUND); + // 目标钱包扣减 + walletTransactionService.reduceWalletBalance(detail.getTargetWalletId(), detail.getBalance(), String.valueOf(detail.getId()), WalletBizEnum.TRANSFER_ACCOUNTS_REFUND); + // 改状态 + WalletRuleTransactionEntity updateObj = new WalletRuleTransactionEntity(); + updateObj.setId(id); + updateObj.setRefundTime(LocalDateTime.now()); + updateObj.setIsRefund(YesNoEnum.YES.getCode()); + baseMapper.updateById(updateObj); + } + + private void disposeList(List list, WalletRuleTransactionDto dto) { + // 用户 + List userIds = list.stream().map(WalletRuleTransactionVo::getUserId).filter(ObjectUtil::isNotEmpty).distinct().toList(); + if (ObjectUtil.isNotEmpty(userIds)) { + List userList = userService.getUserDeptByIds(new ArrayList<>(userIds)).getData(); + if (ObjectUtil.isNotEmpty(userList)) { + DataUtil.convertUserDeptList(list, CollectionUtils.convertMap(userList, UserVO::getUserId)); + } + } } } \ No newline at end of file diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletTransactionMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletTransactionMapper.xml index e0bc3bacc..a3447be01 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletTransactionMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/WalletTransactionMapper.xml @@ -99,10 +99,10 @@ a.del_flag = 0 and a.dept_id is not null - and a.wallet_id = ${dto.walletId} + and a.wallet_id = #{dto.walletId} - and m.wallet_type_id = ${dto.walletTypeId} + and m.wallet_type_id = #{dto.walletTypeId} diff --git a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/rule/WalletRuleTransactionMapper.xml b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/rule/WalletRuleTransactionMapper.xml index f0a0f878b..c09fe7df2 100644 --- a/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/rule/WalletRuleTransactionMapper.xml +++ b/pjcloud-wallet/pjcloud-wallet-biz/src/main/resources/mapper/rule/WalletRuleTransactionMapper.xml @@ -12,6 +12,7 @@ + @@ -30,6 +31,7 @@ a.after_balance, a.balance_multiple, a.is_refund, + a.refund_time, a.create_by, a.create_time, a.update_by, @@ -46,12 +48,21 @@ and a.target_wallet_id = #{dto.targetWalletId} + + and a.is_refund = #{dto.isRefund} + + + and a.create_time between #{dto.createTimeList[0]} and #{dto.createTimeList[1]} + + + and a.refund_time between #{dto.refundTimeList[0]} and #{dto.refundTimeList[1]} + \ No newline at end of file