package com.friday.custody.service.trustService.ebscn.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.friday.base.common.response.DubboResult;
import com.friday.custody.common.CustodyContants;
import com.friday.custody.dto.TenantEscrowAuthorizationInfoDto;
import com.friday.custody.entity.*;
import com.friday.custody.service.basicService.impl.*;
import com.friday.custody.enums.DataDictionaryTypeEnum;
import com.friday.custody.service.basicService.DataDictionaryTypeCertificateCsdcService;
import com.friday.custody.service.logicService.DataDictionaryBasicService;
import com.friday.custody.service.trustService.OutsourceService;
import com.friday.custody.service.trustService.ebscn.common.EbscnConstants;
import com.friday.custody.service.trustService.ebscn.utils.EbscnGetDataUtil;
import com.friday.custody.service.trustService.ebscn.utils.EbscnRemoteUtil;
import com.friday.custody.service.trustService.ebscn.utils.OpenApiHelper;
import com.friday.custody.utils.BigDecimalUtil;
import com.friday.custody.utils.MatchDataDictionaryKeyUtil;
import com.friday.custody.utils.R;
import com.friday.custody.utils.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.friday.custody.common.CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
import static com.friday.custody.service.trustService.ebscn.common.EbscnConstants.SUCCESS_CODE;

@Service
@Slf4j
public class OutsourceEbscnServiceImpl implements OutsourceService {

    @Autowired
    private OpenApiHelper openApiHelper;

    @Autowired
    private EbscnGetDataUtil ebscnGetDataUtil;

    @Autowired
    private EbscnRemoteUtil ebscnRemoteUtil;

    @Autowired
    private DataDictionaryBasicService dataDictionaryBasicService;

    @Autowired
    private FundInfoServiceImpl fundInfoService;

    @Autowired
    private DataDictionaryTypeCertificateCsdcService certificateCsdcService;

    @Autowired
    private CustShareInfoServiceImpl custShareInfoService;

    @Autowired
    private InvestorInfoServiceImpl investorInfoService;

    @Autowired
    private FundNetValueInfoServiceImpl fundNetValueInfoService;

    @Autowired
    private DataDictionarySellerServiceImpl sellerService;

    @Autowired
    private FundTradeInfoServiceImpl fundTradeInfoService;

    @Autowired
    private InvestorBankInfoServiceImpl investorBankInfoService;

    @Autowired
    private FundProfitInfoServiceImpl fundProfitInfoService;

    @Autowired
    private TgAccountBalanceInfoServiceImpl tgAccountBalanceInfoService;

    @Autowired
    private AccountInfoServiceImpl accountInfoService;

    @Autowired
    private MjAccountBalanceInfoServiceImpl mjAccountBalanceInfoService;

    @Autowired
    private TgAccountSeqInfoServiceImpl tgAccountSeqInfoService;

    @Autowired
    private MjAccountSeqInfoServiceImpl mjAccountSeqInfoService;

    @Override
    public R initTenantData(List<TenantEscrowAuthorizationInfoDto> tenants) {
        return null;
    }

    @Override
    public R initTenantDataSingle(TenantEscrowAuthorizationInfoDto tenant) {
        log.info("光大证券托管数据初始化开始！");
        getDataFromEbscn(tenant, CustodyContants.INIT_BY_MONTH_LOOP_TIME);
        log.info("光大证券托管数据初始化结束！");
        return R.ok("光大证券托管数据初始化成功！");
    }

    private void getDataFromEbscn(TenantEscrowAuthorizationInfoDto tenant, int loopTime) {
        String trustNo = "42";
        //1 基金产品信息表（fund_info）
        processFundInfoData(tenant, trustNo);
        //3.基金净值信息表 fund_net_value_info
        processFundNetValueInfoData(tenant,trustNo,loopTime);
        //8.基金交易确认信息表 (fund_trade_info)
        processFundTradeInfoData(tenant,trustNo);
        //10.业绩报酬信息表 fund_profit_info
        processFundProfitInfoData(tenant,trustNo,loopTime);
        // 15 资金账户基本信息表 account_info，16 托管⼾银⾏账⼾余额信息表 TGAccount_balance_info（历史）
        processTgAccountBalanceInfoData(tenant,trustNo,"0");
        // 15 资金账户基本信息表 account_info，16 托管⼾银⾏账⼾余额信息表 TGAccount_balance_info（当日）
        processTgAccountBalanceInfoData(tenant,trustNo,"1");
        // 15 资金账户基本信息表 account_info，16 托管⼾银⾏账⼾余额信息表 MJAccount_balance_info
        processMjAccountBalanceInfoData(tenant,trustNo,loopTime);
        //17 托管户流水表 TGAccount_seq_info (0 : 历史)
        processTgAccountSeqInfoData(tenant,trustNo,loopTime,"0");
        //17 托管户流水表 TGAccount_seq_info (1 : 当日)
        processTgAccountSeqInfoData(tenant,trustNo,loopTime,"1");
        //19.募集户流水表 MJAccount_seq_info
        processMjAccountSeqInfoData(tenant,trustNo,loopTime);
        //4.基金持有信息表 cust_share_info 2.基金出资人信息表 investor_info
        processCustShareAndInvestorInfoData(tenant,trustNo);

    }

