diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/BaseAudit.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/BaseAudit.java index ffffe0305..e6a8c0e69 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/BaseAudit.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/BaseAudit.java @@ -1,5 +1,7 @@ package org.dromara.common.core.domain.model; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; import lombok.Data; import java.time.LocalDateTime; @@ -14,6 +16,10 @@ public class BaseAudit { /** * 创建时间 */ + /** + * 创建部门 + */ + @TableField(fill = FieldFill.INSERT) // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; @@ -25,6 +31,7 @@ public class BaseAudit { /** * 更新时间 */ + @TableField(fill = FieldFill.INSERT_UPDATE) // @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; } diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java index 713d4ce0c..97d7428b6 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java @@ -5,6 +5,7 @@ import cn.hutool.http.HttpStatus; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; +import org.dromara.common.core.domain.model.BaseAudit; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.ObjectUtils; @@ -48,7 +49,11 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler { baseEntity.setCreateDept(ObjectUtils.notNull(baseEntity.getCreateDept(), loginUser.getDeptId())); } } - } else { + } else if(ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseAudit baseAudit) { + baseAudit.setCreateTime(LocalDateTime.now()); + baseAudit.setUpdateTime(LocalDateTime.now()); + + }else{ Date date = new Date(); this.strictInsertFill(metaObject, "createTime", Date.class, date); this.strictInsertFill(metaObject, "updateTime", Date.class, date); @@ -75,6 +80,8 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler { if (ObjectUtil.isNotNull(userId)) { baseEntity.setUpdateBy(userId); } + } else if(ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseAudit baseAudit) { + baseAudit.setUpdateTime(LocalDateTime.now()); } else { this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/controller/WithdrawController.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/controller/WithdrawController.java index aacdde303..02a78dcf7 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/controller/WithdrawController.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/controller/WithdrawController.java @@ -54,12 +54,11 @@ public class WithdrawController { return R.ok(convert.toVO(service.getById(id))); } - @Tag(name = ("处理")) - @Log(title = "修改", businessType = BusinessType.UPDATE) + @Tag(name = ("审批")) + @Log(title = "审批", businessType = BusinessType.UPDATE) @PostMapping("/update") public R update(@RequestBody WithdrawBO bo) { - service.save(convert.toPo(bo)); - return R.ok(); + return R.ok(service.audit(bo)); } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/bo/WithdrawBO.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/bo/WithdrawBO.java index c98fc4f89..6643b3c14 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/bo/WithdrawBO.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/bo/WithdrawBO.java @@ -96,6 +96,12 @@ public class WithdrawBO extends BaseBO { @Schema(description ="审核状态") private Integer auditStatus; + /** + * 审核原因 + */ + @Schema(description ="审核原因") + private String auditReason; + @Override public LambdaQueryWrapper toWrapper() { return super.toWrapper().eq(id!=null, Withdraw::getId, id) diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/MemberAccountChangeRecord.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/MemberAccountChangeRecord.java index c6c9328e0..8efaf1657 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/MemberAccountChangeRecord.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/MemberAccountChangeRecord.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; import lombok.Data; import org.dromara.common.core.domain.model.BaseAudit; import org.dromara.common.excel.annotation.Excel; @@ -18,6 +19,7 @@ import java.math.BigDecimal; @Schema(description="会员账户变动记录") @Data @TableName("ums_account_change_record") +@Builder(toBuilder = true) public class MemberAccountChangeRecord extends BaseAudit { @Schema(description ="主键") diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/Withdraw.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/Withdraw.java index c5c6d8dd2..b56f92bae 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/Withdraw.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/po/Withdraw.java @@ -1,9 +1,12 @@ package com.wzj.soopin.member.domain.po; +import com.alibaba.excel.annotation.format.DateTimeFormat; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; import lombok.Data; import org.dromara.common.core.domain.model.BaseAudit; @@ -19,6 +22,7 @@ import java.time.LocalDateTime; @Schema(description="提现") @Data @TableName("ums_withdraw") +@Builder(toBuilder = true) public class Withdraw extends BaseAudit { /** @@ -69,6 +73,7 @@ public class Withdraw extends BaseAudit { /** * 审核时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime auditTime; /** @@ -80,4 +85,9 @@ public class Withdraw extends BaseAudit { * 审核状态 */ private Integer auditStatus; + + /** + * 审核原因 + */ + private String auditReason; } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/vo/WithdrawVO.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/vo/WithdrawVO.java index abb4b76c4..eb24ade16 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/vo/WithdrawVO.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/vo/WithdrawVO.java @@ -108,4 +108,11 @@ public class WithdrawVO extends BaseAudit { @Schema(description ="审核状态") @ExcelProperty(value ="审核状态", order = 12) private Integer auditStatus; + + /** + * 审核原因 + */ + @Schema(description ="审核原因") + @ExcelProperty(value ="审核原因", order = 13) + private String auditReason; } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/vo/YishengAccountVO.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/vo/YishengAccountVO.java new file mode 100644 index 000000000..570071dcd --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/domain/vo/YishengAccountVO.java @@ -0,0 +1,48 @@ +package com.wzj.soopin.member.domain.vo; + + +import com.alibaba.excel.annotation.ExcelProperty; +import com.wzj.soopin.member.annotation.MemberFillField; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; +import org.dromara.common.core.domain.model.BaseAudit; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 易生平台账户信息 + * + * @author wzj + * @date 2023-03-07 + */ +@Schema(description="易生") +@Data +@Builder(toBuilder = true) +public class YishengAccountVO extends BaseAudit { + + /** + * 主键 + */ + @Schema(description ="主键") + @ExcelProperty(value = "主键", order = 1) + private Long id; + + /** + * 会员id + */ + @Schema(description ="会员id") + @ExcelProperty(value ="会员id", order = 3) + private Long memberId; + + + /** + * 金额 + */ + @Schema(description ="金额") + @ExcelProperty(value ="金额", order = 4) + private BigDecimal balance; + + +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberAccountChangeRecordChangeTypeEnum.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberAccountChangeRecordChangeTypeEnum.java new file mode 100644 index 000000000..7b42f0c1f --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberAccountChangeRecordChangeTypeEnum.java @@ -0,0 +1,26 @@ +package com.wzj.soopin.member.enums; + +public enum MemberAccountChangeRecordChangeTypeEnum { + WITHDRAW(1, "提现"), + CHARGE(2, "充值"), + RECHARGE(3, "充值"), + RECHARGE_REFUND(4, "充值退款"), + WITHDRAW_REFUND(5, "提现退款"), + RECHARGE_REFUND_REFUND(6, "充值退款退款"), + WITHDRAW_REFUND_REFUND(7, "提现退款退款"), + RECHARGE_REFUND_REFUND_REFUND(8, "充值退款退款退款"); + + private Integer code; + private String message; + MemberAccountChangeRecordChangeTypeEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + public Integer getCode() { + return code; + } + public String getMessage() { + return message; + } +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberAccountChangeRecordSourceEnum.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberAccountChangeRecordSourceEnum.java new file mode 100644 index 000000000..f653678ba --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/MemberAccountChangeRecordSourceEnum.java @@ -0,0 +1,23 @@ +package com.wzj.soopin.member.enums; + +public enum MemberAccountChangeRecordSourceEnum { + YISHENG(1, "充值"), + CHARGE(2, "提现"), + WITHDRAW(3, "经营"), + + RECHARGE_REFUND_REFUND_REFUND(9, "充值退款退款退款"); + + private Integer code; + private String message; + MemberAccountChangeRecordSourceEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + public Integer getCode() { + return code; + } + public String getMessage() { + return message; + } +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/WithdrawAuditStatus.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/WithdrawAuditStatus.java new file mode 100644 index 000000000..8f9cb8fd2 --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/WithdrawAuditStatus.java @@ -0,0 +1,20 @@ +package com.wzj.soopin.member.enums; + +public enum WithdrawAuditStatus { + PENDING(0, "待审核"), + APPROVED(1, "审核通过"), + REJECTED(2, "审核拒绝"); + private Integer code; + private String message; + WithdrawAuditStatus(Integer code, String message) { + this.code = code; + this.message = message; + } + public Integer getCode() { + return code; + } + + public String getMessage() { + return message; + } +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/WithdrawStatus.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/WithdrawStatus.java new file mode 100644 index 000000000..b99979231 --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/enums/WithdrawStatus.java @@ -0,0 +1,22 @@ +package com.wzj.soopin.member.enums; + +public enum WithdrawStatus { + WAITING(0, "等待转账"), + PENDING(1, "转账中"), + SUCCESS(2, "转账成功"), + FAIL(3, "转账失败"); + + private Integer code; + private String message; + WithdrawStatus(Integer code, String message) { + this.code = code; + this.message = message; + } + public Integer getCode() { + return code; + } + + public String getMessage() { + return message; + } +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IWithdrawService.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IWithdrawService.java index 9dea55b44..c666c6132 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IWithdrawService.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IWithdrawService.java @@ -1,6 +1,7 @@ package com.wzj.soopin.member.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.wzj.soopin.member.domain.bo.WithdrawBO; import com.wzj.soopin.member.domain.po.Feedback; import com.wzj.soopin.member.domain.po.Withdraw; import com.wzj.soopin.member.domain.vo.FeedbackVO; @@ -8,5 +9,7 @@ import com.wzj.soopin.member.domain.vo.FeedbackVO; import java.io.Serializable; public interface IWithdrawService extends IService { + boolean audit(WithdrawBO bo); + boolean withdraw(Long id); } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IYishengService.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IYishengService.java new file mode 100644 index 000000000..50dd109da --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IYishengService.java @@ -0,0 +1,19 @@ +package com.wzj.soopin.member.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.wzj.soopin.member.domain.po.Withdraw; +import com.wzj.soopin.member.domain.vo.YishengAccountVO; + +import java.math.BigDecimal; + +/** + * 易生支付的service + */ +public interface IYishengService { + YishengAccountVO getYishengAccount(Long memberId); + + boolean withdraw(Long memberId, BigDecimal money); + + + boolean syncMemberAccount(); +} diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/WithdrawServiceImpl.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/WithdrawServiceImpl.java index 0f7384849..45456c9c7 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/WithdrawServiceImpl.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/WithdrawServiceImpl.java @@ -1,16 +1,29 @@ package com.wzj.soopin.member.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wzj.soopin.member.domain.bo.WithdrawBO; import com.wzj.soopin.member.domain.po.Charge; +import com.wzj.soopin.member.domain.po.MemberAccount; +import com.wzj.soopin.member.domain.po.MemberAccountChangeRecord; import com.wzj.soopin.member.domain.po.Withdraw; +import com.wzj.soopin.member.domain.vo.YishengAccountVO; +import com.wzj.soopin.member.enums.MemberAccountChangeRecordChangeTypeEnum; +import com.wzj.soopin.member.enums.MemberAccountChangeRecordSourceEnum; +import com.wzj.soopin.member.enums.WithdrawAuditStatus; +import com.wzj.soopin.member.enums.WithdrawStatus; import com.wzj.soopin.member.mapper.ChargeMapper; +import com.wzj.soopin.member.mapper.MemberAccountMapper; import com.wzj.soopin.member.mapper.WithdrawMapper; -import com.wzj.soopin.member.service.IChargeService; -import com.wzj.soopin.member.service.IWithdrawService; +import com.wzj.soopin.member.service.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.satoken.utils.LoginHelper; import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.Objects; + /** * 会员封禁 * @@ -21,4 +34,92 @@ import org.springframework.stereotype.Service; @Slf4j public class WithdrawServiceImpl extends ServiceImpl implements IWithdrawService { + private final IMemberAccountService memberAccountService; + + /** + * 易生账户充值服务 + */ + private final IYishengService yishengService; + + private final IMemberAccountChangeRecordService memberAccountChangeRecordService; + + @Override + public boolean audit(WithdrawBO bo) { + Withdraw withdraw = getById(bo.getId()); + if (withdraw == null) { + throw new RuntimeException("提现申请不存在"); + } + if (!Objects.equals(WithdrawAuditStatus.PENDING.getCode(), withdraw.getAuditStatus())) { + throw new RuntimeException("提现申请已处理"); + } + withdraw = Withdraw.builder().id(bo.getId()) + .auditReason(bo.getAuditReason()) + .auditTime(LocalDateTime.now()) + .auditStatus(bo.getAuditStatus()) + .auditBy(LoginHelper.getUserId()) + .build(); + return this.updateById(withdraw); + } + + @Override + public boolean save(Withdraw entity) { + entity.setStatus(WithdrawStatus.WAITING.getCode()); + return super.save(entity); + } + + public boolean withdraw(Long id) { + Withdraw withdraw = getById(id); + //获取用户余额信息 + MemberAccount memberAccount = memberAccountService.getById(withdraw.getMemberId()); + if (memberAccount == null) { + throw new RuntimeException("用户不存在"); + } + //检查当前用于的账户余额是否充足 + BigDecimal balance = memberAccount.getMoneyBalance(); + + if (balance.compareTo(withdraw.getMoney()) < 0) { + throw new RuntimeException("用户余额不足"); + } + //调用三方支付平台获取用户余额 + YishengAccountVO yishengAccountVO = yishengService.getYishengAccount(withdraw.getMemberId()); + + if (yishengAccountVO == null) { + throw new RuntimeException("用户余额获取失败"); + } + + BigDecimal yishengBalance = yishengAccountVO.getBalance(); + if (yishengBalance.compareTo(withdraw.getMoney()) < 0) { + throw new RuntimeException("用户余额不足"); + } + + if (!yishengBalance.equals(balance)) { + throw new RuntimeException("用户余额不一致"); + } + + //发起提现 + boolean chargeSuccess = yishengService.withdraw(withdraw.getMemberId(), withdraw.getMoney()); + + if (chargeSuccess) { + //提现成功后,更新会员账户余额 + //从易生取,别用自己计算的 + //// TODO: 2025/6/21 测试的时候用计算的 测试完用易生的 + BigDecimal finalBalance = balance.subtract(withdraw.getMoney()); + yishengAccountVO = yishengService.getYishengAccount(withdraw.getMemberId()); + memberAccountService.updateById(memberAccount.toBuilder().moneyBalance(balance.subtract(finalBalance)).build()); + //生成账户变动记录bh + MemberAccountChangeRecord memberAccountChangeRecord = MemberAccountChangeRecord.builder() + .memberId(withdraw.getMemberId()) + .moneyBalance(finalBalance) + .beforeBalance(balance) + .afterBalance(yishengAccountVO.getBalance()) + .changeType(MemberAccountChangeRecordChangeTypeEnum.WITHDRAW.getCode()) + .changeDesc("提现") + .source(MemberAccountChangeRecordSourceEnum.WITHDRAW.getCode()).build(); + memberAccountChangeRecordService.save(memberAccountChangeRecord); + + } else { + return false; + } + return true; + } } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/YishengServiceImpl.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/YishengServiceImpl.java new file mode 100644 index 000000000..d34b5005a --- /dev/null +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/YishengServiceImpl.java @@ -0,0 +1,40 @@ +package com.wzj.soopin.member.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.wzj.soopin.member.domain.po.Charge; +import com.wzj.soopin.member.domain.vo.YishengAccountVO; +import com.wzj.soopin.member.mapper.ChargeMapper; +import com.wzj.soopin.member.service.IChargeService; +import com.wzj.soopin.member.service.IYishengService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; + +/** + * 会员封禁 + * + * @author zcc + */ +@Service +@RequiredArgsConstructor +@Slf4j +public class YishengServiceImpl implements IYishengService { + + + @Override + public YishengAccountVO getYishengAccount(Long memberId) { + return YishengAccountVO.builder().balance(new BigDecimal(1000)).build(); + } + + @Override + public boolean withdraw(Long memberId, BigDecimal money) { + return true; + } + + @Override + public boolean syncMemberAccount() { + return true; + } +}