diff --git a/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/valid/bank/BankValidUtils.java b/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/valid/bank/BankValidUtils.java index 6d57f52..1b13827 100644 --- a/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/valid/bank/BankValidUtils.java +++ b/common-ruoyi/ruoyi-common/src/main/java/com/ruoyi/common/valid/bank/BankValidUtils.java @@ -44,7 +44,7 @@ public class BankValidUtils { try { HttpResponse res = AliHttpUtils.doPost(host, path, method, headers, querys, bodys); BankValidResponseBody body = JSON.parseObject(EntityUtils.toString(res.getEntity()), BankValidResponseBody.class); - + ServiceUtil.assertion(body == null, "调用三要素API失败,返回值为空"); ServiceUtil.assertion(body.getErrorCode() != 0 || body.getResult() == null, "调用三要素API查询失败"); ServiceUtil.assertion(!Objects.equals(body.getResult().getRespCode(), "0"), body.getResult().getRespMsg()); diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/account/domain/enums/AccountType.java b/ruoyi-service/src/main/java/com/ruoyi/bst/account/domain/enums/AccountType.java index 7cc20fc..8c86a4a 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/account/domain/enums/AccountType.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/account/domain/enums/AccountType.java @@ -1,8 +1,12 @@ package com.ruoyi.bst.account.domain.enums; +import com.ruoyi.common.utils.collection.CollectionUtils; import lombok.AllArgsConstructor; import lombok.Getter; +import java.nio.charset.Charset; +import java.util.List; + /** * @author wjh * 2025/4/7 @@ -17,4 +21,14 @@ public enum AccountType { private final String code; private final String name; + + // 离线列表 + public static List offline() { + return CollectionUtils.map(AccountType::getCode, BANK, QR); + } + + // 在线列表 + public static List online() { + return CollectionUtils.map(AccountType::getCode, WX, ALI); + } } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/account/mapper/AccountMapper.xml b/ruoyi-service/src/main/java/com/ruoyi/bst/account/mapper/AccountMapper.xml index 822975c..f9407c4 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/account/mapper/AccountMapper.xml +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/account/mapper/AccountMapper.xml @@ -21,6 +21,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ba.bank_type, ba.create_time, ba.deleted, + su.nick_name as user_name, su.is_real as user_is_real, su.real_phone as user_real_phone, su.real_id_card as user_real_id_card, diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/balanceLog/domain/enums/BalanceLogBstType.java b/ruoyi-service/src/main/java/com/ruoyi/bst/balanceLog/domain/enums/BalanceLogBstType.java index 14bea8a..83a6960 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/balanceLog/domain/enums/BalanceLogBstType.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/balanceLog/domain/enums/BalanceLogBstType.java @@ -9,7 +9,8 @@ import lombok.Getter; @AllArgsConstructor public enum BalanceLogBstType { - ORDER("ORDER", "订单"),; + ORDER("ORDER", "订单"), + WITHDRAW("WITHDRAW", "提现"); private final String code; private final String name; @@ -21,5 +22,5 @@ public enum BalanceLogBstType { return null; } - + } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/domain/vo/BonusStatVO.java b/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/domain/vo/BonusStatVO.java index acc3477..c375331 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/domain/vo/BonusStatVO.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/domain/vo/BonusStatVO.java @@ -13,8 +13,11 @@ public class BonusStatVO { @ApiModelProperty("分成数量") private Integer count; - + @ApiModelProperty("分成总金额") private BigDecimal amount; - + + @ApiModelProperty("未入账金额") + private BigDecimal waitDivideAmount; + } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/mapper/BonusMapper.java b/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/mapper/BonusMapper.java index 4233b62..a8aea0f 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/mapper/BonusMapper.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/mapper/BonusMapper.java @@ -144,4 +144,10 @@ public interface BonusMapper */ List selectDailyStat(@Param("query") BonusQuery query, @Param("keys") List keys); + /** + * 查询待分成金额 + * @param query + * @return + */ + BigDecimal selectSumOfWaitAmount(@Param("query") BonusQuery query); } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/mapper/BonusMapper.xml b/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/mapper/BonusMapper.xml index ef0fd40..be3dff6 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/mapper/BonusMapper.xml +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/mapper/BonusMapper.xml @@ -334,4 +334,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" group by `date` + + diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/service/impl/BonusDashboardImpl.java b/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/service/impl/BonusDashboardImpl.java index 4a77723..abb3c3e 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/service/impl/BonusDashboardImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/bonus/service/impl/BonusDashboardImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.bst.bonus.service.impl; +import java.math.BigDecimal; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; @@ -28,6 +29,9 @@ public class BonusDashboardImpl implements BonusDashboard { if (keys.contains(StatKeys.BONUS_AMOUNT)) { vo.setAmount(MathUtils.dv(bonusMapper.selectSumOfAmount(query))); } + if (keys.contains(StatKeys.BONUS_WAIT_DIVIDE_AMOUNT)) { + vo.setWaitDivideAmount(MathUtils.dv(bonusMapper.selectSumOfWaitAmount(query))); + } return vo; } @@ -35,5 +39,5 @@ public class BonusDashboardImpl implements BonusDashboard { public List selectDailyStat(BonusQuery query, List keys) { return bonusMapper.selectDailyStat(query, keys); } - + } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/Withdraw.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/Withdraw.java index 22293dd..915def7 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/Withdraw.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/Withdraw.java @@ -30,10 +30,17 @@ public class Withdraw extends BaseEntity private Long id; + @Excel(name = "提现单号") + private String no; + @Excel(name = "申请用户ID") @ApiModelProperty("申请用户ID") private Long userId; + @Excel(name = "提现状态") + @ApiModelProperty("提现状态") + private String status; + @Excel(name = "账户ID") @ApiModelProperty("账户ID") @NotBlank(message = "账户ID不允许为空", groups = {ValidGroup.Create.class}) @@ -41,27 +48,22 @@ public class Withdraw extends BaseEntity @Excel(name = "账户类型") @ApiModelProperty("账户类型") - @NotBlank(message = "账户类型不允许为空", groups = {ValidGroup.Create.class}) private String accountType; @Excel(name = "账号") @ApiModelProperty("账号") - @NotBlank(message = "账号不允许为空", groups = {ValidGroup.Create.class}) private String accountNo; @Excel(name = "账号姓名") @ApiModelProperty("账号姓名") - @NotBlank(message = "账号姓名不允许为空", groups = {ValidGroup.Create.class}) private String accountName; @Excel(name = "账户手机号") @ApiModelProperty("账户手机号") - @NotBlank(message = "账户手机号不允许为空", groups = {ValidGroup.Create.class}) private String accountMobile; @Excel(name = "账户身份证号") @ApiModelProperty("账户身份证号") - @NotBlank(message = "账户身份证号不允许为空", groups = {ValidGroup.Create.class}) private String accountIdCard; @Excel(name = "银行名称") diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/WithdrawQuery.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/WithdrawQuery.java index 37fc130..b07090d 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/WithdrawQuery.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/WithdrawQuery.java @@ -1,11 +1,17 @@ package com.ruoyi.bst.withdraw.domain; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.util.List; + /** * @author wjh * 2025/4/7 */ @Data public class WithdrawQuery extends WithdrawVO { + + @ApiModelProperty("状态列表") + private List statusList; } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/dto/WithdrawVerifyDTO.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/dto/WithdrawVerifyDTO.java new file mode 100644 index 0000000..518108f --- /dev/null +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/dto/WithdrawVerifyDTO.java @@ -0,0 +1,33 @@ +package com.ruoyi.bst.withdraw.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * @author wjh + * 2025/4/7 + */ +@Data +public class WithdrawVerifyDTO { + + @ApiModelProperty("提现ID") + @NotNull(message = "提现ID不允许为空") + private Long id; + + @ApiModelProperty("是否通过") + @NotNull(message = "是否通过不允许为空") + private Boolean pass; + + @ApiModelProperty("审核意见") + @Size(max = 200, message = "审核意见不允许超过200个字符") + private String remark; + + @ApiModelProperty("审核人ID") + private Long verifyId; +} diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/enums/WithdrawStatus.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/enums/WithdrawStatus.java new file mode 100644 index 0000000..905ad63 --- /dev/null +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/enums/WithdrawStatus.java @@ -0,0 +1,29 @@ +package com.ruoyi.bst.withdraw.domain.enums; + +import com.ruoyi.common.utils.collection.CollectionUtils; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +/** + * @author wjh + * 2025/4/7 + */ +@Getter +@AllArgsConstructor +public enum WithdrawStatus { + + WAIT_VERIFY("WAIT_VERIFY", "审核中"), + PAYING("PAYING", "打款中"), + SUCCESS("SUCCESS", "已打款"), + REJECTED("REJECTED", "驳回"), + FAILED("FAILED", "打款失败"); + + private final String code; + private final String name; + + public static List canVerify() { + return CollectionUtils.map(WithdrawStatus::getCode, WAIT_VERIFY); + } +} diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/vo/WithdrawAmountVO.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/vo/WithdrawAmountVO.java index 73a4d3b..3d58822 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/vo/WithdrawAmountVO.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/domain/vo/WithdrawAmountVO.java @@ -15,9 +15,18 @@ public class WithdrawAmountVO { @ApiModelProperty("服务费类型") private String type; - @ApiModelProperty("服务费金额") + @ApiModelProperty("到账金额") private BigDecimal amount; + @ApiModelProperty("服务费金额") + private BigDecimal serviceCharge; + @ApiModelProperty("服务费比例") private BigDecimal point; + + @ApiModelProperty("最低提现金额") + private BigDecimal minAmount; + + @ApiModelProperty("最高提现金额") + private BigDecimal maxAmount; } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/mapper/WithdrawMapper.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/mapper/WithdrawMapper.java index 1f7db33..f9191ec 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/mapper/WithdrawMapper.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/mapper/WithdrawMapper.java @@ -38,15 +38,6 @@ public interface WithdrawMapper */ int insertWithdraw(Withdraw withdraw); - /** - * 批量新增提现 - */ - int batchInsert(@Param("list") List list); - - /** - * 批量修改提现 - */ - int batchUpdate(@Param("list") List list); /** * 修改提现 @@ -71,4 +62,9 @@ public interface WithdrawMapper * @return 结果 */ public int deleteWithdrawByIds(Long[] ids); + + /** + * 根据条件更新 + */ + int updateByQuery(@Param("data") Withdraw data, @Param("query") WithdrawQuery query); } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/mapper/WithdrawMapper.xml b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/mapper/WithdrawMapper.xml index e2faee6..9768130 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/mapper/WithdrawMapper.xml +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/mapper/WithdrawMapper.xml @@ -28,6 +28,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" bw.service_point, bw.amount, bw.arrival_amount, + bw.status, + bw.no, su.nick_name as user_name, suv.nick_name as verify_user_name from bst_withdraw bw @@ -40,7 +42,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and bw.user_id = #{query.userId} and bw.account_id = #{query.accountId} and bw.account_type = #{query.accountType} + and bw.status = #{query.status} and bw.account_no like concat('%', #{query.accountNo}, '%') + and bw.no like concat('%', #{query.no}, '%') and bw.account_name like concat('%', #{query.accountName}, '%') and bw.account_mobile like concat('%', #{query.accountMobile}, '%') and bw.account_id_card like concat('%', #{query.accountIdCard}, '%') @@ -52,6 +56,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and su.nick_name like concat('%', #{query.userName}, '%') and suv.nick_name like concat('%', #{query.verifyUserName}, '%') and bw.service_type = #{query.serviceType} + + and bw.status in + + #{item} + + ${query.params.dataScope} @@ -89,6 +99,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" service_point, amount, arrival_amount, + status, + no, #{userId}, @@ -110,6 +122,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{servicePoint}, #{amount}, #{arrivalAmount}, + #{status}, + #{no}, @@ -121,6 +135,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where id = #{data.id} + + update bst_withdraw bw + + + + + + + + user_id = #{data.userId}, account_id = #{data.accountId}, @@ -141,6 +165,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" service_point = #{data.servicePoint}, amount = #{data.amount}, arrival_amount = #{data.arrivalAmount}, + status = #{data.status}, + no = #{data.no}, diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/WithdrawConverter.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/WithdrawConverter.java new file mode 100644 index 0000000..ef4aa95 --- /dev/null +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/WithdrawConverter.java @@ -0,0 +1,16 @@ +package com.ruoyi.bst.withdraw.service; + +import com.ruoyi.bst.withdraw.domain.vo.WithdrawAmountVO; +import com.ruoyi.common.core.domain.vo.UserVO; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author wjh + * 2025/4/7 + */ +public interface WithdrawConverter { + + WithdrawAmountVO calcAmount(UserVO user, BigDecimal amount); +} diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/WithdrawService.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/WithdrawService.java index 9c78b3f..cf8c8c2 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/WithdrawService.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/WithdrawService.java @@ -4,6 +4,7 @@ import java.util.List; import com.ruoyi.bst.withdraw.domain.Withdraw; import com.ruoyi.bst.withdraw.domain.WithdrawVO; import com.ruoyi.bst.withdraw.domain.WithdrawQuery; +import com.ruoyi.bst.withdraw.domain.dto.WithdrawVerifyDTO; /** * 提现Service接口 @@ -60,4 +61,9 @@ public interface WithdrawService * @return 结果 */ public int deleteWithdrawById(Long id); + + /** + * 提现审核 + */ + int verify(WithdrawVerifyDTO dto); } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/impl/WithdrawConverterImpl.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/impl/WithdrawConverterImpl.java new file mode 100644 index 0000000..b4fc014 --- /dev/null +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/impl/WithdrawConverterImpl.java @@ -0,0 +1,65 @@ +package com.ruoyi.bst.withdraw.service.impl; + +import com.ruoyi.bst.withdraw.domain.enums.WithdrawServiceType; +import com.ruoyi.bst.withdraw.domain.vo.WithdrawAmountVO; +import com.ruoyi.bst.withdraw.service.WithdrawConverter; +import com.ruoyi.common.constants.ConfigKeys; +import com.ruoyi.common.core.domain.vo.UserVO; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.MathUtils; +import com.ruoyi.common.utils.ServiceUtil; +import com.ruoyi.system.config.service.ConfigService; +import lombok.Data; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; + +/** + * @author wjh + * 2025/4/7 + */ +@Service +public class WithdrawConverterImpl implements WithdrawConverter { + + @Autowired + private ConfigService configService; + + /** + * 查询提现服务费 + */ + @Override + public WithdrawAmountVO calcAmount(UserVO user, BigDecimal amount) { + if (user == null || amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) { + return null; + } + + String type = user.getWithdrawServiceType(); + BigDecimal value = user.getWithdrawServiceValue(); + ServiceUtil.assertion(StringUtils.isBlank(type), "提现服务费方式为空"); + ServiceUtil.assertion(value == null, "提现服务费为空"); + + BigDecimal minAmount = configService.getDecimal(ConfigKeys.WITHDRAW_MIN_AMOUNT); + BigDecimal maxAmount = configService.getDecimal(ConfigKeys.WITHDRAW_MAX_AMOUNT); + + WithdrawAmountVO vo = new WithdrawAmountVO(); + vo.setType(type); + vo.setMinAmount(minAmount); + vo.setMaxAmount(maxAmount); + + if (WithdrawServiceType.POINT.getCode().equals(type)) { + vo.setPoint(value); + BigDecimal serviceChange = value.multiply(amount).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); + vo.setServiceCharge(serviceChange); + } else if(WithdrawServiceType.FIXED.getCode().equals(type)) { + vo.setServiceCharge(value); + } else { + throw new ServiceException("暂不支持类型为" + type + "的提现服务费方式"); + } + + vo.setAmount(MathUtils.subtractDecimal(amount, vo.getServiceCharge())); + + return vo; + } +} diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/impl/WithdrawServiceImpl.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/impl/WithdrawServiceImpl.java index 8c6bc6e..e24a933 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/impl/WithdrawServiceImpl.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/service/impl/WithdrawServiceImpl.java @@ -1,7 +1,25 @@ package com.ruoyi.bst.withdraw.service.impl; +import java.time.LocalDateTime; import java.util.List; +import java.util.Objects; + +import com.ruoyi.bst.account.domain.AccountVO; +import com.ruoyi.bst.account.domain.enums.AccountType; +import com.ruoyi.bst.account.service.AccountService; +import com.ruoyi.bst.balanceLog.domain.enums.BalanceLogBstType; +import com.ruoyi.bst.withdraw.domain.dto.WithdrawVerifyDTO; +import com.ruoyi.bst.withdraw.domain.enums.WithdrawStatus; +import com.ruoyi.bst.withdraw.domain.vo.WithdrawAmountVO; +import com.ruoyi.bst.withdraw.service.WithdrawConverter; +import com.ruoyi.bst.withdraw.utils.WithdrawUtil; +import com.ruoyi.common.core.domain.vo.UserVO; +import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.MathUtils; +import com.ruoyi.common.utils.ServiceUtil; +import com.ruoyi.common.utils.SnowFlakeUtil; +import com.ruoyi.system.user.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ruoyi.bst.withdraw.mapper.WithdrawMapper; @@ -9,6 +27,7 @@ import com.ruoyi.bst.withdraw.domain.Withdraw; import com.ruoyi.bst.withdraw.domain.WithdrawVO; import com.ruoyi.bst.withdraw.domain.WithdrawQuery; import com.ruoyi.bst.withdraw.service.WithdrawService; +import org.springframework.transaction.support.TransactionTemplate; /** * 提现Service业务层处理 @@ -22,6 +41,17 @@ public class WithdrawServiceImpl implements WithdrawService @Autowired private WithdrawMapper withdrawMapper; + @Autowired + private UserService userService; + + @Autowired + private WithdrawConverter withdrawConverter; + + @Autowired + private AccountService accountService; + @Autowired + private TransactionTemplate transactionTemplate; + /** * 查询提现 * @@ -53,10 +83,59 @@ public class WithdrawServiceImpl implements WithdrawService * @return 结果 */ @Override - public int insertWithdraw(Withdraw withdraw) - { - withdraw.setCreateTime(DateUtils.getNowDate()); - return withdrawMapper.insertWithdraw(withdraw); + public int insertWithdraw(Withdraw withdraw) { + // 获取用户信息 + UserVO user = userService.selectUserById(withdraw.getUserId()); + ServiceUtil.assertion(user == null, "ID为%s的用户不存在", withdraw.getUserId()); + // 获取账户信息 + AccountVO account = accountService.selectAccountById(withdraw.getAccountId()); + ServiceUtil.assertion(account == null, "ID为%s的收款账户不存在", withdraw.getAccountId()); + + // 获取金额 + WithdrawAmountVO amountVo = withdrawConverter.calcAmount(user, withdraw.getAmount()); + ServiceUtil.assertion(amountVo == null, "计算金额出错"); + // 校验金额 + ServiceUtil.assertion(!MathUtils.equals(amountVo.getServiceCharge(), withdraw.getServiceCharge()), "服务费金额发生变化,请刷新后重试"); + ServiceUtil.assertion(!MathUtils.equals(amountVo.getAmount(), withdraw.getArrivalAmount()), "到账金额发生变化,请刷新后重试"); + ServiceUtil.assertion(MathUtils.smallerThan(withdraw.getAmount(), amountVo.getMinAmount()), "提现金额不允许小于最低金额:%s", amountVo.getMinAmount()); + ServiceUtil.assertion(MathUtils.biggerThan(withdraw.getAmount(), amountVo.getMaxAmount()), "提现金额不允许大于最高金额:%s", amountVo.getMaxAmount()); + + // 组装提现数据 + Withdraw data = new Withdraw(); + // 基础 + data.setUserId(withdraw.getUserId()); + data.setCreateTime(DateUtils.getNowDate()); + data.setNo(String.valueOf(SnowFlakeUtil.newId())); + data.setStatus(WithdrawStatus.WAIT_VERIFY.getCode()); + // 账户 + data.setAccountId(withdraw.getAccountId()); + data.setAccountType(account.getType()); + data.setAccountNo(account.getNo()); + data.setAccountName(account.getName()); + data.setAccountMobile(account.getMobile()); + data.setAccountIdCard(account.getIdCard()); + data.setBankName(account.getBankName()); + data.setBankCardName(account.getBankCardName()); + data.setBankType(account.getBankType()); + // 金额 + data.setServiceType(amountVo.getType()); + data.setServiceCharge(amountVo.getServiceCharge()); + data.setServicePoint(amountVo.getPoint()); + data.setAmount(withdraw.getAmount()); + data.setArrivalAmount(amountVo.getAmount()); + Integer result = transactionTemplate.execute(status -> { + int rows = withdrawMapper.insertWithdraw(data); + + if (rows > 0) { + // 扣减用户余额 + int sub = userService.subtractBalance(data.getUserId(), data.getAmount(), BalanceLogBstType.WITHDRAW, data.getId(), "提现申请:" + data.getNo(), true); + ServiceUtil.assertion(sub != 1, "扣减用户余额失败,请检查余额是否充足"); + } + + return rows; + }); + + return result == null ? 0 : result; } /** @@ -94,4 +173,55 @@ public class WithdrawServiceImpl implements WithdrawService { return withdrawMapper.deleteWithdrawById(id); } + + @Override + public int verify(WithdrawVerifyDTO dto) { + WithdrawVO withdraw = selectWithdrawById(dto.getId()); + ServiceUtil.assertion(withdraw == null, "待审核的提现不存在"); + ServiceUtil.assertion(!WithdrawStatus.canVerify().contains(withdraw.getStatus()), "ID为%s的提现当前状态不允许审核", dto.getId()); + + boolean pass = dto.getPass() != null && dto.getPass(); + + Integer result = transactionTemplate.execute(status -> { + Withdraw data = new Withdraw(); + if (pass) { + if (AccountType.offline().contains(withdraw.getAccountType())) { + data.setStatus(WithdrawStatus.SUCCESS.getCode()); + } else { + data.setStatus(WithdrawStatus.PAYING.getCode()); + } + } else { + data.setStatus(WithdrawStatus.REJECTED.getCode()); + } + data.setVerifyUserId(dto.getVerifyId()); + data.setVerifyTime(LocalDateTime.now()); + data.setVerifyRemark(dto.getRemark()); + WithdrawQuery query = new WithdrawQuery(); + query.setId(dto.getId()); + query.setStatusList(WithdrawStatus.canVerify()); + int rows = withdrawMapper.updateByQuery(data, query); + + if (rows > 0 ) { + if (WithdrawStatus.PAYING.getCode().equals(data.getStatus())) { + // TODO 支付中,线上提现打款 + throw new ServiceException("暂未开通线上提现打款"); + } else if (WithdrawStatus.REJECTED.getCode().equals(data.getStatus())) { + // 驳回,恢复用户余额 + int add = userService.addBalance( + withdraw.getUserId(), + withdraw.getAmount(), + BalanceLogBstType.WITHDRAW, + withdraw.getId(), + "提现驳回:" + withdraw.getNo() + ); + ServiceUtil.assertion(add != 1, "恢复用户余额失败"); + } + } + + return rows; + }); + + return result == null ? 0 : result; + } + } diff --git a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/utils/WithdrawUtil.java b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/utils/WithdrawUtil.java index 0fb6e28..98cb277 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/utils/WithdrawUtil.java +++ b/ruoyi-service/src/main/java/com/ruoyi/bst/withdraw/utils/WithdrawUtil.java @@ -16,34 +16,4 @@ import java.math.BigDecimal; */ public class WithdrawUtil { - - /** - * 查询提现服务费 - */ - public static WithdrawAmountVO calcAmount(UserVO user, BigDecimal amount) { - if (user == null || amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) { - return null; - } - - String type = user.getWithdrawServiceType(); - BigDecimal value = user.getWithdrawServiceValue(); - ServiceUtil.assertion(StringUtils.isBlank(type), "提现服务费方式为空"); - ServiceUtil.assertion(value == null, "提现服务费为空"); - - WithdrawAmountVO vo = new WithdrawAmountVO(); - vo.setType(type); - - if (WithdrawServiceType.POINT.getCode().equals(type)) { - vo.setPoint(value); - BigDecimal serviceAmount = value.multiply(amount).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP); - vo.setAmount(serviceAmount); - } else if(WithdrawServiceType.FIXED.getCode().equals(type)) { - vo.setAmount(value); - } else { - throw new ServiceException("暂不支持类型为" + type + "的提现服务费方式"); - } - - return vo; - - } } diff --git a/ruoyi-service/src/main/java/com/ruoyi/common/constants/ConfigKeys.java b/ruoyi-service/src/main/java/com/ruoyi/common/constants/ConfigKeys.java index 8950a2a..f5dfe9d 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/common/constants/ConfigKeys.java +++ b/ruoyi-service/src/main/java/com/ruoyi/common/constants/ConfigKeys.java @@ -10,4 +10,8 @@ public class ConfigKeys { public static final String USER_DEFAULT_WITHDRAW_SERVICE_TYPE = "user.default.withdraw.service.type"; // 用户默认服务费值 public static final String USER_DEFAULT_WITHDRAW_SERVICE_VALUE = "user.default.withdraw.service.value"; + // 最低提现金额 + public static final String WITHDRAW_MIN_AMOUNT = "withdraw.min.amount"; + // 最高提现金额 + public static final String WITHDRAW_MAX_AMOUNT = "withdraw.max.amount"; } diff --git a/ruoyi-service/src/main/java/com/ruoyi/dashboard/constants/StatKeys.java b/ruoyi-service/src/main/java/com/ruoyi/dashboard/constants/StatKeys.java index d6bb990..c9eb6c4 100644 --- a/ruoyi-service/src/main/java/com/ruoyi/dashboard/constants/StatKeys.java +++ b/ruoyi-service/src/main/java/com/ruoyi/dashboard/constants/StatKeys.java @@ -13,7 +13,7 @@ public class StatKeys { public static final String ORDER_COUNT = "order_count"; // 订单支付金额 public static final String ORDER_PAY_AMOUNT = "order_pay_amount"; - // 订单退款金额 + // 订单退款金额 public static final String ORDER_REFUND_AMOUNT = "order_refund_amount"; // 分成数量 @@ -22,6 +22,8 @@ public class StatKeys { public static final String BONUS_AMOUNT = "bonus_amount"; // 分成总退款 public static final String BONUS_REFUND_AMOUNT = "bonus_refund_amount"; + // 分成未入账金额 + public static final String BONUS_WAIT_DIVIDE_AMOUNT = "bonus_wait_divide_amount"; // 用户数量 public static final String USER_COUNT = "user_count"; diff --git a/ruoyi-web/src/main/java/com/ruoyi/web/bst/WithdrawController.java b/ruoyi-web/src/main/java/com/ruoyi/web/bst/WithdrawController.java index 0472cfb..22184dc 100644 --- a/ruoyi-web/src/main/java/com/ruoyi/web/bst/WithdrawController.java +++ b/ruoyi-web/src/main/java/com/ruoyi/web/bst/WithdrawController.java @@ -4,6 +4,8 @@ import java.math.BigDecimal; import java.util.List; import javax.servlet.http.HttpServletResponse; +import com.ruoyi.bst.withdraw.domain.dto.WithdrawVerifyDTO; +import com.ruoyi.bst.withdraw.service.WithdrawConverter; import com.ruoyi.bst.withdraw.utils.WithdrawUtil; import com.ruoyi.common.core.domain.vo.UserVO; import com.ruoyi.system.user.service.UserService; @@ -38,6 +40,9 @@ public class WithdrawController extends BaseController @Autowired private UserService userService; + @Autowired + private WithdrawConverter withdrawConverter; + /** * 查询提现列表 */ @@ -78,9 +83,13 @@ public class WithdrawController extends BaseController * 申请提现 */ @PreAuthorize("@ss.hasPermi('bst:withdraw:add')") - @Log(title = "提现", businessType = BusinessType.INSERT) + @Log(title = "申请提现", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@RequestBody @Validated Withdraw withdraw) { + // 若是不是系统管理员,则无权给他人提现 + if (!isSysAdmin() || withdraw.getUserId() == null) { + withdraw.setUserId(getUserId()); + } return toAjax(withdrawService.insertWithdraw(withdraw)); } @@ -93,7 +102,15 @@ public class WithdrawController extends BaseController userId = getUserId(); } UserVO user = userService.selectUserById(userId); - return success(WithdrawUtil.calcAmount(user, amount)); + return success(withdrawConverter.calcAmount(user, amount)); + } + + @PreAuthorize("@ss.hasPermi('bst:withdraw:verify')") + @Log(title = "提现审核", businessType = BusinessType.VERIFY) + @PutMapping("/verify") + public AjaxResult verify(@RequestBody @Validated WithdrawVerifyDTO dto) { + dto.setVerifyId(getUserId()); + return toAjax(withdrawService.verify(dto)); } }