zainali5120
2021-03-31 55a4f22db43ec34bc7f59103f4a94005bd613850
Merge remote-tracking branch 'origin/activity' into activity
22 files modified
549 ■■■■ changed files
src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java 132 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java 17 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/dao/ContractOrderDao.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/parameter/dto/SymbolDto.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java 66 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java 53 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java 45 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerProfitDao.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderProfitDetailDao.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java 51 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java 27 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/LoopExecutorJob.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/CalculateUtil.java 43 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/contract/ContractOrderDao.xml 19 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml 7 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml 26 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/documentary/FollowTraderProfitDetailDao.xml 13 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/MemberAccountMoneyChangeDao.xml 2 ●●● patch | view | raw | blame | history
src/test/java/com/xcong/excoin/WholeTest.java 19 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java
@@ -9,7 +9,13 @@
import javax.annotation.Resource;
import javax.validation.Valid;
import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity;
import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
import com.xcong.excoin.modules.contract.entity.ContractOrderEntity;
import com.xcong.excoin.modules.platform.entity.PlatformCnyUsdtExchangeEntity;
import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
import com.xcong.excoin.utils.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -48,10 +54,6 @@
import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity;
import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity;
import com.xcong.excoin.modules.platform.dao.PlatformCnyUsdtExchangeDao;
import com.xcong.excoin.utils.CoinTypeConvert;
import com.xcong.excoin.utils.MessageSourceUtils;
import com.xcong.excoin.utils.RedisUtils;
import com.xcong.excoin.utils.ThreadPoolUtils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -81,6 +83,10 @@
    MemberCoinWithdrawDao memberCoinWithdrawDao;
    @Resource
    RedisUtils redisUtils;
    @Resource
    CacheSettingUtils cacheSettingUtils;
    @Resource
    ContractHoldOrderDao contractHoldOrderDao;
    @Override
@@ -318,7 +324,9 @@
            //更新合约全仓模式下的订单权益
            MemberEntity memberEntity = memberDao.selectById(memberId);
            String symbols = symbol+"/USDT";
            ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
            //ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
            // 全仓爆仓
            ThreadPoolUtils.sendWholePrice(memberEntity.getId());
            
            //添加币币资金划转历史记录
            MemberAccountMoneyChange memberAccountRecord = new MemberAccountMoneyChange();
@@ -402,15 +410,53 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result contractTransferToWalletCoins(BigDecimal balance, String symbol) {
        if (balance.compareTo(BigDecimal.ZERO) <= 0) {
        //获取用户ID
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        MemberEntity memberEntity = memberDao.selectById(memberId);
        if (balance.compareTo(BigDecimal.ZERO) <= 0) {
            return Result.fail(MessageSourceUtils.getString("member_service_0004"));
        }
        //获取用户ID
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        //获取合约当前持仓类型
        Integer contractPositionType = memberEntity.getContractPositionType();
        // 总盈利
        BigDecimal totalProfitOrLess = BigDecimal.ZERO;
        if(contractPositionType == 2){
            //获取全仓模式下的所有持仓信息
            PlatformTradeSettingEntity tradeSetting = cacheSettingUtils.getTradeSetting();
            List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListForWholeByMemberIdAndSymbol(memberEntity.getId(),"");
            if (CollUtil.isNotEmpty(holdOrderEntities)) {
                for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
                    // 获取最新价
                    BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(holdOrderEntity.getSymbol())));
                    BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(holdOrderEntity.getSymbol());
                    // 单个订单盈利
                    BigDecimal profitOrLess = BigDecimal.ZERO;
                    // 开多
                    if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
                        profitOrLess = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
                        // 开空
                    } else {
                        profitOrLess = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
                    }
                    if (MemberEntity.IS_PROFIT_Y == memberEntity.getIsProfit()) {
                        if (profitOrLess.compareTo(BigDecimal.ZERO) > 0) {
                            profitOrLess = profitOrLess.multiply(BigDecimal.ONE.subtract(tradeSetting.getForceParam()));
                        } else {
                            profitOrLess = profitOrLess.multiply(BigDecimal.ONE.add(tradeSetting.getForceParam()));
                        }
                    }
                    totalProfitOrLess = totalProfitOrLess.add(profitOrLess);
                }
            }
        }
        String walletCode = MemberWalletCoinEnum.WALLETCOINCODE.getValue();
        MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberId, symbol);
        BigDecimal availableBalance = walletContract.getAvailableBalance();
        //可用减去盈亏
        if(totalProfitOrLess.compareTo(BigDecimal.ZERO) < 0){
            availableBalance = availableBalance.add(totalProfitOrLess);
        }
        // 扣币
        BigDecimal availableSubtract = availableBalance.subtract(balance);
        if (availableSubtract.compareTo(BigDecimal.ZERO) < 0) {
@@ -438,11 +484,9 @@
        if (updateById < 1) {
            return Result.fail(MessageSourceUtils.getString("member_service_0096"));
        }
        //更新合约全仓模式下的订单权益
        MemberEntity memberEntity = memberDao.selectById(memberId);
        String symbols = symbol+"/USDT";
        ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
        // 全仓爆仓
        ThreadPoolUtils.sendWholePrice(memberEntity.getId());
        
        //添加资金划转历史记录
        MemberAccountMoneyChange memberAccountRecord = new MemberAccountMoneyChange();
@@ -467,8 +511,52 @@
    public Result findWalletContractBySymbol(String symbol) {
        //获取用户ID
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        MemberEntity memberEntity = memberDao.selectById(memberId);
        //获取合约当前持仓类型
        Integer contractPositionType = memberEntity.getContractPositionType();
        // 总盈利
        BigDecimal totalProfitOrLess = BigDecimal.ZERO;
        if(contractPositionType == 2){
            //获取全仓模式下的所有持仓信息
            PlatformTradeSettingEntity tradeSetting = cacheSettingUtils.getTradeSetting();
            List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListForWholeByMemberIdAndSymbol(memberEntity.getId(),"");
            if (CollUtil.isNotEmpty(holdOrderEntities)) {
                for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
                    // 获取最新价
                    BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(holdOrderEntity.getSymbol())));
                    BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(holdOrderEntity.getSymbol());
                    // 单个订单盈利
                    BigDecimal profitOrLess = BigDecimal.ZERO;
                    // 开多
                    if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
                        profitOrLess = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
                        // 开空
                    } else {
                        profitOrLess = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
                    }
                    if (MemberEntity.IS_PROFIT_Y == memberEntity.getIsProfit()) {
                        if (profitOrLess.compareTo(BigDecimal.ZERO) > 0) {
                            profitOrLess = profitOrLess.multiply(BigDecimal.ONE.subtract(tradeSetting.getForceParam()));
                        } else {
                            profitOrLess = profitOrLess.multiply(BigDecimal.ONE.add(tradeSetting.getForceParam()));
                        }
                    }
                    totalProfitOrLess = totalProfitOrLess.add(profitOrLess);
                }
            }
        }
        MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberId, symbol);
        BigDecimal availableBalance = walletContract.getAvailableBalance().setScale(4, BigDecimal.ROUND_DOWN);
        BigDecimal availableBalance = walletContract.getAvailableBalance();
        //可用减去盈亏
        if(totalProfitOrLess.compareTo(BigDecimal.ZERO) < 0){
            availableBalance = availableBalance.add(totalProfitOrLess);
        }
        if(availableBalance.compareTo(BigDecimal.ZERO) > 0){
            availableBalance = availableBalance.setScale(4, BigDecimal.ROUND_DOWN);
        }else{
            availableBalance = BigDecimal.ZERO;
        }
        return Result.ok(availableBalance);
    }
