
package com.tmerclub.cloud.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import com.tmerclub.cloud.api.order.constant.OrderStatus;
import com.tmerclub.cloud.api.order.feign.OrderFeignClient;
import com.tmerclub.cloud.api.order.feign.OrderRefundFeignClient;
import com.tmerclub.cloud.api.order.vo.OrderRefundVO;
import com.tmerclub.cloud.api.payment.constant.PaySysType;
import com.tmerclub.cloud.api.platform.feign.ConfigFeignClient;
import com.tmerclub.cloud.api.user.bo.UserOrderScoreBo;
import com.tmerclub.cloud.api.user.dto.UserExtensionDTO;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.order.bo.EsOrderBO;
import com.tmerclub.cloud.common.order.bo.EsOrderItemBO;
import com.tmerclub.cloud.common.order.constant.OrderCloseType;
import com.tmerclub.cloud.common.order.constant.OrderType;
import com.tmerclub.cloud.common.order.constant.ReturnProcessStatusEnum;
import com.tmerclub.cloud.common.response.ResponseEnum;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.rocketmq.config.RocketMqConstant;
import com.tmerclub.cloud.common.util.Arith;
import com.tmerclub.cloud.common.util.Json;
import com.tmerclub.cloud.common.util.PriceUtil;
import com.tmerclub.cloud.user.bo.mongo.MongoUserBalanceLogBO;
import com.tmerclub.cloud.user.bo.mongo.MongoUserScoreLogBO;
import com.tmerclub.cloud.user.constant.*;
import com.tmerclub.cloud.user.mapper.UserExtensionMapper;
import com.tmerclub.cloud.user.model.UserExtension;
import com.tmerclub.cloud.user.model.UserGrowthLog;
import com.tmerclub.cloud.user.model.UserScoreGetLog;
import com.tmerclub.cloud.user.model.UserScoreLog;
import com.tmerclub.cloud.user.service.*;
import com.tmerclub.cloud.user.vo.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 用户扩展信息
 *
 * @author YXF
 * @date 2020-12-08 10:16:53
 */
@Service
public class UserExtensionServiceImpl implements UserExtensionService {

    private static final Logger log = LoggerFactory.getLogger(UserExtensionServiceImpl.class);

    @Autowired
    private UserExtensionMapper userExtensionMapper;
    @Autowired
    private UserLevelService userLevelService;
    @Autowired
    private UserRightsService userRightsService;
    @Autowired
    private UserScoreLogService userScoreLogService;
    @Autowired
    private UserScoreGetLogService userScoreGetLogService;
    @Autowired
    private UserGrowthLogService userGrowthLogService;
    @Autowired
    private SegmentManager segmentManager;
    @Autowired
    private RocketMQTemplate addUserScoreLogTemplate;
    @Autowired
    private RocketMQTemplate addUserBalanceLogTemplate;
    @DubboReference
    private ConfigFeignClient configFeignClient;
    @DubboReference
    private OrderFeignClient orderFeignClient;
    @DubboReference
    private OrderRefundFeignClient orderRefundFeignClient;


    @Override
    public PageVO<UserExtensionVO> page(PageDTO pageDTO) {
        return PageUtil.doPage(pageDTO, () -> userExtensionMapper.list());
    }

    @Override
    public UserExtension getByUserExtensionId(Long userExtensionId) {
        return userExtensionMapper.getByUserExtensionId(userExtensionId);
    }

    @Override
    public void save(UserExtension userExtension) {
        userExtensionMapper.save(userExtension);
    }

    @Override
    public void update(UserExtension userExtension) {
        userExtensionMapper.update(userExtension);
    }

    @Override
    public void deleteById(Long userExtensionId) {
        userExtensionMapper.deleteById(userExtensionId);
    }

    @Override
    public void updateUserLevel(Integer level, int minGrowth, Integer maxGrowth) {
        userExtensionMapper.updateUserLevel(level, minGrowth, maxGrowth);
    }

    @Override
    public void updateUserScoreOrGrowth(List<Long> userIds, Long score, Integer growth) {
        if (Objects.isNull(score) && Objects.isNull(growth)) {
            return;
        }
        //增加/减少积分或者成长值 , sql中处理积分和成长值不能为负数，最小为0
        userExtensionMapper.updateUserScoreOrGrowth(userIds, score, growth);
    }

