GitBucket
4.23.0
Toggle navigation
Sign in
Files
Branches
1
Releases
Issues
Pull requests
Labels
Priorities
Milestones
Wiki
Forks
yn-bftl-byx
/
thirdparty
Browse code
打印日志
master
1 parent
e337b19
commit
a73b1b7a56ae5bc646b3e3558194e7d2b6156e77
Jing
authored
on 21 Oct
Patch
Showing
1 changed file
src/main/java/com/yn/bftl/thirdparty/modules/unionpay/service/impl/UnionpayAccountServiceImpl.java
Ignore Space
Show notes
View
src/main/java/com/yn/bftl/thirdparty/modules/unionpay/service/impl/UnionpayAccountServiceImpl.java
package com.yn.bftl.thirdparty.modules.unionpay.service.impl; import com.yn.bftl.common.common.exception.YnceError; import com.yn.bftl.common.modules.account.dto.AccountUpdateDTO; import com.yn.bftl.common.modules.account.dto.PaymentDTO; import com.yn.bftl.common.modules.account.dto.RechargeDTO; import com.yn.bftl.common.modules.account.entity.*; import com.yn.bftl.common.modules.account.enums.*; import com.yn.bftl.common.modules.account.vo.AccountPaymentsVO; import com.yn.bftl.common.modules.account.vo.WithdrawalsVO; import com.yn.bftl.common.modules.company.entity.Company; import com.yn.bftl.common.modules.company.entity.ErpAccountSet; import com.yn.bftl.common.modules.subaccount.entity.AllinpayMutual; import com.yn.bftl.common.modules.subaccount.enums.DealStatus; import com.yn.bftl.thirdparty.common.exception.YnceErrorException; import com.yn.bftl.thirdparty.common.repository.*; import com.yn.bftl.thirdparty.common.service.BaseMemberService; import com.yn.bftl.thirdparty.common.util.DateTimeUtils; import com.yn.bftl.thirdparty.common.util.SequenceUtil; import com.yn.bftl.thirdparty.modules.unionpay.service.UnionpayAccountService; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; /** * 电子账户服务实现类 * * @author huabiao * @create 2022/9/7 9:54 **/ @Service(value = "unionpayAccountServiceImpl") public class UnionpayAccountServiceImpl extends BaseMemberService implements UnionpayAccountService { private static final Logger log = LoggerFactory.getLogger(UnionpayAccountServiceImpl.class); @Resource private CompanyRepository companyRepository; @Resource private AccountRepository accountRepository; @Resource private StringRedisTemplate stringRedisTemplate; @Resource private SequenceUtil sequenceUtil; @Resource private AccountChangeListRepository accountChangeListRepository; @Resource private TopUpListRepository topUpListRepository; @Resource private TransferListRepository transferListRepository; @Resource private AllinpayMutualRepository allinpayMutualRepository; @Resource private ReimbursementRecordRepository reimbursementRecordRepository; public final static Map<String, TransferState> TRANSFER_STATE_MAP = new HashMap<String, TransferState>() {{ put("succeeded", TransferState.SUCCESS); put("processing", TransferState.PROCESSING); put("failed", TransferState.FAIL); }}; private final static Map<String, DealStatus> DEAL_STATUS_MAP = new HashMap<String, DealStatus>() {{ put("processing", DealStatus.DEALSTATUS_ING); put("succeeded", DealStatus.DEALSTATUS_SUCC); put("failed", DealStatus.DEALSTATUS_FAIL); }}; @Override @Transactional(rollbackFor = Exception.class) public boolean rechargeMoney(RechargeDTO rechargeDTO) { log.info("recharge money:{}", rechargeDTO); if (rechargeDTO.getCompanyId() == null) { rechargeDTO.setCompanyId(getUser().getCompany().getId()); } Account account = accountRepository.findDepositAccount(rechargeDTO.getCompanyId()); if (account == null) { account = this.createDepositAccount(companyRepository.findById(rechargeDTO.getCompanyId()).orElse(null)); } AccountUpdateDTO accountUpdateDTO = new AccountUpdateDTO(); accountUpdateDTO.setId(account.getId()); accountUpdateDTO.setMoveAmount(rechargeDTO.getRechargeAmount()); accountUpdateDTO.setChangeDirection(rechargeDTO.getChangeDirection()); accountUpdateDTO.setAccountChangeType(rechargeDTO.getAccountChangeType()); accountUpdateDTO.setRemark(rechargeDTO.getRemarks()); accountUpdateDTO.setSourceNo(rechargeDTO.getSourceNo()); accountUpdateDTO.setSourceCompanyId(rechargeDTO.getCompanyId()); this.accountUpdate(accountUpdateDTO); if(ChangeDirection.ADD.equals(rechargeDTO.getChangeDirection())) { //生成充值记录 this.createChangeRecord(rechargeDTO.getRechargeAmount(), account, "PAID", rechargeDTO.getRemarks(), rechargeDTO.getPaymentMethod(), rechargeDTO.getErpAccountSet(), rechargeDTO.getFinishedDate()); } return true; } /** * 充值记录-生成 * * @param sum * @param account * @param state * @param remark * @param paidMode * @param erpAccountSet ERP账套 * @param finishedDate * @return */ public boolean createChangeRecord(BigDecimal sum, Account account, String state, String remark, String paidMode, ErpAccountSet erpAccountSet, LocalDateTime finishedDate) { TopUpList topUpList = new TopUpList(); topUpList.setCompany(account.getCompany()); topUpList.setTopUpNo(sequenceUtil.getNextSequenceNumber("CZ")); topUpList.setAmount(sum); topUpList.setAccount(account); topUpList.setState(TopUpState.valueOf(state)); topUpList.setFinishTime(finishedDate); topUpList.setRemark(remark); topUpList.setPaidMode(paidMode); topUpList.setErpAccountSet(erpAccountSet); topUpListRepository.saveAndFlush(topUpList); return true; } /** * 账户-更新余额 * * @param accountUpdateDTO * @return */ @Transactional(rollbackFor = Exception.class) @Override public boolean accountUpdate(AccountUpdateDTO accountUpdateDTO) { log.info("accountUpdate:{}", accountUpdateDTO); // 加锁,避免并发请求 String lockKey = getAccountUpdateLockKey(accountUpdateDTO.getId()); Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, lockKey); int i = 1; // 拿不到锁时,睡眠一段时间然后重试,重试超过指定次数还未拿到则放弃 while (!lock) { if (i > 10) { throw new YnceErrorException(YnceError.YNCE_000000); } try { Thread.sleep(500); } catch (InterruptedException e) { throw new YnceErrorException(YnceError.YNCE_000000); } lock = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, lockKey); i++; } log.info("accountUpdate lock:{}", lock); stringRedisTemplate.expire(lockKey, 5, TimeUnit.SECONDS); try { // 获取账户信息 Optional<Account> accountOptional = accountRepository.findById(accountUpdateDTO.getId()); log.info("accountUpdate accountOptional:{}", accountOptional); if (BooleanUtils.isFalse(accountOptional.isPresent())) { throw new YnceErrorException(YnceError.YNCE_205004); } Account account = accountOptional.get(); log.info("accountUpdate account:{}", account); // 更新账户数据 if (accountUpdateDTO.getChangeDirection().equals(ChangeDirection.ADD)) { account.setBalance(account.getBalance().add(accountUpdateDTO.getMoveAmount())); } else { if (account.getBalance().compareTo(accountUpdateDTO.getMoveAmount()) == -1) { throw new YnceErrorException(YnceError.YNCE_205005, account.getType().getName() + "账户"); } account.setBalance(account.getBalance().subtract(accountUpdateDTO.getMoveAmount())); } log.info("accountUpdate account:{}", account); accountRepository.saveAndFlush(account); Company sourceCompany = null; if (accountUpdateDTO.getSourceCompanyId() != null) { Optional<Company> companyOpt = companyRepository.findById(accountUpdateDTO.getSourceCompanyId()); sourceCompany = companyOpt.get(); } log.info("accountUpdate sourceCompany:{}", sourceCompany); // 生成对应异动记录 this.createChangeRecord(account, accountUpdateDTO.getChangeDirection(), accountUpdateDTO.getAccountChangeType(), accountUpdateDTO.getMoveAmount(), accountUpdateDTO.getSourceNo(), accountUpdateDTO.getRemark(), sourceCompany); } finally { // 执行成功和失败都需要删除锁 stringRedisTemplate.delete(lockKey); } return true; } /** * 转账后续处理 * * @param amount * @param inputAccount * @param outputAccount * @param transferResult */ @Transactional(rollbackFor = Exception.class) @Override public void transferHandle(BigDecimal amount, Account inputAccount, Account outputAccount, AccountPaymentsVO transferResult) { TransferList transferList = transferListRepository.findByTransOrderNo(transferResult.getOutOrderNo()); if (!TransferState.PROCESSING.equals(transferList.getState())) { return; } transferList.setState(TRANSFER_STATE_MAP.get(transferResult.getStatus())); transferList.setMctOrderNo(transferResult.getPaymentId()); transferList.setReason(transferResult.getReason()); if (StringUtils.isNotEmpty(transferResult.getFinishedAt())) { // transferList.setFinishTime(LocalDateTime.parse(transferResult.getFinishedAt(), // DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzz"))); transferList.setFinishTime(DateTimeUtils.getLocalDateTimeByRFC3339(transferResult.getFinishedAt())); } transferListRepository.save(transferList); if (TransferState.SUCCESS.equals(transferList.getState())) { // 更新账户数据 outputAccount.setBalance(outputAccount.getBalance().subtract(amount)); inputAccount.setBalance(inputAccount.getBalance().add(amount)); accountRepository.saveAndFlush(inputAccount); accountRepository.saveAndFlush(outputAccount); // 生成对应异动记录 this.createChangeRecord(inputAccount, ChangeDirection.ADD, AccountChangeType.TRANSFER, amount, transferResult.getOutOrderNo(), StringUtils.isNotBlank(transferResult.getRemark()) ? transferResult.getRemark() : "转账-来自" + outputAccount.getCompany().getName(), outputAccount.getCompany()); this.createChangeRecord(outputAccount, ChangeDirection.REDUCE, AccountChangeType.TRANSFER, amount, transferResult.getOutOrderNo(), StringUtils.isNotEmpty(transferList.getRemark()) ? transferList.getRemark() : inputAccount.getCompany().getName(), inputAccount.getCompany()); } } @Transactional(rollbackFor = Exception.class) @Override public void withdrawalsHandle(Account account, WithdrawalsVO withdrawalsVO) { AllinpayMutual dbAllinpayMutual = allinpayMutualRepository.findFirstByBizOrderNo(withdrawalsVO.getOutOrderNo()); if (!DealStatus.DEALSTATUS_ING.equals(dbAllinpayMutual.getDealStatus())) { return; } dbAllinpayMutual.setOriBizOrderNo(withdrawalsVO.getWithdrawalId()); dbAllinpayMutual.setDealStatus(DEAL_STATUS_MAP.get(withdrawalsVO.getStatus())); dbAllinpayMutual.setAttrs(withdrawalsVO.getReason()); if (DealStatus.DEALSTATUS_SUCC.equals(dbAllinpayMutual.getDealStatus())) { // dbAllinpayMutual.setFinishedTime(LocalDateTime.parse(withdrawalsVO.getFinishedAt(), // DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzz"))); dbAllinpayMutual.setFinishedTime(DateTimeUtils.getLocalDateTimeByRFC3339(withdrawalsVO.getFinishedAt())); AccountUpdateDTO accountUpdateDTO = new AccountUpdateDTO(); accountUpdateDTO.setId(account.getId()); accountUpdateDTO.setMoveAmount(new BigDecimal(withdrawalsVO.getAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); accountUpdateDTO.setChangeDirection(ChangeDirection.REDUCE); accountUpdateDTO.setAccountChangeType(AccountChangeType.WITHDRAWDEPOSIT); accountUpdateDTO.setSourceNo(withdrawalsVO.getOutOrderNo()); accountUpdateDTO.setSourceCompanyId(account.getCompany().getId()); accountUpdateDTO.setRemark("提现"); this.accountUpdate(accountUpdateDTO); } allinpayMutualRepository.save(dbAllinpayMutual); } @Transactional(rollbackFor = Exception.class) @Override public void unionpayCreditRefundHandle(PaymentDTO paymentDTO, Long saleCompanyId, AccountPaymentsVO transferResult) { ReimbursementRecord record = reimbursementRecordRepository.findByOrderNo(transferResult.getOutOrderNo()); if (!TransferState.PROCESSING.equals(record.getState())) { return; } record.setState(TRANSFER_STATE_MAP.get(transferResult.getStatus())); record.setUnionpayPaymentId(transferResult.getPaymentId()); record.setReason(transferResult.getReason()); if (StringUtils.isNotEmpty(transferResult.getFinishedAt())) { // transferList.setFinishTime(LocalDateTime.parse(transferResult.getFinishedAt(), // DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzz"))); record.setFinishTime(DateTimeUtils.getLocalDateTimeByRFC3339(transferResult.getFinishedAt())); } reimbursementRecordRepository.save(record); if (TransferState.SUCCESS.equals(record.getState())) { Long companyId = record.getCompany().getId(); String remark = StringUtils.isNotBlank(paymentDTO.getRemarks()) ? paymentDTO.getRemarks() : "信用还款"; // 预存款账户 Account depositAccount = accountRepository.findDepositAccount(companyId); // 扣除预存款 AccountUpdateDTO depositAccountUpdate = new AccountUpdateDTO(); depositAccountUpdate.setId(depositAccount.getId()); depositAccountUpdate.setMoveAmount(paymentDTO.getPaymentAmount()); depositAccountUpdate.setChangeDirection(ChangeDirection.REDUCE); depositAccountUpdate.setAccountChangeType(AccountChangeType.REIMBURSEMENT); depositAccountUpdate.setSourceNo(transferResult.getOutOrderNo()); depositAccountUpdate.setSourceCompanyId(companyId); depositAccountUpdate.setRemark(remark); this.accountUpdate(depositAccountUpdate); // 信用还款 AccountUpdateDTO creditAccountUpdate = new AccountUpdateDTO(); creditAccountUpdate.setId(paymentDTO.getId()); creditAccountUpdate.setMoveAmount(paymentDTO.getPaymentAmount()); creditAccountUpdate.setChangeDirection(ChangeDirection.ADD); creditAccountUpdate.setAccountChangeType(AccountChangeType.REIMBURSEMENT); creditAccountUpdate.setSourceNo(transferResult.getOutOrderNo()); creditAccountUpdate.setSourceCompanyId(companyId); creditAccountUpdate.setRemark(remark); this.accountUpdate(creditAccountUpdate); // 收款方预存款账户 // Account receiptDepositAccount = accountRepository.findDepositAccount(saleCompanyId); // 收款方增加预存款 /*AccountUpdateDTO receiptDepositAccountUpdate = new AccountUpdateDTO(); receiptDepositAccountUpdate.setId(receiptDepositAccount.getId()); receiptDepositAccountUpdate.setMoveAmount(paymentDTO.getPaymentAmount()); receiptDepositAccountUpdate.setChangeDirection(ChangeDirection.ADD); receiptDepositAccountUpdate.setAccountChangeType(AccountChangeType.REIMBURSEMENT); receiptDepositAccountUpdate.setSourceNo(transferResult.getOutOrderNo()); receiptDepositAccountUpdate.setSourceCompanyId(companyId); receiptDepositAccountUpdate.setRemark(transferResult.getRemark()); this.accountUpdate(receiptDepositAccountUpdate);*/ } } /** * 创建异动记录 * * @param account 账户 * @param direction 异动方向 * @param type 异动类型 * @param sum 金额 * @param sourceNo 来源单号 * @param remark 备注 * @return 是否成功 */ public boolean createChangeRecord(Account account, ChangeDirection direction, AccountChangeType type, BigDecimal sum, String sourceNo, String remark, Company sourceCompany) { log.info("创建异动记录:{}", account); AccountChangeList accountChangeList = new AccountChangeList(); accountChangeList.setAccount(account); accountChangeList.setDirection(direction); accountChangeList.setType(type); accountChangeList.setSum(direction.equals(ChangeDirection.ADD) ? sum : sum.negate()); accountChangeList.setTime(LocalDateTime.now()); accountChangeList.setRemark(remark); accountChangeList.setSerialNumber(sequenceUtil.getNextSequenceNumber("YD")); accountChangeList.setSourceNo(sourceNo); accountChangeList.setSourceCompany(sourceCompany); accountChangeList.setBalance(account.getBalance()); accountChangeListRepository.saveAndFlush(accountChangeList); return true; } private Account createDepositAccount(Company company) { Account account = new Account(); account.setType(AccountType.DEPOSIT); account.setBalance(BigDecimal.ZERO); account.setState(AccountState.ENABLED); account.setCompany(company); accountRepository.saveAndFlush(account); return account; } /** * 获取账户更新锁key * * @param accountId * @return */ @Override public String getAccountUpdateLockKey(Long accountId) { return accountId + ":ACCOUNT_UPDATE"; } }
package com.yn.bftl.thirdparty.modules.unionpay.service.impl; import com.yn.bftl.common.common.exception.YnceError; import com.yn.bftl.common.modules.account.dto.AccountUpdateDTO; import com.yn.bftl.common.modules.account.dto.PaymentDTO; import com.yn.bftl.common.modules.account.dto.RechargeDTO; import com.yn.bftl.common.modules.account.entity.*; import com.yn.bftl.common.modules.account.enums.*; import com.yn.bftl.common.modules.account.vo.AccountPaymentsVO; import com.yn.bftl.common.modules.account.vo.WithdrawalsVO; import com.yn.bftl.common.modules.company.entity.Company; import com.yn.bftl.common.modules.company.entity.ErpAccountSet; import com.yn.bftl.common.modules.subaccount.entity.AllinpayMutual; import com.yn.bftl.common.modules.subaccount.enums.DealStatus; import com.yn.bftl.thirdparty.common.exception.YnceErrorException; import com.yn.bftl.thirdparty.common.repository.*; import com.yn.bftl.thirdparty.common.service.BaseMemberService; import com.yn.bftl.thirdparty.common.util.DateTimeUtils; import com.yn.bftl.thirdparty.common.util.SequenceUtil; import com.yn.bftl.thirdparty.modules.unionpay.service.UnionpayAccountService; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; /** * 电子账户服务实现类 * * @author huabiao * @create 2022/9/7 9:54 **/ @Service(value = "unionpayAccountServiceImpl") public class UnionpayAccountServiceImpl extends BaseMemberService implements UnionpayAccountService { private static final Logger log = LoggerFactory.getLogger(UnionpayAccountServiceImpl.class); @Resource private CompanyRepository companyRepository; @Resource private AccountRepository accountRepository; @Resource private StringRedisTemplate stringRedisTemplate; @Resource private SequenceUtil sequenceUtil; @Resource private AccountChangeListRepository accountChangeListRepository; @Resource private TopUpListRepository topUpListRepository; @Resource private TransferListRepository transferListRepository; @Resource private AllinpayMutualRepository allinpayMutualRepository; @Resource private ReimbursementRecordRepository reimbursementRecordRepository; public final static Map<String, TransferState> TRANSFER_STATE_MAP = new HashMap<String, TransferState>() {{ put("succeeded", TransferState.SUCCESS); put("processing", TransferState.PROCESSING); put("failed", TransferState.FAIL); }}; private final static Map<String, DealStatus> DEAL_STATUS_MAP = new HashMap<String, DealStatus>() {{ put("processing", DealStatus.DEALSTATUS_ING); put("succeeded", DealStatus.DEALSTATUS_SUCC); put("failed", DealStatus.DEALSTATUS_FAIL); }}; @Override @Transactional(rollbackFor = Exception.class) public boolean rechargeMoney(RechargeDTO rechargeDTO) { log.info("recharge money:{}", rechargeDTO); if (rechargeDTO.getCompanyId() == null) { rechargeDTO.setCompanyId(getUser().getCompany().getId()); } Account account = accountRepository.findDepositAccount(rechargeDTO.getCompanyId()); if (account == null) { account = this.createDepositAccount(companyRepository.findById(rechargeDTO.getCompanyId()).orElse(null)); } AccountUpdateDTO accountUpdateDTO = new AccountUpdateDTO(); accountUpdateDTO.setId(account.getId()); accountUpdateDTO.setMoveAmount(rechargeDTO.getRechargeAmount()); accountUpdateDTO.setChangeDirection(rechargeDTO.getChangeDirection()); accountUpdateDTO.setAccountChangeType(rechargeDTO.getAccountChangeType()); accountUpdateDTO.setRemark(rechargeDTO.getRemarks()); accountUpdateDTO.setSourceNo(rechargeDTO.getSourceNo()); accountUpdateDTO.setSourceCompanyId(rechargeDTO.getCompanyId()); this.accountUpdate(accountUpdateDTO); if(ChangeDirection.ADD.equals(rechargeDTO.getChangeDirection())) { //生成充值记录 this.createChangeRecord(rechargeDTO.getRechargeAmount(), account, "PAID", rechargeDTO.getRemarks(), rechargeDTO.getPaymentMethod(), rechargeDTO.getErpAccountSet(), rechargeDTO.getFinishedDate()); } return true; } /** * 充值记录-生成 * * @param sum * @param account * @param state * @param remark * @param paidMode * @param erpAccountSet ERP账套 * @param finishedDate * @return */ public boolean createChangeRecord(BigDecimal sum, Account account, String state, String remark, String paidMode, ErpAccountSet erpAccountSet, LocalDateTime finishedDate) { TopUpList topUpList = new TopUpList(); topUpList.setCompany(account.getCompany()); topUpList.setTopUpNo(sequenceUtil.getNextSequenceNumber("CZ")); topUpList.setAmount(sum); topUpList.setAccount(account); topUpList.setState(TopUpState.valueOf(state)); topUpList.setFinishTime(finishedDate); topUpList.setRemark(remark); topUpList.setPaidMode(paidMode); topUpList.setErpAccountSet(erpAccountSet); topUpListRepository.saveAndFlush(topUpList); return true; } /** * 账户-更新余额 * * @param accountUpdateDTO * @return */ @Transactional(rollbackFor = Exception.class) @Override public boolean accountUpdate(AccountUpdateDTO accountUpdateDTO) { log.info("accountUpdate:{}", accountUpdateDTO); // 加锁,避免并发请求 String lockKey = getAccountUpdateLockKey(accountUpdateDTO.getId()); Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, lockKey); int i = 1; // 拿不到锁时,睡眠一段时间然后重试,重试超过指定次数还未拿到则放弃 while (!lock) { if (i > 10) { throw new YnceErrorException(YnceError.YNCE_000000); } try { Thread.sleep(500); } catch (InterruptedException e) { throw new YnceErrorException(YnceError.YNCE_000000); } lock = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, lockKey); i++; } stringRedisTemplate.expire(lockKey, 5, TimeUnit.SECONDS); try { // 获取账户信息 Optional<Account> accountOptional = accountRepository.findById(accountUpdateDTO.getId()); if (BooleanUtils.isFalse(accountOptional.isPresent())) { throw new YnceErrorException(YnceError.YNCE_205004); } Account account = accountOptional.get(); // 更新账户数据 if (accountUpdateDTO.getChangeDirection().equals(ChangeDirection.ADD)) { account.setBalance(account.getBalance().add(accountUpdateDTO.getMoveAmount())); } else { if (account.getBalance().compareTo(accountUpdateDTO.getMoveAmount()) == -1) { throw new YnceErrorException(YnceError.YNCE_205005, account.getType().getName() + "账户"); } account.setBalance(account.getBalance().subtract(accountUpdateDTO.getMoveAmount())); } accountRepository.saveAndFlush(account); Company sourceCompany = null; if (accountUpdateDTO.getSourceCompanyId() != null) { Optional<Company> companyOpt = companyRepository.findById(accountUpdateDTO.getSourceCompanyId()); sourceCompany = companyOpt.get(); } // 生成对应异动记录 this.createChangeRecord(account, accountUpdateDTO.getChangeDirection(), accountUpdateDTO.getAccountChangeType(), accountUpdateDTO.getMoveAmount(), accountUpdateDTO.getSourceNo(), accountUpdateDTO.getRemark(), sourceCompany); } finally { // 执行成功和失败都需要删除锁 stringRedisTemplate.delete(lockKey); } return true; } /** * 转账后续处理 * * @param amount * @param inputAccount * @param outputAccount * @param transferResult */ @Transactional(rollbackFor = Exception.class) @Override public void transferHandle(BigDecimal amount, Account inputAccount, Account outputAccount, AccountPaymentsVO transferResult) { TransferList transferList = transferListRepository.findByTransOrderNo(transferResult.getOutOrderNo()); if (!TransferState.PROCESSING.equals(transferList.getState())) { return; } transferList.setState(TRANSFER_STATE_MAP.get(transferResult.getStatus())); transferList.setMctOrderNo(transferResult.getPaymentId()); transferList.setReason(transferResult.getReason()); if (StringUtils.isNotEmpty(transferResult.getFinishedAt())) { // transferList.setFinishTime(LocalDateTime.parse(transferResult.getFinishedAt(), // DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzz"))); transferList.setFinishTime(DateTimeUtils.getLocalDateTimeByRFC3339(transferResult.getFinishedAt())); } transferListRepository.save(transferList); if (TransferState.SUCCESS.equals(transferList.getState())) { // 更新账户数据 outputAccount.setBalance(outputAccount.getBalance().subtract(amount)); inputAccount.setBalance(inputAccount.getBalance().add(amount)); accountRepository.saveAndFlush(inputAccount); accountRepository.saveAndFlush(outputAccount); // 生成对应异动记录 this.createChangeRecord(inputAccount, ChangeDirection.ADD, AccountChangeType.TRANSFER, amount, transferResult.getOutOrderNo(), StringUtils.isNotBlank(transferResult.getRemark()) ? transferResult.getRemark() : "转账-来自" + outputAccount.getCompany().getName(), outputAccount.getCompany()); this.createChangeRecord(outputAccount, ChangeDirection.REDUCE, AccountChangeType.TRANSFER, amount, transferResult.getOutOrderNo(), StringUtils.isNotEmpty(transferList.getRemark()) ? transferList.getRemark() : inputAccount.getCompany().getName(), inputAccount.getCompany()); } } @Transactional(rollbackFor = Exception.class) @Override public void withdrawalsHandle(Account account, WithdrawalsVO withdrawalsVO) { AllinpayMutual dbAllinpayMutual = allinpayMutualRepository.findFirstByBizOrderNo(withdrawalsVO.getOutOrderNo()); if (!DealStatus.DEALSTATUS_ING.equals(dbAllinpayMutual.getDealStatus())) { return; } dbAllinpayMutual.setOriBizOrderNo(withdrawalsVO.getWithdrawalId()); dbAllinpayMutual.setDealStatus(DEAL_STATUS_MAP.get(withdrawalsVO.getStatus())); dbAllinpayMutual.setAttrs(withdrawalsVO.getReason()); if (DealStatus.DEALSTATUS_SUCC.equals(dbAllinpayMutual.getDealStatus())) { // dbAllinpayMutual.setFinishedTime(LocalDateTime.parse(withdrawalsVO.getFinishedAt(), // DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzz"))); dbAllinpayMutual.setFinishedTime(DateTimeUtils.getLocalDateTimeByRFC3339(withdrawalsVO.getFinishedAt())); AccountUpdateDTO accountUpdateDTO = new AccountUpdateDTO(); accountUpdateDTO.setId(account.getId()); accountUpdateDTO.setMoveAmount(new BigDecimal(withdrawalsVO.getAmount()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); accountUpdateDTO.setChangeDirection(ChangeDirection.REDUCE); accountUpdateDTO.setAccountChangeType(AccountChangeType.WITHDRAWDEPOSIT); accountUpdateDTO.setSourceNo(withdrawalsVO.getOutOrderNo()); accountUpdateDTO.setSourceCompanyId(account.getCompany().getId()); accountUpdateDTO.setRemark("提现"); this.accountUpdate(accountUpdateDTO); } allinpayMutualRepository.save(dbAllinpayMutual); } @Transactional(rollbackFor = Exception.class) @Override public void unionpayCreditRefundHandle(PaymentDTO paymentDTO, Long saleCompanyId, AccountPaymentsVO transferResult) { ReimbursementRecord record = reimbursementRecordRepository.findByOrderNo(transferResult.getOutOrderNo()); if (!TransferState.PROCESSING.equals(record.getState())) { return; } record.setState(TRANSFER_STATE_MAP.get(transferResult.getStatus())); record.setUnionpayPaymentId(transferResult.getPaymentId()); record.setReason(transferResult.getReason()); if (StringUtils.isNotEmpty(transferResult.getFinishedAt())) { // transferList.setFinishTime(LocalDateTime.parse(transferResult.getFinishedAt(), // DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzz"))); record.setFinishTime(DateTimeUtils.getLocalDateTimeByRFC3339(transferResult.getFinishedAt())); } reimbursementRecordRepository.save(record); if (TransferState.SUCCESS.equals(record.getState())) { Long companyId = record.getCompany().getId(); String remark = StringUtils.isNotBlank(paymentDTO.getRemarks()) ? paymentDTO.getRemarks() : "信用还款"; // 预存款账户 Account depositAccount = accountRepository.findDepositAccount(companyId); // 扣除预存款 AccountUpdateDTO depositAccountUpdate = new AccountUpdateDTO(); depositAccountUpdate.setId(depositAccount.getId()); depositAccountUpdate.setMoveAmount(paymentDTO.getPaymentAmount()); depositAccountUpdate.setChangeDirection(ChangeDirection.REDUCE); depositAccountUpdate.setAccountChangeType(AccountChangeType.REIMBURSEMENT); depositAccountUpdate.setSourceNo(transferResult.getOutOrderNo()); depositAccountUpdate.setSourceCompanyId(companyId); depositAccountUpdate.setRemark(remark); this.accountUpdate(depositAccountUpdate); // 信用还款 AccountUpdateDTO creditAccountUpdate = new AccountUpdateDTO(); creditAccountUpdate.setId(paymentDTO.getId()); creditAccountUpdate.setMoveAmount(paymentDTO.getPaymentAmount()); creditAccountUpdate.setChangeDirection(ChangeDirection.ADD); creditAccountUpdate.setAccountChangeType(AccountChangeType.REIMBURSEMENT); creditAccountUpdate.setSourceNo(transferResult.getOutOrderNo()); creditAccountUpdate.setSourceCompanyId(companyId); creditAccountUpdate.setRemark(remark); this.accountUpdate(creditAccountUpdate); // 收款方预存款账户 // Account receiptDepositAccount = accountRepository.findDepositAccount(saleCompanyId); // 收款方增加预存款 /*AccountUpdateDTO receiptDepositAccountUpdate = new AccountUpdateDTO(); receiptDepositAccountUpdate.setId(receiptDepositAccount.getId()); receiptDepositAccountUpdate.setMoveAmount(paymentDTO.getPaymentAmount()); receiptDepositAccountUpdate.setChangeDirection(ChangeDirection.ADD); receiptDepositAccountUpdate.setAccountChangeType(AccountChangeType.REIMBURSEMENT); receiptDepositAccountUpdate.setSourceNo(transferResult.getOutOrderNo()); receiptDepositAccountUpdate.setSourceCompanyId(companyId); receiptDepositAccountUpdate.setRemark(transferResult.getRemark()); this.accountUpdate(receiptDepositAccountUpdate);*/ } } /** * 创建异动记录 * * @param account 账户 * @param direction 异动方向 * @param type 异动类型 * @param sum 金额 * @param sourceNo 来源单号 * @param remark 备注 * @return 是否成功 */ public boolean createChangeRecord(Account account, ChangeDirection direction, AccountChangeType type, BigDecimal sum, String sourceNo, String remark, Company sourceCompany) { log.info("创建异动记录:{}", account); AccountChangeList accountChangeList = new AccountChangeList(); accountChangeList.setAccount(account); accountChangeList.setDirection(direction); accountChangeList.setType(type); accountChangeList.setSum(direction.equals(ChangeDirection.ADD) ? sum : sum.negate()); accountChangeList.setTime(LocalDateTime.now()); accountChangeList.setRemark(remark); accountChangeList.setSerialNumber(sequenceUtil.getNextSequenceNumber("YD")); accountChangeList.setSourceNo(sourceNo); accountChangeList.setSourceCompany(sourceCompany); accountChangeList.setBalance(account.getBalance()); accountChangeListRepository.saveAndFlush(accountChangeList); return true; } private Account createDepositAccount(Company company) { Account account = new Account(); account.setType(AccountType.DEPOSIT); account.setBalance(BigDecimal.ZERO); account.setState(AccountState.ENABLED); account.setCompany(company); accountRepository.saveAndFlush(account); return account; } /** * 获取账户更新锁key * * @param accountId * @return */ @Override public String getAccountUpdateLockKey(Long accountId) { return accountId + ":ACCOUNT_UPDATE"; } }
Show line notes below