zainali5120
2021-03-14 0f4df6c351d87054ded6bd54f0c6b9f6253ea56f
Merge remote-tracking branch 'origin/whole_new' into whole_new
10 files added
44 files modified
1080 ■■■■■ changed files
src/main/java/com/xcong/excoin/common/aop/ExceptionCatchAspect.java 69 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/system/bean/SysExceptionDetailEntity.java 30 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/configurations/RabbitMqConfig.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/configurations/security/WebSecurityConfig.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/blackchain/service/TrxUsdtUpdateService.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtErc20UpdateService.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/parameter/vo/ContractMoneyInfoVo.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/parameter/vo/OrderListVo.java 12 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java 41 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/controller/DocumentaryController.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/controller/TraderController.java 18 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerSettingDao.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderInfoDao.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dto/BeTraderDto.java 26 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/dto/FollowTraderProfitInfoDto.java 44 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderInfoEntity.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderProfitInfoEntity.java 22 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/service/DocumentaryService.java 12 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/service/impl/DocumentaryServiceImpl.java 296 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java 36 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/BeTraderConditionVo.java 32 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/DocumentaryOrderSetInfoVo.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/DocumentaryOrderSetStateVo.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/FollowInfoVo.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/FollowTraderProfitInfoVo.java 25 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/HistoryOrderRecordsVo.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/TradeProfitInfoVo.java 17 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/documentary/vo/TradeSetInfoVo.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/dao/MemberSettingDao.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/parameter/dto/MemberAddCoinAddressDto.java 13 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/platform/dao/PlatformSymbolsCoinDao.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/platform/dao/SysExceptionDetailDao.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java 3 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/consumer/FollowConsumer.java 31 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/producer/FollowProducer.java 44 ●●●●● patch | view | raw | blame | history
src/main/resources/application-app.yml 18 ●●●● patch | view | raw | blame | history
src/main/resources/application-dayline.yml 18 ●●●● patch | view | raw | blame | history
src/main/resources/application-loop.yml 18 ●●●● patch | view | raw | blame | history
src/main/resources/application-newprice.yml 18 ●●●● patch | view | raw | blame | history
src/main/resources/application.yml 20 ●●●● patch | view | raw | blame | history
src/main/resources/i18n/messages_en_US.properties 2 ●●●●● patch | view | raw | blame | history
src/main/resources/i18n/messages_zh_CN.properties 2 ●●●●● patch | view | raw | blame | history
src/main/resources/logback-spring.xml 2 ●●● patch | view | raw | blame | history
src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml 1 ●●●● patch | view | raw | blame | history
src/main/resources/mapper/documentary/FollowFollowerSettingDao.xml 8 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/documentary/FollowTraderInfoDao.xml 6 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/documentary/FollowTraderProfitInfoDao.xml 35 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/MemberSettingDao.xml 7 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/platform/PlatformSymbolsCoinDao.xml 8 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/platform/SysExceptionDetailDao.xml 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/aop/ExceptionCatchAspect.java
New file
@@ -0,0 +1,69 @@
package com.xcong.excoin.common.aop;
import com.xcong.excoin.common.exception.GlobalException;
import com.xcong.excoin.common.system.bean.SysExceptionDetailEntity;
import com.xcong.excoin.modules.platform.dao.SysExceptionDetailDao;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MethodArgumentNotValidException;
import javax.validation.ValidationException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
 * @author wzy
 * @date 2021-03-05
 **/
@Slf4j
@Aspect
@Component
public class ExceptionCatchAspect {
    private static final List EXCLUDE_EXCEPTION = new ArrayList(Arrays.asList("java.io.IOException: Broken pipe"));
    @Autowired
    private SysExceptionDetailDao sysExceptionDetailDao;
    @Pointcut("execution(* com.xcong.excoin..*.*(..))")
    public void exceptionCatch() {
    }
    @AfterThrowing(pointcut = "exceptionCatch()", throwing = "ex")
    public void afterThrows(JoinPoint jp, Exception ex) throws Exception {
        if (ex instanceof GlobalException || ex instanceof MethodArgumentNotValidException || ex instanceof ValidationException || ex instanceof DuplicateKeyException || ex instanceof BadCredentialsException) {
            throw ex;
        }
        if (EXCLUDE_EXCEPTION.contains(ex.getMessage())) {
            throw ex;
        }
        SysExceptionDetailEntity exceptionData = new SysExceptionDetailEntity();
        exceptionData.setCreateTime(new Date());
        exceptionData.setMachine(InetAddress.getLocalHost().getHostName());
        exceptionData.setAddress(InetAddress.getLocalHost().getHostAddress());
        exceptionData.setExceptionMsg(printStackTraceToString(ex));
        exceptionData.setSimpleMsg(ex.getMessage());
        sysExceptionDetailDao.insert(exceptionData);
        throw ex;
    }
    public String printStackTraceToString(Throwable t) {
        StringWriter sw = new StringWriter();
        t.printStackTrace(new PrintWriter(sw, true));
        return sw.getBuffer().toString();
    }
}
src/main/java/com/xcong/excoin/common/system/bean/SysExceptionDetailEntity.java
New file
@@ -0,0 +1,30 @@
package com.xcong.excoin.common.system.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
 * @author wzy
 * @date 2021-03-05
 **/
@Data
@TableName("sys_exception_detail")
public class SysExceptionDetailEntity {
    @TableId(value = "id",type = IdType.AUTO)
    private Long id;
    private Date createTime;
    private String machine;
    private String simpleMsg;
    private String exceptionMsg;
    private String address;
}
src/main/java/com/xcong/excoin/configurations/RabbitMqConfig.java
@@ -79,6 +79,10 @@
    // 全仓价格操作
    public static final String QUEUE_WHOLE_PRICE = "QUEUE_WHOLE_PRCE";
    // 跟单下单
    public static final String QUEUE_FOLLOW_ORDER = "QUEUE_FOLLOW_ORDER";
    public static final String ROUTINGKEY_FOLLOW_ORDER = "ROUTINGKEY_FOLLOW_ORDER";
    // 开多止盈路由键
    public static final String ROUTINGKEY_MOREPRO = "ROUTINGKEY_MOREPRO";
@@ -295,6 +299,16 @@
        return new Queue(QUEUE_WHOLE_BOMB, true);
    }
    @Bean
    public Queue queueFollowOrder() {
        return new Queue(QUEUE_FOLLOW_ORDER, true);
    }
    @Bean
    public Binding bindingFollowOrder() {
        return BindingBuilder.bind(queueFollowOrder()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_FOLLOW_ORDER);
    }
    @Bean
    public Binding bindingWholePrice() {
src/main/java/com/xcong/excoin/configurations/security/WebSecurityConfig.java
@@ -55,6 +55,7 @@
                .antMatchers("/api/orderCoin/findCollect").permitAll()
                .antMatchers("/api/orderCoin/findCollect").permitAll()
                .antMatchers("/api/documentary/getFollowTraderProfitInfo").permitAll()
                .antMatchers("/api/trader/beTraderStatusCondition").permitAll()
                .antMatchers("/api/helpCenter/**").permitAll()
                .anyRequest().authenticated()
                .and().apply(securityConfiguereAdapter());
src/main/java/com/xcong/excoin/modules/blackchain/service/TrxUsdtUpdateService.java
@@ -65,7 +65,7 @@
        // 扫块区块
        Object trc20BlockNum = redisUtils.get("USDT_TRC20_BLOCK_NUM");
        if(trc20BlockNum==null){
            trc20BlockNum = 27805917L;
            trc20BlockNum = 28095275L;
        }
        Long blockNum = Long.valueOf(trc20BlockNum.toString());
src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtErc20UpdateService.java
@@ -85,7 +85,7 @@
        // 获取最新区块
        String string = redisUtils.getString(ETH_USDT_BLOCK_NUM);
        if(string==null){
            string = "11892420";
            string = "11957825";
        }
        BigInteger blockNum = new BigInteger(string);
        Credentials credentials = Credentials.create(privateKey);
src/main/java/com/xcong/excoin/modules/contract/parameter/vo/ContractMoneyInfoVo.java
@@ -17,6 +17,12 @@
    @ApiModelProperty(value = "占用保证金")
    private BigDecimal beUsedBondAmount;
    @ApiModelProperty(value = "开多占用保证金")
    private BigDecimal moreBondAmount;
    @ApiModelProperty(value = "开空占用保证金")
    private BigDecimal lessBondAmount;
    @ApiModelProperty(value = "冻结保证金")
    private BigDecimal frozenBondAmount;
src/main/java/com/xcong/excoin/modules/contract/parameter/vo/OrderListVo.java
@@ -1,5 +1,6 @@
package com.xcong.excoin.modules.contract.parameter.vo;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -35,7 +36,7 @@
    @ApiModelProperty("开仓均价")
    private BigDecimal openingPrice;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @JsonFormat(pattern = "MM-dd HH:mm:ss", timezone = "GMT+8")
    @ApiModelProperty("开仓价")
    private Date openingTime;
@@ -60,7 +61,7 @@
    @ApiModelProperty("平仓手续费")
    private BigDecimal closingFeeAmount;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @JsonFormat(pattern = "MM-dd HH:mm:ss", timezone = "GMT+8")
    @ApiModelProperty("平仓时间")
    private Date closingTime;
@@ -76,6 +77,13 @@
    @ApiModelProperty(value = "合约类型 1-普通 2-跟单")
    private Integer contractType;
    @ApiModelProperty(value = "订单编号")
    private String orderNo;
    public String getOrderNo() {
        return StrUtil.isNotBlank(orderNo) ? orderNo.substring(orderNo.length() - 6) : "";
    }
    public String getOpeningFeeAmount() {
        return openingFeeAmount == null ? "" : openingFeeAmount.setScale(4, BigDecimal.ROUND_DOWN).toPlainString();
    }
src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
@@ -1,6 +1,8 @@
package com.xcong.excoin.modules.contract.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.sql.visitor.functions.If;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -37,11 +39,13 @@
import com.xcong.excoin.modules.member.entity.*;
import com.xcong.excoin.modules.platform.dao.TradeSettingDao;
import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
import com.xcong.excoin.rabbit.producer.FollowProducer;
import com.xcong.excoin.rabbit.producer.OrderProducer;
import com.xcong.excoin.utils.*;
import com.xcong.excoin.rabbit.pricequeue.OrderModel;
import jnr.a64asm.Mem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.rmi.runtime.Log;
@@ -100,6 +104,9 @@
    private FollowTraderInfoDao followTraderInfoDao;
    @Resource
    private FollowFollowerOrderRelationDao followFollowerOrderRelationDao;
    @Autowired
    private FollowProducer followProducer;
    @Transactional(rollbackFor = Exception.class)
    @Override
@@ -320,7 +327,7 @@
        FollowTraderInfoEntity tradeInfo = null;
        if (MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
            tradeInfo = followTraderInfoDao.selectTraderInfoByMemberId(memberEntity.getId());
            if (tradeInfo.getIsOpen().equals(FollowTraderInfoEntity.ISOPEN_Y)) {
            if (FollowTraderInfoEntity.ISOPEN_Y.equals(tradeInfo.getIsOpen())) {
                isOpenFollow = true;
            }
        }
@@ -380,7 +387,8 @@
                relationEntity.setTradeOrderNo(holdOrderEntity.getOrderNo());
                followFollowerOrderRelationDao.insert(relationEntity);
                ThreadPoolUtils.sendFollowOrderTask(holdOrderEntity.getId());
                followProducer.sendAddFollowOrder(holdOrderEntity.getId());
//                ThreadPoolUtils.sendFollowOrderTask(holdOrderEntity.getId());
            }
            // 提交成功
            return Result.ok(MessageSourceUtils.getString("member_service_0024"));
@@ -824,6 +832,8 @@
        // 占用保证金 -- 即持仓单中的保证金之和
        BigDecimal beUsedBondAmount = BigDecimal.ZERO;
        BigDecimal moreBondAmount = BigDecimal.ZERO;
        BigDecimal lessBondAmount = BigDecimal.ZERO;
        // 总盈利
        BigDecimal totalProfitOrLess = BigDecimal.ZERO;
        if (CollUtil.isNotEmpty(holdOrderEntities)) {
@@ -837,9 +847,11 @@
                BigDecimal profitOrLess = BigDecimal.ZERO;
                // 开多
                if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
                    moreBondAmount = moreBondAmount.add(holdOrderEntity.getBondAmount());
                    profitOrLess = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
                    // 开空
                } else {
                    lessBondAmount = lessBondAmount.add(holdOrderEntity.getBondAmount());
                    profitOrLess = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())).multiply(lotNumber);
                }