@@ -682,7 +770,9 @@
            //更新合约全仓模式下的订单权益
            MemberEntity memberEntity = memberDao.selectById(memberId);
            String symbols = symbol+"/USDT";
            ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
            //ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
            // 全仓爆仓
            ThreadPoolUtils.sendWholePrice(memberEntity.getId());
            
            //添加资金划转历史记录
            memberAccountRecord.setMemberId(memberId);
@@ -862,7 +952,9 @@
        //更新合约全仓模式下的订单权益
        MemberEntity memberEntity = memberDao.selectById(memberId);
        String symbols = symbolOut+"/USDT";
        ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
        //ThreadPoolUtils.sendWholeForceClosingPrice(symbols, memberEntity);
        // 全仓爆仓
        ThreadPoolUtils.sendWholePrice(memberEntity.getId());
        
        // 加币
        // 查询合约账户
@@ -880,9 +972,9 @@
        
        //更新合约全仓模式下的订单权益
        String symbolIns = symbolIn+"/USDT";
        ThreadPoolUtils.sendWholeForceClosingPrice(symbolIns, memberEntity);
        ThreadPoolUtils.sendWholePrice(memberId);
        //ThreadPoolUtils.sendWholeForceClosingPrice(symbolIns, memberEntity);
        // 全仓爆仓
        ThreadPoolUtils.sendWholePrice(memberEntity.getId());
        
        //添加币币资金划转历史记录
        MemberAccountMoneyChange memberAccountRecord = new MemberAccountMoneyChange();
src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java
@@ -2,6 +2,8 @@
import com.xcong.excoin.common.LoginUserUtils;
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
import com.xcong.excoin.modules.contract.entity.ContractOrderEntity;
import com.xcong.excoin.modules.contract.parameter.dto.*;
import com.xcong.excoin.modules.contract.parameter.vo.ContractMoneyInfoVo;
import com.xcong.excoin.modules.contract.parameter.vo.HoldOrderListVo;
@@ -76,6 +78,14 @@
    @ApiOperation(value = "一键平仓")
    @PostMapping(value = "/oneKeyClosing")
    public Result oneKeyClosing(@RequestBody SymbolDto symbolDto) {
        symbolDto.setType(ContractOrderEntity.CONTRACTTYPE_NORMAL);
        return contractHoldOrderService.cancelHoldOrderBatch(symbolDto);
    }
    @ApiOperation(value = "带单一键平仓")
    @PostMapping(value = "/oneKeyClosingForFollow")
    public Result oneKeyClosingForFollow(@RequestBody SymbolDto symbolDto) {
        symbolDto.setType(ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY);
        return contractHoldOrderService.cancelHoldOrderBatch(symbolDto);
    }
@@ -127,6 +137,13 @@
        return contractHoldOrderService.cancelHoldOrder(wholeCloseOrderDto);
    }
    @ApiOperation(value = "全仓模式 - 一键平仓")
    @PostMapping(value = "/oneKeyClosingForWhole")
    public Result oneKeyClosingForWhole() {
        SymbolDto symbolDto = new SymbolDto();
        return contractHoldOrderService.cancelHoldOrderBatch(symbolDto);
    }
    @ApiOperation(value = "全仓模式 - 变更仓位类型")
    @GetMapping(value = "/changePositionType")
    public Result changePositionType() {
src/main/java/com/xcong/excoin/modules/contract/dao/ContractOrderDao.java
@@ -33,4 +33,8 @@
    int updateOrderProfitOrLessById(@Param("rewardAmount") BigDecimal rewardAmount, @Param("rewardRatio") BigDecimal rewardRatio, @Param("id") Long id);
    public BigDecimal getBurstUsdtByMemberId(@Param("memberId") Long memberId);
    public List<ContractOrderEntity> selectFollowOrderListByMemberId(@Param("tradeMemberId")Long tradeMemberId);
    public String selectOrderNoByOrderIds(@Param("orderId")Long orderId);
}
src/main/java/com/xcong/excoin/modules/contract/parameter/dto/SymbolDto.java
@@ -14,4 +14,7 @@
    @ApiModelProperty(value = "币种", example = "BTC/USDT")
    private String symbol;
    @ApiModelProperty(hidden = true)
    private Integer type;
}
src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java
@@ -4,6 +4,8 @@
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
import com.xcong.excoin.modules.contract.parameter.dto.*;
import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.rabbit.pricequeue.OrderModel;
import org.apache.ibatis.annotations.Param;
@@ -49,4 +51,6 @@
    public Result changePositionType();
    public void calHoldFeeAmountForBondAmount();
    public void sendFollowOrder(FollowTraderInfoEntity traderInfoEntity, ContractHoldOrderEntity holdOrderEntity);
}
src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
@@ -385,17 +385,7 @@
            // 若该用户为交易员且开启带单模式,则发送带单异步
            if (isOpenFollow) {
                FollowFollowerOrderRelationEntity relationEntity = new FollowFollowerOrderRelationEntity();
                relationEntity.setIsShow(FollowFollowerOrderRelationEntity.IS_SHOW_Y);
                relationEntity.setMemberId(holdOrderEntity.getMemberId());
                relationEntity.setOrderId(holdOrderEntity.getId());
                relationEntity.setOrderType(FollowFollowerOrderRelationEntity.ORDER_TYPE_HOLD);
                relationEntity.setTradeId(tradeInfo.getId());
                relationEntity.setTradeMemberId(tradeInfo.getMemberId());
                relationEntity.setTradeOrderNo(holdOrderEntity.getOrderNo());
                followFollowerOrderRelationDao.insert(relationEntity);
                followProducer.sendAddFollowOrder(holdOrderEntity.getId());
                sendFollowOrder(tradeInfo, holdOrderEntity);
//                ThreadPoolUtils.sendFollowOrderTask(holdOrderEntity.getId());
            }
            // 提交成功
