package com.bizzan.bitrade.service;

import com.bizzan.bitrade.constant.PageModel;
import com.bizzan.bitrade.constant.TransactionType;
import com.bizzan.bitrade.dao.MemberTransactionDao;
import com.bizzan.bitrade.entity.MemberTransaction;
import com.bizzan.bitrade.entity.MemberWallet;
import com.bizzan.bitrade.entity.QMember;
import com.bizzan.bitrade.entity.QMemberTransaction;
import com.bizzan.bitrade.pagination.Criteria;
import com.bizzan.bitrade.pagination.PageResult;
import com.bizzan.bitrade.pagination.Restrictions;
import com.bizzan.bitrade.service.Base.BaseService;
import com.bizzan.bitrade.util.DateUtil;
import com.bizzan.bitrade.vo.MemberTransactionControlVo;
import com.bizzan.bitrade.vo.MemberTransactionStat;
import com.bizzan.bitrade.vo.MemberTransactionVO;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class MemberTransactionService extends BaseService {
    @Autowired
    private MemberTransactionDao transactionDao;
    @Autowired
    private MemberWalletService walletService;

    /**
     * 条件查询对象 pageNo pageSize 同时传时分页
     *
     * @param booleanExpressionList
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Transactional(readOnly = true)
    public PageResult<MemberTransaction> queryWhereOrPage(List<BooleanExpression> booleanExpressionList, Integer pageNo, Integer pageSize) {
        List<MemberTransaction> list;
        JPAQuery<MemberTransaction> jpaQuery = queryFactory.selectFrom(QMemberTransaction.memberTransaction);
        if (booleanExpressionList != null) {
            jpaQuery.where(booleanExpressionList.toArray(new BooleanExpression[booleanExpressionList.size()]));
        }
        if (pageNo != null && pageSize != null) {
            list = jpaQuery.offset((pageNo - 1) * pageSize).limit(pageSize).fetch();
        } else {
            list = jpaQuery.fetch();
        }
        return new PageResult<>(list, jpaQuery.fetchCount());
    }

    /**
     * 保存交易记录
     *
     * @param transaction
     * @return
     */
    public MemberTransaction save(MemberTransaction transaction) {
    	//不保存机器人交易记录
    	if(transaction.getMemberId()==1)
    		return null;
        return transactionDao.saveAndFlush(transaction);
    }

    @Override
    public List<MemberTransaction> findAll() {
        return transactionDao.findAll();
    }


    public MemberTransaction findOne(Long id) {
        return transactionDao.findOne(id);
    }


    public List findAllByWhere(Date startTime, Date endTime, TransactionType type, Long memberId) {
        QMemberTransaction qMemberTransaction = QMemberTransaction.memberTransaction;
        List<BooleanExpression> booleanExpressionList = new ArrayList();
        if (startTime != null) {
            booleanExpressionList.add(qMemberTransaction.createTime.gt(startTime));
        }
        if (endTime != null) {
            booleanExpressionList.add(qMemberTransaction.createTime.lt(endTime));
        }
        if (type != null) {
            booleanExpressionList.add(qMemberTransaction.type.eq(type));
        }
        if (memberId != null) {
            booleanExpressionList.add(qMemberTransaction.memberId.eq(memberId));
        }
        return queryFactory.selectFrom(qMemberTransaction).
                where(booleanExpressionList.toArray(booleanExpressionList.toArray(new BooleanExpression[booleanExpressionList.size()])))
                .fetch();
    }
    
    public MemberTransaction getLastByMemberIdAndType(Long uid, TransactionType type){
    	return transactionDao.getLastByMemberIdAndType(uid, type.getOrdinal());
    }
    
    public MemberTransaction getFirstByMemberIdAndType(Long uid, TransactionType type){
    	return transactionDao.getFirstByMemberIdAndType(uid, type.getOrdinal());
    }
    
    /**
     * 根据用户ID，Type获取所有记录
     * @param uid
     * @param type
     * @return
     */
    public List<MemberTransaction> queryByMember(Long uid, TransactionType type){
    	Criteria<MemberTransaction> specification = new Criteria<MemberTransaction>();
        specification.add(Restrictions.eq("memberId", uid, false));
        specification.add(Restrictions.eq("type", type, false));
        return transactionDao.findAll(specification);
    }
    public List<MemberTransaction> queryExchangeFee() throws ParseException{
    	Criteria<MemberTransaction> specification = new Criteria<MemberTransaction>();
        specification.add(Restrictions.eq("type", TransactionType.SPOT_FEE, false));
        specification.add(Restrictions.gte("createTime", DateUtil.YYYY_MM_DD.parse(DateUtil.getDate()), false));
        specification.add(Restrictions.eq("flag", 0, false));
        return transactionDao.findAll(specification);
    }
    public void updateRewardFlag(Long id) {
    	transactionDao.updateRewardFlag(id);
    }
    public Page<MemberTransaction> queryByMember(Long uid, Integer pageNo, Integer pageSize, TransactionType type) {
        //排序方式 (需要倒序 这样    Criteria.sort("id","createTime.desc") ) //参数实体类为字段名
        Sort orders = Criteria.sortStatic("createTime.desc");
        //分页参数
        PageRequest pageRequest = new PageRequest(pageNo, pageSize, orders);
        //查询条件
        Criteria<MemberTransaction> specification = new Criteria<MemberTransaction>();
        specification.add(Restrictions.eq("memberId", uid, false));
        specification.add(Restrictions.eq("type", type, false));
        return transactionDao.findAll(specification, pageRequest);
    }
    public Page<MemberTransaction> queryByMemberAndTypes(Long uid, Integer pageNo, Integer pageSize, List<TransactionType> types) {
        //排序方式 (需要倒序 这样    Criteria.sort("id","createTime.desc") ) //参数实体类为字段名
        Sort orders = Criteria.sortStatic("createTime.desc");
        //分页参数
        PageRequest pageRequest = new PageRequest(pageNo, pageSize, orders);
        //查询条件
        Criteria<MemberTransaction> specification = new Criteria<MemberTransaction>();
        specification.add(Restrictions.eq("memberId", uid, false));
        specification.add(Restrictions.in("type",types,false));
        return transactionDao.findAll(specification, pageRequest);
    }

    public Page<MemberTransaction> queryByMember(Long uid, Integer pageNo, Integer pageSize,TransactionType type,String startDate,String endDate,String symbol) throws ParseException {
        return queryByMember(uid, pageNo, pageSize, type, startDate, endDate, symbol, null);
    }

    /**
     * 查询资金流水，支持排除指定类型
     *
     * @param uid          用户ID
     * @param pageNo       页码（从1开始）
     * @param pageSize     每页条数
     * @param type         流水类型，为空则不过滤单类型
     * @param startDate    开始日期 yyyy-MM-dd
     * @param endDate      结束日期 yyyy-MM-dd
     * @param symbol       币种代码
     * @param excludeTypes 需要排除的类型列表，为空则不排除
     * @return 分页结果
     * @author auto
     * @date 2026-05-12
     */
    public Page<MemberTransaction> queryByMember(Long uid, Integer pageNo, Integer pageSize,
            TransactionType type, String startDate, String endDate, String symbol,
            List<TransactionType> excludeTypes) throws ParseException {
        Sort orders = Criteria.sortStatic("createTime.desc");
        PageRequest pageRequest = new PageRequest(pageNo - 1, pageSize, orders);
        Criteria<MemberTransaction> specification = new Criteria<MemberTransaction>();
        specification.add(Restrictions.eq("memberId", uid, false));
        if (type != null) {
            final int ordinal = type.getOrdinal();
            specification.add((root, query, builder) ->
                builder.equal(root.get("type").as(Integer.class), ordinal));
        }
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            specification.add(Restrictions.gte("createTime", DateUtil.YYYY_MM_DD_MM_HH_SS.parse(startDate + " 00:00:00"), false));
            specification.add(Restrictions.lte("createTime", DateUtil.YYYY_MM_DD_MM_HH_SS.parse(endDate + " 23:59:59"), false));
        }
        if (StringUtils.isNotEmpty(symbol)) {
            specification.add(Restrictions.eq("symbol", symbol, false));
        }
        if (excludeTypes != null && !excludeTypes.isEmpty()) {
            specification.add((root, query, builder) ->
                builder.not(root.get("type").as(Integer.class).in(
                    excludeTypes.stream().map(TransactionType::getOrdinal).collect(java.util.stream.Collectors.toList()))));
        }
        return transactionDao.findAll(specification, pageRequest);
    }

    public BigDecimal findMatchTransactionSum(Long uid,String symbol){
        List<TransactionType> types = new ArrayList<>();
        types.add(TransactionType.RECHARGE);
        types.add(TransactionType.EXCHANGE);
        types.add(TransactionType.ADMIN_RECHARGE);
        Map<String,Object> result = transactionDao.findMatchTransactionSum(uid,symbol,types);
        return new BigDecimal(result.get("amount").toString());
    }

    public List<MemberTransaction> findMatchTransaction(Long uid,String symbol){
        Sort orders = Criteria.sortStatic("createTime.asc");
        //查询条件
        Criteria<MemberTransaction> specification = new Criteria<MemberTransaction>();
        specification.add(Restrictions.eq("memberId", uid, false));
        specification.add(Restrictions.eq("flag",0,false));
        specification.add(Restrictions.eq("symbol",symbol,false));
        specification.add(Restrictions.gt("amount",0,false));
        List<TransactionType> types = new ArrayList<>();
        types.add(TransactionType.RECHARGE);
        types.add(TransactionType.EXCHANGE);
        types.add(TransactionType.ADMIN_RECHARGE);
        specification.add(Restrictions.in("type",types,false));
        List<MemberTransaction> transactions = transactionDao.findAll(specification,orders);
        return transactions;
    }

    @Transactional
    public void matchWallet(Long uid,String symbol,BigDecimal amount){
        List<MemberTransaction> transactions = findMatchTransaction(uid,symbol);
        BigDecimal deltaAmount = BigDecimal.ZERO;
        MemberWallet gccWallet = walletService.findByCoinUnitAndMemberId("GCC",uid);
        MemberWallet gcxWallet = walletService.findByCoinUnitAndMemberId("GCX",uid);

        for(MemberTransaction transaction:transactions){
            if(amount.compareTo(deltaAmount) > 0) {
                BigDecimal  amt = amount.subtract(deltaAmount).compareTo(transaction.getAmount()) > 0 ? transaction.getAmount() : amount.subtract(deltaAmount);
                deltaAmount = deltaAmount.add(amt);
                transaction.setFlag(1);
            }
            else {
                break;
            }
        }

        gccWallet.setBalance(gccWallet.getBalance().subtract(deltaAmount));
        gcxWallet.setBalance(gcxWallet.getBalance().add(deltaAmount));

        MemberTransaction transaction = new MemberTransaction();
        transaction.setAmount(deltaAmount);
        transaction.setSymbol(gcxWallet.getCoin().getUnit());
        transaction.setAddress(gcxWallet.getAddress());
        transaction.setMemberId(gcxWallet.getMemberId());
        transaction.setType(TransactionType.MATCH);
        transaction.setFee(BigDecimal.ZERO);
        //保存配对记录
        save(transaction);
        if(gccWallet.getBalance().compareTo(BigDecimal.ZERO) < 0){
            gccWallet.setBalance(BigDecimal.ZERO);
        }
    }

    public boolean isOverMatchLimit(String day,double limit) throws Exception {
        BigDecimal totalAmount;
        Date date1 = DateUtil.YYYY_MM_DD_MM_HH_SS.parse(day+" 00:00:00");
        Date date2 = DateUtil.YYYY_MM_DD_MM_HH_SS.parse(day+" 23:59:59");
        Map<String,Object> result = transactionDao.findMatchTransactionSum("GCX",TransactionType.MATCH,date1,date2);
        if(result !=null && result.containsKey("amount")) {
            totalAmount = new BigDecimal(result.get("amount").toString());
        }
        else{
            totalAmount = BigDecimal.ZERO;
        }
        System.out.println("totalAmount:"+totalAmount);
        return totalAmount.doubleValue() >= limit;
    }

    public BigDecimal findMemberDailyMatch(Long uid,String day) throws Exception {
        Date date1 = DateUtil.YYYY_MM_DD_MM_HH_SS.parse(day+" 00:00:00");
        Date date2 = DateUtil.YYYY_MM_DD_MM_HH_SS.parse(day+" 23:59:59");
        Map<String,Object> result = transactionDao.findMatchTransactionSum(uid,"GCX",TransactionType.MATCH,date1,date2);
        if(result !=null && result.containsKey("amount")) {
            return new BigDecimal(result.get("amount").toString());
        }
        else {
            return BigDecimal.ZERO;
        }
    }

    public Page<MemberTransactionVO> joinFind(List<Predicate> predicates, PageModel pageModel){
        List<OrderSpecifier> orderSpecifiers = pageModel.getOrderSpecifiers() ;
        JPAQuery<MemberTransactionVO> query = queryFactory.select(Projections.fields(MemberTransactionVO.class,
                QMemberTransaction.memberTransaction.address,
                QMemberTransaction.memberTransaction.amount,
                QMemberTransaction.memberTransaction.createTime.as("createTime"),
                QMemberTransaction.memberTransaction.fee,
                QMemberTransaction.memberTransaction.flag,
                QMemberTransaction.memberTransaction.id.as("id"),
                QMemberTransaction.memberTransaction.symbol,
                QMemberTransaction.memberTransaction.type,
                QMember.member.username.as("memberUsername"),
                QMember.member.mobilePhone.as("phone"),
                QMember.member.email,
                QMember.member.realName.as("memberRealName"),
                QMember.member.id.as("memberId")))
                .from(QMemberTransaction.memberTransaction, QMember.member);
        predicates.add(QMemberTransaction.memberTransaction.memberId.eq(QMember.member.id));
                query.where(predicates.toArray(new BooleanExpression[predicates.size()]));
        query.orderBy(orderSpecifiers.toArray(new OrderSpecifier[orderSpecifiers.size()]));
        List<MemberTransactionVO> list = query.offset((pageModel.getPageNo()-1)*pageModel.getPageSize()).limit(pageModel.getPageSize()).fetch();
        long total = query.fetchCount();
        return new PageImpl<>(list, pageModel.getPageable(), total);
    }
    
    public BigDecimal getTotalProfit(List<Long> ids, String startTime, String endTime) {
    	return transactionDao.getTotalProfitByIds(ids, startTime, endTime, 20);
    }
    
    public BigDecimal getTotalLoss(List<Long> ids, String startTime, String endTime) {
    	return transactionDao.getTotalLossByIds(ids, startTime, endTime, 21);
    }
    
    public BigDecimal sumTotal(String startTime, String endTime) {
    	return transactionDao.sumTotal(startTime, endTime);
    }
    
    public BigDecimal sumTotalByType(String startTime, String endTime, TransactionType type) {
    	BigDecimal amount =  transactionDao.sumTotalByType(startTime, endTime, type.getOrdinal());
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberId(Long memberId) {
    	BigDecimal amount = transactionDao.sumAmountByMemberId(memberId);
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumTodayAmountByMemberIdAndType(long memberId, TransactionType type) {
    	String[] dateStr = DateUtil.getTodayRealSartAndEndDateStr();
    	BigDecimal amount = transactionDao.sumAmountByMemberIdAndTypeAndTime(dateStr[0], dateStr[1], memberId, type.getOrdinal());
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberIdAndType(long memberId, TransactionType type) {
    	BigDecimal amount = transactionDao.sumAmountByMemberIdAndType(memberId, type.getOrdinal());
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberIdAndTypes(long memberId, List<Integer> typeList) {
    	BigDecimal amount =  transactionDao.sumAmountByMemberIdAndTypes(memberId, typeList);
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberIdAndTypeAndTime(String startTime, String endTime, long memberId, TransactionType type) {
    	BigDecimal amount =  transactionDao.sumAmountByMemberIdAndTypeAndTime(startTime, endTime, memberId, type.getOrdinal());
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberIdAndTypesAndTime(String startTime, String endTime, long memberId, List<Integer> typeList) {
    	BigDecimal amount =  transactionDao.sumAmountByMemberIdAndTypesAndTime(startTime, endTime, memberId, typeList);
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberIdAndNotTypesAndTime(String startTime, String endTime, long memberId, List<Integer> noTypeList) {
    	BigDecimal amount =  transactionDao.sumAmountByMemberIdAndNotTypesAndTime(startTime, endTime, memberId, noTypeList);
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberIdsAndTypeAndTime(String startTime, String endTime, List<Long> ids, TransactionType type) {
    	BigDecimal amount =  transactionDao.sumAmountByMemberIdsAndTypeAndTime(startTime, endTime, ids, type.getOrdinal());
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumPositiveAmountByMemberIdsAndTypeAndTime(String startTime, String endTime, List<Long> ids, TransactionType type) {
    	BigDecimal amount =  transactionDao.sumPositiveAmountByMemberIdsAndTypeAndTime(startTime, endTime, ids, type.getOrdinal());
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberIdAndTime(String startTime, String endTime, long memberId) {
    	BigDecimal amount =  transactionDao.sumAmountByMemberIdAndTime(startTime, endTime, memberId);
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public BigDecimal sumAmountByMemberIdsAndTime(String startTime, String endTime, List<Long> ids) {
    	BigDecimal amount =  transactionDao.sumAmountByMemberIdsAndTime(startTime, endTime, ids);
    	if(amount == null)
    		return BigDecimal.ZERO;
    	else
    		return amount;
    }
    
    public List<MemberTransactionControlVo> statFarmingControl(String startTime, String endTime) {
    	List<MemberTransactionControlVo> list = new ArrayList<>();
    	Object[][] objArray = transactionDao.statFarmingControl(startTime, endTime);
    	for (Object[] obj : objArray) {
    		MemberTransactionControlVo vo = new MemberTransactionControlVo();
        	if(obj[0]!=null)
        		vo.setMemberId(Long.parseLong(obj[0].toString()));
        	if(obj[1]!=null)
        		vo.setTotalAmount(BigDecimal.valueOf(Double.parseDouble(obj[1].toString())));
        	if(obj[2]!=null)
        		vo.setAwardAmount(BigDecimal.valueOf(Double.parseDouble(obj[2].toString())));
        	list.add(vo);
    	}
    	return list;
    }
    
    public List<MemberTransactionStat> statByType() {
    	return transactionDao.statByType();
    }
    
    public BigDecimal sumRechargeAndWithdrawAmountBySymbol(String startTime, String endTime, TransactionType type, String symbol) {
    	List<String> list = new ArrayList<String>();
    	list.add(symbol);
    	if(symbol.equals("USDT")) {
    		list.add("USDT-TRC20");
    		list.add("USDT-ERC20");
    		list.add("USDT-BEP20");
    	}
    	return transactionDao.sumRechargeAndWithdrawAmountBySymbol(startTime,endTime,type.getOrdinal(),list);
    }
    
    public List<Long> getMemberIdListByTimeAndSign(String startTime, String endTime, int sign) {
    	List<BigInteger> memberIdList = transactionDao.getMemberIdListByTimeAndSign(startTime, endTime, sign);
    	List<Long> memberIdLongList = new ArrayList<>();
    	for(BigInteger memberId : memberIdList) {
    		memberIdLongList.add(memberId.longValue());
    	}
    	return memberIdLongList;
    }
    
    public void recordRecharge(Long memberId, BigDecimal amount, String address) {
    	MemberTransaction transaction = new MemberTransaction();
        transaction.setAmount(amount);
        transaction.setSymbol("USDT");
        transaction.setAddress(address);
        transaction.setMemberId(memberId);
        if(address==null)
        	transaction.setType(TransactionType.ADMIN_RECHARGE);
        else
        	transaction.setType(TransactionType.RECHARGE);
        transaction.setFee(BigDecimal.ZERO);
        transaction.setDiscountFee("0");
        transaction.setRealFee("0");
        transaction.setCreateTime(new Date());
    }
    
    public void recordProfitOrLoss(Long memberId, String symbol, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(amount);
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        if(amount.compareTo(BigDecimal.ZERO)>=0)
        	memberTransaction.setType(TransactionType.CONTRACT_PROFIT);
        else
        	memberTransaction.setType(TransactionType.CONTRACT_LOSS);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    public void recordContractFee(Long memberId, String symbol, BigDecimal amount, int direction) {
        recordContractFee(memberId, symbol, amount, direction, DateUtil.getCurrentDate());
	}

    public void recordContractFee(Long memberId, String symbol, BigDecimal amount, int direction, Date createTime) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.CONTRACT_FEE);
        memberTransaction.setCreateTime(createTime);
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction.setDirection(direction);
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordContractOvernightFee(Long memberId, String symbol, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.CONTRACT_OVERNIGHT_FEE);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordFollowOvernightFee(Long memberId, String symbol, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.FOLLOW_OVERNIGHT_FEE);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordContractBlastFee(Long memberId, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol("USDT");
        memberTransaction.setType(TransactionType.CONTRACT_BLAST_FEE);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordFollowProfitOrLoss(Long memberId, String symbol, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(amount);
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        if(amount.compareTo(BigDecimal.ZERO)>=0)
        	memberTransaction.setType(TransactionType.FOLLOW_PROFIT);
        else
        	memberTransaction.setType(TransactionType.FOLLOW_LOSS);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    public void recordFollowFee(Long memberId, String symbol, BigDecimal amount, int direction) {
		/*MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.FOLLOW_FEE);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction.setDirection(direction);
        memberTransaction = transactionDao.save(memberTransaction);*/
        this.recordFollowFee(memberId, symbol, amount, direction, DateUtil.getCurrentDate());
	}
    public void recordFollowFee(Long memberId, String symbol, BigDecimal amount, int direction, Date createTime) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.FOLLOW_FEE);
        memberTransaction.setCreateTime(createTime);
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction.setDirection(direction);
        memberTransaction = transactionDao.save(memberTransaction);
	}
    public void recordFollowDividend(Long memberId, String symbol, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(amount);
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.FOLLOW_DIVIDEND);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordGameFee(Long memberId, String symbol, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.GAME_FEE);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}

    public void recordGameProfit(Long memberId, String symbol, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(amount);
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.GAME_PROFIT);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordGameLoss(Long memberId, String symbol, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(amount);
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol(symbol);
        memberTransaction.setType(TransactionType.GAME_LOSS);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordSpotProfit(Long memberId, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol("USDT");
        memberTransaction.setType(TransactionType.SPOT_PROFIT);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordSpotLoss(Long memberId, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol("USDT");
        memberTransaction.setType(TransactionType.SPOT_LOSS);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordSpotFee(Long memberId, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(BigDecimal.ZERO.subtract(amount));
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol("USDT");
        memberTransaction.setType(TransactionType.SPOT_FEE);
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    public void recordFee(Long memberId, int type, BigDecimal amount) {
		MemberTransaction memberTransaction = new MemberTransaction();
        memberTransaction.setAmount(amount);
        memberTransaction.setMemberId(memberId);
        memberTransaction.setSymbol("USDT");
        memberTransaction.setType(TransactionType.valueOfOrdinal(type));
        memberTransaction.setCreateTime(DateUtil.getCurrentDate());
        memberTransaction.setFee(BigDecimal.ZERO);
        memberTransaction.setRealFee("0");
        memberTransaction.setDiscountFee("0");
        memberTransaction = transactionDao.save(memberTransaction);
	}
    
    /**
     * 清理机器人交易记录
     * @param beforeTime
     * @return
     */
    public int deleteHistory(Date beforeTime) {
    	return transactionDao.deleteHistory(beforeTime);
    }
}