@@ -886,6 +898,8 @@
        contractMoneyInfoVo.setUpOrDown(upOrDown);
        contractMoneyInfoVo.setSymbolSku(cacheSettingUtils.getSymbolSku(symbol));
        contractMoneyInfoVo.setLeverRate(rateEntity.getLevelRateUp());
        contractMoneyInfoVo.setMoreBondAmount(moreBondAmount);
        contractMoneyInfoVo.setLessBondAmount(lessBondAmount);
        return Result.ok(contractMoneyInfoVo);
    }
@@ -1016,8 +1030,27 @@
        List<ContractHoldOrderEntity> list = contractHoldOrderDao.selectHoldOrderListByMemberId(member.getId());
        List<ContractEntrustOrderEntity> entrustList = contractEntrustOrderDao.selectEntrustOrderListByMemberId(member.getId());
        if (CollUtil.isNotEmpty(list) || CollUtil.isNotEmpty(entrustList)) {
//        if (CollUtil.isNotEmpty(list) || CollUtil.isNotEmpty(entrustList)) {
//            return Result.fail("存在持仓/委托, 无法更改");
//        }
        if(CollUtil.isNotEmpty(list)) {
            for(ContractHoldOrderEntity contractHoldOrderEntity : list) {
                String symbol = contractHoldOrderEntity.getSymbol();
                if(StrUtil.isEmpty(symbol)) {
            return Result.fail("存在持仓/委托, 无法更改");
                }
                return Result.fail("币种"+symbol+"存在持仓/委托, 无法更改");
            }
        }
        if(CollUtil.isNotEmpty(entrustList)) {
            for(ContractEntrustOrderEntity contractEntrustOrderEntity : entrustList) {
                String symbol = contractEntrustOrderEntity.getSymbol();
                if(StrUtil.isEmpty(symbol)) {
                    return Result.fail("存在持仓/委托, 无法更改");
                }
                return Result.fail("币种"+symbol+"存在持仓/委托, 无法更改");
            }
        }
        
        /**
@@ -1069,9 +1102,11 @@
                holdOrderEntity.setOperateNo(holdOrderEntity.getOperateNo() + 1);
                contractHoldOrderDao.updateById(holdOrderEntity);
                if (ContractEntrustOrderEntity.POSITION_TYPE_ADD == holdOrderEntity.getPositionType()) {
                // 发送爆仓消息
                sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), newForcePrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo(), holdOrderEntity.getMemberId());
            }
        }
    }
}
}
src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java
@@ -16,6 +16,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.documentary.service.FollowOrderOperationService;
import com.xcong.excoin.modules.member.dao.AgentReturnDao;
import com.xcong.excoin.modules.member.dao.MemberSettingDao;
import com.xcong.excoin.modules.member.entity.AgentReturnEntity;
@@ -80,7 +81,8 @@
    private ContractEntrustOrderDao contractEntrustOrderDao;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private FollowOrderOperationService followOrderOperationService;
    public void dealOrderFromMq(List<OrderModel> list, Integer type) {
        if (CollectionUtils.isNotEmpty(list)) {
@@ -794,6 +796,7 @@
                    continue;
                }
                // 仅逐仓有用
                if (ContractEntrustOrderEntity.POSITION_TYPE_ADD == coinsOrder.getPositionType()) {
                    bombOrder(coinsOrder);
                } else {
@@ -880,6 +883,12 @@
                record.setSymbol(coinsOrder.getSymbol());
                record.setPrice(coinsOrder.getBondAmount());
                memberAccountFlowEntityDao.insert(record);
                MemberEntity memberEntity = memberService.getById(memId);
                // 如果订单为交易员的订单,爆仓了,则旗下的所有跟单都进行平仓
                if (ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY == coinsOrder.getContractType() && MemberEntity.IS_TRADER_Y.equals(memberEntity.getIsTrader())) {
                    followOrderOperationService.closingFollowOrders(coinsOrder.getOrderNo());
                }
            } else {
                MemberWalletContractEntity wallet = memberWalletContractService.findWalletContractByMemberIdAndSymbol(memId, "USDT");
src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java
@@ -215,7 +215,7 @@
                    followOrderOperationService.closingFollowOrders(holdOrderEntity.getOrderNo());
                } else {
                    followFollowerProfitDao.updateFollowerProfitByTradeMemberId(holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()), profitOrLoss, traderInfoEntity.getMemberId(), memberEntity.getId());
                    LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.CLOSE_ORDER_TITLE, StrUtil.format(NoticeConstant.CLOSE_ORDER_CONTENT, contractOrderEntity.getSymbol(), contractOrderEntity.getClosingPrice(), profitOrLoss.setScale(8, BigDecimal.ROUND_DOWN), traderInfoEntity.getNickname()));
                    LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.CLOSE_ORDER_TITLE, StrUtil.format(NoticeConstant.CLOSE_ORDER_CONTENT, contractOrderEntity.getSymbol(), contractOrderEntity.getClosingPrice(), profitOrLoss.setScale(8, BigDecimal.ROUND_DOWN).toString(), traderInfoEntity.getNickname()));
                }
            }
        }
src/main/java/com/xcong/excoin/modules/documentary/controller/DocumentaryController.java
@@ -16,6 +16,7 @@
import com.xcong.excoin.modules.documentary.dto.DocumentaryOrderSetDto;
import com.xcong.excoin.modules.documentary.dto.FollowFollowerNoticeDto;
import com.xcong.excoin.modules.documentary.dto.FollowRecordsDto;
import com.xcong.excoin.modules.documentary.dto.FollowTraderProfitInfoDto;
import com.xcong.excoin.modules.documentary.dto.HistoryOrderRecordsDto;
import com.xcong.excoin.modules.documentary.dto.MyFollowOrderDto;
import com.xcong.excoin.modules.documentary.dto.MyFollowTraderInfoDto;
@@ -23,6 +24,7 @@
import com.xcong.excoin.modules.documentary.service.DocumentaryService;
import com.xcong.excoin.modules.documentary.vo.DocumentaryOrderInfoVo;
import com.xcong.excoin.modules.documentary.vo.DocumentaryOrderSetInfoVo;
import com.xcong.excoin.modules.documentary.vo.DocumentaryOrderSetStateVo;
import com.xcong.excoin.modules.documentary.vo.FollowFollowerNoticeVo;
import com.xcong.excoin.modules.documentary.vo.FollowInfoVo;
import com.xcong.excoin.modules.documentary.vo.FollowRecordsVo;
@@ -76,7 +78,7 @@
    @ApiOperation(value="交易员列表", notes="交易员列表")
    @ApiResponses({@ApiResponse( code = 200, message = "success", response = FollowTraderProfitInfoVo.class)})
    @PostMapping(value = "/getFollowTraderProfitInfo")
    public Result  getFollowTraderProfitInfo(@RequestBody @Valid RecordsPageDto recordsPageDto) {
    public Result  getFollowTraderProfitInfo(@RequestBody @Valid FollowTraderProfitInfoDto recordsPageDto) {
        return documentaryService.getFollowTraderProfitInfo(recordsPageDto);
    }
    
@@ -165,6 +167,18 @@
    }
    
    /**
     *  跟单---跟单设置--是否已跟单
     */
    @ApiOperation(value="跟单---跟单设置--是否已跟单", notes="跟单---跟单设置--是否已跟单")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "tradeId", value = "交易员ID", required = true, dataType = "String", paramType="query")
    })
    @GetMapping(value = "/getDocumentaryOrderSetState")
    public Result  getDocumentaryOrderSetState(String tradeId) {
        return documentaryService.getDocumentaryOrderSetState(tradeId);
    }
    /**
     *  跟单---跟单设置--新增跟单
     */
    @ApiOperation(value="跟单---跟单设置--新增跟单", notes="跟单---跟单设置--新增跟单")