@@ -405,6 +395,20 @@
        return Result.fail(MessageSourceUtils.getString("member_service_0067"));
    }
    @Override
    public void sendFollowOrder(FollowTraderInfoEntity tradeInfo, ContractHoldOrderEntity holdOrderEntity) {
        FollowFollowerOrderRelationEntity relationEntity = new FollowFollowerOrderRelationEntity();
        relationEntity.setIsShow(FollowFollowerOrderRelationEntity.IS_SHOW_Y);
        relationEntity.setMemberId(holdOrderEntity.getMemberId());
        relationEntity.setOrderId(holdOrderEntity.getId());
        relationEntity.setOrderType(FollowFollowerOrderRelationEntity.ORDER_TYPE_HOLD);
        relationEntity.setTradeId(tradeInfo.getId());
        relationEntity.setTradeMemberId(tradeInfo.getMemberId());
        relationEntity.setTradeOrderNo(holdOrderEntity.getOrderNo());
        followFollowerOrderRelationDao.insert(relationEntity);
        followProducer.sendAddFollowOrder(holdOrderEntity.getId());
    }
    /**
     * 全仓模式--若当前已经存在持仓,则合并当前持仓
@@ -527,7 +531,7 @@
                holdOrderListVo.setReturnRate(returnRate);
                holdOrderListVo.setProfitOrLoss(rewardRatio);
                if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == memberEntity.getContractPositionType()) {
                    BigDecimal forcePrice = CalculateUtil.getForceSetPriceForWhole(holdOrderEntity.getSymbol(), memberEntity);
                    BigDecimal forcePrice = CalculateUtil.calForcePriceForWhole(memberEntity, holdOrderEntity);
                    holdOrderListVo.setForceClosingPrice(forcePrice);
                }
                resultList.add(holdOrderListVo);
@@ -648,7 +652,7 @@
            return Result.loading("loading_type");
        }
        
        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberEntity.getId(), symbolDto.getSymbol(), 1);
        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberEntity.getId(), symbolDto.getSymbol(), symbolDto.getType());
        if (CollUtil.isEmpty(holdOrderEntities)) {
            return Result.fail("订单不存在");
        }
@@ -859,7 +863,7 @@
        BigDecimal newPriceSymbol = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol)));
        List<ContractEntrustOrderEntity> entrustOrderEntities = contractEntrustOrderDao.selectEntrustOrderListByMemberId(memberEntity.getId());
        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbolTest(memberEntity.getId(), ContractOrderEntity.CONTRACTTYPE_NORMAL);
        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberIdAndSymbolTest(memberEntity.getId(), null);
        MemberWalletContractEntity walletContractEntity = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberEntity.getId(), CoinTypeEnum.USDT.name());
//        if (memberEntity.getContractPositionType().equals(ContractEntrustOrderEntity.POSITION_TYPE_ADD)) {
//            // 当前合约委托单
@@ -1135,29 +1139,35 @@
        if (CollUtil.isNotEmpty(list)) {
            for (ContractHoldOrderEntity holdOrderEntity : list) {
                BigDecimal thisTimeHold = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()).multiply(tradeSettingEntity.getDoingRatio());
                MemberWalletContractEntity wallet = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(holdOrderEntity.getMemberId(), CoinTypeEnum.USDT.name());
                log.info("订单编号:{}, 持仓费:{}", holdOrderEntity.getOrderNo(), thisTimeHold);
                BigDecimal holdAmount = holdOrderEntity.getHoldAmount();
                if (holdAmount == null) {
                    holdAmount = BigDecimal.ZERO;
                }
                BigDecimal thisTimeHold = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()).multiply(tradeSettingEntity.getDoingRatio());
                log.info("订单编号:{}, 持仓费:{}", holdOrderEntity.getOrderNo(), thisTimeHold);
                MemberEntity memberEntity = memberDao.selectById(holdOrderEntity.getMemberId());
                BigDecimal subBond = holdOrderEntity.getBondAmount().subtract(thisTimeHold);
                BigDecimal newForcePrice = CalculateUtil.getForceSetPrice(subBond.subtract(holdOrderEntity.getOpeningFeeAmount()), holdOrderEntity.getOpeningPrice(), holdOrderEntity.getSymbolCnt(), holdOrderEntity.getSymbolSku(), holdOrderEntity.getOpeningType(), memberEntity);
                holdAmount = holdAmount.add(thisTimeHold);
                holdOrderEntity.setBondAmount(subBond);
                holdOrderEntity.setHoldAmount(holdAmount);
                holdOrderEntity.setForceClosingPrice(newForcePrice);
                holdOrderEntity.setOperateNo(holdOrderEntity.getOperateNo() + 1);
                contractHoldOrderDao.updateById(holdOrderEntity);
                memberWalletContractDao.increaseWalletContractBalanceById(null, thisTimeHold.negate(), null, holdOrderEntity.getMemberId());
                if (ContractEntrustOrderEntity.POSITION_TYPE_ADD == holdOrderEntity.getPositionType()) {
                    MemberEntity memberEntity = memberDao.selectById(holdOrderEntity.getMemberId());
                    BigDecimal subBond = holdOrderEntity.getBondAmount().subtract(thisTimeHold);
                    BigDecimal newForcePrice = CalculateUtil.getForceSetPrice(subBond.subtract(holdOrderEntity.getOpeningFeeAmount()), holdOrderEntity.getOpeningPrice(), holdOrderEntity.getSymbolCnt(), holdOrderEntity.getSymbolSku(), holdOrderEntity.getOpeningType(), memberEntity);
                    holdOrderEntity.setBondAmount(subBond);
                    holdOrderEntity.setHoldAmount(holdAmount);
                    holdOrderEntity.setForceClosingPrice(newForcePrice);
                    holdOrderEntity.setOperateNo(holdOrderEntity.getOperateNo() + 1);
                    contractHoldOrderDao.updateById(holdOrderEntity);
                    memberWalletContractDao.increaseWalletContractBalanceById(null, thisTimeHold.negate(), null, wallet.getId());
                    // 发送爆仓消息
                    sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), newForcePrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo(), holdOrderEntity.getMemberId());
                } else {
                    holdOrderEntity.setHoldAmount(holdAmount);
                    contractHoldOrderDao.updateById(holdOrderEntity);
                    memberWalletContractDao.increaseWalletContractBalanceById(thisTimeHold.negate(), thisTimeHold.negate(), null, wallet.getId());
                    ThreadPoolUtils.sendWholePrice(holdOrderEntity.getMemberId());
                }
            }
        }
src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java
@@ -19,6 +19,7 @@
import com.xcong.excoin.modules.contract.service.ContractEntrustOrderService;
import com.xcong.excoin.modules.contract.service.ContractHoldOrderService;
import com.xcong.excoin.modules.contract.service.ContractOrderService;
import com.xcong.excoin.modules.contract.service.RabbitOrderService;
import com.xcong.excoin.modules.documentary.common.NoticeConstant;
import com.xcong.excoin.modules.documentary.dao.FollowFollowerOrderRelationDao;
import com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao;
@@ -39,6 +40,7 @@
import com.xcong.excoin.modules.member.service.MemberWalletContractService;
import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
import com.xcong.excoin.rabbit.pricequeue.OrderModel;
import com.xcong.excoin.rabbit.producer.FollowProducer;
import com.xcong.excoin.rabbit.producer.OrderProducer;
import com.xcong.excoin.utils.*;
import lombok.extern.slf4j.Slf4j;
@@ -104,6 +106,9 @@
    private RedisUtils redisUtils;
    @Resource
    private FollowOrderOperationService followOrderOperationService;
    @Resource
    private FollowProducer followProducer;
    public void dealOrderFromMq(List<OrderModel> list, Integer type) {
        if (CollectionUtils.isNotEmpty(list)) {
@@ -171,6 +176,21 @@
        if (CollUtil.isNotEmpty(entrustOrders)) {
            for (ContractEntrustOrderEntity entrustOrder : entrustOrders) {
                contractEntrustOrderDao.deleteById(entrustOrder.getId());
            }
        }
    }
    private void closingFollowerOrders(MemberEntity memberEntity, ContractHoldOrderEntity holdOrderEntity, ContractOrderEntity contractOrderEntity) {
        // 判断当前持仓是否为跟单订单
        if (ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY == holdOrderEntity.getContractType()) {
            FollowTraderInfoEntity traderInfoEntity = followTraderInfoDao.selectTraderInfoByOrderId(holdOrderEntity.getId());
            updateFollowOrderRelation(holdOrderEntity.getId(), contractOrderEntity.getId());
            // 若为交易员,则平仓跟随者订单
            if (MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
                followOrderOperationService.closingFollowOrders(holdOrderEntity.getOrderNo());
            } else {
                LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.CLOSE_ORDER_TITLE, StrUtil.format(NoticeConstant.CLOSE_ORDER_CONTENT, contractOrderEntity.getSymbol(), contractOrderEntity.getClosingPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toString(), contractOrderEntity.getRewardAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toString(), traderInfoEntity.getNickname()));
            }
        }
    }
@@ -269,6 +289,8 @@
                        if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == order.getPositionType()) {
                            ThreadPoolUtils.sendWholePrice(memberId);
                            deleteEntrustCloseOrder(order.getOrderNo());
                        } else {
                            closingFollowerOrders(memberEntity, order, contractOrderEntity);
                        }
                    }
                }
@@ -370,6 +392,8 @@
                        if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == order.getPositionType()) {
                            ThreadPoolUtils.sendWholePrice(memberId);
                            deleteEntrustCloseOrder(order.getOrderNo());
                        } else {
                            closingFollowerOrders(memberEntity, order, contractOrderEntity);
                        }
                    }
                }
@@ -469,6 +493,8 @@
                        if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == order.getPositionType()) {
                            ThreadPoolUtils.sendWholePrice(memberId);
                            deleteEntrustCloseOrder(order.getOrderNo());
                        } else {
                            closingFollowerOrders(memberEntity, order, contractOrderEntity);
                        }
                    }
                }
@@ -567,6 +593,8 @@
                        if (ContractEntrustOrderEntity.POSITION_TYPE_ALL == order.getPositionType()) {
                            ThreadPoolUtils.sendWholePrice(memberId);
                            deleteEntrustCloseOrder(order.getOrderNo());
                        } else {
                            closingFollowerOrders(memberEntity, order, contractOrderEntity);
                        }
                    }
                }
@@ -625,6 +653,16 @@
                    contractHoldOrderEntity.setOpeningType(ContractHoldOrderEntity.OPENING_TYPE_LESS);
                }
                // 判断是否开启了带单
                boolean isOpenFollow = false;
                FollowTraderInfoEntity tradeInfo = null;
                if (MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
                    tradeInfo = followTraderInfoDao.selectTraderInfoByMemberId(memberEntity.getId());
                    if (FollowTraderInfoEntity.ISOPEN_Y.equals(tradeInfo.getIsOpen())) {
                        isOpenFollow = true;
                    }
                }
                //持仓单赋值
                contractHoldOrderEntity.setMemberId(memId);
                contractHoldOrderEntity.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_Y);
@@ -647,6 +685,7 @@
                contractHoldOrderEntity.setTradeType(ContractHoldOrderEntity.TRADE_TYPE_LIMIT);
                contractHoldOrderEntity.setOperateNo(1);
                contractHoldOrderEntity.setSymbolCntSale(contractHoldOrderEntity.getSymbolCnt());
                contractHoldOrderEntity.setContractType(isOpenFollow ? ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY : ContractOrderEntity.CONTRACTTYPE_NORMAL);
                contractHoldOrderService.save(contractHoldOrderEntity);
                // 需要一个历史插入
@@ -675,6 +714,12 @@
                //返佣
                ThreadPoolUtils.calReturnMoney(memberEntity.getId(), openFeePrice, contractOrderEntity, AgentReturnEntity.ORDER_TYPE_OPEN);
                // 若该用户为交易员且开启带单模式,则发送带单异步
                if (isOpenFollow) {
                    contractHoldOrderService.sendFollowOrder(tradeInfo, contractHoldOrderEntity);
                }
            }
        }
    }
@@ -916,10 +961,10 @@
                    QueryWrapper<FollowFollowerSettingEntity> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("member_id",coinsOrder.getMemberId());
                    FollowFollowerSettingEntity followFollowerSettingEntity = followFollowerSettingDao.selectOne(queryWrapper);
                    if(ObjectUtil.isNotEmpty(followFollowerSettingEntity)){
                        Long traderMemberId = followFollowerSettingEntity.getTraderMemberId();
                        followFollowerProfitDao.updateFollowerProfitByTradeMemberId(coinsOrder.getBondAmount().negate(), coinsOrder.getBondAmount().negate(), traderMemberId, memberEntity.getId());
                    }
//                    if(ObjectUtil.isNotEmpty(followFollowerSettingEntity)){
//                        Long traderMemberId = followFollowerSettingEntity.getTraderMemberId();
//                        followFollowerProfitDao.updateFollowerProfitByTradeMemberId(coinsOrder.getBondAmount().negate(), coinsOrder.getBondAmount().negate(), traderMemberId, memberEntity.getId());
//                    }
                    FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoDao.selectById(followFollowerSettingEntity.getTraderId());
                    //更新跟随者-订单关联表
                    updateFollowOrderRelation(coinsOrder.getId(), contractOrderEntity.getId());
src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java
@@ -6,9 +6,11 @@
import com.alibaba.fastjson.JSONObject;
import com.xcong.excoin.common.contants.AppContants;
import com.xcong.excoin.common.enumerates.CoinTypeEnum;
import com.xcong.excoin.common.enumerates.MemberWalletCoinEnum;
import com.xcong.excoin.common.enumerates.OrderClosingTypeEnum;
import com.xcong.excoin.common.system.service.CommonService;
import com.xcong.excoin.modules.coin.entity.MemberAccountFlowEntity;
import com.xcong.excoin.modules.coin.entity.MemberAccountMoneyChange;
import com.xcong.excoin.modules.contract.dao.ContractEntrustOrderDao;
import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
import com.xcong.excoin.modules.contract.dao.ContractOrderDao;
@@ -113,7 +115,14 @@
                    List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectBatchIds(ids);
                    if (CollUtil.isNotEmpty(holdOrderEntities)) {
                        for (ContractHoldOrderEntity holdOrder : holdOrderEntities) {
                            cancelHoldOrderMethod(holdOrder);
                            // 判断仓位类型是否逐仓
                            if (holdOrder.getPositionType() == ContractEntrustOrderEntity.POSITION_TYPE_ADD) {
                                // 逐仓平仓
                                cancelHoldOrderMethod(holdOrder);
                            } else {
                                // 全仓模式平仓
                                closingWholeOrder(holdOrder);
                            }
                        }
                    }
                }
@@ -186,13 +195,24 @@
                        memberWalletContractDao.increaseWalletContractBalanceById(returnMoney, returnMoney, null, traderWallet.getId());
                        insertReturnProfitDetail(traderInfoEntity.getMemberId(), memberEntity.getId(), returnMoney, holdOrderEntity.getOrderNo());
                        //增加返佣提醒
                        String orderNo = holdOrderEntity.getOrderNo();
                        LogRecordUtils.insertFollowerNotice(traderInfoEntity.getMemberId(),
                                NoticeConstant.RETURN_MONEY_TITLE,
                                StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT,
                                        memberEntity.getInviteId(),
                                        orderNo,
                                        returnMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()));
//                        String orderNo = holdOrderEntity.getOrderNo();
//                        LogRecordUtils.insertFollowerNotice(traderInfoEntity.getMemberId(),
//                                NoticeConstant.RETURN_MONEY_TITLE,
//                                StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT,
//                                        orderNo,
//                                        holdOrderEntity.getSymbol(),
//                                        returnMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()));
//                        //带单返利的记录要在资产页面的其他记录
//                        LogRecordUtils.insertMemberAccountMoneyChange(
//                                traderInfoEntity.getMemberId(),
//                                StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT_MAMC,
//                                        orderNo,
//                                        holdOrderEntity.getSymbol(),
//                                        returnMoney.setScale(2, BigDecimal.ROUND_HALF_UP).toString()),
//                                returnMoney.setScale(2, BigDecimal.ROUND_HALF_UP),
//                                MemberWalletCoinEnum.WALLETCOINCODE.getValue(),
//                                MemberAccountMoneyChange.STATUS_SUCCESS_INTEGER,
//                                MemberAccountMoneyChange.TYPE_WALLET_AGENT);
                    }
                }
            }
@@ -226,7 +246,7 @@
                if (MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
                    followOrderOperationService.closingFollowOrders(holdOrderEntity.getOrderNo());
                } else {
                    followFollowerProfitDao.updateFollowerProfitByTradeMemberId(holdOrderEntity.getBondAmount(), profitOrLoss, traderInfoEntity.getMemberId(), memberEntity.getId());
                    //followFollowerProfitDao.updateFollowerProfitByTradeMemberId(holdOrderEntity.getBondAmount(), profitOrLoss, traderInfoEntity.getMemberId(), memberEntity.getId());
                    LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.CLOSE_ORDER_TITLE, StrUtil.format(NoticeConstant.CLOSE_ORDER_CONTENT, contractOrderEntity.getSymbol(), contractOrderEntity.getClosingPrice().setScale(2, BigDecimal.ROUND_HALF_UP).toString(), profitOrLoss.setScale(2, BigDecimal.ROUND_HALF_UP).toString(), traderInfoEntity.getNickname()));
                }
            }
@@ -286,6 +306,11 @@
            // 获取平仓张数
            Integer closeCnt = (Integer) redisUtils.get(AppContants.CLOSING_ORDER_PREFIX + holdOrderEntity.getId());
            // 无法从redis中获取平仓张数,说明来自一键平仓
            if (closeCnt == null) {
                closeCnt = holdOrderEntity.getSymbolCntSale();
                holdOrderEntity.setSymbolCntSale(0);
            }
            MemberSettingEntity memberSettingEntity = memberSettingDao.selectMemberSettingByMemberId(memberEntity.getId());
            // 开多
@@ -511,7 +536,7 @@
                    continue;
                }
//                holdOrderEntity.setForceClosingPrice(getForceSetPrice(wholePriceData, holdOrderEntity, holdOrderDataModel.getSymbol()));
                holdOrderEntity.setStopProfitPrice(CalculateUtil.calForcePriceForWhole(memberEntity, holdOrderEntity));
                contractHoldOrderDao.deleteById(holdOrderDataModel.getId());
                ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity);
src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java
@@ -30,7 +30,8 @@
    public static final String BOMB_ORDER_CONTENT = "因市场剧烈波动,您的{}合约已被强制平仓,交易员:{}";
    public static final String RETURN_MONEY_TITLE = "跟单-平仓返佣";
    public static final String RETURN_MONEY_CONTENT = "跟单平仓成功,收到{}的合约单号:{}的返佣金额:{}";
    public static final String RETURN_MONEY_TITLE = "跟单-平仓返利";
    public static final String RETURN_MONEY_CONTENT = "平仓成功,收到的合约{},币种{}的返利金额:{}";
    public static final String RETURN_MONEY_CONTENT_MAMC = "合约-{},订单{}的带单返利";
}
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java
@@ -18,6 +18,7 @@
    FollowFollowerOrderRelationEntity selectNowOneByorderId(@Param("orderId")Long orderId);
    List<FollowFollowerOrderRelationEntity> selectFollowHoldOrderByTradeOrderNo(@Param("orderNo") String orderNo);
    List<FollowFollowerOrderRelationEntity> selectFollowOrderByTradeOrderNo(@Param("orderNo") String orderNo);
    BigDecimal selectTraderTotalProfit(@Param("memberId") Long memberId);
    BigDecimal selectTraderTotalProfitSelf(@Param("memberId") Long memberId);
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerProfitDao.java
@@ -44,5 +44,9 @@
    BigDecimal selectAllFollowerProfit(@Param("tradeMemberId") Long tradeMemberId);
    
    List<FollowFollowerProfitEntity> selectByMemberIdandIsFollow(@Param("id") Long id, @Param("isFollowY") Integer isFollowY);
    BigDecimal selectSumBondAmountBymemberId(@Param("memberId")Long memberId,@Param("tradeId") Long tradeId);
    BigDecimal selectSumRewardAmountByMemberId(@Param("memberId")Long memberId,@Param("tradeId") Long tradeId);
    
}
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderProfitDetailDao.java
@@ -1,8 +1,15 @@
package com.xcong.excoin.modules.documentary.dao;
import java.math.BigDecimal;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitDetailEntity;
public interface FollowTraderProfitDetailDao extends BaseMapper<FollowTraderProfitDetailEntity> {
    BigDecimal selectFollowHoldOrderByFollowOrderNo(@Param("orderNos")List<String> orderNos);
}
src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java
@@ -7,9 +7,11 @@
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xcong.excoin.common.enumerates.CoinTypeEnum;
import com.xcong.excoin.common.enumerates.MemberWalletCoinEnum;
import com.xcong.excoin.common.enumerates.RabbitPriceTypeEnum;
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.common.system.service.CommonService;
import com.xcong.excoin.modules.coin.entity.MemberAccountMoneyChange;
import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
import com.xcong.excoin.modules.contract.dao.ContractOrderDao;
import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity;
@@ -18,10 +20,7 @@
import com.xcong.excoin.modules.contract.mapper.ContractHoldOrderEntityMapper;
import com.xcong.excoin.modules.contract.service.RabbitOrderService;
import com.xcong.excoin.modules.documentary.common.NoticeConstant;
import com.xcong.excoin.modules.documentary.dao.FollowFollowerOrderRelationDao;
import com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao;
import com.xcong.excoin.modules.documentary.dao.FollowFollowerSettingDao;
import com.xcong.excoin.modules.documentary.dao.FollowTraderInfoDao;
import com.xcong.excoin.modules.documentary.dao.*;
import com.xcong.excoin.modules.documentary.entity.FollowFollowerOrderRelationEntity;
import com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity;
import com.xcong.excoin.modules.documentary.entity.FollowFollowerSettingEntity;
@@ -88,6 +87,8 @@
    @Autowired
    private FollowProducer followProducer;
    @Autowired
    private FollowTraderProfitDetailDao followTraderProfitDetailDao;
    @Override
@@ -268,6 +269,48 @@
                ids.add(orderRelation.getOrderId());
                rabbitOrderService.cancelHoldOrder(ids);
            }
            //生成返利记录和资金变化记录
            List<FollowFollowerOrderRelationEntity> orderRelationDone = followFollowerOrderRelationDao.selectFollowOrderByTradeOrderNo(orderNo);
            if(CollUtil.isNotEmpty(orderRelationDone)) {
                List<Long> orderIds = new ArrayList<>();
                for (FollowFollowerOrderRelationEntity orderRelationd : orderRelationDone) {
                    orderIds.add(orderRelationd.getOrderId());
                }
                if(CollUtil.isNotEmpty(orderIds)){
                    //获取对应的平仓记录单号
                    List<String> orderNosList = new ArrayList<>();
                    for(Long orderId : orderIds) {
                        String orderNos = contractOrderDao.selectOrderNoByOrderIds(orderId);
                        orderNosList.add(orderNos);
                    }
                    //获取总返佣
                    BigDecimal totalAmount = followTraderProfitDetailDao.selectFollowHoldOrderByFollowOrderNo(orderNosList);
                    totalAmount = (totalAmount == null?BigDecimal.ZERO:totalAmount.setScale(2, BigDecimal.ROUND_DOWN));
                    if(totalAmount.compareTo(BigDecimal.ZERO) > 0){
                        //增加返佣提醒
                        String symbol = contractOrderDao.selectById(orderIds.get(0)).getSymbol();
                        String orderNoTrader = orderRelationDone.get(0).getTradeOrderNo();
                        Long traderMemberId = orderRelationDone.get(0).getTradeMemberId();
                        LogRecordUtils.insertFollowerNotice(traderMemberId,
                                NoticeConstant.RETURN_MONEY_TITLE,
                                StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT,
                                        orderNoTrader,
                                        symbol,
                                        totalAmount));
                        //带单返利的记录要在资产页面的其他记录
                        LogRecordUtils.insertMemberAccountMoneyChange(
                                traderMemberId,
                                StrUtil.format(NoticeConstant.RETURN_MONEY_CONTENT_MAMC,
                                        symbol,
                                        orderNoTrader.substring(8)),
                                totalAmount,
                                MemberWalletCoinEnum.WALLETCOINCODE.getValue(),
                                MemberAccountMoneyChange.STATUS_SUCCESS_INTEGER,
                                MemberAccountMoneyChange.TYPE_WALLET_AGENT);
                    }
                }
            }
        }
    }
}
src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java
@@ -7,6 +7,7 @@
import com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao;
import com.xcong.excoin.modules.documentary.dao.FollowTraderInfoDao;
import com.xcong.excoin.modules.documentary.dao.FollowTraderProfitInfoDao;
import com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitInfoEntity;
import lombok.extern.slf4j.Slf4j;
@@ -17,7 +18,9 @@
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 *
@@ -51,6 +54,27 @@
        if (CollUtil.isNotEmpty(allTraders)) {
            for (FollowTraderInfoEntity trader : allTraders) {
                Long tradeMemberId = trader.getMemberId();
                //获取交易员的当前跟随者
                Map<String, Object> hashMap = new HashMap<>();
                hashMap.put("trade_member_id", tradeMemberId);
                hashMap.put("is_follow", FollowFollowerProfitEntity.IS_FOLLOW_Y);
                List<FollowFollowerProfitEntity> followFollowerProfitEntityList = followFollowerProfitDao.selectByMap(hashMap);
                if(CollUtil.isNotEmpty(followFollowerProfitEntityList)) {
                    for(FollowFollowerProfitEntity followFollowerProfitEntity : followFollowerProfitEntityList) {
                        //获取当前跟随者的跟随本金
                        Long memberId = followFollowerProfitEntity.getMemberId();
                        BigDecimal sumBondAmountBigDecimal = followFollowerProfitDao.selectSumBondAmountBymemberId(memberId,trader.getId());
                        sumBondAmountBigDecimal = (sumBondAmountBigDecimal == null?BigDecimal.ZERO:sumBondAmountBigDecimal.setScale(2, BigDecimal.ROUND_DOWN));
                        followFollowerProfitEntity.setTotalPrincipal(sumBondAmountBigDecimal);
                        //获取当前的盈亏
                        BigDecimal sumRewardAmountBigDecimal = followFollowerProfitDao.selectSumRewardAmountByMemberId(memberId,trader.getId());
                        sumRewardAmountBigDecimal = (sumRewardAmountBigDecimal == null?BigDecimal.ZERO:sumRewardAmountBigDecimal.setScale(2, BigDecimal.ROUND_DOWN));
                        followFollowerProfitEntity.setTotalProfit(sumRewardAmountBigDecimal);
                        followFollowerProfitDao.updateById(followFollowerProfitEntity);
                    }
                }
                FollowTraderProfitInfoEntity traderInfoProfit = followTraderProfitInfoDao.selectTraderInfoProfitByMemberId(tradeMemberId);
                // 累计收益率
                BigDecimal ljsyl = contractOrderDao.selectFollowOrderTotalProfitByMemberId(tradeMemberId);
@@ -61,7 +85,8 @@
                //BigDecimal totalProfit = followFollowerOrderRelationDao.selectTraderTotalProfit(tradeMemberId);
                traderInfoProfit.setTotalProfit(totalProfit);
                // 交易笔数
                List<ContractOrderEntity> orders = contractOrderDao.selectFollowOrderByMemberId(tradeMemberId);
//                List<ContractOrderEntity> orders = contractOrderDao.selectFollowOrderByMemberId(tradeMemberId);
                List<ContractOrderEntity> orders = contractOrderDao.selectFollowOrderListByMemberId(tradeMemberId);
                traderInfoProfit.setTotalOrderCnt(CollUtil.isNotEmpty(orders) ? orders.size() : 0);
                // 近三周胜率
                Integer winCnt = contractOrderDao.selectFollowOrderCntForWinRate(tradeMemberId, 1);
src/main/java/com/xcong/excoin/quartz/job/LoopExecutorJob.java
@@ -47,6 +47,7 @@
     * 持仓费计算
     */
    @Scheduled(cron = "0 0 0/8 * * ?")