    private void processMjAccountSeqInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopTime) {
        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0; i < loopTime; i++) {
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            int pageIndex = 0;
            try {
                for (; ; ) {
                    pageIndex++;
                    //封装请求参数
                    Map<String, Object> params = new HashMap<>();
                    params.put("service_name", EbscnConstants.MJACCOUNT_SEQ_INFO_API);
                    params.put("version", EbscnConstants.MJACCOUNT_SEQ_INFO_API_VERSION);
                    params.put("limit", "500");
                    params.put("pageIndex", pageIndex);
                    params.put("start_tradetime", finalStartDate);
                    params.put("end_tradetime", finalEndDate);
                    //调用光大接口，获取数据
                    Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                    Integer total = 0;
                    if (!ObjectUtils.isEmpty(result)) {
                        Map data = (Map<String, Object>) result.get("data");
                        total = Integer.valueOf(data.get("total").toString());
                        Object remoteData = data.get("rows");
                        if (!ObjectUtils.isEmpty(remoteData)) {
                            List<JSONObject> remoteDataList = JSONObject.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                            List<MjAccountSeqInfoEntity> mjAccountSeqInfoEntities = getMjAccountSeqInfo(tenant, remoteDataList, trustNo);
                            mjAccountSeqInfoService.saveData(null, mjAccountSeqInfoEntities);
                        }
                    }
                    if (pageIndex * 500 > total) {
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("Ebscn ：processMjAccountSeqInfoData批量保存数据失败！", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }

    private List<MjAccountSeqInfoEntity> getMjAccountSeqInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典
        //收付方向
        Map<String, String> paymentDirectionDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PAYMENT_DIRECTION_SERVICE, trustNo);
        //2.封装数据
        List<MjAccountSeqInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
            List<AccountInfoEntity> accountInfoEntities = accountInfoService.queryList(AccountInfoEntity.builder()
                    .trustNo(trustNo).accoTypeCode("ZJ002").fundCode(remoteDataMap.get("nddisplaycode")).build());
            String account = "";
            String accountName = "";
            String opAccount = "";
            String opAccountName = "";
            String transferInOut = "";
            if (!ObjectUtils.isEmpty(accountInfoEntities)){
                AccountInfoEntity accountInfoEntity = accountInfoEntities.get(0);
                if (accountInfoEntity.getBankAcco().equals(remoteDataMap.get("tbankacc"))){
                    transferInOut = "2";//付款
                    account = remoteDataMap.get("tbankacc");
                    accountName = remoteDataMap.get("taccname");
                    opAccount = remoteDataMap.get("bankacc");
                    opAccountName = remoteDataMap.get("accname");
                }
                if (accountInfoEntity.getBankAcco().equals(remoteDataMap.get("bankacc"))){
                    transferInOut = "1";//收款
                    account = remoteDataMap.get("bankacc");
                    accountName = remoteDataMap.get("accname");
                    opAccount = remoteDataMap.get("tbankacc");
                    opAccountName = remoteDataMap.get("taccname");
                }
            }
            String seqNo = remoteDataMap.get("nkjour");
            if (StringUtils.isEmpty(remoteDataMap.get("nkjour"))){
                log.error("当前nkjour为空！",remoteDataMap);
            }
            entityList.add(MjAccountSeqInfoEntity.builder()
                    .fundCode(remoteDataMap.get("nddisplaycode"))
                    .fundName(remoteDataMap.get("ndfullname"))
                    .transferDate(StringUtils.isEmpty(remoteDataMap.get("curdate")) ? "" : remoteDataMap.get("curdate").replace("-",""))
                    .transferTime(remoteDataMap.get("curtime").replaceAll("(\\d{2})(\\d{2})(\\d{2})", "$1:$2:$3"))
                    .transferInOut(transferInOut)
                    .account(account)
                    .accountName(accountName)
                    .opAccount(opAccount)
                    .opAccountName(opAccountName)
                    .amount(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("curamt").replace(",","")))
                    .balance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("ctbal").replace(",","")))
                    .summary(remoteDataMap.get("nknote"))
                    .remark(remoteDataMap.get("bz"))
                    .seqNo(StrUtil.getSeqNoWithoutNoRandom(seqNo))
                    .currency("156")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    /**
     *
     * @param tenant
     * @param trustNo
     * @param loopTime
     * @param flag “0”（0-否），表示历史流水数据，更新时间为每天早上、晚上7点； “1”（1-是），表示当日流水数据，更新频率为每半个小时更新一次
     */
    private void processTgAccountSeqInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopTime, String flag) {
        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0; i < loopTime; i++) {
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            int pageIndex = 0;
            try {
                for (; ; ) {
                    pageIndex++;
                    //封装请求参数
                    Map<String, Object> params = new HashMap<>();
                    params.put("service_name", EbscnConstants.TGACCOUNT_SEQ_INFO_API);
                    params.put("version", EbscnConstants.TGACCOUNT_SEQ_INFO_API_VERSION);
                    params.put("limit", "500");
                    params.put("pageIndex", pageIndex);
                    params.put("start_tradetime", finalStartDate);
                    params.put("end_tradetime", finalEndDate);
                    params.put("isToYqzl", flag);
                    //调用光大接口，获取数据
                    Integer total = 0;
                    Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                    if (!ObjectUtils.isEmpty(result) && result.containsKey("data")) {
                        Map data = (Map<String, Object>) result.get("data");
                        total = Integer.valueOf(data.get("total").toString());
                        Object remoteData = data.get("rows");
                        if (!ObjectUtils.isEmpty(remoteData)) {
                            List<JSONObject> remoteDataList = JSONObject.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                            List<TgAccountSeqInfoEntity> tgAccountSeqInfoEntities = getTgAccountSeqInfo(tenant, remoteDataList, trustNo);
                            tgAccountSeqInfoService.saveData(null, tgAccountSeqInfoEntities);
                        }
                    }
                    if (pageIndex * 500 > total) {
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("Ebscn ：processTgAccountSeqInfoData批量保存数据失败！", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }

    private List<TgAccountSeqInfoEntity> getTgAccountSeqInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典
        //收付方向
        Map<String, String> paymentDirectionDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PAYMENT_DIRECTION_SERVICE, trustNo);
        //2.封装数据
        List<TgAccountSeqInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList){
            remoteDataMap = JSONObject.toJavaObject(remoteData,Map.class);
            List<AccountInfoEntity> accountInfoEntities = accountInfoService.queryList(AccountInfoEntity.builder()
                    .trustNo(trustNo).accoTypeCode("ZJ001").fundCode(remoteDataMap.get("fundcode")).build());
            String account = "";
            String accountName = "";
            String opAccount = "";
            String opAccountName = "";
            String transferInOut = "";
            if (!ObjectUtils.isEmpty(accountInfoEntities)) {
                AccountInfoEntity accountInfo = accountInfoEntities.get(0);
                if (!ObjectUtils.isEmpty(accountInfo)) {
                    if (accountInfo.getBankAcco().equals(remoteDataMap.get("fkzh"))) {
                        account = remoteDataMap.get("fkzh");
                        accountName = remoteDataMap.get("fkzhmc");
                        opAccount = remoteDataMap.get("skzh");
                        opAccountName = remoteDataMap.get("skzhmc");
                        transferInOut = "2";
                    } else if (accountInfo.getBankAcco().equals(remoteDataMap.get("skzh"))) {
                        account = remoteDataMap.get("skzh");
                        accountName = remoteDataMap.get("skzhmc");
                        opAccount = remoteDataMap.get("fkzh");
                        opAccountName = remoteDataMap.get("fkzhmc");
                        transferInOut = "1";
                    }
                }
            }
            entityList.add(TgAccountSeqInfoEntity.builder()
                    .fundCode(remoteDataMap.get("fundcode"))
                    .fundName(remoteDataMap.get("fundname"))
                    .amount(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("je").replace(",","")))
                    .transferDate(StringUtils.isEmpty(remoteDataMap.get("rq")) ? "" : remoteDataMap.get("rq").substring(0,10).replace("-",""))
                    .summary(remoteDataMap.get("zy"))
                    .updateDate(remoteDataMap.get("sj"))
                    .account(account)
                    .accountName(accountName)
                    .opAccount(opAccount)
                    .opAccountName(opAccountName)
                    .transferInOut(transferInOut)
                    .transferTime("00:00:00")
                    .currency("156")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    public void processMjAccountBalanceInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopTime) {
        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastDate = localDate.minusMonths(loopTime);
        LocalDate nextMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        startDate = dateTimeFormatter.format(lastDate);
        for (int i = 0; i < loopTime; i++) {
            nextMonth = lastDate.plusMonths(1);
            endDate = dateTimeFormatter.format(nextMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            int pageIndex = 0;
            try {
                for (; ; ) {
                    pageIndex++;
                    //封装请求参数
                    Map<String, Object> params = new HashMap<>();
                    params.put("service_name", EbscnConstants.MJACCOUNT_BALANCE_AND_ACCOUNT_INFO_API);
                    params.put("version", EbscnConstants.MJACCOUNT_BALANCE_AND_ACCOUNT_INFO_API_VERSION);
                    params.put("limit", "500");
                    params.put("pageIndex", pageIndex);
                    params.put("start_ldate", finalStartDate);
                    params.put("end_ldate", finalEndDate);
                    //调用光大接口，获取数据
                    Integer total = 0;
                    Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                    if (!ObjectUtils.isEmpty(result)) {
                        Map data = (Map<String, Object>) result.get("data");
                        total = Integer.valueOf(data.get("total").toString());
                        Object remoteData = data.get("rows");
                        if (!ObjectUtils.isEmpty(remoteData)) {
                            List<JSONObject> remoteDataList = JSONObject.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                            List<AccountInfoEntity> mjAccountInfoEntities = getMjAccountInfo(tenant, remoteDataList, trustNo);
                            //保存accountInfo
                            accountInfoService.saveData(null, mjAccountInfoEntities);
                            List<MjAccountBalanceInfoEntity> mjAccountBalanceInfoEntities = getMjAccountBalanceInfo(tenant, remoteDataList, trustNo);
                            //保存数据 type暂时loopTime
                            mjAccountBalanceInfoService.saveData(String.valueOf(loopTime), mjAccountBalanceInfoEntities);
                        }
                    }
                    if (pageIndex * 500 > total) {
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("Ebscn ：processMjAccountBalanceInfoData批量保存数据失败！", e);
            }
            lastDate = nextMonth;
            startDate = endDate;
        }
    }

    private List<AccountInfoEntity> getMjAccountInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典
        //银行编码
        Map<String, String> bankCodeDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BANK_CODE_SERVICE, "资金清算系统银行编码");
        //2.封装数据
        List<AccountInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList){
            remoteDataMap = JSONObject.toJavaObject(remoteData,Map.class);
            entityList.add(AccountInfoEntity.builder()
                    .fundCode(remoteDataMap.get("nddisplaycode"))
                    .fundName(remoteDataMap.get("ndfullname"))
                    .bankCode(MatchDataDictionaryKeyUtil.getKey(bankCodeDir,remoteDataMap.get("nkcode")))
                    .branchBankName(remoteDataMap.get("nkname"))
                    .bankAcco(remoteDataMap.get("nkacc"))
                    .nameInBank(remoteDataMap.get("cname"))
                    .accoTypeCode("ZJ002")
                    .currency("156")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    private List<MjAccountBalanceInfoEntity> getMjAccountBalanceInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典
        //2.封装数据
        List<MjAccountBalanceInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList) {
            remoteDataMap = JSONObject.toJavaObject(remoteData,Map.class);
            String ldate = "";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
            if (!ObjectUtils.isEmpty(remoteDataMap.get("ldate"))){
                try {
                    ldate = sdf.format(sdf1.parse(remoteDataMap.get("ldate")));
                } catch (ParseException e) {
                    log.error("光大证券MjAccountBalanceInfo updateDate转化格式失败！", e);
                }
            }
            entityList.add(MjAccountBalanceInfoEntity.builder()
                    .updateDate(ldate)
                    .bankAcco(remoteDataMap.get("nkacc"))
                    .accoBalance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("ctbal").replace(",","")))
                    .availableBalance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("ailablebal").replace(",","")))
                    .accoTypeCode("ZJ002")
                    .currency("156")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    /**
     *
     * @param tenant
     * @param trustNo
     * @param flag  “0”（0-否），表示历史余额数据，更新时间为每天早上、晚上7点；   “1”（1-是），表示当日余额数据，更新频率为每半个小时更新一次
     */
    public void processTgAccountBalanceInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, String flag) {
        int pageIndex = 0;
        try {
            for (; ; ) {
                pageIndex++;
                //封装请求参数
                Map<String, Object> params = new HashMap<>();
                params.put("service_name", EbscnConstants.TGACCOUNT_BALANCE_AND_ACCOUNT_API);
                params.put("version", EbscnConstants.TGACCOUNT_BALANCE_AND_ACCOUNT_API_VERSION);
                params.put("limit", "500");
                params.put("pageIndex", pageIndex);
                params.put("isToYqzl", flag);
                //调用光大接口，获取数据
                Integer total = 0;
                Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                if (!ObjectUtils.isEmpty(result)) {
                    Map data = (Map<String, Object>) result.get("data");
                    total = Integer.valueOf(data.get("total").toString());
                    Object remoteData = data.get("rows");
                    if (!ObjectUtils.isEmpty(remoteData)) {
                        List<JSONObject> remoteDataList = JSONObject.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                        List<AccountInfoEntity> accountInfoEntities = getTgAccountInfo(tenant, remoteDataList, trustNo);
                        //保存accountInfo
                        accountInfoService.saveData(null, accountInfoEntities);
                        List<TgAccountBalanceInfoEntity> tgAccountBalanceInfoEntities = getTgAccountBalanceInfo(tenant, remoteDataList, trustNo);
                        //保存tgaccountbalanceinfo
                        tgAccountBalanceInfoService.saveData(null, tgAccountBalanceInfoEntities);
                    }
                }
                if (pageIndex * 500 > total) {
                    break;
                }

            }
        } catch (Exception e) {
            log.error("Ebscn ：processTgAccountBalanceInfoData批量保存数据失败！", e);
        }
    }

    private List<AccountInfoEntity> getTgAccountInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典
        //账号类型
        Map<String, String> accountTypeDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.ACCOUNT_TYPE_SERVICE, trustNo);
        //2.封装数据
        List<AccountInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList){
            remoteDataMap = JSONObject.toJavaObject(remoteData,Map.class);
            entityList.add(AccountInfoEntity.builder()
                    .fundCode(remoteDataMap.get("fundcode"))
                    .fundName(remoteDataMap.get("fundname"))
                    .bankAcco(remoteDataMap.get("zh"))
                    .nameInBank(remoteDataMap.get("zhmc"))
                    .accoTypeCode(MatchDataDictionaryKeyUtil.getKey(accountTypeDic,remoteDataMap.get("zhlx")))
                    .branchBankName(remoteDataMap.get("khhmc"))
                    .currency("156")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    private List<TgAccountBalanceInfoEntity> getTgAccountBalanceInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典

        //2.封装数据
        List<TgAccountBalanceInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList){
            remoteDataMap = JSONObject.toJavaObject(remoteData,Map.class);
            entityList.add(TgAccountBalanceInfoEntity.builder()
                    .bankAcco(remoteDataMap.get("zh"))
                    .accoBalance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("ye").replace(",","")))
                    .updateDate(remoteDataMap.get("sj"))
                    .currency("156")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    private void processFundProfitInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopTime) {
        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0; i < loopTime; i++) {
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            int pageIndex = 0;
            try {
                for (; ; ) {
                    pageIndex++;
                    //封装请求参数
                    Map<String, Object> params = new HashMap<>();
                    params.put("service_name", EbscnConstants.FUND_PROFIT_INFO_API);
                    params.put("version", EbscnConstants.FUND_PROFIT_INFO_API_VERSION);
                    params.put("limit", "500");
                    params.put("pageIndex", pageIndex);
                    params.put("start_cdate", finalStartDate);
                    params.put("end_cdate", finalEndDate);
                    //调用光大接口，获取数据
                    Integer total = 0;
                    Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                    if (!ObjectUtils.isEmpty(result)) {
                        Map data = (Map<String, Object>) result.get("data");
                        total = Integer.valueOf(data.get("total").toString());
                        Object remoteData = data.get("rows");
                        if (!ObjectUtils.isEmpty(remoteData)) {
                            List<JSONObject> remoteDataList = JSONObject.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                            List<FundProfitInfoEntity> entityList = getFundProfitInfo(tenant, remoteDataList, trustNo);
                            //保存数据
                            fundProfitInfoService.saveData(null, entityList);
                        }
                    }
                    if (pageIndex * 500 > total) {
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("Ebscn ：processFundProfitInfoData批量保存数据失败！", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }

    private List<FundProfitInfoEntity> getFundProfitInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典
        //业务类型
        Map<String, String> businessNameDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BUSINESS_NAME_SERVICE, trustNo);
        //销售商
        Map<String, String> sellerDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.SELLER_SERVICE, "光大证券");
        //封装数据
        List<FundProfitInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList){
            remoteDataMap = JSONObject.toJavaObject(remoteData,Map.class);
            //获取cserialNo
            String cserialNo = remoteDataMap.get("cserialno");
            if (!StringUtils.isEmpty(cserialNo) && cserialNo.length() > 32){
                cserialNo = cserialNo.substring(32);
            }
            //仅仅打印日志提醒一下
            if (StringUtils.isEmpty(cserialNo)){
                log.error("当前cserialno为空！",remoteDataMap);
            }
            //根据agencyNo获取agencyName
            String agencyName = sellerService.queryAgencyName("光大证券", remoteDataMap.get("agencyno"));
            entityList.add(FundProfitInfoEntity.builder()
                    .fundCode(remoteDataMap.get("fundcode"))
                    .fundName(remoteDataMap.get("fundname"))
                    .fundAcco(remoteDataMap.get("fundacco"))
                    .agencyNo(MatchDataDictionaryKeyUtil.getKey(sellerDic,remoteDataMap.get("agencyno")))
                    .confirmDate(StringUtils.isEmpty(remoteDataMap.get("cdate")) ? "" : remoteDataMap.get("cdate").replace("-",""))
                    .shares(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("confshares").replace(",","")))
                    .oriNav(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("beginnetvalue").replace(",",""),4))
                    .oriTotalNav(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("begintotalnetvalue").replace(",",""),4))
                    .nav(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("netvalue").replace(",",""),4))
                    .totalNav(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("totalnetvalue").replace(",",""),4))
                    .currRatio(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("curratio").replace(",",""),4))
                    .yearRatio(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("yearratio").replace(",",""),4))
                    .factBalance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("factdeductbalance").replace(",","")))
                    .factShares(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("factdeductshares").replace(",","")))
                    .businessName(MatchDataDictionaryKeyUtil.getKey(businessNameDic,remoteDataMap.get("businflag")))
                    .requestDate(StringUtils.isEmpty(remoteDataMap.get("date")) ? "" : remoteDataMap.get("date").replace("-",""))
                    .cserialNo(cserialNo)
                    .agencyName(agencyName)
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    private void processFundTradeInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo) {
        int pageIndex = 0;
        try {
            for (; ; ) {
                pageIndex++;
                //1.封装请求参数
                Map<String, Object> params = new HashMap<>();
                params.put("service_name", EbscnConstants.FUND_TRADE_INFO_AND_INVESTOR_BANK_API);
                params.put("version", EbscnConstants.FUND_TRADE_INFO_AND_INVESTOR_BANK_API_VERSION);
                params.put("limit", "500");
                params.put("pageIndex", pageIndex);
                //2.调用光大解口，获取数据
                Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                Integer total = 0;
                if (!ObjectUtils.isEmpty(result)) {
                    Map data = (Map<String, Object>) result.get("data");
                    total = Integer.valueOf(data.get("total").toString());
                    Object remoteData = data.get("rows");
                    if (!ObjectUtils.isEmpty(remoteData)) {
                        //3.封装成标准表数据
                        List<JSONObject> remoteDataList = JSONObject.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                        //封装fundTradeInfo数据
                        List<FundTradeInfoEntity> fundTradeInfoEntities = getFundTradeInfo(tenant, remoteDataList, trustNo);
                        //保存fundTradeInfo
                        fundTradeInfoService.saveData(null, fundTradeInfoEntities);
                    }
                }
                if (pageIndex * 500 > total) {
                    break;
                }
            }
        } catch (Exception e) {
            log.info("Ebasc:processFundTradeAndInvestorBankInfoData批量保存数据失败！", e);
        }
    }

    private List<InvestorBankInfoEntity> getInvestorBankInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典
        //2.封装数据
        List<InvestorBankInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList){
            remoteDataMap = JSONObject.toJavaObject(remoteData,Map.class);
            entityList.add(InvestorBankInfoEntity.builder()
                    .fundAcco(remoteDataMap.get("fundacco"))
                    .tradeAcco(remoteDataMap.get("tradeacco"))
                    .bankNo(remoteDataMap.get("bankacco"))
                    .branchBankName(remoteDataMap.get("bankname"))
                    .nameInBank(remoteDataMap.get("nameinbank"))
                    .bankNoType("银行卡号")
                    .admin(tenant.getTenantName())
                    .trustNo(trustNo)
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    private List<FundTradeInfoEntity> getFundTradeInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取字典
        //确认状态
        Map<String, String> confirmStatusDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CONFIRM_STATUS_SERVICE, trustNo);
        //业务类型
        Map<String, String> buinessNameDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BUSINESS_NAME_SERVICE, trustNo);
        //2.封装数据
        List<FundTradeInfoEntity> entityList = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList) {
            remoteDataMap = JSONObject.toJavaObject(remoteData,Map.class);
            //获取cserialNo
            String cserialNo = remoteDataMap.get("cserialno");
            if (!StringUtils.isEmpty(cserialNo) && cserialNo.length() > 32){
                cserialNo =cserialNo.substring(32);
            }
            //仅仅打印日志提醒一下
            if (StringUtils.isEmpty(cserialNo)){
                log.error("当前cserialno为空！",remoteDataMap);
            }
            //根据agencyname获取agencyNo
            String agencyNo = sellerService.queryKey("光大证券", remoteDataMap.get("agencyname"));
            entityList.add(FundTradeInfoEntity.builder()
                    .fundCode(remoteDataMap.get("fundcode"))
                    .fundName(remoteDataMap.get("fundname"))
                    .fundAcco(remoteDataMap.get("fundacco"))
                    .tradeAcco(remoteDataMap.get("tradeacco"))
                    .agencyName(remoteDataMap.get("agencyname"))
                    .requestDate(StringUtils.isEmpty(remoteDataMap.get("date")) ? "" : remoteDataMap.get("date").replace("-",""))
                    .confirmDate(StringUtils.isEmpty(remoteDataMap.get("cdate")) ? "" : remoteDataMap.get("cdate").replace("-",""))
                    .applyShares(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("shares").replace(",","")))
                    .applyBalance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("balance").replace(",","")))
                    .confirmShares(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("confirmshares").replace(",","")))
                    .confirmBalance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("confirmbalance").replace(",","")))
                    .tradeFare(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("tradefare").replace(",","")))
                    .profitBalance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("factdeductbalance").replace(",","")))
                    .registFare(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("registfare").replace(",","")))
                    .fundFare(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("fundfare").replace(",","")))
                    .interest(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("interest").replace(",","")))
                    .interestShare(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("interestshare").replace(",","")))
                    .netValue(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("netvalue"),4))
                    .confirmStatus(MatchDataDictionaryKeyUtil.getKey(confirmStatusDic,remoteDataMap.get("status")))
                    .businessName(MatchDataDictionaryKeyUtil.getKey(buinessNameDic,remoteDataMap.get("businnesflag")))
                    .confirmNavVol(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("turnover").replace(",","")))
                    .cserialNo(cserialNo)
                    .totalFare(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("totalfare").replace(",","")))
                    .agencyNo(agencyNo)
                    .currency("156")
                    .admin(tenant.getTenantName())
                    .trustNo(trustNo)
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    public void processFundNetValueInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopTime) {
        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0;i < loopTime;i++){
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            int pageIndex = 0;
            try {
                for (; ; ) {
                    //1.封装请求参数
                    pageIndex++;
                    Map<String, Object> params = new HashMap<>();
                    params.put("service_name", EbscnConstants.FUND_NET_VALUE_INFO_API);
                    params.put("version", EbscnConstants.FUND_NET_VALUE_INFO_API_VERSION);
                    params.put("limit", "500");
                    params.put("pageIndex", pageIndex);
                    params.put("start_date", finalStartDate);
                    params.put("end_date", finalEndDate);
                    params.put("sfqr", 1);//确认状态 1 ：已确认；0未确认
                    params.put("sfqr1", 1);//确认状态 1 ：已确认；0未确认
                    //2.调用光大接口，获取数据
                    Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                    Integer total = 0;
                    if (!ObjectUtils.isEmpty(result) && SUCCESS_CODE.equals(result.get("status").toString())) {
                        Map data = (Map<String, Object>) result.get("data");
                        total = Integer.valueOf(data.get("total").toString());
                        Object remoteData = data.get("rows");
                        if (!ObjectUtils.isEmpty(remoteData)) {
                            //3.封装成标准表数据
                            List<JSONObject> remoteDataList = JSONArray.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                            List<FundNetValueInfoEntity> entities = getFundNetValue(tenant, remoteDataList, trustNo);
                            //保存
                            fundNetValueInfoService.saveData(null, entities);
                            log.info("Ebscn:保存fundNetValueInfo成功！");
                        }
                    }
                    if (pageIndex * 500 > total) {
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("Ebscn:批量保存fundNetValueInfo失败！！", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }

    private List<FundNetValueInfoEntity> getFundNetValue(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {

        List<FundNetValueInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
            result.add(FundNetValueInfoEntity.builder()
                    .fundName(remoteDataMap.get("jjmc"))
                    .fundCode(remoteDataMap.get("fjjjdm"))
                    .netValueDate(StringUtils.isEmpty(remoteDataMap.get("rq")) ? "" : remoteDataMap.get("rq").replace("-",""))
                    .netValue(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("dwjz").replace(",", ""), 4))
                    .totalNetValue(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("ljdwjz").replace(",", ""), 4))
                    .assetValue(StringUtils.isEmpty(remoteDataMap.get("zcjz")) ? BigDecimalUtil.obj2BigDecimal("0") : BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("zcjz").replace(",", "")))
                    .shares(StringUtils.isEmpty(remoteDataMap.get("zcfe")) ? BigDecimalUtil.obj2BigDecimal("0") : BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("zcfe").replace(",", "")))
                    .totalAsset(StringUtils.isEmpty(remoteDataMap.get("zchj")) ? BigDecimalUtil.obj2BigDecimal("0") : BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("zchj").replace(",", "")))
                    .currency("156")
                    .admin(tenant.getTenantName())
                    .trustNo(trustNo)
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());

        }
        return result;
    }

    private void processCustShareAndInvestorInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo) {
        int pageIndex = 0;
        try {
            List<CustShareInfoEntity> entityList = new ArrayList<>();
            for (; ; ) {
                //1.封装请求参数
                pageIndex++;
                Map<String, Object> params = new HashMap<>();
                params.put("service_name", EbscnConstants.CUST_SHARE_AND_INVESTOR_INFO_API);
                params.put("version", EbscnConstants.CUST_SHARE_AND_INVESTOR_INFO_API_VERSION);
                params.put("limit", "500");
                params.put("pageIndex", pageIndex);
                //2、调用光大接口，获取数据
                Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                Integer total = 0;
                if (!ObjectUtils.isEmpty(result)) {
                    Map data = (Map<String, Object>) result.get("data");
                    total = Integer.valueOf(data.get("total").toString());
                    Object remoteData = data.get("rows");
                    //3、封装成标准表数据
                    if (!ObjectUtils.isEmpty(remoteData)) {
                        List<JSONObject> remoteDataList = JSONArray.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                        //封装custShareInfo数据
                        List<CustShareInfoEntity> custShareInfoEntities = getCustShareInfo(tenant, remoteDataList, trustNo);
                        entityList.addAll(custShareInfoEntities);
                        //封装investorInfo数据
                        List<InvestorInfoEntity> investorInfoEntities = getInvestorInfo(tenant, remoteDataList, trustNo);
                        //保存
                        investorInfoService.saveData(null, investorInfoEntities);
                        log.info("Ebscn：保存InvestorInfo数据成功！");
                    }
                }
                if (pageIndex * 500 > total) {
                    break;
                }
            }
            //保存
            custShareInfoService.saveData(null, entityList);
            log.info("Ebscn:保存custShareInfo数据成功！");
        } catch (Exception e) {
            log.error("Ebscn：批量保存数据失败！", e);
        }
    }

    private List<InvestorInfoEntity> getInvestorInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取数据字典
        //客户类型 中登
        Map<String, String> custTypeCsdcDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CUST_TYPE_CSDC_SERVICE, trustNo);
        //证件类型 中登
        Map<String, Map<String, String>> identityTypeCsdcDic = certificateCsdcService.queryCertificateWithDetail(trustNo);
        List<InvestorInfoEntity> result = new ArrayList<>();
        Map<String,String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
            String custTypeKey = MatchDataDictionaryKeyUtil.getKey(custTypeCsdcDic, remoteDataMap.get("custtype"));
            result.add(
                    InvestorInfoEntity.builder()
                            .fundAcco(remoteDataMap.get("fundacco"))
                            .custName(remoteDataMap.get("custname"))
                            .updateDate(StringUtils.isEmpty(remoteDataMap.get("lastmodify")) ? "" : remoteDataMap.get("lastmodify").replace("-",""))
                            .custType(custTypeKey)
                            .identityNo(remoteDataMap.get("identityno"))
                            .identityType(MatchDataDictionaryKeyUtil.getKey(custTypeKey,identityTypeCsdcDic,remoteDataMap.get("identitytype")))
                            .trustNo(trustNo)
                            .admin(tenant.getTenantName())
                            .createTime(new Date())
                            .updateTime(new Date())
                            .build()
            );
        }
        return result;
    }

    private List<CustShareInfoEntity> getCustShareInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //1.获取数据字典
        //分红方式
        Map<String, String> dividendWayDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.DIVIDEND_WAY_SERVICE, trustNo);
        //2.封装数据
        List<CustShareInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
            BigDecimal shares = fundNetValueInfoService.getSharesByFundInfo(FundNetValueInfoEntity.builder().
                    admin(tenant.getTenantName()).fundCode(remoteDataMap.get("fundcode")).fundName(remoteDataMap.get("fundname")).build());
            String key = sellerService.queryKey("光大证券", remoteDataMap.get("agencyname"));
            result.add(
                    CustShareInfoEntity.builder()
                            .tradeAcco("")
                            .fundCode(remoteDataMap.get("fundcode"))
                            .fundName(remoteDataMap.get("fundname"))
                            .fundAcco(remoteDataMap.get("fundacco"))
                            .lastHoldShares(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("realshares").replace(",","")))
                            .agencyName(remoteDataMap.get("agencyname"))
                            .updateDate(remoteDataMap.get("lastmodify").replace("-",""))
                            .bonusMethod(MatchDataDictionaryKeyUtil.getKey(dividendWayDic,remoteDataMap.get("bonustype")))
                            .income(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("income").replace(",","")))
                            .shareRatio(BigDecimalUtil.getShareRatio(shares,BigDecimalUtil.str2BigDecimal(remoteDataMap.get("realshares").replace(",",""))))
                            .currency("156")
                            .agencyNo(key)
                            .trustNo(trustNo)
                            .admin(tenant.getTenantName())
                            .createTime(new Date())
                            .updateTime(new Date())
                            .build()
            );
        }
        return result;
    }

    public void processFundInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo) {
        int pageIndex = 0;
        try {
            for (; ; ) {
                //1.封装请求参数
                pageIndex++;
                Map<String, Object> params = new HashMap<>();
                params.put("service_name", EbscnConstants.FUND_INFO_API);
                params.put("version", EbscnConstants.FUND_INFO_API_VERSION);
                params.put("limit", "500");
                params.put("pageIndex", pageIndex);
                //2.调用光大证券接口 获取远端数据
                Map<String, Object> result = ebscnRemoteUtil.sendMessage(params, tenant, false);
                JSONObject resultJson = new JSONObject(result);
                Integer total = 0;
                if (JSONPath.contains(resultJson, "$.data.total") && JSONPath.contains(resultJson, "$.data.rows")) {
                    total = Integer.valueOf(JSONPath.extract(resultJson.toJSONString(), "$.data.total").toString());
                    Object remoteData = JSONPath.extract(resultJson.toJSONString(), "$.data.rows");
                    if (!ObjectUtils.isEmpty(remoteData)) {
                        //3.封装成标准表数据
                        List<JSONObject> remoteDataList = JSONArray.parseArray(JSONObject.toJSONString(remoteData), JSONObject.class);
                        List<FundInfoEntity> fundInfoEntities = getFundInfo(tenant, remoteDataList, trustNo);
                        fundInfoService.saveData(null, fundInfoEntities);
                        log.info("Ebscn:processFundInfoData保存FundInfo成功！");
                    }
                }
                if (pageIndex * 500 > total) {
                    break;
                }
            }
        } catch (Exception e) {
            log.error("Ebscn:processFundInfoData保存FundInfo失败！", e);
        }
    }

    private List<FundInfoEntity> getFundInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDataList, String trustNo) {
        //获取字典数据
        Map<String, String> fundStatuDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PRODUCT_STATUS_SERVICE, trustNo);
        //封装数据
        List<FundInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        for (JSONObject remoteData : remoteDataList) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
            result.add(FundInfoEntity.builder()
                    .fundCode(remoteDataMap.get("showfundcode"))
                    .fundName(remoteDataMap.get("fundname"))
                    .fundStatus(MatchDataDictionaryKeyUtil.getKey(fundStatuDic, remoteDataMap.get("status")))
                    .createDate(remoteDataMap.get("cclrq").replace("-",""))
                    .innerFundCode(remoteDataMap.get("fundcode"))
                    .createTime(new Date())
                    .updateTime(new Date())
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .build());
        }
        return result;
    }

    @Override
    public R updateDataDaily(List<TenantEscrowAuthorizationInfoDto> tenants) {
        return null;
    }

    @Override
    public R updateSingleDataDaily(TenantEscrowAuthorizationInfoDto tenant) {
        log.info("光大证券托管数据初始化...");
        getDataFromEbscnAt7AM(tenant, UPDATE_BY_MONTH_DAILY_LOOP_TIME);
        log.info("光大证券托管数据初始化结束:");
        return R.ok("光大证券托管数据初始化结束！");
    }

    private void getDataFromEbscnAt7AM(TenantEscrowAuthorizationInfoDto tenant, int loopTime) {
        String trustNo = "42";
        //1 基金产品信息表（fund_info）
        processFundInfoData(tenant, trustNo);
        //8.基金交易确认信息表 (fund_trade_info)
        processFundTradeInfoData(tenant,trustNo);
        //10.业绩报酬信息表 fund_profit_info
        processFundProfitInfoData(tenant,trustNo,loopTime);
        // 15 资金账户基本信息表 account_info，16 托管⼾银⾏账⼾余额信息表 TGAccount_balance_info（历史）
        processTgAccountBalanceInfoData(tenant,trustNo,"0");
        // 15 资金账户基本信息表 account_info，16 托管⼾银⾏账⼾余额信息表 MJAccount_balance_info
        processMjAccountBalanceInfoData(tenant,trustNo,loopTime);
        //17 托管户流水表 TGAccount_seq_info (0 : 历史)
        processTgAccountSeqInfoData(tenant,trustNo,loopTime,"0");
        //19.募集户流水表 MJAccount_seq_info
        processMjAccountSeqInfoData(tenant,trustNo,loopTime);
        //4.基金持有信息表 cust_share_info 2.基金出资人信息表 investor_info
        processCustShareAndInvestorInfoData(tenant,trustNo);
    }

    @Override
    public R PullRemoteDataFirstQueueJob() {
        return null;
    }

    @Override
    public R initLaterTenantData(String versionStr, List<TenantEscrowAuthorizationInfoDto> tenants) {
        return null;
    }

    @Override
    public R initLaterSingleTenantData(String versionStr, TenantEscrowAuthorizationInfoDto tenant) {
        log.info("ebscn:initLaterSingleTenantData is begin...the versionStr is {} ,the tenant is {}", versionStr, JSON.toJSONString(tenant));
        String trustNo = tenant.getTrustNo();
        Integer loopNum = CustodyContants.INIT_BY_MONTH_LOOP_TIME;
        try {
            switch (versionStr) {
                case CustodyContants.R_PT_S_CUSTODY_3_2_6:
                    //19.募集户流水表 MJAccount_seq_info
                    processMjAccountSeqInfoData(tenant, trustNo, loopNum);
                    log.info("管理人{}光大证券募集户流水更新完成!", tenant.getTenantName());
                    //17 托管⼾流⽔表（TGAccount_seq_info）(0 : 历史)
                    processTgAccountSeqInfoData(tenant, trustNo, loopNum, "0");
                    log.info("管理人{}光大证券托管户流水更新完成!", tenant.getTenantName());
                    break;
            }
        } catch (Exception e) {
            log.error("光大证券更新流水表失败!");
        }
        return null;

    }

    @Override
    public R initByAppointedTrustNoAndMouth(TenantEscrowAuthorizationInfoDto tenant, int month) {
        log.info("光大证券托管数据初始化...");
        getDataFromEbscn(tenant, month);
        log.info("光大证券托管数据初始化结束:");
        return R.ok("光大证券托管数据初始化结束！");
    }

    @Override
    public R updateData20min(List<TenantEscrowAuthorizationInfoDto> data) {
        return null;
    }

    @Override
    public R updateSingleData20min(TenantEscrowAuthorizationInfoDto tenant) {
        log.info("光大证券托管数据每30ming更新开始...");
        String trustNo = tenant.getTrustNo();//42
        Integer loopTime = CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
        // 15 资金账户基本信息表 account_info，16 托管⼾银⾏账⼾余额信息表 TGAccount_balance_info（当日）
        processTgAccountBalanceInfoData(tenant,trustNo,"1");
        //17 托管户流水表 TGAccount_seq_info (1 : 当日)
        processTgAccountSeqInfoData(tenant,trustNo,loopTime,"1");
        log.info("光大证券托管数据每30min更新新结束:");
        return R.ok("光大证券托管数据每30min更新完成");
    }

    @Override
    public R updateData1h(List<TenantEscrowAuthorizationInfoDto> data) {
        return null;
    }

    @Override
    public R updateSingleData1h(TenantEscrowAuthorizationInfoDto tenant) {
        return null;
    }

    @Override
    public R updateDataCJ(String date, String flag, TenantEscrowAuthorizationInfoDto tenant) {
        return null;
    }

    @Override
    public R updateNetValueData(List<TenantEscrowAuthorizationInfoDto> tenants) {
        return null;
    }

    @Override
    public R updateSingleNetValueData(TenantEscrowAuthorizationInfoDto tenant) {
        log.info("光大证券托管数据每8点、12点、20点更新开始...");
        try {
            String trustNo = tenant.getTrustNo();//42
            Integer loopTime = CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
            //3.基金净值信息表 fund_net_value_info
            processFundNetValueInfoData(tenant,trustNo,loopTime);
            log.info("光大证券托管数据每8点、12点、20点更新结束~ ");
        }catch (Exception e){
            log.error("光大证券托管数据每8点、12点、20点更新异常！");
        }
        return R.ok("光大证券托管数据每8点、12点、20点更新完成");
    }

    @Override
    public DubboResult updateMJBalanceData(TenantEscrowAuthorizationInfoDto tenant) {
        try {
            processMjAccountBalanceInfoData(tenant, tenant.getTrustNo(), CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME);

            return DubboResult.newSuccess();
        } catch (Exception e) {
            log.error("手动更新募集户余额失败", e);
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, "手动更新募集户余额失败" + e.getMessage());
        }
    }

    @Override
    public DubboResult updateMJSeqData(TenantEscrowAuthorizationInfoDto tenant) {
        try {
            // 托管户流⽔表（TGAccount_seq_info）(1 : 当天)
            processMjAccountSeqInfoData(tenant, tenant.getTrustNo(), CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME);
            return DubboResult.newSuccess();
        } catch (Exception e) {
            log.error("手动更新募集户流水失败", e);
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, "手动更新募集户流水失败" + e.getMessage());
        }
    }

    @Override
    public DubboResult updateTGBalanceData(TenantEscrowAuthorizationInfoDto tenant) {
        try {
            String trustNo = tenant.getTrustNo();
            // 资金账户基本信息表 account_info， 托管户银行账户余额信息表 TGAccount_balance_info（当日）
            processTgAccountBalanceInfoData(tenant, trustNo, "1");
            return DubboResult.newSuccess();
        } catch (Exception e) {
            log.error("手动更新托管户余额失败", e);
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, "手动更新托管户余额失败" + e.getMessage());
        }
    }

    @Override
    public DubboResult updateTGSeqData(TenantEscrowAuthorizationInfoDto tenant) {
        try {
            String trustNo = tenant.getTrustNo();
            // 托管户流水表 TGAccount_seq_info (1 : 当日)
            processTgAccountSeqInfoData(tenant, trustNo, CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME, "1");
            return DubboResult.newSuccess();
        } catch (Exception e) {
            log.error("手动更新托管户流水失败", e);
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, "手动更新托管户流水失败" + e.getMessage());
        }
    }


}