src/main/java/com/xcong/excoin/modules/documentary/controller/TraderController.java
@@ -10,11 +10,13 @@
import org.springframework.web.bind.annotation.RestController;
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.modules.documentary.dto.BeTraderDto;
import com.xcong.excoin.modules.documentary.dto.OutFollowInfoDto;
import com.xcong.excoin.modules.documentary.dto.TradeFollowInfoDto;
import com.xcong.excoin.modules.documentary.dto.TradeOrderInfoDto;
import com.xcong.excoin.modules.documentary.dto.UpdateTradeSetInfoDto;
import com.xcong.excoin.modules.documentary.service.DocumentaryService;
import com.xcong.excoin.modules.documentary.vo.BeTraderConditionVo;
import com.xcong.excoin.modules.documentary.vo.TradeFollowInfoVo;
import com.xcong.excoin.modules.documentary.vo.TradeHistoryOrderInfoVo;
import com.xcong.excoin.modules.documentary.vo.TradeOrderInfoVo;
@@ -39,6 +41,16 @@
    
    @Resource
    DocumentaryService documentaryService;
    /**
     *  成为交易员---条件查询
     */
    @ApiOperation(value="成为交易员---条件查询", notes="成为交易员---条件查询")
    @ApiResponses({@ApiResponse( code = 200, message = "success", response = BeTraderConditionVo.class)})
    @GetMapping(value = "/beTraderStatusCondition")
    public Result  beTraderCondition() {
        return documentaryService.beTraderCondition();
    }
    
    /**
     *  成为交易员---状态查询
@@ -103,9 +115,9 @@
     *  成为交易员---立即入驻
     */
    @ApiOperation(value="成为交易员---立即入驻", notes="成为交易员---立即入驻")
    @GetMapping(value = "/beTrader")
    public Result  beTrader() {
        return documentaryService.beTrader();
    @PostMapping(value = "/beTrader")
    public Result  beTrader(@RequestBody @Valid BeTraderDto beTraderDto) {
        return documentaryService.beTrader(beTraderDto);
    }
    
    /**
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerSettingDao.java
@@ -17,4 +17,6 @@
    FollowFollowerSettingEntity selectOneBymemberIdAndTradeId(@Param("memberId")Long memberId, @Param("traderId")Long traderId);
    List<FollowFollowerSettingEntity> selectAllFollowerSettingByTradeMemberId(@Param("memberId") Long memberId);
    List<FollowFollowerSettingEntity> selectDocumentaryOrderSetInfosBymemberId(@Param("memberId")Long memberId);
}
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderInfoDao.java
@@ -2,6 +2,8 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
import com.xcong.excoin.modules.documentary.vo.BeTraderConditionVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -15,4 +17,6 @@
    FollowTraderInfoEntity selectTraderInfoByOrderId(@Param("orderId") Long orderId);
    List<FollowTraderInfoEntity> selectAllTraderInfo();
    List<BeTraderConditionVo> selectBeTraderCondition(@Param("type")String type);
}
src/main/java/com/xcong/excoin/modules/documentary/dto/BeTraderDto.java
New file
@@ -0,0 +1,26 @@
package com.xcong.excoin.modules.documentary.dto;
import javax.validation.constraints.NotNull;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "BeTraderDto", description = "参数接受类")
public class BeTraderDto {
    @ApiModelProperty("头像")
    private String avatar;
    @NotNull(message = "名称不能为空")
    @ApiModelProperty("名称")
    private String nickname;
    @ApiModelProperty("宣言")
    private String declaration;
    @NotNull(message = "标签不能为空")
    @ApiModelProperty("标签")
    private String labels;
}
src/main/java/com/xcong/excoin/modules/documentary/dto/FollowTraderProfitInfoDto.java
New file
@@ -0,0 +1,44 @@
package com.xcong.excoin.modules.documentary.dto;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "FollowTraderProfitInfoDto", description = "参数接受类")
public class FollowTraderProfitInfoDto {
    @NotNull
    @Min(1)
    @ApiModelProperty(value = "第几页", example = "1")
    private int pageNum;
    @NotNull
    @ApiModelProperty(value = "每页数量", example = "10")
    private int pageSize;
    @ApiModelProperty(value = "1:首页", example = "1")
    private int type;
    @ApiModelProperty(value = "昵称", example = "哈哈")
    private String nickname;
    /**
     * 累计收益率排序(1正序 2倒序)
     */
    @ApiModelProperty(value = "累计收益率排序(0不参与 1正序 2倒序)", example = "1")
    private int totalProfitRatioSc;
    /**
     * 胜率排序(1正序 2倒序)
     */
    @ApiModelProperty(value = "胜率排序(0不参与 1正序 2倒序)", example = "1")
    private int winRateSc;
    /**
     * 累计跟随人数排序(1正序 2倒序)
     */
    @ApiModelProperty(value = "累计跟随人数排序(0不参与 1正序 2倒序)", example = "1")
    private int totalFollowerCntSc;
}
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderInfoEntity.java
@@ -1,8 +1,10 @@
package com.xcong.excoin.modules.documentary.entity;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xcong.excoin.common.system.base.BaseEntity;
import lombok.Data;
@@ -21,6 +23,12 @@
    private static final long serialVersionUID = 1L;
    
    public static final String DECLARATION_DEFAULT = "正忙着赚钱,什么也没写";
    public static final Integer FOLLOWNUM_DEFAULT = 500;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date entryTime;
     /**
     * 会员ID
     */
@@ -33,6 +41,12 @@
     * 名称
     */
    private String nickname;
    /**
     * 名称是否已修改
     */
    private Integer nicknameState;
    public static final Integer STATE_Y = 1;
    public static final Integer STATE_N = 0;
    /**
     * 宣言
     */
@@ -47,6 +61,12 @@
    private Integer isAll;
    public static final Integer IS_ALL_Y = 1;
    public static final Integer IS_ALL_N = 2;
    /**
     * 设置成首页
     */
    private Integer isSetFrist;
    public static final Integer IS_SETFRIST_Y = 1;
    /**
     * 利润
     */
@@ -64,6 +84,10 @@
    private Integer isOpen;
    public static final Integer ISOPEN_Y = 1;
    public static final Integer ISOPEN_N = 2;
    /**
     * 最大跟随人数
     */
    private Integer followNum;
    
}
src/main/java/com/xcong/excoin/modules/documentary/entity/FollowTraderProfitInfoEntity.java
@@ -2,9 +2,11 @@
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xcong.excoin.common.system.base.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -53,5 +55,25 @@
     */
    private int totalOrderCnt;
    
    @TableField(exist = false)
    private int type;
    @TableField(exist = false)
    private String nickname;
    /**
     * 累计收益率排序(1正序 2倒序)
     */
    @TableField(exist = false)
    private int totalProfitRatioSc;
    /**
     * 胜率排序(1正序 2倒序)
     */
    @TableField(exist = false)
    private int winRateSc;
    /**
     * 累计跟随人数排序(1正序 2倒序)
     */
    @TableField(exist = false)
    private int totalFollowerCntSc;
}
src/main/java/com/xcong/excoin/modules/documentary/service/DocumentaryService.java
@@ -2,13 +2,17 @@
import javax.validation.Valid;
import org.springframework.web.bind.annotation.RequestBody;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.modules.coin.parameter.dto.RecordsPageDto;
import com.xcong.excoin.modules.documentary.dto.BeTraderDto;
import com.xcong.excoin.modules.documentary.dto.CancelDocumentaryOrderSetDto;
import com.xcong.excoin.modules.documentary.dto.DocumentaryOrderSetDto;
import com.xcong.excoin.modules.documentary.dto.FollowFollowerNoticeDto;
import com.xcong.excoin.modules.documentary.dto.FollowRecordsDto;
import com.xcong.excoin.modules.documentary.dto.FollowTraderProfitInfoDto;
import com.xcong.excoin.modules.documentary.dto.HistoryOrderRecordsDto;
import com.xcong.excoin.modules.documentary.dto.MyFollowOrderDto;
import com.xcong.excoin.modules.documentary.dto.MyFollowTraderInfoDto;
@@ -23,7 +27,7 @@
    public Result getMemberIsTradeInfo();
    public Result getFollowTraderProfitInfo(@Valid RecordsPageDto recordsPageDto);
    public Result getFollowTraderProfitInfo(@Valid FollowTraderProfitInfoDto recordsPageDto);
    public Result getHistoryOrderRecords(@Valid HistoryOrderRecordsDto historyOrderRecordsDto);
@@ -49,7 +53,7 @@
    public Result getFollowTraderProfit(long traderId);
    public Result beTrader();
    public Result beTrader(@Valid BeTraderDto beTraderDto);
    public Result beTraderStatus();