//    @Scheduled(cron = "0 0/5 * * * ?")
    public void updateDoingPrice() {
        log.info("#持仓费计算#");
        try {
src/main/java/com/xcong/excoin/utils/CalculateUtil.java
@@ -163,6 +163,47 @@
        return result;
    }
    /**
     * 开仓价 +/- (权益 - 其他币种成本 - 当前币种维持保证金)/(规格*张数)
     *
     * @param memberEntity
     * @param contractHoldOrderEntity
     * @return
     */
    public static BigDecimal calForcePriceForWhole(MemberEntity memberEntity, ContractHoldOrderEntity contractHoldOrderEntity) {
        ContractHoldOrderDao holdOrderDao = SpringContextHolder.getBean(ContractHoldOrderDao.class);
        MemberWalletContractDao walletContractDao = SpringContextHolder.getBean(MemberWalletContractDao.class);
        Long memberId = memberEntity.getId();
        MemberWalletContractEntity walletContract = walletContractDao.findWalletContractByMemberIdAndSymbol(memberId, CoinTypeEnum.USDT.name());
        List<ContractHoldOrderEntity> holdOrderEntities = holdOrderDao.selectHoldOrderListForWholeByMemberIdAndSymbol(memberId, null);
        BigDecimal forcePrice = BigDecimal.ZERO;
        if (CollUtil.isNotEmpty(holdOrderEntities)) {
            BigDecimal totalBondAmount = BigDecimal.ZERO;
            BigDecimal totalProfitOrLoss = BigDecimal.ZERO;
            for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
                if (holdOrderEntity.getId().equals(contractHoldOrderEntity.getId())) {
//                    totalBondAmount = totalBondAmount.add(holdOrderEntity.getHoldBond());
                } else {
                    totalBondAmount = totalBondAmount.add(holdOrderEntity.getBondAmount());
                }
                totalProfitOrLoss =  totalProfitOrLoss.add(calProfitOrLoss(holdOrderEntity, memberEntity));
            }
            BigDecimal divideChild = walletContract.getTotalBalance().subtract(totalBondAmount).add(totalProfitOrLoss);
            BigDecimal divideParent = contractHoldOrderEntity.getSymbolSku().multiply(new BigDecimal(contractHoldOrderEntity.getSymbolCntSale()));
            BigDecimal divide = divideChild.divide(divideParent, 8, BigDecimal.ROUND_DOWN);
            if (ContractHoldOrderEntity.OPENING_TYPE_MORE == contractHoldOrderEntity.getOpeningType()) {
                forcePrice = contractHoldOrderEntity.getOpeningPrice().subtract(divide);
            } else {
                forcePrice = contractHoldOrderEntity.getOpeningPrice().add(divide);
            }
        }
        return forcePrice;
    }
    public static BigDecimal calProfitOrLoss(ContractHoldOrderEntity holdOrderEntity, MemberEntity memberEntity) {
        CacheSettingUtils cacheSettingUtils = SpringContextHolder.getBean(CacheSettingUtils.class);
        RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);
