|  | @@ -2,25 +2,27 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  import com.alibaba.fastjson.JSONObject;
 |  |  import com.alibaba.fastjson.JSONObject;
 | 
											
												
													
														|  |  import com.baomidou.mybatisplus.core.metadata.IPage;
 |  |  import com.baomidou.mybatisplus.core.metadata.IPage;
 | 
											
												
													
														|  | 
 |  | +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 | 
											
												
													
														|  |  import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 |  |  import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 | 
											
												
													
														|  |  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 |  |  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
 |  |  import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.dto.req.TotalReq;
 |  |  import com.yonge.cooleshow.biz.dal.dto.req.TotalReq;
 | 
											
												
													
														|  | 
 |  | +import com.yonge.cooleshow.biz.dal.entity.PlatformCashAccountRecord;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.entity.UserAccountRecord;
 |  |  import com.yonge.cooleshow.biz.dal.entity.UserAccountRecord;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 |  |  import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 | 
											
												
													
														|  | 
 |  | +import com.yonge.cooleshow.biz.dal.enums.AccountBizTypeEnum;
 | 
											
												
													
														|  | 
 |  | +import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.enums.InOrOutEnum;
 |  |  import com.yonge.cooleshow.biz.dal.enums.InOrOutEnum;
 | 
											
												
													
														|  | -import com.yonge.cooleshow.biz.dal.service.UserOrderService;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import com.yonge.cooleshow.biz.dal.service.*;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.vo.UserAccountRecordVo;
 |  |  import com.yonge.cooleshow.biz.dal.vo.UserAccountRecordVo;
 | 
											
												
													
														|  | -import com.yonge.cooleshow.biz.dal.vo.res.OrderPayRes;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import com.yonge.cooleshow.common.entity.MallOrderItemDto;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.common.enums.CacheNameEnum;
 |  |  import com.yonge.cooleshow.common.enums.CacheNameEnum;
 | 
											
												
													
														|  | -import com.yonge.cooleshow.biz.dal.enums.FrozenTypeEnum;
 |  | 
 | 
											
												
													
														|  | -import com.yonge.cooleshow.biz.dal.service.UserAccountRecordService;
 |  | 
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.vo.res.AccountTotal;
 |  |  import com.yonge.cooleshow.biz.dal.vo.res.AccountTotal;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.common.entity.HttpResponseResult;
 |  |  import com.yonge.cooleshow.common.entity.HttpResponseResult;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.common.enums.PostStatusEnum;
 |  |  import com.yonge.cooleshow.common.enums.PostStatusEnum;
 | 
											
												
													
														|  |  import com.yonge.toolset.base.exception.BizException;
 |  |  import com.yonge.toolset.base.exception.BizException;
 | 
											
												
													
														|  |  import com.yonge.toolset.payment.util.DistributedLock;
 |  |  import com.yonge.toolset.payment.util.DistributedLock;
 | 
											
												
													
														|  | -import org.redisson.api.RLock;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import com.yonge.toolset.utils.collection.ListUtil;
 | 
											
												
													
														|  |  import org.redisson.api.RedissonClient;
 |  |  import org.redisson.api.RedissonClient;
 | 
											
												
													
														|  |  import org.slf4j.Logger;
 |  |  import org.slf4j.Logger;
 | 
											
												
													
														|  |  import org.slf4j.LoggerFactory;
 |  |  import org.slf4j.LoggerFactory;
 | 
											
										
											
												
													
														|  | @@ -30,15 +32,12 @@ import com.yonge.cooleshow.biz.dal.entity.UserAccount;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.vo.UserAccountVo;
 |  |  import com.yonge.cooleshow.biz.dal.vo.UserAccountVo;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.dto.search.UserAccountSearch;
 |  |  import com.yonge.cooleshow.biz.dal.dto.search.UserAccountSearch;
 | 
											
												
													
														|  |  import com.yonge.cooleshow.biz.dal.dao.UserAccountDao;
 |  |  import com.yonge.cooleshow.biz.dal.dao.UserAccountDao;
 | 
											
												
													
														|  | -import com.yonge.cooleshow.biz.dal.service.UserAccountService;
 |  | 
 | 
											
												
													
														|  |  import org.springframework.transaction.annotation.Transactional;
 |  |  import org.springframework.transaction.annotation.Transactional;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  import java.math.BigDecimal;
 |  |  import java.math.BigDecimal;
 | 
											
												
													
														|  |  import java.math.RoundingMode;
 |  |  import java.math.RoundingMode;
 | 
											
												
													
														|  | -import java.util.Date;
 |  | 
 | 
											
												
													
														|  | -import java.util.List;
 |  | 
 | 
											
												
													
														|  | -import java.util.Objects;
 |  | 
 | 
											
												
													
														|  | -import java.util.concurrent.*;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import java.util.*;
 | 
											
												
													
														|  | 
 |  | +import java.util.stream.Collectors;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  @Service
 |  |  @Service
 | 
											
										
											
												
													
														|  | @@ -52,6 +51,12 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
 | 
											
												
													
														|  |      @Autowired
 |  |      @Autowired
 | 
											
												
													
														|  |      private UserOrderService orderService;
 |  |      private UserOrderService orderService;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    @Autowired
 | 
											
												
													
														|  | 
 |  | +    private PlatformCashAccountRecordService platformCashAccountRecordService;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    @Autowired
 | 
											
												
													
														|  | 
 |  | +    private UserOrderService userOrderService;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      @Override
 |  |      @Override
 | 
											
												
													
														|  |      public UserAccountVo detail(Long id) {
 |  |      public UserAccountVo detail(Long id) {
 | 
											
												
													
														|  |          UserAccountVo detail = baseMapper.detail(id);
 |  |          UserAccountVo detail = baseMapper.detail(id);
 | 
											
										
											
												
													
														|  | @@ -67,66 +72,139 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @Override
 |  |      @Override
 | 
											
												
													
														|  | -    public HttpResponseResult<UserAccountRecord> accountRecord(UserAccountRecordDto accountRecordDto) {
 |  | 
 | 
											
												
													
														|  | -        if (null == accountRecordDto.getInOrOut()
 |  | 
 | 
											
												
													
														|  | -                || null == accountRecordDto.getPostStatus()
 |  | 
 | 
											
												
													
														|  | -                || (!PostStatusEnum.WAIT.equals(accountRecordDto.getPostStatus()) && !PostStatusEnum.FROZEN.equals(accountRecordDto.getPostStatus()))
 |  | 
 | 
											
												
													
														|  | -        ) {
 |  | 
 | 
											
												
													
														|  | -            throw new BizException("记录入账-入账状态异常: param is {}", JSONObject.toJSONString(accountRecordDto));
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | 
 |  | +    public HttpResponseResult accountRecord(UserAccountRecordDto accountRecordDto) {
 | 
											
												
													
														|  | 
 |  | +        return accountRecord(Arrays.asList(accountRecordDto));
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        if (null == accountRecordDto.getTransAmount() || null == accountRecordDto.getBizId()
 |  | 
 | 
											
												
													
														|  | -                || null == accountRecordDto.getBizType()) {
 |  | 
 | 
											
												
													
														|  | -            throw new BizException("记录入账-缺少入账参数: param is {}", JSONObject.toJSONString(accountRecordDto));
 |  | 
 | 
											
												
													
														|  | 
 |  | +    @Override
 | 
											
												
													
														|  | 
 |  | +    public HttpResponseResult accountRecord(List<UserAccountRecordDto> accountRecordDtos) {
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isEmpty(accountRecordDtos)) {
 | 
											
												
													
														|  | 
 |  | +            return HttpResponseResult.succeed();
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | -        if (BigDecimal.ZERO.compareTo(accountRecordDto.getTransAmount()) > 0) {
 |  | 
 | 
											
												
													
														|  | -            throw new BizException("记录入账-变动金额不能为负数: param is {}", JSONObject.toJSONString(accountRecordDto));
 |  | 
 | 
											
												
													
														|  | 
 |  | +        //校验参数
 | 
											
												
													
														|  | 
 |  | +        for (UserAccountRecordDto accountRecordDto : accountRecordDtos) {
 | 
											
												
													
														|  | 
 |  | +            if (null == accountRecordDto.getInOrOut()
 | 
											
												
													
														|  | 
 |  | +                    || null == accountRecordDto.getPostStatus()
 | 
											
												
													
														|  | 
 |  | +                    || (!PostStatusEnum.WAIT.equals(accountRecordDto.getPostStatus()) && !PostStatusEnum.FROZEN.equals(accountRecordDto.getPostStatus()))
 | 
											
												
													
														|  | 
 |  | +            ) {
 | 
											
												
													
														|  | 
 |  | +                throw new BizException("记录入账-入账状态异常: param is {}", JSONObject.toJSONString(accountRecordDto));
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            if (null == accountRecordDto.getTransAmount() || null == accountRecordDto.getBizId()
 | 
											
												
													
														|  | 
 |  | +                    || null == accountRecordDto.getBizType()) {
 | 
											
												
													
														|  | 
 |  | +                throw new BizException("记录入账-缺少入账参数: param is {}", JSONObject.toJSONString(accountRecordDto));
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +            if (BigDecimal.ZERO.compareTo(accountRecordDto.getTransAmount()) > 0) {
 | 
											
												
													
														|  | 
 |  | +                if (null == accountRecordDto.getTransAmount() || null == accountRecordDto.getBizId()
 | 
											
												
													
														|  | 
 |  | +                        || null == accountRecordDto.getBizType()) {
 | 
											
												
													
														|  | 
 |  | +                    throw new BizException("记录入账-缺少入账参数: param is {}", JSONObject.toJSONString(accountRecordDto));
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +                if (BigDecimal.ZERO.compareTo(accountRecordDto.getTransAmount()) < 0) {
 | 
											
												
													
														|  | 
 |  | +                    throw new BizException("记录入账-变动金额不能为负数: param is {}", JSONObject.toJSONString(accountRecordDto));
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | 
 |  | +        //按照不同的账户分组
 | 
											
												
													
														|  | 
 |  | +        Map<Long, List<UserAccountRecordDto>> accountMap = accountRecordDtos.stream().collect(Collectors.groupingBy(UserAccountRecordDto::getAccountId));
 | 
											
												
													
														|  | 
 |  | +        Set<Long> accountIds = accountMap.keySet();
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        HttpResponseResult<UserAccountRecord> res = DistributedLock.of(redissonClient)
 |  | 
 | 
											
												
													
														|  | -                .runIfLockToFunction(CacheNameEnum.LOCK_RECORD_ACCOUNT.getRedisKey(accountRecordDto.getAccountId())
 |  | 
 | 
											
												
													
														|  | -                        , this::doAccountRecord, accountRecordDto, 10L);
 |  | 
 | 
											
												
													
														|  | -        if (null != res) {
 |  | 
 | 
											
												
													
														|  | -            return res;
 |  | 
 | 
											
												
													
														|  | -        } else {
 |  | 
 | 
											
												
													
														|  | -            throw new BizException("记录入账-插入账户记录失败: param is {}", JSONObject.toJSONString(accountRecordDto));
 |  | 
 | 
											
												
													
														|  | 
 |  | +        for (Long accountId : accountIds) {
 | 
											
												
													
														|  | 
 |  | +            List<UserAccountRecordDto> userAccountRecordDtos = accountMap.get(accountId);
 | 
											
												
													
														|  | 
 |  | +            HttpResponseResult<UserAccountRecord> res = DistributedLock.of(redissonClient)
 | 
											
												
													
														|  | 
 |  | +                    .runIfLockToFunction(CacheNameEnum.LOCK_RECORD_ACCOUNT.getRedisKey(accountId)
 | 
											
												
													
														|  | 
 |  | +                            , this::doAccountRecords, userAccountRecordDtos, 10L);
 | 
											
												
													
														|  | 
 |  | +            if (null != res) {
 | 
											
												
													
														|  | 
 |  | +                return res;
 | 
											
												
													
														|  | 
 |  | +            } else {
 | 
											
												
													
														|  | 
 |  | +                throw new BizException("记录入账-插入账户记录失败: param is {}", JSONObject.toJSONString(userAccountRecordDtos));
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | 
 |  | +        return HttpResponseResult.succeed();
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      @Transactional(rollbackFor = Exception.class)
 |  |      @Transactional(rollbackFor = Exception.class)
 | 
											
												
													
														|  | -    HttpResponseResult<UserAccountRecord> doAccountRecord(UserAccountRecordDto accountRecordDto) {
 |  | 
 | 
											
												
													
														|  | -        //收入要校验金额
 |  | 
 | 
											
												
													
														|  | -        if (InOrOutEnum.IN.equals(accountRecordDto.getInOrOut())) {
 |  | 
 | 
											
												
													
														|  | -            UserOrder userOrder = orderService.getOne(Wrappers.<UserOrder>lambdaQuery()
 |  | 
 | 
											
												
													
														|  | -                    .eq(UserOrder::getOrderNo, accountRecordDto.getOrderNo()));
 |  | 
 | 
											
												
													
														|  | -            if (null == userOrder) {
 |  | 
 | 
											
												
													
														|  | -                throw new BizException("记录入账-未找到入账对应订单信息: param is {}", JSONObject.toJSONString(accountRecordDto));
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -            //收入判断订单金额,所有收入不能大于订单用户付款
 |  | 
 | 
											
												
													
														|  | -            BigDecimal totalTransAmount = baseMapper.totalTransAmount(accountRecordDto);
 |  | 
 | 
											
												
													
														|  | -            if (null == totalTransAmount) {
 |  | 
 | 
											
												
													
														|  | -                totalTransAmount = BigDecimal.ZERO;
 |  | 
 | 
											
												
													
														|  | 
 |  | +    HttpResponseResult doAccountRecords(List<UserAccountRecordDto> accountRecordDtos) {
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isEmpty(accountRecordDtos)) {
 | 
											
												
													
														|  | 
 |  | +            return HttpResponseResult.succeed();
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        Long accountId = accountRecordDtos.get(0).getAccountId();
 | 
											
												
													
														|  | 
 |  | +        //收入入账
 | 
											
												
													
														|  | 
 |  | +        List<UserAccountRecordDto> collectIn = accountRecordDtos.stream().filter(dto -> InOrOutEnum.IN.equals(dto.getInOrOut())).collect(Collectors.toList());
 | 
											
												
													
														|  | 
 |  | +        //支出入账
 | 
											
												
													
														|  | 
 |  | +        List<UserAccountRecordDto> collectOut = accountRecordDtos.stream().filter(dto -> InOrOutEnum.OUT.equals(dto.getInOrOut())).collect(Collectors.toList());
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        //******************************************收入***********************************//
 | 
											
												
													
														|  | 
 |  | +        if (!CollectionUtils.isEmpty(collectIn)) {
 | 
											
												
													
														|  | 
 |  | +            //收入按照 业务类型-订单号-入账记录 进行分组
 | 
											
												
													
														|  | 
 |  | +            Map<AccountBizTypeEnum, Map<String, List<UserAccountRecordDto>>> collectInMap = collectIn.stream().collect(
 | 
											
												
													
														|  | 
 |  | +                    Collectors.groupingBy(UserAccountRecordDto::getBizType,
 | 
											
												
													
														|  | 
 |  | +                            Collectors.groupingBy(UserAccountRecordDto::getOrderNo)
 | 
											
												
													
														|  | 
 |  | +                    )
 | 
											
												
													
														|  | 
 |  | +            );
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            for (AccountBizTypeEnum bizType : collectInMap.keySet()) {
 | 
											
												
													
														|  | 
 |  | +                Map<String, List<UserAccountRecordDto>> collectBizTypeMap = collectInMap.get(bizType);
 | 
											
												
													
														|  | 
 |  | +                for (String orderNo : collectBizTypeMap.keySet()) {
 | 
											
												
													
														|  | 
 |  | +                    List<UserAccountRecordDto> userAccountRecords = collectBizTypeMap.get(orderNo);
 | 
											
												
													
														|  | 
 |  | +                    //本组入账金额
 | 
											
												
													
														|  | 
 |  | +                    BigDecimal transAmount = BigDecimal.ZERO;
 | 
											
												
													
														|  | 
 |  | +                    //冻结入账金额
 | 
											
												
													
														|  | 
 |  | +                    BigDecimal frozenTransAmount = BigDecimal.ZERO;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                    for (UserAccountRecordDto o : userAccountRecords) {
 | 
											
												
													
														|  | 
 |  | +                        transAmount = transAmount.add(o.getTransAmount());
 | 
											
												
													
														|  | 
 |  | +                        if (PostStatusEnum.FROZEN.equals(o.getPostStatus())) {
 | 
											
												
													
														|  | 
 |  | +                            frozenTransAmount = frozenTransAmount.add(o.getTransAmount());
 | 
											
												
													
														|  | 
 |  | +                        }
 | 
											
												
													
														|  | 
 |  | +                    }
 | 
											
												
													
														|  | 
 |  | +                    if (!checkInOrderAmount(bizType, orderNo, transAmount)) {
 | 
											
												
													
														|  | 
 |  | +                        log.error("记录入账-订单入账金额异常: bizType is {} ,orderNo is {} , transAmount is {} ", bizType.getCode(), orderNo, transAmount);
 | 
											
												
													
														|  | 
 |  | +                        throw new BizException("记录入账-订单入账金额有误");
 | 
											
												
													
														|  | 
 |  | +                    }
 | 
											
												
													
														|  | 
 |  | +                    //冻结入账
 | 
											
												
													
														|  | 
 |  | +                    if (frozenTransAmount.compareTo(BigDecimal.ZERO) > 0) {
 | 
											
												
													
														|  | 
 |  | +                        //有冻结金额入账
 | 
											
												
													
														|  | 
 |  | +                        baseMapper.frozenChangeAccount(accountId, frozenTransAmount, InOrOutEnum.IN.getCode());
 | 
											
												
													
														|  | 
 |  | +                    }
 | 
											
												
													
														|  | 
 |  | +                    //批量入账
 | 
											
												
													
														|  | 
 |  | +                    List<UserAccountRecord> records = ListUtil.convertList(userAccountRecords, UserAccountRecord.class);
 | 
											
												
													
														|  | 
 |  | +                    userAccountRecordService.saveBatch(records);
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  | -            //金额校验失败
 |  | 
 | 
											
												
													
														|  | -            if (null == userOrder || totalTransAmount.add(accountRecordDto.getTransAmount()).compareTo(userOrder.getActualPrice()) > 0) {
 |  | 
 | 
											
												
													
														|  | -                log.error("记录入账-订单入账总金额大于购买金额: param is {}" + JSONObject.toJSONString(accountRecordDto));
 |  | 
 | 
											
												
													
														|  | -                accountRecordDto.setErrFlag(1);
 |  | 
 | 
											
												
													
														|  | -                accountRecordDto.setErrMsg("账户变更异常,订单入账总金额大于购买金额,订单号:" + accountRecordDto.getOrderNo());
 |  | 
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        //******************************************支出***********************************//
 | 
											
												
													
														|  | 
 |  | +        if (!CollectionUtils.isEmpty(collectOut)) {
 | 
											
												
													
														|  | 
 |  | +            //支出入账金额
 | 
											
												
													
														|  | 
 |  | +            BigDecimal outTransAmount = BigDecimal.ZERO;
 | 
											
												
													
														|  | 
 |  | +            //冻结入账金额
 | 
											
												
													
														|  | 
 |  | +            BigDecimal frozenTransAmount = BigDecimal.ZERO;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            for (UserAccountRecordDto o : collectOut) {
 | 
											
												
													
														|  | 
 |  | +                outTransAmount = outTransAmount.add(o.getTransAmount());
 | 
											
												
													
														|  | 
 |  | +                if (PostStatusEnum.FROZEN.equals(o.getPostStatus())) {
 | 
											
												
													
														|  | 
 |  | +                    frozenTransAmount = frozenTransAmount.add(o.getTransAmount());
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  | -        } else {
 |  | 
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |              //支出 需要判断所有支出金额不能大于账户余额
 |  |              //支出 需要判断所有支出金额不能大于账户余额
 | 
											
												
													
														|  | -            UserAccountVo detail = baseMapper.detail(accountRecordDto.getAccountId());
 |  | 
 | 
											
												
													
														|  | -            if (detail.getAmountUsable().compareTo(accountRecordDto.getTransAmount()) < 0) {
 |  | 
 | 
											
												
													
														|  | -                throw new BizException("记录入账-账户余额不足: param is {}", JSONObject.toJSONString(accountRecordDto));
 |  | 
 | 
											
												
													
														|  | 
 |  | +            UserAccountVo detail = baseMapper.detail(accountId);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            if (detail.getAmountUsable().compareTo(outTransAmount) < 0) {
 | 
											
												
													
														|  | 
 |  | +                log.error("记录入账-订单入账金额异常: param is {} ", JSONObject.toJSONString(collectOut));
 | 
											
												
													
														|  | 
 |  | +                throw new BizException("记录入账-账户余额不足");
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  | 
 |  | +            //冻结入账
 | 
											
												
													
														|  | 
 |  | +            if (frozenTransAmount.compareTo(BigDecimal.ZERO) > 0) {
 | 
											
												
													
														|  | 
 |  | +                //有冻结金额入账
 | 
											
												
													
														|  | 
 |  | +                baseMapper.frozenChangeAccount(accountId, frozenTransAmount, InOrOutEnum.OUT.getCode());
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +            //批量入账
 | 
											
												
													
														|  | 
 |  | +            List<UserAccountRecord> records = ListUtil.convertList(collectOut, UserAccountRecord.class);
 | 
											
												
													
														|  | 
 |  | +            userAccountRecordService.saveBatch(records);
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | -        //如果是冻结入账,需要修改主账户冻结金额和可用余额
 |  | 
 | 
											
												
													
														|  | -        if (PostStatusEnum.FROZEN.equals(accountRecordDto.getPostStatus()) && accountRecordDto.getErrFlag() == 0) {
 |  | 
 | 
											
												
													
														|  | -            baseMapper.frozenChangeAccount(accountRecordDto.getAccountId(), accountRecordDto.getTransAmount(), accountRecordDto.getInOrOut().getCode());
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | -        //插入账户变更记录
 |  | 
 | 
											
												
													
														|  | -        userAccountRecordService.save(accountRecordDto);
 |  | 
 | 
											
												
													
														|  | -        return HttpResponseResult.succeed(accountRecordDto);
 |  | 
 | 
											
												
													
														|  | 
 |  | +        return HttpResponseResult.succeed();
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @Override
 |  |      @Override
 | 
											
										
											
												
													
														|  | @@ -154,6 +232,10 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
 | 
											
												
													
														|  |          if (null == detail) {
 |  |          if (null == detail) {
 | 
											
												
													
														|  |              throw new BizException("入账状态变更, 未找到记录信息: recordId is {} postStatus is {}", param.getId(), param.getPostStatus().getCode());
 |  |              throw new BizException("入账状态变更, 未找到记录信息: recordId is {} postStatus is {}", param.getId(), param.getPostStatus().getCode());
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | 
 |  | +        if (!PostStatusEnum.WAIT.equals(detail.getPostStatus())
 | 
											
												
													
														|  | 
 |  | +                && !PostStatusEnum.FROZEN.equals(detail.getPostStatus())) {
 | 
											
												
													
														|  | 
 |  | +            return HttpResponseResult.succeed();
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  |          detail.setPostStatus(param.getPostStatus());
 |  |          detail.setPostStatus(param.getPostStatus());
 | 
											
												
													
														|  |          //待入账
 |  |          //待入账
 | 
											
												
													
														|  |          if (PostStatusEnum.WAIT.equals(detail.getPostStatus())) {
 |  |          if (PostStatusEnum.WAIT.equals(detail.getPostStatus())) {
 | 
											
										
											
												
													
														|  | @@ -279,5 +361,116 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
 | 
											
												
													
														|  |          return HttpResponseResult.succeed(total);
 |  |          return HttpResponseResult.succeed(total);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 判断是否可以入账
 | 
											
												
													
														|  | 
 |  | +     *
 | 
											
												
													
														|  | 
 |  | +     * @param bizType     入账类型
 | 
											
												
													
														|  | 
 |  | +     * @param orderNo     该笔入账对应订单号
 | 
											
												
													
														|  | 
 |  | +     * @param transAmount 入账金额
 | 
											
												
													
														|  | 
 |  | +     * @return
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private Boolean checkInOrderAmount(AccountBizTypeEnum bizType, String orderNo, BigDecimal transAmount) {
 | 
											
												
													
														|  | 
 |  | +        BigDecimal orderExpectPrice = BigDecimal.ZERO;
 | 
											
												
													
														|  | 
 |  | +        if (AccountBizTypeEnum.MALL_SHARE.equals(bizType)) {
 | 
											
												
													
														|  | 
 |  | +            return true;
 | 
											
												
													
														|  | 
 |  | +        } else {
 | 
											
												
													
														|  | 
 |  | +            UserOrder userOrder = orderService.getOne(Wrappers.<UserOrder>lambdaQuery()
 | 
											
												
													
														|  | 
 |  | +                    .eq(UserOrder::getOrderNo, orderNo));
 | 
											
												
													
														|  | 
 |  | +            if (null == userOrder) {
 | 
											
												
													
														|  | 
 |  | +                return false;
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +            orderExpectPrice = userOrder.getExpectPrice();
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        //收入判断订单金额,所有收入不能大于订单用户付款
 | 
											
												
													
														|  | 
 |  | +        BigDecimal totalTransAmount = baseMapper.totalTransAmountByOrderNo(orderNo);
 | 
											
												
													
														|  | 
 |  | +        if (null == totalTransAmount) {
 | 
											
												
													
														|  | 
 |  | +            totalTransAmount = BigDecimal.ZERO;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        //金额校验失败
 | 
											
												
													
														|  | 
 |  | +        if (totalTransAmount.add(transAmount).compareTo(orderExpectPrice) > 0) {
 | 
											
												
													
														|  | 
 |  | +            return false;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        return true;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    @Override
 | 
											
												
													
														|  | 
 |  | +    public void mallTeacherRecordState(List<MallOrderItemDto> shareDto) {
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isEmpty(shareDto)) {
 | 
											
												
													
														|  | 
 |  | +            return ;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        for (MallOrderItemDto mallOrderItemDto : shareDto) {
 | 
											
												
													
														|  | 
 |  | +            mallTeacherRecordState(mallOrderItemDto);
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    public void mallTeacherRecordState(MallOrderItemDto shareDto) {
 | 
											
												
													
														|  | 
 |  | +        List<UserAccountRecord> list = userAccountRecordService.lambdaQuery()
 | 
											
												
													
														|  | 
 |  | +                                                               .eq(UserAccountRecord::getOrderNo, shareDto.getOrderSn())
 | 
											
												
													
														|  | 
 |  | +                                                               .eq(UserAccountRecord::getBizId, shareDto.getProductSkuId())
 | 
											
												
													
														|  | 
 |  | +                                                               .list();
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isEmpty(list)) {
 | 
											
												
													
														|  | 
 |  | +            return;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        for (UserAccountRecord userAccount : list) {
 | 
											
												
													
														|  | 
 |  | +            this.accountChange(userAccount.getId(),shareDto.getStatus());
 | 
											
												
													
														|  | 
 |  | +            if (shareDto.getStatus().equals(PostStatusEnum.RECORDED)) {
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                platformCashAccountRecordService.mallRecordedRecord(shareDto.getProductSkuId(),shareDto.getOrderSn(),GoodTypeEnum.MALL.getCode());
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +            } else if (shareDto.getStatus().equals(PostStatusEnum.CANCEL)) {
 | 
											
												
													
														|  | 
 |  | +                platformCashAccountRecordService.cancelRecord(shareDto.getOrderSn(),GoodTypeEnum.MALL.getCode(),shareDto.getProductSkuId());
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 记录平台收入和用户分润收入
 | 
											
												
													
														|  | 
 |  | +     * @return
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    @Override
 | 
											
												
													
														|  | 
 |  | +    public boolean saveMallAccountRecord(List<MallOrderItemDto> shareDto) {
 | 
											
												
													
														|  | 
 |  | +        if (CollectionUtils.isEmpty(shareDto)) {
 | 
											
												
													
														|  | 
 |  | +            return false;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        for (MallOrderItemDto mallOrderItemDto : shareDto) {
 | 
											
												
													
														|  | 
 |  | +            saveMallAccountRecord(mallOrderItemDto);
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        return true;
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    public void saveMallAccountRecord(MallOrderItemDto shareDto) {
 | 
											
												
													
														|  | 
 |  | +        BigDecimal expectPrice = shareDto.getRealAmount();
 | 
											
												
													
														|  | 
 |  | +        if (expectPrice.compareTo(BigDecimal.ZERO) <= 0) {
 | 
											
												
													
														|  | 
 |  | +            return;
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        //平台收入
 | 
											
												
													
														|  | 
 |  | +        PlatformCashAccountRecord platformCashAccountRecord = new PlatformCashAccountRecord(shareDto.getUserId(), expectPrice,
 | 
											
												
													
														|  | 
 |  | +                          InOrOutEnum.IN, PostStatusEnum.WAIT, AccountBizTypeEnum.MALL, shareDto.getProductSkuId(), shareDto.getOrderSn());
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        platformCashAccountRecordService.save(platformCashAccountRecord);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +        //分润
 | 
											
												
													
														|  | 
 |  | +        if (null != shareDto.getPromoterId()) {
 | 
											
												
													
														|  | 
 |  | +            //获取分润收益费率
 | 
											
												
													
														|  | 
 |  | +            BigDecimal shareFeeRate = userOrderService.getShareFreeByGoodType(GoodTypeEnum.MALL);
 | 
											
												
													
														|  | 
 |  | +            if (shareFeeRate.compareTo(BigDecimal.ZERO) > 0) {
 | 
											
												
													
														|  | 
 |  | +                //入老师账户
 | 
											
												
													
														|  | 
 |  | +                BigDecimal shareFee = expectPrice.multiply(shareFeeRate).setScale(2, RoundingMode.HALF_UP);
 | 
											
												
													
														|  | 
 |  | +                AccountBizTypeEnum bizTypeEnum = AccountBizTypeEnum.MALL_SHARE;
 | 
											
												
													
														|  | 
 |  | +                //插入分润老师账户变更记录-分润老师预收
 | 
											
												
													
														|  | 
 |  | +                HttpResponseResult<UserAccountRecord> recomRecordRes = this.accountRecord(
 | 
											
												
													
														|  | 
 |  | +                        new UserAccountRecordDto(shareDto.getPromoterId(), PostStatusEnum.WAIT, shareFee, InOrOutEnum.IN,
 | 
											
												
													
														|  | 
 |  | +                                                 bizTypeEnum, shareDto.getProductSkuId(), shareDto.getProductName(), shareDto.getOrderSn()));
 | 
											
												
													
														|  | 
 |  | +                if(recomRecordRes.getStatus()){
 | 
											
												
													
														|  | 
 |  | +                    //插入平台预支
 | 
											
												
													
														|  | 
 |  | +                    platformCashAccountRecord = new PlatformCashAccountRecord(shareDto.getPromoterId(), shareFee,
 | 
											
												
													
														|  | 
 |  | +                            InOrOutEnum.OUT, PostStatusEnum.WAIT, AccountBizTypeEnum.MALL_SHARE, shareDto.getProductSkuId(), shareDto.getOrderSn());
 | 
											
												
													
														|  | 
 |  | +                    platformCashAccountRecordService.save(platformCashAccountRecord);
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +            }
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +    }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  }
 |  |  }
 |