@@ -71,5 +75,9 @@
    public Result getTradeSetLabelInfo();
    public Result beTraderCondition();
    public Result getDocumentaryOrderSetState(String tradeId);
}
src/main/java/com/xcong/excoin/modules/documentary/service/impl/DocumentaryServiceImpl.java
@@ -2,6 +2,7 @@
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -11,9 +12,12 @@
import javax.validation.Valid;
import com.xcong.excoin.modules.documentary.common.NoticeConstant;
import com.xcong.excoin.modules.member.entity.MemberSettingEntity;
import com.xcong.excoin.modules.member.parameter.vo.MemberMessageReminderVo;
import com.xcong.excoin.utils.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -37,10 +41,12 @@
import com.xcong.excoin.modules.documentary.dao.FollowTraderLabelDao;
import com.xcong.excoin.modules.documentary.dao.FollowTraderProfitDetailDao;
import com.xcong.excoin.modules.documentary.dao.FollowTraderProfitInfoDao;
import com.xcong.excoin.modules.documentary.dto.BeTraderDto;
import com.xcong.excoin.modules.documentary.dto.CancelDocumentaryOrderSetDto;
import com.xcong.excoin.modules.documentary.dto.DocumentaryOrderSetDto;
import com.xcong.excoin.modules.documentary.dto.FollowFollowerNoticeDto;
import com.xcong.excoin.modules.documentary.dto.FollowRecordsDto;
import com.xcong.excoin.modules.documentary.dto.FollowTraderProfitInfoDto;
import com.xcong.excoin.modules.documentary.dto.HistoryOrderRecordsDto;
import com.xcong.excoin.modules.documentary.dto.MyFollowOrderDto;
import com.xcong.excoin.modules.documentary.dto.MyFollowTraderInfoDto;
@@ -57,8 +63,10 @@
import com.xcong.excoin.modules.documentary.entity.FollowTraderLabelEntity;
import com.xcong.excoin.modules.documentary.entity.FollowTraderProfitInfoEntity;
import com.xcong.excoin.modules.documentary.service.DocumentaryService;
import com.xcong.excoin.modules.documentary.vo.BeTraderConditionVo;
import com.xcong.excoin.modules.documentary.vo.DocumentaryOrderInfoVo;
import com.xcong.excoin.modules.documentary.vo.DocumentaryOrderSetInfoVo;
import com.xcong.excoin.modules.documentary.vo.DocumentaryOrderSetStateVo;
import com.xcong.excoin.modules.documentary.vo.FollowFollowerNoticeVo;
import com.xcong.excoin.modules.documentary.vo.FollowInfoVo;
import com.xcong.excoin.modules.documentary.vo.FollowRecordsVo;
@@ -76,6 +84,7 @@
import com.xcong.excoin.modules.documentary.vo.TraderStatusVo;
import com.xcong.excoin.modules.member.dao.MemberDao;
import com.xcong.excoin.modules.member.dao.MemberLevelRateDao;
import com.xcong.excoin.modules.member.dao.MemberSettingDao;
import com.xcong.excoin.modules.member.dao.MemberWalletContractDao;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.modules.member.entity.MemberLevelRateEntity;
@@ -124,6 +133,8 @@
    private FollowFollowerNoticeDao followFollowerNoticeDao;
    @Resource
    private FollowTraderLabelDao followTraderLabelDao;
    @Resource
    private MemberSettingDao memberSettingDao;
    
    
    @Override
@@ -143,10 +154,24 @@
    }
    @Override
    public Result getFollowTraderProfitInfo(@Valid RecordsPageDto recordsPageDto) {
    public Result getFollowTraderProfitInfo(@Valid FollowTraderProfitInfoDto recordsPageDto) {
        
        int type = recordsPageDto.getType();
        Page<FollowTraderProfitInfoVo> page = new Page<>(recordsPageDto.getPageNum(), recordsPageDto.getPageSize());
        FollowTraderProfitInfoEntity followTraderProfitInfoEntity = new FollowTraderProfitInfoEntity();
        if(FollowTraderInfoEntity.IS_SETFRIST_Y.equals(type)) {
            followTraderProfitInfoEntity.setType(type);
        }else {
            String nicknameDto = recordsPageDto.getNickname();
            followTraderProfitInfoEntity.setNickname(nicknameDto);
            int totalProfitRatioSc = recordsPageDto.getTotalProfitRatioSc();
            followTraderProfitInfoEntity.setTotalProfitRatioSc(totalProfitRatioSc);
            int totalFollowerCntSc = recordsPageDto.getTotalFollowerCntSc();
            followTraderProfitInfoEntity.setTotalFollowerCntSc(totalFollowerCntSc);
            int winRateSc = recordsPageDto.getWinRateSc();
            followTraderProfitInfoEntity.setWinRateSc(winRateSc);
        }
        IPage<FollowTraderProfitInfoVo> followTraderProfitInfoList = followTraderProfitInfoDao.selectFollowTraderProfitInfoEntity(page, followTraderProfitInfoEntity);
        
        List<FollowTraderProfitInfoVo> followTraderProfitInfoVoList = followTraderProfitInfoList.getRecords();
@@ -162,9 +187,27 @@
                    }else {
                        FollowTraderProfitInfoVo.setDocumentaryType(2);
                    }
                }
                Long traderId = FollowTraderProfitInfoVo.getTraderId();
                FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoDao.selectFollowTraderInfoEntityBytreaderId(traderId);
                //获取当前跟单人数
                Map<String, Object> columnMap = new HashMap<>();
                columnMap.put("trader_id", traderId);
                List<FollowFollowerSettingEntity> selectByMap = followFollowerSettingDao.selectByMap(columnMap);
                if(CollUtil.isNotEmpty(selectByMap)) {
                    Integer followNum = followTraderInfoEntity.getFollowNum();
                    int size = selectByMap.size();
                    if(followNum > size) {
                        FollowTraderProfitInfoVo.setIsActualAll(2);
                    }else {
                        FollowTraderProfitInfoVo.setIsActualAll(1);
                    }
                }else {
                    FollowTraderProfitInfoVo.setIsActualAll(2);
                }
                String avatar = followTraderInfoEntity.getAvatar();
                FollowTraderProfitInfoVo.setAvatar(avatar);
                String nickname = followTraderInfoEntity.getNickname();
@@ -221,6 +264,7 @@
                historyOrderRecordsVo.setClosingPrice(closingPrice);
                BigDecimal openingPrice = historyOrderRecordsVo.getOpeningPrice().setScale(2, BigDecimal.ROUND_DOWN);
                historyOrderRecordsVo.setOpeningPrice(openingPrice);
                historyOrderRecordsVo.setClosingTimeStamp(historyOrderRecordsVo.getClosingTime().getTime());
            }
        }
        return Result.ok(historyOrderRecordsVoList);
@@ -274,6 +318,42 @@
            followInfoVo.setNickname(phone);
        }
        
        List<ContractHoldOrderEntity> myFollowOrder = followFollowerProfitDao.getFollowOrderNowRecords(memberId);
        BigDecimal totalBondAmount = BigDecimal.ZERO;
        BigDecimal profitOrLess = BigDecimal.ZERO;
        if (CollUtil.isNotEmpty(myFollowOrder)) {
            for(ContractHoldOrderEntity contractHoldOrderEntity : myFollowOrder) {
                BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(contractHoldOrderEntity.getSymbol())));
                BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(contractHoldOrderEntity.getSymbol());
                // 盈亏
                BigDecimal rewardRatio = BigDecimal.ZERO;
                // 开多
                if (contractHoldOrderEntity.OPENING_TYPE_MORE == contractHoldOrderEntity.getOpeningType()) {
                    // (最新价-开仓价)*规格*张数
                    rewardRatio = newPrice.subtract(contractHoldOrderEntity.getOpeningPrice()).multiply(lotNumber).multiply(new BigDecimal(contractHoldOrderEntity.getSymbolCnt()));
                    // 开空
                } else {
                    // (开仓价-最新价)*规格*张数
                    rewardRatio = contractHoldOrderEntity.getOpeningPrice().subtract(newPrice).multiply(lotNumber).multiply(new BigDecimal(contractHoldOrderEntity.getSymbolCnt()));
                }
                if (member.getIsProfit() == MemberEntity.IS_PROFIT_Y) {
                    PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
                    if (rewardRatio.compareTo(BigDecimal.ZERO) > -1) {
                        rewardRatio = rewardRatio.multiply(BigDecimal.ONE.subtract(tradeSettingEntity.getProfitParam()));
                    }
                }
                profitOrLess = profitOrLess.add(rewardRatio).setScale(2, BigDecimal.ROUND_DOWN);
                totalBondAmount = totalBondAmount.add(contractHoldOrderEntity.getBondAmount()).setScale(2, BigDecimal.ROUND_DOWN);
            }
        }
        followInfoVo.setTotalAmount(totalBondAmount);
        followInfoVo.setTotalProfitOrLess(profitOrLess);
        BigDecimal totalPrincipals =  BigDecimal.ZERO;
        BigDecimal totalProfits =  BigDecimal.ZERO;
        Map<String, Object> columnMap = new HashMap<>();
@@ -308,13 +388,15 @@
                    MyFollowOrderVo myFollowOrderVo = new MyFollowOrderVo();
                    //获取交易员信息
                    Long orderId = contractOrderEntity.getId();
                    myFollowOrderVo.setOrderId(orderId);
                    FollowFollowerOrderRelationEntity FollowFollowerOrderRelation = followFollowerOrderRelationDao.selectHistoryOneByorderId(orderId);
                    if(ObjectUtil.isNotEmpty(FollowFollowerOrderRelation)) {
                        myFollowOrderVo.setOrderId(orderId);
                    Long tradeId = FollowFollowerOrderRelation.getTradeId();
                    FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoDao.selectById(tradeId);
                        if(ObjectUtil.isNotEmpty(followTraderInfoEntity)) {
                    String nickname = followTraderInfoEntity.getNickname();
                    myFollowOrderVo.setNickname(nickname);
                        }
                    String symbol = contractOrderEntity.getSymbol();
                    myFollowOrderVo.setSymbol(symbol);
                    int orderType = contractOrderEntity.getOrderType();
@@ -340,6 +422,7 @@
                    String orderNo = contractOrderEntity.getOrderNo();
                    myFollowOrderVo.setOrderNo(orderNo);
                    myFollowOrderVos.add(myFollowOrderVo);
                    }
                }
            }
        return Result.ok(myFollowOrderVos);