@@ -286,6 +327,6 @@
            redisUtils.set(AppContants.HOLD_BOND_RATIO, tradeSetting.getHoldBondRatio());
        }
        return contractHoldOrder.getOpeningPrice().multiply(new BigDecimal(contractHoldOrder.getSymbolCntSale())).multiply(holdBondRatio).multiply(contractHoldOrder.getSymbolSku());
        return contractHoldOrder.getOpeningPrice().multiply(new BigDecimal(contractHoldOrder.getSymbolCntSale())).multiply(holdBondRatio.multiply(new BigDecimal(100))).multiply(contractHoldOrder.getSymbolSku()).divide(new BigDecimal(contractHoldOrder.getLeverRatio()), 8, BigDecimal.ROUND_DOWN);
    }
}
src/main/resources/mapper/contract/ContractOrderDao.xml
@@ -2,6 +2,25 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.modules.contract.dao.ContractOrderDao">
    <select id="selectOrderNoByOrderIds" resultType="java.lang.String">
        SELECT
            order_no
        FROM
            contract_order
        WHERE
              id = #{orderId}
    </select>
    <select id="selectFollowOrderListByMemberId" resultType="com.xcong.excoin.modules.contract.entity.ContractOrderEntity">
        SELECT
            *
        FROM
            contract_order
        WHERE
            member_id = #{tradeMemberId}
          AND contract_type = 2
          AND closing_price IS NOT NULL;
    </select>
    <select id="selectContractOrderInPage" resultType="com.xcong.excoin.modules.contract.entity.ContractOrderEntity">
        select