    @Override
    public List<UserExtension> getByUserIdsAndLevelType(List<Long> userIds) {
        return userExtensionMapper.getByUserIdsAndLevelType(userIds);
    }

    @Override
    public UserExtension getByUserId(Long userId) {
        return userExtensionMapper.getByUserId(userId);
    }


    @Override
    public void updateBatchUserBalanceByUserIds(List<Long> userIds, Long balance, DateTime now) {
        userExtensionMapper.updateBatchUserBalanceByUserIds(userIds, balance, now);
    }

    @Override
    public List<UserExtension> filterExistExtensions(List<UserExtension> userExtensions) {
        return userExtensionMapper.filterExistExtensions(userExtensions);
    }

    @Override
    public void saveBatch(List<UserExtension> userExtensionList) {
        userExtensionMapper.saveBatch(userExtensionList);
    }

    @Override
    public void updateScoreAndGrowth(Long orderId) {
        ServerResponseEntity<EsOrderBO> esOrderBoServerResponseEntity = orderFeignClient.getEsOrder(orderId);
        if (!esOrderBoServerResponseEntity.isSuccess()) {
            throw new LuckException(esOrderBoServerResponseEntity.getMsg());
        }
        EsOrderBO esOrderBO = esOrderBoServerResponseEntity.getData();
        // 如果订单已经关闭（整单都已经退款了）不需要进行积分、成长值结算
        if (Objects.equals(esOrderBO.getStatus(), OrderStatus.CLOSE.value()) && Objects.equals(esOrderBO.getCloseType(), OrderCloseType.REFUND.value())) {
            return;
        }
        // 如果是积分订单不能获取成长值和积分
        if (Objects.equals(esOrderBO.getOrderType(), OrderType.SCORE.value())) {
            return;
        }
        // 判断订单是否有订单项退款成功，如果有减少用户可以获取的部分积分
        ServerResponseEntity<List<OrderRefundVO>> orderRefundListServerResponseEntity = orderRefundFeignClient.getOrderRefundByOrderIdAndRefundStatus(esOrderBO.getOrderId(), ReturnProcessStatusEnum.SUCCESS.value());
        if (!orderRefundListServerResponseEntity.isSuccess()) {
            throw new LuckException(orderRefundListServerResponseEntity.getMsg());
        }
        List<OrderRefundVO> orderRefunds = orderRefundListServerResponseEntity.getData();
        List<Long> orderItemIds = new ArrayList<>(Constant.INITIAL_CAPACITY);
        if (CollectionUtils.isNotEmpty(orderRefunds)) {
            orderRefunds.forEach(refund -> orderItemIds.add(refund.getOrderItemId()));
        }
        // 这里保证了其幂等性
        UserScoreLog orderScoreLog = userScoreLogService.getOrderScoreLog(esOrderBO.getUserId(), esOrderBO.getOrderId(), ScoreLogTypeEnum.SHOP.value(), 1);
        if (Objects.nonNull(orderScoreLog)) {
            return;
        }
        // 根据比例取可以获取的积分上限
        List<EsOrderItemBO> products = esOrderBO.getOrderItems();
        // 筛选用户可以获得的订单项积分
        products = products.stream().filter(prodOrderParam -> orderItemIds.stream().noneMatch(
                orderItemId -> Objects.equals(orderItemId, prodOrderParam.getOrderItemId()))).collect(Collectors.toList());
        // 获取积分和成长值获取比例
        ServerResponseEntity<String> scoreConfigServerResponseEntity = configFeignClient.getConfig(Constant.SCORE_CONFIG);
        if (!scoreConfigServerResponseEntity.isSuccess()) {
            throw new LuckException(scoreConfigServerResponseEntity.getMsg());
        }
        ScoreCompleteConfigVO scoreParam = Json.parseObject(scoreConfigServerResponseEntity.getData(), ScoreCompleteConfigVO.class);
        ServerResponseEntity<String> growthConfigServerResponseEntity = configFeignClient.getConfig(Constant.GROWTH_CONFIG);
        if (!growthConfigServerResponseEntity.isSuccess()) {
            throw new LuckException(growthConfigServerResponseEntity.getMsg());
        }
        GrowthCompleteConfigVO growthCompleteConfigVO = Json.parseObject(growthConfigServerResponseEntity.getData(), GrowthCompleteConfigVO.class);
        if (Objects.isNull(scoreParam) && Objects.isNull(growthCompleteConfigVO)) {
            return;
        }
        UserExtension userExtension = this.getByUserId(esOrderBO.getUserId());
        //初始每笔订单可以获取的成长值
        double growthPrice = Objects.requireNonNull(growthCompleteConfigVO).getBuyOrder();
        double getRatioLimit = Objects.isNull(scoreParam) || Objects.isNull(scoreParam.getGetRatioLimit()) ? 0.0 : scoreParam.getGetRatioLimit();
        long totalScore = 0;
        //需要批量修改的orderItem
        List<com.tmerclub.cloud.common.order.vo.OrderItemVO> orderItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (EsOrderItemBO product : products) {
            double scoreLimit;
            double score = Arith.div(product.getActualTotal(), Objects.requireNonNull(scoreParam).getShoppingGetScore());
            //计算出成长值
            growthPrice += Arith.div(PriceUtil.toDecimalPrice(product.getActualTotal()).doubleValue(), growthCompleteConfigVO.getBuyPrice());
            //判断积分购物获取是全平台还是根据分类上限
            scoreLimit = Arith.div(Arith.mul(esOrderBO.getActualTotal(), getRatioLimit), 100);
            //上限取最小值
            score = Math.min(score, scoreLimit);
            //根据用户等级获取积分倍数
            List<UserRightsVO> userRights = userRightsService.listRightByLevel(userExtension.getLevel(), userExtension.getLevelType());
            for (UserRightsVO userRightsVO : userRights) {
                if (userRightsVO.getRateScore() != null && userRightsVO.getRateScore() > 1) {
                    score = Arith.div(Arith.mul(score, userRightsVO.getRateScore()), 10);
                }
            }
            long gainScore = (long) score;
            if (gainScore <= 0) {
                continue;
            }
            com.tmerclub.cloud.common.order.vo.OrderItemVO orderItem = new com.tmerclub.cloud.common.order.vo.OrderItemVO();
            orderItem.setOrderItemId(product.getOrderItemId());
            orderItem.setGainScore(gainScore);
            orderItems.add(orderItem);
            totalScore += gainScore;
        }
        checkScoreAndGrowth(esOrderBO, Objects.requireNonNull(scoreParam), growthCompleteConfigVO, userExtension, growthPrice, totalScore, orderItems);
    }