@@ -579,8 +662,23 @@
    public Result getDocumentaryOrderSetInfo(String tradeId) {
        //获取用户ID
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        log.info("跟单---点击跟单或者编辑---"+memberId+"参数"+tradeId);
        DocumentaryOrderSetInfoVo documentaryOrderSetInfoVo = new DocumentaryOrderSetInfoVo();
        long parseLong = Long.parseLong(tradeId);
        //只能跟随一个人
//        Map<String, Object> columnMaps = new HashMap<>();
//        columnMaps.put("member_id", memberId);
//        List<FollowFollowerSettingEntity> followFollowerSettingEntityAllows = followFollowerSettingDao.selectByMap(columnMaps);
//        if(CollUtil.isNotEmpty(followFollowerSettingEntityAllows)) {
//            for(FollowFollowerSettingEntity followFollowerSettingEntityAllow : followFollowerSettingEntityAllows) {
//                Long tradeIdAllow = followFollowerSettingEntityAllow.getTraderId();
//                if(parseLong != tradeIdAllow) {
//                    return Result.fail(MessageSourceUtils.getString("documentary_service_0015"));
//                }
//            }
//        }
        //获取【跟随者设置】数据
        FollowFollowerSettingEntity followFollowerSettingEntity = followFollowerSettingDao.selectOneBymemberIdAndTradeId(memberId,parseLong);
@@ -607,8 +705,12 @@
        documentaryOrderSetInfoVo.setFollowCnt(followCnt);
        
        Integer maxFollowCnt = followFollowerSettingEntity.getMaxFollowCnt();
        documentaryOrderSetInfoVo.setMaxFollowCnt(maxFollowCnt);
        if(maxFollowCnt > 0){
            documentaryOrderSetInfoVo.setMaxFollowCnt(maxFollowCnt.toString());
        }else {
            documentaryOrderSetInfoVo.setMaxFollowCnt("");
        }
        log.info(memberId + "-最大持仓张数-"+maxFollowCnt.toString());
        return Result.ok(documentaryOrderSetInfoVo);
    }
@@ -676,6 +778,30 @@
        String nickname = followTraderInfoEntity.getNickname();
        String declaration = followTraderInfoEntity.getDeclaration();
        Integer isAll = followTraderInfoEntity.getIsAll();
        Integer followNum = followTraderInfoEntity.getFollowNum();
        Date entryTime = followTraderInfoEntity.getEntryTime();
        int datePoor = getDatePoor(entryTime, new Date());
        followTraderProfitInfoVo.setEntryDays(datePoor);
        //获取当前跟单人数
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("trade_id", traderId);
        columnMap.put("is_follow", FollowFollowerProfitEntity.IS_FOLLOW_Y);
        List<FollowFollowerProfitEntity> selectByMap = followFollowerProfitDao.selectByMap(columnMap);
        if(CollUtil.isNotEmpty(selectByMap)) {
            followTraderProfitInfoVo.setFollowNumNow(selectByMap.size());
        }else {
            followTraderProfitInfoVo.setFollowNumNow(0);
        }
        if(CollUtil.isNotEmpty(selectByMap)) {
            if(followNum > selectByMap.size()){
                followTraderProfitInfoVo.setIsActualAll(2);
            }else{
                followTraderProfitInfoVo.setIsActualAll(1);
            }
        }else {
            followTraderProfitInfoVo.setIsActualAll(2);
        }
        followTraderProfitInfoVo.setFollowNum(followNum);
        followTraderProfitInfoVo.setAvatar(avatar);
        followTraderProfitInfoVo.setNickname(nickname);
        followTraderProfitInfoVo.setDeclaration(declaration);