src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml
@@ -33,6 +33,13 @@
        and a.order_type=1
    </select>
    <select id="selectFollowOrderByTradeOrderNo" resultType="com.xcong.excoin.modules.documentary.entity.FollowFollowerOrderRelationEntity">
        select a.*
        from follow_follower_order_relation a, follow_follower_profit b
        where a.trade_member_id=b.trade_member_id and a.trade_order_no=#{orderNo} and b.is_follow=1
          and a.order_type=2
    </select>
    <select id="selectTraderTotalProfit" resultType="java.math.BigDecimal">
        select sum(b.reward_amount)
        from follow_follower_order_relation a, contract_order b
src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml
@@ -1,7 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao">
    <select id="selectSumRewardAmountByMemberId" resultType="java.math.BigDecimal">
        SELECT
            SUM(a.reward_amount)
        FROM
            contract_order a
                LEFT JOIN follow_follower_order_relation b ON a.id = b.order_id
        WHERE
            a.member_id = #{memberId}
          AND b.order_type = 2
            and b.trade_id = #{tradeId};
    </select>
    <select id="selectSumBondAmountBymemberId" resultType="java.math.BigDecimal">
        SELECT
            SUM(a.bond_amount)
        FROM
            contract_order a
                LEFT JOIN follow_follower_order_relation b ON a.id = b.order_id
        WHERE
            a.member_id = #{memberId}
          AND b.order_type = 2
          and b.trade_id = #{tradeId};
    </select>
    <select id="selectByMemberIdandIsFollow" resultType="com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity">
        SELECT
            *