    private void checkScoreAndGrowth(EsOrderBO esOrderBO, ScoreCompleteConfigVO scoreParam, GrowthCompleteConfigVO growthCompleteConfigVO, UserExtension userExtension, double growthPrice, long totalScore, List<com.tmerclub.cloud.common.order.vo.OrderItemVO> orderItems) {
        // 如果成长值获取开关关闭了，则无法获取成长值
        if (Objects.isNull(growthCompleteConfigVO.getShopGrowthSwitch()) || !growthCompleteConfigVO.getShopGrowthSwitch()) {
            growthPrice = 0;
        }
        if (CollectionUtils.isNotEmpty(orderItems) && totalScore > 0) {
            orderFeignClient.updateOrderItemBatchById(orderItems);
        }
        // 成长值和积分大于0 增加用户成长值和积分
        if (growthPrice > 0 || totalScore > 0) {
            userLevelService.addGrowthAndScore(growthPrice, totalScore, esOrderBO.getUserId(), esOrderBO.getOrderId(), userExtension, 1);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void refundScore(UserOrderScoreBo userOrderScoreBo) {
        Long orderId = userOrderScoreBo.getOrderId();
        List<MongoUserScoreLogBO> saveUserScoreLogList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        UserScoreGetLog userScoreGetLog = userScoreGetLogService.getLogByBizId(orderId);
        if (Objects.nonNull(userScoreGetLog)) {
            Long completeOrderBack = userScoreGetLog.getUsableScore();
            MongoUserScoreLogBO userScoreLog = new MongoUserScoreLogBO();
            userScoreLog.setLogId(segmentManager.getSegmentId(DistributedIdKey.tmerclub_USER_SCORE_LOG));
            userScoreLog.setUserId(userOrderScoreBo.getUserId());
            userScoreLog.setSource(ScoreLogTypeEnum.COMPLETE_ORDER_BACK.value());
            userScoreLog.setScore(completeOrderBack);
            userScoreLog.setBizId(userOrderScoreBo.getRefundId());
            userScoreLog.setIoType(ScoreIoTypeEnum.EXPENDITURE.value());
            saveUserScoreLogList.add(userScoreLog);
            userScoreGetLog.setStatus(-1);
            userScoreGetLogService.update(userScoreGetLog);
            userExtensionMapper.updateUserScoreOrGrowth(Collections.singletonList(userOrderScoreBo.getUserId()), -completeOrderBack, null);
        }

        // 如果没有使用积分抵扣就不需要退回积分给用户
        if (Objects.isNull(userOrderScoreBo.getOrderScore()) || Objects.equals(0L, userOrderScoreBo.getOrderScore())) {
            saveUserScoreLog(saveUserScoreLogList);
            return;
        }

        ServerResponseEntity<EsOrderBO> esOrder = orderFeignClient.getEsOrder(orderId);
        if (!esOrder.isSuccess()) {
            throw new LuckException(esOrder.getMsg());
        }
        Long refundId = userOrderScoreBo.getRefundId();
        ServerResponseEntity<OrderRefundVO> orderRefundResponse = orderRefundFeignClient.getOrderRefundByRefundId(refundId);
        if (!orderRefundResponse.isSuccess()) {
            throw new LuckException(esOrder.getMsg());
        }
        EsOrderBO orderBO = esOrder.getData();
        // 获取退款项
        OrderRefundVO orderRefundVO = orderRefundResponse.getData();
        // 获取退还积分
        Long orderScore;
        if (Objects.equals(1, orderRefundVO.getRefundType())) {
            // 整单退款，退款的积分是整个订单的抵扣积分数值
            orderScore = orderBO.getOrderScore();
        } else {
            // 单个退款，退款积分是该订单项下单优惠的积分抵扣数值
            // 单个退款，一定是有orderItemId的
            Long orderItemId = orderRefundVO.getOrderItemId();
            List<EsOrderItemBO> orderItems = orderBO.getOrderItems();
            EsOrderItemBO orderItemVO = orderItems.stream().filter(item -> Objects.equals(item.getOrderItemId(), orderItemId)).findAny().orElse(null);
            orderScore = Objects.isNull(orderItemVO) ? 0L : orderItemVO.getUseScore();
        }
        // 退款退积分比例逻辑：下单选择了积分抵扣，如果订单退款，只退了支付的部分金额，抵扣的积分是退款订单项的抵扣使用积分全部都退回
        if (Objects.isNull(orderScore) || orderScore <= 0L) {
            saveUserScoreLog(saveUserScoreLogList);
            return;
        }
        Long userId = orderBO.getUserId();
        // 查看是否已有退还记录,如果已经退过积分了，就不用再次退积分了
        // 这里保证了其幂等性
        UserScoreLog orderScoreLog = userScoreLogService.getOrderScoreLog(userId, refundId, ScoreLogTypeEnum.SCORE_CASH_BACK.value(), 1);
        if (Objects.nonNull(orderScoreLog)) {
            saveUserScoreLog(saveUserScoreLogList);
            return;
        }
        MongoUserScoreLogBO userScoreLog = new MongoUserScoreLogBO();
        userScoreLog.setLogId(segmentManager.getSegmentId(DistributedIdKey.tmerclub_USER_SCORE_LOG));
        userScoreLog.setUserId(orderBO.getUserId());
        userScoreLog.setSource(ScoreLogTypeEnum.SCORE_CASH_BACK.value());
        userScoreLog.setScore(orderScore);
        userScoreLog.setBizId(refundId);
        userScoreLog.setIoType(ScoreIoTypeEnum.INCOME.value());

        UserScoreGetLog addDetail = new UserScoreGetLog();
        addDetail.setStatus(ScoreGetLogStatusEnum.NORMAL.value());
        addDetail.setUserId(userId);
        addDetail.setUsableScore(orderScore);

        saveUserScoreLogList.add(userScoreLog);
        userScoreGetLogService.save(addDetail);
        userExtensionMapper.updateUserScoreOrGrowth(Collections.singletonList(userId), orderScore, null);
        saveUserScoreLog(saveUserScoreLogList);
    }

    private void saveUserScoreLog(List<MongoUserScoreLogBO> saveUserScoreLogList) {
        SendStatus sendStatus = addUserScoreLogTemplate.syncSend(RocketMqConstant.ADD_USER_SCORE_LOG_TOPIC, new GenericMessage<>(saveUserScoreLogList)).getSendStatus();
        if (!Objects.equals(sendStatus, SendStatus.SEND_OK)) {
            // 消息发不出去就抛异常，发的出去无所谓
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void registerUserScoreGrowthBalanceLog(List<UserExtension> userExtensionList) {
        // 积分、成长值、余额日志
        if (CollUtil.isEmpty(userExtensionList)) {
            return;
        }
        List<MongoUserScoreLogBO> userScoreLogs = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<UserScoreGetLog> userScoreDetails = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<UserGrowthLog> userGrowthLogs = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<MongoUserBalanceLogBO> userBalanceLogs = new ArrayList<>(Constant.INITIAL_CAPACITY);

        List<Long> userBalanceLogIds = segmentManager.listSegmentId(DistributedIdKey.tmerclub_USER_BALANCE_LOG, userExtensionList.size());
        List<Long> userScoreLogIds = segmentManager.listSegmentId(DistributedIdKey.tmerclub_USER_SCORE_LOG, userExtensionList.size());

        int index = 0;
        for (UserExtension userExtension : userExtensionList) {
            Long userId = userExtension.getUserId();
            Integer growth = userExtension.getGrowth();
            Long score = userExtension.getScore();
            Long balance = userExtension.getBalance();
            // 积分日志
            if (score > 0) {
                MongoUserScoreLogBO userScoreLog = new MongoUserScoreLogBO();
                userScoreLog.setLogId(userScoreLogIds.get(index));
                userScoreLog.setUserId(userId);
                userScoreLog.setSource(ScoreLogTypeEnum.SYSTEM.value());
                userScoreLog.setScore(score);
                userScoreLog.setIoType(ScoreIoTypeEnum.INCOME.value());
                userScoreLogs.add(userScoreLog);
                // 积分明细
                UserScoreGetLog userScoreGetLog = new UserScoreGetLog();
                userScoreGetLog.setUserId(userId);
                userScoreGetLog.setUsableScore(score);
                userScoreGetLog.setStatus(ScoreGetLogStatusEnum.NORMAL.value());
                userScoreDetails.add(userScoreGetLog);
            }
            if (growth > 0) {
                // 成长值
                UserGrowthLog userGrowthLog = new UserGrowthLog();
                userGrowthLog.setUserId(userId);
                userGrowthLog.setSource(GrowthLogSourceEnum.SYSTEM.value());
                userGrowthLog.setChangeGrowth(growth);
                userGrowthLog.setRemarks("导入初始化设置成长值");
                userGrowthLogs.add(userGrowthLog);
            }
            if (balance > 0) {
                // 余额日志
                MongoUserBalanceLogBO userBalanceLog = new MongoUserBalanceLogBO();
                userBalanceLog.setBalanceLogId(userBalanceLogIds.get(index));
                userBalanceLog.setUserId(userId);
                userBalanceLog.setChangeBalance(balance);
                userBalanceLog.setIoType(RechargeIoTypeEnum.INCOME.value());
                userBalanceLog.setType(RechargeTypeEnum.SYSTEM.value());
                userBalanceLog.setPaySysType(PaySysType.DEFAULT.value());
                userBalanceLogs.add(userBalanceLog);
            }
            index++;
        }
        if (CollUtil.isNotEmpty(userGrowthLogs)) {
            userGrowthLogService.saveBatch(userGrowthLogs);
        }
        if (CollUtil.isNotEmpty(userScoreLogs)) {
            userScoreGetLogService.saveBatch(userScoreDetails);
            saveUserScoreLog(userScoreLogs);
        }
        if (CollUtil.isNotEmpty(userBalanceLogs)) {
            saveUserBalanceLog(userBalanceLogs);
        }
    }

    private void saveUserBalanceLog(List<MongoUserBalanceLogBO> userBalanceLogs) {
        SendStatus sendStatus = addUserBalanceLogTemplate.syncSend(RocketMqConstant.ADD_USER_BALANCE_LOG_TOPIC, new GenericMessage<>(userBalanceLogs)).getSendStatus();
        if (!Objects.equals(sendStatus, SendStatus.SEND_OK)) {
            // 消息发不出去就抛异常，发的出去无所谓
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
    }

    @Override
    public void updateByUserRecharge(UserRechargeVO userRechargeVO, MongoUserBalanceLogBO userBalanceLog) {
        userExtensionMapper.updateByUserRecharge(userRechargeVO, userBalanceLog);
    }

    @Override
    public void addByUserBalanceLog(MongoUserBalanceLogBO userBalanceLog) {
        UserExtension userExtension = userExtensionMapper.getByUserId(userBalanceLog.getUserId());
        if (Objects.equals(userBalanceLog.getPaySysType(), PaySysType.DEFAULT.value())) {
            // 修改默认余额(退款增加的余额不加到总余额中)
            if (!Objects.equals(userBalanceLog.getType(), RechargeTypeEnum.REFUND.value())) {
                userExtension.setBalance(userExtension.getBalance() + userBalanceLog.getChangeBalance());
            }
            userExtension.setActualBalance(userExtension.getActualBalance() + userBalanceLog.getChangeBalance());
        } else if (Objects.equals(userBalanceLog.getPaySysType(), PaySysType.ALLINPAY.value())) {
            // 修改通联余额(退款增加的余额不加到总余额中)
            if (!Objects.equals(userBalanceLog.getType(), RechargeTypeEnum.REFUND.value())) {
                userExtension.setAllinpayBalance(userExtension.getAllinpayBalance() + userBalanceLog.getChangeBalance());
            }
            userExtension.setAllinpayActualBalance(userExtension.getAllinpayActualBalance() + userBalanceLog.getChangeBalance());
        } else {
            return;
        }
        // 更新数据
        userExtensionMapper.update(userExtension);
//        userExtensionMapper.addByUserBalanceLog(userBalanceLog);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeAllinpayBalance(Long userId, Long balance, Integer type) {
        // 修改通联余额（余额增加，累计余额也进行计算）
        UserExtension userExtension = userExtensionMapper.getByUserId(userId);
        if (balance > 0
                && !Objects.equals(type, RechargeTypeEnum.REFUND.value())) {
            userExtension.setAllinpayBalance(userExtension.getAllinpayBalance() + balance);
        }
        userExtension.setAllinpayActualBalance(userExtension.getAllinpayActualBalance() + balance);
        userExtensionMapper.update(userExtension);
        // 插入用户余额日志
        MongoUserBalanceLogBO userBalanceLog = new MongoUserBalanceLogBO();
        userBalanceLog.setBalanceLogId(segmentManager.getSegmentId(DistributedIdKey.tmerclub_USER_BALANCE_LOG));
        userBalanceLog.setUserId(userId);
        userBalanceLog.setChangeBalance(Math.abs(balance));
        userBalanceLog.setIoType(balance >= 0L ? 1 : 0);
        userBalanceLog.setType(type);
        userBalanceLog.setIsPayed(1);
        userBalanceLog.setPaySysType(PaySysType.ALLINPAY.value());
        saveUserBalanceLog(Collections.singletonList(userBalanceLog));
    }

    @Override
    public List<UserExtensionVO> listUserExtensions(UserExtensionDTO userExtensionDTO) {
        return userExtensionMapper.listUserExtensions(userExtensionDTO);
    }

    @Override
    public void updateBatchStatus(UserExtensionDTO userExtensionDTO, List<Long> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return;
        }
        userExtensionMapper.updateBatchStatus(userExtensionDTO, userIds);
    }
}