@@ -683,9 +809,30 @@
        return Result.ok(followTraderProfitInfoVo);
    }
    //获取两个时间之间的日期
    private int getDatePoor(Date endDate, Date nowDate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(endDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(nowDate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);
        int parseInt = Integer.parseInt(String.valueOf(between_days));
        parseInt = parseInt + 1;
        return parseInt ;
    }
    @Override
    @Transactional
    public Result beTrader() {
    public Result beTrader(@Valid BeTraderDto beTraderDto) {
        //头像
        String avatar = beTraderDto.getAvatar();
        //昵称
        String nickname = beTraderDto.getNickname();
        //宣言
        String declaration = beTraderDto.getDeclaration();
        //标签
        String labels = beTraderDto.getLabels();
        //获取用户ID
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        MemberEntity memberEntity = memberDao.selectById(memberId);
@@ -723,14 +870,25 @@
        followTraderInfoEntity.setMemberId(memberId);
        followTraderInfoEntity.setProfitRatio(BigDecimal.valueOf(0.1));
//        followTraderInfoEntity.setAvatar(FollowTraderInfoEntity.AVATAR_DEFAULT);
        String phone = memberEntity.getPhone();
        String email = memberEntity.getEmail();
        if(StrUtil.isNotEmpty(phone)) {
            followTraderInfoEntity.setNickname(phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
        }else {
            followTraderInfoEntity.setNickname(email.replaceAll("(\\w?)(\\w+)(\\w)(@\\w+\\.[a-z]+(\\.[a-z]+)?)","$1****$3$4"));
//        String phone = memberEntity.getPhone();
//        String email = memberEntity.getEmail();
//        if(StrUtil.isNotEmpty(phone)) {
//            followTraderInfoEntity.setNickname(phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
//        }else {
//            followTraderInfoEntity.setNickname(email.replaceAll("(\\w?)(\\w+)(\\w)(@\\w+\\.[a-z]+(\\.[a-z]+)?)","$1****$3$4"));
//        }
        if(StrUtil.isNotEmpty(avatar)) {
            followTraderInfoEntity.setAvatar(avatar);
        }
        followTraderInfoEntity.setNickname(nickname);
        followTraderInfoEntity.setNicknameState(FollowTraderInfoEntity.STATE_Y);
        if(StrUtil.isEmpty(declaration)) {
        followTraderInfoEntity.setDeclaration(FollowTraderInfoEntity.DECLARATION_DEFAULT);
        }else {
            followTraderInfoEntity.setDeclaration(declaration);
        }
        followTraderInfoEntity.setLabels(labels);
        followTraderInfoEntity.setFollowNum(FollowTraderInfoEntity.FOLLOWNUM_DEFAULT);
        followTraderInfoEntity.setIsAll(FollowTraderInfoEntity.IS_ALL_N);
        followTraderInfoEntity.setProfitRatio(BigDecimal.ZERO);
        followTraderInfoEntity.setVerifyStatus(FollowTraderInfoEntity.VERIFYSTATUS_ING);
@@ -776,6 +934,8 @@
        tradeSetInfoVo.setAvatar(avatar);
        String nickname = followTraderInfoEntity.getNickname();
        tradeSetInfoVo.setNickname(nickname);
        Integer nicknameState = followTraderInfoEntity.getNicknameState();
        tradeSetInfoVo.setNicknameState(nicknameState);
        String declaration = followTraderInfoEntity.getDeclaration();
        tradeSetInfoVo.setDeclaration(declaration);
        Integer isOpen = followTraderInfoEntity.getIsOpen();
@@ -810,6 +970,14 @@
        String declaration = updateTradeSetInfoDto.getDeclaration();
        int isOpen = updateTradeSetInfoDto.getIsOpen();
        String labels = updateTradeSetInfoDto.getLabels();
        Integer nicknameState = followTraderInfoEntity.getNicknameState();
        if(FollowTraderInfoEntity.STATE_Y == nicknameState && !nickname.equals(followTraderInfoEntity.getNickname())) {
            return Result.ok(MessageSourceUtils.getString("member_service_0099"));
        }
        if(!nickname.equals(followTraderInfoEntity.getNickname())) {
            followTraderInfoEntity.setNickname(nickname);
            followTraderInfoEntity.setNicknameState(FollowTraderInfoEntity.STATE_Y);
        }
        followTraderInfoEntity.setLabels(labels);
        followTraderInfoEntity.setAvatar(avatar);
        followTraderInfoEntity.setNickname(nickname);
@@ -826,7 +994,22 @@
        TradeProfitInfoVo tradeProfitInfoVo = new TradeProfitInfoVo();
        //获取【交易员信息表】数据
        FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoDao.selectTraderInfoByMemberId(memberId);
        Date entryTime = followTraderInfoEntity.getEntryTime();
        int datePoor = getDatePoor(entryTime, new Date());
        tradeProfitInfoVo.setEntryDays(datePoor);
        if(ObjectUtil.isNotEmpty(followTraderInfoEntity)) {
            Integer followNum = followTraderInfoEntity.getFollowNum();
            //获取当前跟单人数
            Map<String, Object> columnMap = new HashMap<>();
            columnMap.put("trade_id", followTraderInfoEntity.getId());
            columnMap.put("is_follow", FollowFollowerProfitEntity.IS_FOLLOW_Y);
            List<FollowFollowerProfitEntity> selectByMap = followFollowerProfitDao.selectByMap(columnMap);
            if(CollUtil.isNotEmpty(selectByMap)) {
                tradeProfitInfoVo.setFollowNumNow(selectByMap.size());
            }else {
                tradeProfitInfoVo.setFollowNumNow(0);
            }
            tradeProfitInfoVo.setFollowNum(followNum);
            String avatar = followTraderInfoEntity.getAvatar();
            tradeProfitInfoVo.setAvatar(avatar);
            String nickname = followTraderInfoEntity.getNickname();
@@ -870,11 +1053,11 @@
                    TradeOrderInfoVo myFollowOrderVo = new TradeOrderInfoVo();
                    //获取交易员信息
                    Long orderId = contractHoldOrderEntity.getId();
                    myFollowOrderVo.setOrderId(orderId);
                    FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoDao.selectTraderInfoByMemberId(memberId);
                    if(ObjectUtil.isNotEmpty(followTraderInfoEntity)) {
                        myFollowOrderVo.setOrderId(orderId);
                    String nickname = followTraderInfoEntity.getNickname();
                    myFollowOrderVo.setNickname(nickname);
                    String symbol = contractHoldOrderEntity.getSymbol();
                    myFollowOrderVo.setSymbol(symbol);
                    int orderType = contractHoldOrderEntity.getOpeningType();
@@ -922,6 +1105,7 @@
                    myFollowOrderVo.setRewardRatio(returnRate.setScale(4, BigDecimal.ROUND_DOWN));
                    
                    myFollowOrderVos.add(myFollowOrderVo);
                    }
                }
            }
        
@@ -1054,6 +1238,18 @@
        long id = outFollowInfoDto.getId();
        //获取【跟随者收益】
        FollowFollowerProfitEntity followFollowerProfitEntity = followFollowerProfitDao.selectById(id);
        //当前有跟单合约不允许移除
        //获取【跟随者-订单关联表】
        Map<String, Object> selectColumnMap = new HashMap<>();
        selectColumnMap.put("member_id", followFollowerProfitEntity.getMemberId());
        selectColumnMap.put("trade_member_id", memberId);
        selectColumnMap.put("order_type", FollowFollowerOrderRelationEntity.ORDER_TYPE_HOLD);
        List<FollowFollowerOrderRelationEntity> followFollowerOrderRelationEntitys = followFollowerOrderRelationDao.selectByMap(selectColumnMap);
        if(CollUtil.isNotEmpty(followFollowerOrderRelationEntitys)) {
            return Result.fail(MessageSourceUtils.getString("documentary_service_0019"));
        }
        followFollowerProfitEntity.setIsFollow(FollowFollowerProfitEntity.IS_FOLLOW_N);
        followFollowerProfitDao.updateById(followFollowerProfitEntity);
@@ -1079,6 +1275,7 @@
    }
    @Override
    @Transactional
    public Result getFollowFollowerNoticeList(FollowFollowerNoticeDto followFollowerNoticeDto) {
        //获取用户ID
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
@@ -1100,6 +1297,12 @@
                followFollowerNoticeVo.setCreateTime(createTime);
                arrayList.add(followFollowerNoticeVo);
            }
        }
        MemberSettingEntity memberSettingEntity = memberSettingDao.selectMemberSettingByMemberId(memberId);
        if(ObjectUtil.isNotEmpty(memberSettingEntity)) {
            log.info(memberId + "的消息提醒状态变更");
            memberSettingEntity.setMessageReminder(0);
            memberSettingDao.updateById(memberSettingEntity);
        }
        
        return Result.ok(arrayList);
@@ -1126,6 +1329,71 @@
        return Result.ok(arrayList);
    }
    
    @Override
    public Result beTraderCondition() {
        String type = "apply_trader_rule";
        List<BeTraderConditionVo> beTraderConditionVos = followTraderInfoDao.selectBeTraderCondition(type);
        return Result.ok(beTraderConditionVos);
    }
    @Override
    public Result getDocumentaryOrderSetState(String tradeId) {
        //获取用户ID
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        long parseLong = Long.parseLong(tradeId);
        //交易员判断
        Map<String, Object> columnMapTrader = new HashMap<>();
        columnMapTrader.put("member_id", memberId);
        List<FollowTraderInfoEntity> followTraderInfoEntitys = followTraderInfoDao.selectByMap(columnMapTrader);
        //只能跟随一个人
        Map<String, Object> columnMaps = new HashMap<>();
        columnMaps.put("member_id", memberId);
        List<FollowFollowerSettingEntity> followFollowerSettingEntityAllows = followFollowerSettingDao.selectByMap(columnMaps);
        //没有交易员审核记录
        if(CollUtil.isEmpty(followTraderInfoEntitys)) {
            //没有跟随记录
            if(CollUtil.isEmpty(followFollowerSettingEntityAllows)) {
                return Result.ok("获取成功");
            }else {
                //有跟随记录
                if(followFollowerSettingEntityAllows.size() == 1) {
                    Long tradeIdAllow = followFollowerSettingEntityAllows.get(0).getTraderId();
                    if(parseLong == tradeIdAllow) {
                        return Result.ok("获取成功");
                    }else{
                        return Result.fail("最多跟单一人");
                    }
                }else{
                    return Result.fail("已经跟随多人,请修改");
                }
            }
        }else{
            Integer verifyStatus = followTraderInfoEntitys.get(0).getVerifyStatus();
            if(FollowTraderInfoEntity.VERIFYSTATUS_N == verifyStatus) {
                if(CollUtil.isEmpty(followFollowerSettingEntityAllows)) {
                    return Result.ok("获取成功");
                }else {
                    if(followFollowerSettingEntityAllows.size() == 1) {
                        Long tradeIdAllow = followFollowerSettingEntityAllows.get(0).getTraderId();
                        if(parseLong == tradeIdAllow) {
                            return Result.ok("获取成功");
                        }else{
                            return Result.fail("最多跟单一人");
                        }
                    }else{
                        return Result.fail("已经跟随多人,请修改");
                    }
                }
            }else if(FollowTraderInfoEntity.VERIFYSTATUS_Y == verifyStatus){
                return Result.fail("交易员不允许跟单");
            }else {
                return Result.fail("交易员审核中不允许跟单");
            }
        }
    }
    
    
    
src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java
@@ -1,8 +1,11 @@
package com.xcong.excoin.modules.documentary.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
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.RabbitPriceTypeEnum;
import com.xcong.excoin.common.response.Result;
@@ -31,13 +34,16 @@
import com.xcong.excoin.modules.member.entity.*;
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.CacheSettingUtils;
import com.xcong.excoin.utils.CalculateUtil;
import com.xcong.excoin.utils.LogRecordUtils;
import com.xcong.excoin.utils.ThreadPoolUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -80,14 +86,30 @@
    @Resource
    private MemberSettingDao memberSettingDao;
    @Autowired
    private FollowProducer followProducer;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFollowerOrder(Long id) {
        log.info("进入跟单处理逻辑");
        log.info("进入跟单处理逻辑 : {}", id);
        // 查询交易员订单
        ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectById(id);
        if (holdOrderEntity == null) {
            try {
                log.info("等待事务提交:{}", id);
                Thread.sleep(200);
                followProducer.sendAddFollowOrder(id);
                return;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        List<FollowFollowerSettingEntity> followerSettings = followFollowerSettingDao.selectAllFollowerSettingByTradeMemberId(holdOrderEntity.getMemberId());
        log.info("进入跟单处理逻辑---跟单人数"+followerSettings.size());
        // 开仓价
        BigDecimal openPrice = holdOrderEntity.getOpeningPrice();
        PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
@@ -100,6 +122,14 @@
        Long tradeMemberId = holdOrderEntity.getMemberId();
        if (CollUtil.isNotEmpty(followerSettings)) {
            for (FollowFollowerSettingEntity followerSetting : followerSettings) {
                //更新更新消息提醒的状态
                MemberSettingEntity memberSettingEntity = memberSettingDao.selectMemberSettingByMemberId(followerSetting.getId());
                if(ObjectUtil.isNotEmpty(memberSettingEntity)){
                    Long memberId = memberSettingEntity.getMemberId();
                    log.info("更新更新消息提醒的状态");
                    memberSettingDao.updateMessageReminderByMemberId(memberId);
                }
                if (!followerSetting.getSymbols().contains(holdOrderEntity.getSymbol().replace("/USDT", ""))) {
                    log.info("不在跟单币种内,不跟单:{},{}", followerSetting.getSymbols(), holdOrderEntity.getSymbol());
@@ -211,10 +241,6 @@
                        LogRecordUtils.insertMemberAccountFlow(memberEntity.getId(), prePaymentAmount, walletContract.getAvailableBalance().subtract(prePaymentAmount), holdOrderEntity.getSymbol(), "买跌持仓", "买跌:" + holdOrderEntity.getSymbol());
                        LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.OPEN_ORDER_TITLE, StrUtil.format(NoticeConstant.OPEN_ORDER_CONTENT, holdOrderEntity.getSymbol() + "开空", openPrice, followTraderInfoEntity.getNickname()));
                    }
                    //更新更新消息提醒的状态
                    MemberSettingEntity memberSettingEntity = memberSettingDao.selectById(memberEntity.getId());
                    memberSettingEntity.setMessageReminder(1);
                    memberSettingDao.updateById(memberSettingEntity);
                }
            }
        }
src/main/java/com/xcong/excoin/modules/documentary/vo/BeTraderConditionVo.java
New file
@@ -0,0 +1,32 @@
package com.xcong.excoin.modules.documentary.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "BeTraderConditionVo", description = "参数返回类")
public class BeTraderConditionVo {
    /**
     * 名称
     */
    @ApiModelProperty("名称")
    private String name;
    /**
     * 所属分类(对应英文简写)
     */
    @ApiModelProperty("所属分类(对应英文简写)")
    private String type;
    /**
     * 内容
     */
    @ApiModelProperty("内容")
    private String content;
    /**
     * 状态0禁用 1 启用
     */
    @ApiModelProperty("状态0禁用 1 启用")
    private int state;
}
src/main/java/com/xcong/excoin/modules/documentary/vo/DocumentaryOrderSetInfoVo.java
@@ -32,9 +32,9 @@
    private Integer followCnt;
    
    @ApiModelProperty(value = "跟单最大持仓张数数量", example = "2")
    private int maxFollowCnt;
    private String maxFollowCnt;
    public BigDecimal getProfit() {
        return profit.multiply(BigDecimal.valueOf(10));
        return profit.multiply(BigDecimal.valueOf(1));
    }
}
src/main/java/com/xcong/excoin/modules/documentary/vo/DocumentaryOrderSetStateVo.java
New file
@@ -0,0 +1,14 @@
package com.xcong.excoin.modules.documentary.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "DocumentaryOrderSetStateVo", description = "参数返回类")
public class DocumentaryOrderSetStateVo {
    @ApiModelProperty("是否允许跟单的状态")
    private Boolean state;
}
src/main/java/com/xcong/excoin/modules/documentary/vo/FollowInfoVo.java
@@ -35,5 +35,11 @@
     */
    @ApiModelProperty(value = "累计收益")
    private BigDecimal totalProfit;
    @ApiModelProperty(value = "总金额")
    private BigDecimal totalAmount;
    @ApiModelProperty(value = "未实现盈亏")
    private BigDecimal totalProfitOrLess;
    
}
src/main/java/com/xcong/excoin/modules/documentary/vo/FollowTraderProfitInfoVo.java
@@ -82,12 +82,35 @@
    /**
     * 是否满员 1-是2-否
     */
    @ApiModelProperty("是否满员 1-是2-否")
    @ApiModelProperty("交易员是否设置满员 1-是2-否")
    private Integer isAll;
    /**
     * 是否满员 1-是2-否
     */
    @ApiModelProperty("实际是否满员 1-是2-否")
    private Integer isActualAll;
    /**
     * 跟单状态 1:已跟单2:未跟单
     */
    @ApiModelProperty("跟单状态 1:已跟单2:未跟单")
    private Integer documentaryType;
    /**
     * 最大跟单人数
     */
    @ApiModelProperty("最大跟单人数")
    private Integer followNum;
    /**
     * 当前跟单人数
     */
    @ApiModelProperty("当前跟单人数")
    private Integer followNumNow;
    /**
     * 入驻天数(从审核通过开始计算)
     */
    @ApiModelProperty("入驻天数")
    private Integer entryDays;
}
src/main/java/com/xcong/excoin/modules/documentary/vo/HistoryOrderRecordsVo.java
@@ -38,6 +38,9 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @ApiModelProperty("平仓时间")
    private Date closingTime;
    @ApiModelProperty("平仓时间时间戳")
    private long closingTimeStamp;
    
    @ApiModelProperty("订单编号")
    private String orderNo;