src/main/resources/mapper/documentary/FollowTraderProfitDetailDao.xml
@@ -1,6 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.modules.documentary.dao.FollowTraderProfitDetailDao">
    <select id="selectFollowHoldOrderByFollowOrderNo" resultType="java.math.BigDecimal">
        SELECT
        sum(amount)
        FROM
        follow_trader_profit_detail
        WHERE
        order_no in
        <foreach collection="orderNos" item="item" index="" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>
    
</mapper>
src/main/resources/mapper/member/MemberAccountMoneyChangeDao.xml
@@ -64,7 +64,7 @@
        <if test="record != null">
            <where>
                type = 3
                and (content like '%佣金到账%' or content like '%活动%')
                and (content like '%佣金到账%' or content like '%活动%' or content like '%返利%')
                <if test="record.memberId != null" >
                    and member_id=#{record.memberId}
                </if>
src/test/java/com/xcong/excoin/WholeTest.java
@@ -115,8 +115,15 @@
     */
    @Test
    public void forceSetPriceTest() {
        MemberEntity memberEntity = memberDao.selectById(21L);
        CalculateUtil.getForceSetPriceForWhole("BTC/USDT", memberEntity);
        MemberEntity memberEntity = memberDao.selectById(15L);
        System.out.println(CalculateUtil.getForceSetPriceForWhole("BTC/USDT", memberEntity));
    }
    @Test
    public void profitOrLessTest() {
        MemberEntity memberEntity = memberDao.selectById(15L);
        ContractHoldOrderEntity contractHoldOrderEntity = contractHoldOrderDao.selectById(144L);
        System.out.println(CalculateUtil.calProfitOrLoss(contractHoldOrderEntity, memberEntity));
    }
    @Resource
@@ -191,4 +198,12 @@
        // 29157.72306836 --
    }
    @Test
    public void wholeForceNewTest() {
        MemberEntity memberEntity = memberDao.selectById(15L);
        ContractHoldOrderEntity holdOrder = contractHoldOrderDao.selectById(400L);
        System.out.println(CalculateUtil.calForcePriceForWhole(memberEntity, holdOrder));
    }
}