src/main/java/com/xcong/excoin/modules/documentary/vo/TradeProfitInfoVo.java
@@ -55,5 +55,22 @@
     */
    @ApiModelProperty("宣言")
    private String declaration;
    /**
     * 最大跟单人数
     */
    @ApiModelProperty("最大跟单人数")
    private Integer followNum;
    /**
     * 当前跟单人数
     */
    @ApiModelProperty("当前跟单人数")
    private Integer followNumNow;
    /**
     * 入驻天数(从审核通过开始计算)
     */
    @ApiModelProperty("入驻天数")
    private Integer entryDays;
}
src/main/java/com/xcong/excoin/modules/documentary/vo/TradeSetInfoVo.java
@@ -18,6 +18,9 @@
    
    @ApiModelProperty("名称")
    private String nickname;
    @ApiModelProperty("名称状态:0:未修改 1:已修改")
    private int nicknameState;
    
    @ApiModelProperty("是否开启带单 1是2否")
    private int isOpen;
src/main/java/com/xcong/excoin/modules/member/dao/MemberSettingDao.java
@@ -16,4 +16,6 @@
    public int batchInsert(@Param("list") List<MemberSettingEntity> list);
    public void updateMessageReminderByMemberId(@Param("memberId")Long memberId);
}
src/main/java/com/xcong/excoin/modules/member/parameter/dto/MemberAddCoinAddressDto.java
@@ -10,9 +10,16 @@
@ApiModel(value = "MemberAddCoinAddressDto", description = "增加提币地址参数接收类")
public class MemberAddCoinAddressDto {
    
    @NotNull(message = "币种ID不能为空")
    @ApiModelProperty(value = "币种ID")
    private Long symbolscoinId;
    //@NotNull(message = "币种ID不能为空")
    //@ApiModelProperty(value = "币种ID")
    //private Long symbolscoinId;
    /**
     * 地址
     */
    @NotNull(message = "币种不能为空")
    @ApiModelProperty(value = "币种")
    private String symbol;
    /**
     * 地址
     */
src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java
@@ -677,10 +677,10 @@
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        String address = memberAddCoinAddressDto.getAddress();
        String isBiyict = memberAddCoinAddressDto.getIsBiyict();
        Long symbolscoinId = memberAddCoinAddressDto.getSymbolscoinId();
        String symbol = memberAddCoinAddressDto.getSymbol();
        String remark = memberAddCoinAddressDto.getRemark();
        PlatformSymbolsCoinEntity platformSymbolsCoinEntity = platformSymbolsCoinDao.selectById(symbolscoinId);
        PlatformSymbolsCoinEntity platformSymbolsCoinEntity = platformSymbolsCoinDao.selectOneBySymbol(symbol);
        Long symbolscoinId = platformSymbolsCoinEntity.getId();
        MemberCoinAddressEntity memberCoinAddressEntity = new MemberCoinAddressEntity();
        memberCoinAddressEntity.setAddress(address);
@@ -1151,12 +1151,15 @@
    }
    @Override
    @Transactional
    public Result memberMessageReminder() {
        //获取用户ID
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        MemberSettingEntity selectById = memberSettingDao.selectById(memberId);
        MemberMessageReminderVo memberMessageReminderVo = new MemberMessageReminderVo();
        MemberSettingEntity selectById = memberSettingDao.selectMemberSettingByMemberId(memberId);
        if(ObjectUtil.isNotEmpty(selectById)) {
        memberMessageReminderVo.setMessageReminder(selectById.getMessageReminder());
        }
        return Result.ok(memberMessageReminderVo);
    }
src/main/java/com/xcong/excoin/modules/platform/dao/PlatformSymbolsCoinDao.java
@@ -5,9 +5,11 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xcong.excoin.modules.member.parameter.vo.MemberCoinAddressCountVo;
import com.xcong.excoin.modules.platform.entity.PlatformSymbolsCoinEntity;
import org.apache.ibatis.annotations.Param;
public interface PlatformSymbolsCoinDao extends BaseMapper<PlatformSymbolsCoinEntity> {
    
    List<MemberCoinAddressCountVo> selectCoinAddressCount(Long memberId);
    
    PlatformSymbolsCoinEntity selectOneBySymbol(@Param("symbol")String symbol);
}
src/main/java/com/xcong/excoin/modules/platform/dao/SysExceptionDetailDao.java
New file
@@ -0,0 +1,11 @@
package com.xcong.excoin.modules.platform.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xcong.excoin.common.system.bean.SysExceptionDetailEntity;
/**
 * @author wzy
 * @date 2021-03-05
 **/
public interface SysExceptionDetailDao extends BaseMapper<SysExceptionDetailEntity> {
}
src/main/java/com/xcong/excoin/quartz/job/FollowProfitUpdateJob.java
@@ -41,7 +41,8 @@
    @Resource
    private FollowTraderProfitInfoDao followTraderProfitInfoDao;
    @Scheduled(cron = "0 0/30 * * * ? ")
    //@Scheduled(cron = "0 0/30 * * * ? ")
    @Scheduled(cron = "0 0/5 * * * ?")
    public void traderProfitUpdate() {
        log.info("交易员定时任务执行");
        // 查询所有交易员信息
src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java
@@ -1,5 +1,6 @@
package com.xcong.excoin.quartz.job;
import com.alibaba.fastjson.JSONObject;
import com.huobi.client.SubscriptionClient;
import com.huobi.client.SubscriptionOptions;
import com.huobi.client.model.Candlestick;
src/main/java/com/xcong/excoin/rabbit/consumer/FollowConsumer.java
New file
@@ -0,0 +1,31 @@
package com.xcong.excoin.rabbit.consumer;
import com.rabbitmq.client.Channel;
import com.xcong.excoin.configurations.RabbitMqConfig;
import com.xcong.excoin.modules.documentary.service.FollowOrderOperationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
/**
 * @author wzy
 * @date 2021-03-04
 **/
@Slf4j
@Component
@ConditionalOnProperty(prefix = "app", name = "rabbit-consumer", havingValue = "true")
public class FollowConsumer {
    @Autowired
    private FollowOrderOperationService followOrderOperationService;
    @RabbitListener(queues = RabbitMqConfig.QUEUE_FOLLOW_ORDER)
    public void addFollowOrder(Message message, Channel channel) {
        String content = new String(message.getBody());
        log.info("==收到跟单下单消息 : {}", content);
        followOrderOperationService.addFollowerOrder(Long.parseLong(content));
    }
}
src/main/java/com/xcong/excoin/rabbit/producer/FollowProducer.java
New file
@@ -0,0 +1,44 @@
package com.xcong.excoin.rabbit.producer;
import com.xcong.excoin.configurations.RabbitMqConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
 * @author wzy
 * @date 2021-03-04
 **/
@Slf4j
@Component
public class FollowProducer implements RabbitTemplate.ConfirmCallback {
    private RabbitTemplate rabbitTemplate;
    @Autowired
    public FollowProducer(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
        rabbitTemplate.setConfirmCallback(this);
    }
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
    }
    /**
     * 发送跟单下单消息
     *
     * @param id
     */
    public void sendAddFollowOrder(Long id) {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        log.info("发送跟单下单消息: {}, {}", id, correlationData.getId());
        rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_FOLLOW_ORDER, id.toString(), correlationData);
    }
}
src/main/resources/application-app.yml
@@ -7,9 +7,9 @@
  profiles:
    active: app
  datasource:
    url: jdbc:mysql://120.27.238.55:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: ct_test
    password: 123456
    url: jdbc:mysql://192.168.0.151:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: db_hibit
    password: hibit123!@#
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
@@ -48,13 +48,13 @@
  ## redis配置
  redis:
    ## Redis数据库索引(默认为0)
    database: 1
    database: 0
    ## Redis服务器地址
    host: 114.55.92.106
    host: 192.168.0.36
    ## Redis服务器连接端口
    port: 6379
    ## Redis服务器连接密码(默认为空)
    password: hibit123
    password: d32ncxe@i3#!dV
    jedis:
      pool:
        ## 连接池最大连接数(使用负值表示没有限制)
@@ -72,10 +72,10 @@
    ## 连接超时时间(毫秒)
    timeout: 30000
  rabbitmq:
    host: 120.55.86.146
    host: 192.168.0.36
    port: 5672
    username: biyict
    password: biyict123
    username: hibit
    password: hibit123
    publisher-confirm-type: correlated
src/main/resources/application-dayline.yml
@@ -7,9 +7,9 @@
  profiles:
    active: dayline
  datasource:
    url: jdbc:mysql://120.27.238.55:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: ct_test
    password: 123456
    url: jdbc:mysql://192.168.0.151:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: db_hibit
    password: hibit123!@#
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
@@ -48,13 +48,13 @@
  ## redis配置
  redis:
    ## Redis数据库索引(默认为0)
    database: 1
    database: 0
    ## Redis服务器地址
    host: 114.55.92.106
    host: 192.168.0.36
    ## Redis服务器连接端口
    port: 6379
    ## Redis服务器连接密码(默认为空)
    password: hibit123
    password: d32ncxe@i3#!dV
    jedis:
      pool:
        ## 连接池最大连接数(使用负值表示没有限制)
@@ -72,10 +72,10 @@
    ## 连接超时时间(毫秒)
    timeout: 30000
  rabbitmq:
    host: 120.55.86.146
    host: 192.168.0.36
    port: 5672
    username: biyict
    password: biyict123
    username: hibit
    password: hibit123
    publisher-confirm-type: correlated
src/main/resources/application-loop.yml
@@ -7,9 +7,9 @@
  profiles:
    active: loop
  datasource:
    url: jdbc:mysql://120.27.238.55:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: ct_test
    password: 123456
    url: jdbc:mysql://192.168.0.151:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: db_hibit
    password: hibit123!@#
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
@@ -48,13 +48,13 @@
  ## redis配置
  redis:
    ## Redis数据库索引(默认为0)
    database: 1
    database: 0
    ## Redis服务器地址
    host: 114.55.92.106
    host: 192.168.0.36
    ## Redis服务器连接端口
    port: 6379
    ## Redis服务器连接密码(默认为空)
    password: hibit123
    password: d32ncxe@i3#!dV
    jedis:
      pool:
        ## 连接池最大连接数(使用负值表示没有限制)
@@ -72,10 +72,10 @@
    ## 连接超时时间(毫秒)
    timeout: 30000
  rabbitmq:
    host: 120.55.86.146
    host: 192.168.0.36
    port: 5672
    username: biyict
    password: biyict123
    username: hibit
    password: hibit123
    publisher-confirm-type: correlated
src/main/resources/application-newprice.yml
@@ -7,9 +7,9 @@
  profiles:
    active: newprice
  datasource:
    url: jdbc:mysql://120.27.238.55:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: ct_test
    password: 123456
    url: jdbc:mysql://192.168.0.151:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: db_hibit
    password: hibit123!@#
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
@@ -48,13 +48,13 @@
  ## redis配置
  redis:
    ## Redis数据库索引(默认为0)
    database: 1
    database: 0
    ## Redis服务器地址
    host: 114.55.92.106
    host: 192.168.0.36
    ## Redis服务器连接端口
    port: 6379
    ## Redis服务器连接密码(默认为空)
    password: hibit123
    password: d32ncxe@i3#!dV
    jedis:
      pool:
        ## 连接池最大连接数(使用负值表示没有限制)
@@ -72,10 +72,10 @@
    ## 连接超时时间(毫秒)
    timeout: 30000
  rabbitmq:
    host: 120.55.86.146
    host: 192.168.0.36
    port: 5672
    username: biyict
    password: biyict123
    username: hibit
    password: hibit123
    publisher-confirm-type: correlated
src/main/resources/application.yml
@@ -5,14 +5,14 @@
spring:
  profiles:
    active: test
    active: dev
  datasource:
#    url: jdbc:mysql://rm-bp151tw8er79ig9kb5o.mysql.rds.aliyuncs.com:3306/db_biue?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
#    username: ctcoin_data
#    password: ctcoin_123
    url: jdbc:mysql://120.27.238.55:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: ct_test
    password: 123456
    url: jdbc:mysql://124.70.222.34:3306/db_hibit?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8
    username: db_hibit
    password: hibit123!@#
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
@@ -51,13 +51,13 @@
  ## redis配置
  redis:
    ## Redis数据库索引(默认为0)
    database: 1
    database: 0
    ## Redis服务器地址
    host: 120.27.238.55
    host: 121.37.162.173
    ## Redis服务器连接端口
    port: 6379
    ## Redis服务器连接密码(默认为空)
    password: xcong123
    password: d32ncxe@i3#!dV
    jedis:
      pool:
        ## 连接池最大连接数(使用负值表示没有限制)
@@ -75,10 +75,10 @@
    ## 连接超时时间(毫秒)
    timeout: 30000
  rabbitmq:
    host: 120.27.238.55
    host: 121.37.162.173
    port: 5672
    username: ct_rabbit
    password: 123456
    username: hibit
    password: hibit123
    publisher-confirm-type: correlated
src/main/resources/i18n/messages_en_US.properties
@@ -140,6 +140,7 @@
member_service_0096=Transfer fail
member_service_0097=Payment method already exists
member_service_0098=Please select another account
member_service_0099=The nickname can only be modified once
order_service_0001=Wrong parameter value
order_service_0002=Not logged in
@@ -230,6 +231,7 @@
documentary_service_0016=The trader has been set not to follow orders
documentary_service_0017=Please change the contract to separate margin mode
documentary_service_0018=In documentary, cannot adjust to full position margin mode
documentary_service_0019=The follower has a documentary contract and cannot kick out
uploadFile_controller_0001=Upload failed
src/main/resources/i18n/messages_zh_CN.properties
@@ -140,6 +140,7 @@
member_service_0096=划转失败
member_service_0097=支付方式已存在
member_service_0098=请选择其他账户
member_service_0099=昵称只允许修改一次
order_service_0001=参值有误
order_service_0002=未登录
@@ -230,6 +231,7 @@
documentary_service_0016=该交易员已设置不能跟单
documentary_service_0017=请将合约修改为分仓保证金模式
documentary_service_0018=正在跟单中,无法调整为全仓保证金模式
documentary_service_0019=跟随者拥有跟单合约,无法踢出
uploadFile_controller_0001=上传失败
src/main/resources/logback-spring.xml
@@ -2,7 +2,7 @@
<configuration>
    <contextName>logback</contextName>
    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
    <property name="log.path" value="biue/logs" />
    <property name="log.path" value="hibit/logs" />
<!--    <springProperty scope="context" name="log.path" source="logging.file.path"/>-->
    <!-- 彩色日志 -->
src/main/resources/mapper/documentary/FollowFollowerProfitDao.xml
@@ -82,7 +82,6 @@
        WHERE 
            member_id = #{memberId} 
            and contract_type = 2
        order by opening_time desc
    </select>
    
    <select id="selectDocumentaryOrderSetInfoBymemberIdAndTradeId" resultType="com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity">
src/main/resources/mapper/documentary/FollowFollowerSettingDao.xml
@@ -25,5 +25,13 @@
        from follow_follower_setting a, follow_follower_profit b
        where a.member_id=b.member_id and a.trader_member_id=b.trade_member_id and a.trader_member_id=#{memberId} and b.is_follow=1
    </select>
    <select id="selectDocumentaryOrderSetInfosBymemberId" resultType="com.xcong.excoin.modules.documentary.entity.FollowFollowerSettingEntity">
        SELECT
            *
        FROM
            follow_follower_setting
        WHERE
            member_id = #{memberId}
    </select>
</mapper>
src/main/resources/mapper/documentary/FollowTraderInfoDao.xml
@@ -23,4 +23,10 @@
        from follow_trader_info
        where verify_status=1
    </select>
    <select id="selectBeTraderCondition" resultType="com.xcong.excoin.modules.documentary.vo.BeTraderConditionVo">
        select *
        from common_configuration
        where state=1 and type = #{type}
    </select>
</mapper>
src/main/resources/mapper/documentary/FollowTraderProfitInfoDao.xml
@@ -3,9 +3,38 @@
<mapper namespace="com.xcong.excoin.modules.documentary.dao.FollowTraderProfitInfoDao">
    
    <select id="selectFollowTraderProfitInfoEntity" resultType="com.xcong.excoin.modules.documentary.vo.FollowTraderProfitInfoVo">
        select * from follow_trader_profit_info f left join member m on f.member_id = m.id
        where m.is_trader = 1
        order by f.id desc
        select * from follow_trader_profit_info f
            left join member m on f.member_id = m.id
            left join follow_trader_info t on t.member_id = f.member_id
        <where>
            m.is_trader = 1
            <if test="record.type != null and record.type != '' ">
                and t.is_set_frist = #{record.type}
            </if>
            <if test="record.nickname != null and record.nickname != '' ">
                and t.nickname like concat('%',#{record.nickname},'%')
            </if>
        </where>
        order by
        <if test="record.totalProfitRatioSc != null and record.totalProfitRatioSc != '' and record.totalProfitRatioSc == 1" >
            f.total_profit_ratio,
        </if>
        <if test="record.totalProfitRatioSc != null and record.totalProfitRatioSc != '' and record.totalProfitRatioSc == 2" >
            f.total_profit_ratio desc,
        </if>
        <if test="record.winRateSc != null and record.winRateSc != '' and record.winRateSc == 1" >
            f.win_rate,
        </if>
        <if test="record.winRateSc != null and record.winRateSc != '' and record.winRateSc == 2" >
            f.win_rate desc,
        </if>
        <if test="record.totalFollowerCntSc != null and record.totalFollowerCntSc != '' and record.totalFollowerCntSc == 1" >
            f.total_follower_cnt,
        </if>
        <if test="record.totalFollowerCntSc != null and record.totalFollowerCntSc != '' and record.totalFollowerCntSc == 2" >
            f.total_follower_cnt desc,
        </if>
        f.id desc
    </select>
    
    <select id="selectOneByMemberId" resultType="com.xcong.excoin.modules.documentary.vo.FollowTraderProfitInfoVo">
src/main/resources/mapper/member/MemberSettingDao.xml
@@ -35,4 +35,11 @@
        </foreach>
    </insert>
    <update id="updateMessageReminderByMemberId">
        UPDATE member_setting s
        SET s.message_reminder = 1
        WHERE
            member_id = #{memberId}
    </update>
</mapper>
src/main/resources/mapper/platform/PlatformSymbolsCoinDao.xml
@@ -15,5 +15,13 @@
            a.id,
            a. NAME
    </select>
    <select id="selectOneBySymbol" resultType="com.xcong.excoin.modules.platform.entity.PlatformSymbolsCoinEntity">
        SELECT
            *
        FROM
            platform_symbols_coin a
            where a.name = #{symbol}
    </select>
    
</mapper>
src/main/resources/mapper/platform/SysExceptionDetailDao.xml
New file
@@ -0,0 +1,5 @@
<?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.platform.dao.SysExceptionDetailDao">
</mapper>