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

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.friday.base.common.response.DubboResult;
import com.friday.custody.entity.*;
import com.friday.custody.service.basicService.impl.*;
import com.friday.custody.service.trustService.citicZhongXin.service.OutsourceZhongXinService;
import com.friday.custody.service.trustService.haitong.utils.HaiTongHttpUtil;
import com.friday.custody.common.CustodyContants;
import com.friday.custody.dto.HaitongAppSecretDTO;
import com.friday.custody.dto.HaitongEmailDto;
import com.friday.custody.dto.TenantEscrowAuthorizationInfoDto;
import com.friday.custody.utils.*;
import com.friday.custody.enums.DataDictionaryTypeEnum;
import com.friday.custody.enums.EmailConfigPurposeEnum;
import com.friday.custody.service.basicService.DataDictionaryTypeCertificateCsdcService;
import com.friday.custody.service.basicService.PullDataFailureLogService;
import com.friday.custody.service.logicService.DataDictionaryBasicService;
import com.friday.custody.service.trustService.OutsourceService;
import com.friday.custody.service.trustService.gtja.utils.RandomStrUtil;
import com.friday.custody.service.trustService.haitong.common.HaiTongConstants;
import com.friday.custody.service.trustService.htsc.utils.HTSCGetDataUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.friday.custody.common.CustodyContants.TIME_PATTERN;

/**
 * @Description
 * @Author wulifeng
 * @Date: 2022/3/22
 */
@Slf4j
@Service
public class OutsourceHaiTongServiceImpl implements OutsourceService {


    @Autowired
    HTSCGetDataUtil hTSCGetDataUtil;

    @Autowired
    private HaiTongHttpUtil haiTongHttpUtil;


    @Autowired
    private PullDataFailureLogService pullDataFailureLogService;
    @Autowired
    private DataDictionaryBasicService dataDictionaryBasicService;
    @Autowired
    DataDictionaryTypeCertificateCsdcService certificateCsdcService;
    @Autowired
    private FundInfoServiceImpl fundInfoService;//a
    @Autowired
    private InvestorInfoServiceImpl investorInfoService;//b
    @Autowired
    private FundNetValueInfoServiceImpl fundNetValueInfoService;//c
    @Autowired
    private CustShareInfoServiceImpl custShareInfoService;//d
    @Autowired
    private TgAccountBalanceInfoServiceImpl tgAccountBalanceInfoService;//e
    @Autowired
    private TgAccountSeqInfoServiceImpl tgAccountSeqInfoService;//f
    @Autowired
    private MjAccountBalanceInfoServiceImpl mjAccountBalanceInfoService;//g
    @Autowired
    private MjAccountSeqInfoServiceImpl mjAccountSeqInfoService;//h
    @Autowired
    private FundTradeInfoServiceImpl fundTradeInfoService;//i
    @Autowired
    private FundValueTableDataInfoServiceImpl fundValueTableDataInfoService;//j
    @Autowired
    private AccountInfoServiceImpl accountInfoService;//11
    @Autowired
    private CustShareSeqInfoServiceImpl custShareSeqInfoService;//12
    @Autowired
    private InvestorBankInfoServiceImpl investorBankInfoService;//13
    @Autowired
    private FundProfitInfoServiceImpl fundProfitInfoService;//14
    @Autowired
    private CustShareDetailInfoServiceImpl custShareDetailInfoService;//15
    @Autowired
    private DataDictionarySellerServiceImpl sellerService;
    @Autowired
    private FundFeeDataInfoServiceImpl fundFeeDataInfoService;
    @Autowired
    private FundOpenInfoServiceImpl fundOpenInfoService;
    @Autowired
    private DataDictionaryOpenStateServiceImpl openStateService;
    @Autowired
    private DataDictionaryTypeOfFundValuationServiceImpl typeOfFundValuationService;
    @Autowired
    private FundValuationServiceImpl fundValuationService;
    @Autowired
    @Lazy
    OutsourceHaiTongServiceImpl outsourceHaiTongService;

    @Resource(name = "pullDataThreadPool")
    private ExecutorService pullDataThreadPool;
    @Autowired
    private MailNewUtils mailNewUtils;
    @Override
    public R initTenantData(List<TenantEscrowAuthorizationInfoDto> tenants) {
        return null;
    }

    @Override
    public R initTenantDataSingle(TenantEscrowAuthorizationInfoDto tenant) {
        log.info("***************初始化海通托管数据开始****************");
        int loopTime = CustodyContants.INIT_BY_MONTH_LOOP_TIME;
        getDataFromHaiTong(tenant, loopTime);
        return R.ok("初始化海通托管数据成功！");
    }

    @Override
    public R updateDataDaily(List<TenantEscrowAuthorizationInfoDto> tenants) {
        boolean hasUpdate = false;
        for (TenantEscrowAuthorizationInfoDto tenant : tenants) {
            if ("21".equals(tenant.getTrustNo())) {
                getDataFromHaiTong(tenant,1);
                hasUpdate = true;
            }
        }
        if(!hasUpdate){
            log.error("没有租户，updateDataDaily未更新海通!");
        }
        return null;
    }

    @Override
    public R updateSingleDataDaily(TenantEscrowAuthorizationInfoDto tenant) {

        log.info("海通托管数据初始化...");
        getUpdateDataFromHaiTong(tenant, 1); //先都拿1年，客户有需求再增加到3年
        log.info("海通托管数据初始化结束:");
        return R.ok("海通托管数据初始化结束！");

    }

    @Autowired
    private TenantEmailAuthorizationInfoServiceImpl tenantEmailInfoService;

    @Autowired
    private OutsourceZhongXinService outsourceZhongXinService;

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

    public static final String LIN_YUAN_TENANT_NAME = "P1002894";

    private ObjectMapper objectMapper = new ObjectMapper();
    public HaitongAppSecretDTO getHaitongAppSecretDTO(TenantEscrowAuthorizationInfoDto tenant){
        String tenantAppSecret = tenant.getAppSecret();
        if (ObjectUtil.isEmpty(tenantAppSecret)){
            return null;
        }
        HaitongAppSecretDTO haitongAppSecretDTO = new HaitongAppSecretDTO();
        try {
            haitongAppSecretDTO = objectMapper.readValue(tenantAppSecret, HaitongAppSecretDTO.class);
        } catch (IOException e) {
            log.error("解析账密{}失败{}!", haitongAppSecretDTO, e);
        }
        return haitongAppSecretDTO;
    }
    public void getDataFromHaiTong(TenantEscrowAuthorizationInfoDto tenant, int loopNum){
        String trustNo = "21"; //每分钟 30次
        String tenantName = tenant.getTenantName();
        try {
            //林园API接口使用中转服务，邮件解析使用华泰服务器
            if(!LIN_YUAN_TENANT_NAME.equals(tenantName)){
                //1
                log.info("海通开始");
                processFundInfoData(tenant, trustNo, loopNum);
                log.info("海通进度1/16");
                //2&13
                processInvestorInfoAndInvestorBankInfoData(tenant,trustNo,loopNum);
                log.info("海通进度2/16");
                //4
                processCustShareInfoData(tenant,trustNo,loopNum);
                log.info("海通进度3/16");
                //9
                processFundTradeInfoData(tenant,trustNo,loopNum);
                log.info("海通进度4/16");
                //14
                processFundProfitInfoData(tenant,trustNo,loopNum);
                log.info("海通进度5/16");
                //15
                processCustShareDetailInfoData(tenant,trustNo,loopNum);
                log.info("海通进度6/16");

                //mjAccount_seq_info
                processT0213Data(tenant,trustNo,loopNum);
                log.info("海通进度7/16");

                // account_info+MJAccount_balance_info
                processT0214Data(tenant,trustNo,loopNum);
                log.info("海通进度8/16");

                //testOtherInterface(tenant,trustNo,loopNum);
                outsourceHaiTongService.processFundFeeDataInfoData(tenant,trustNo,loopNum);
                log.info("海通进度9/16");

                //TGAccount_seq_info
                processT0215Data(tenant,trustNo,loopNum);
                log.info("海通进度10/16");

                //TGAccount_seq_info
                processT0216Data(tenant,trustNo,loopNum);
                log.info("海通进度11/16");

                //account_info + TGAccount_balance_info
                processT0217Data(tenant,trustNo,loopNum);
                log.info("海通进度12/16");

                outsourceHaiTongService.processFundNetValueData(tenant,trustNo,loopNum);
                log.info("海通进度13/16");

                //TGAccount_balance_info
                processT0218Data(tenant,trustNo,loopNum);
                log.info("海通进度14/16");

                outsourceHaiTongService.processFundOpenInfoData(tenant, trustNo, loopNum);
                log.info("海通进度15/16");
            }
            log.info("处理邮件解析FundValueTableInfo和FundNetValueInfo表的数据");
            processFundValueTableAndFundNetValueByEmail(tenant,trustNo,loopNum);

            log.info("海通进度16/16");
            log.info("海通拉取数据结束！");
        } catch (Exception e) {
            log.error("海通托管数据拉取失败:", e);
        } finally {
        }
    }

    public void getUpdateDataFromHaiTong(TenantEscrowAuthorizationInfoDto tenant, int loopNum){
        String trustNo = "21"; //每分钟 30次
        String tenantName = tenant.getTenantName();
        try {
            //林园API接口使用中转服务，邮件解析使用华泰服务器
            if(!LIN_YUAN_TENANT_NAME.equals(tenantName)){
                //1
                log.info("海通更新开始");
                processFundInfoData(tenant, trustNo, loopNum);
                log.info("海通更新进度1/10");
                //2&13
                processInvestorInfoAndInvestorBankInfoData(tenant,trustNo,loopNum);
                log.info("海通更新进度2/10");
                //4
                processCustShareInfoData(tenant,trustNo,loopNum);
                log.info("海通更新进度3/10");
                //9
                processFundTradeInfoData(tenant,trustNo,loopNum);
                log.info("海通更新进度4/10");
                //14
                processFundProfitInfoData(tenant,trustNo,loopNum);
                log.info("海通更新进度5/10");
                //15
                processCustShareDetailInfoData(tenant,trustNo,loopNum);
                log.info("海通更新进度6/10");

                //testOtherInterface(tenant,trustNo,loopNum);
                outsourceHaiTongService.processFundFeeDataInfoData(tenant,trustNo,loopNum);
                log.info("海通更新进度7/10");

                //TGAccount_seq_info
                processT0215Data(tenant,trustNo,loopNum);
                log.info("海通更新进度8/10");

                //account_info + TGAccount_balance_info
                processT0217Data(tenant,trustNo,loopNum);
                log.info("海通更新进度9/10");

                outsourceHaiTongService.processFundOpenInfoData(tenant, trustNo, loopNum);
                log.info("海通更新进度10/10");
            }
            log.info("海通更新进度10/10");
            log.info("海通更新数据结束！");
        } catch (Exception e) {
            log.error("海通托管更新数据拉取失败:", e);
        } finally {
        }
    }

    public void processFundOpenInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        List<String> fundCodeList = fundInfoService.getFundCodeList(trustNo, tenant.getTenantName());
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0; i < loopNum; i++) {
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            for (String fundCode : fundCodeList) {
                if (StringUtils.isBlank(fundCode)) {
                    continue;
                }
                try {
                    //1、封装请求参数
                    HashMap<String, Object> params = new HashMap<>();
                    String api = HaiTongConstants.FUND_OPEN_INFO;
                    List<JSONObject> objects;
                    params.put("beginDate", finalStartDate);
                    params.put("endDate", finalEndDate);
                    params.put("fundCode", fundCode);
                    String jsonString = JSON.toJSONString(params);
                    //2、获取远端数据
                    Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO, jsonString, api, tenant, trustNo);
                    if (CollectionUtils.isEmpty(stringObjectMap)) {
                        log.info("processFundOpenInfoData 查询结果为空，终止查询");
                        break;
                    }
                    boolean result = (boolean) stringObjectMap.get("result");
                    if (result) {
                        objects = (List<JSONObject>) stringObjectMap.get("data");
                        if (!CollectionUtils.isEmpty(objects)) {
                            //3、封装成标准表的对象
                            List<FundOpenInfoEntity> entities = getFundOpenInfo(tenant, objects, trustNo);
                            log.info("海通processFundOpenInfoData封装数据为：{}", entities.size());
                            //4、调用 basicservice 的保存数据接口
                            fundOpenInfoService.saveData(null, entities);
                        }
                    }
                } catch (Exception e) {
                    log.error("OutsourceHaiTongServiceImpl:processFundOpenInfoData:", e);
                }
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }

    public List<FundOpenInfoEntity> getFundOpenInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> objects, String trustNo) {
        //获取数据字典
        //开放日类型
        Map<String, String> typeOfOpenDayDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.TYPE_OF_OPEN_DAY_SERVICE, trustNo);
        //开放状态
        Map<String, Map<String, String>> openStateDic = openStateService.queryOpenStateWithDetail(trustNo);
        //封装数据
        List<FundOpenInfoEntity> entityList = new ArrayList<>();
        Map<String, String> dataMap;
        for (JSONObject data : objects){
            dataMap = JSONObject.toJavaObject(data, Map.class);
            //转义开放日类型
            String openType = MatchDataDictionaryKeyUtil.getKey(typeOfOpenDayDic, dataMap.get("openSrc"));
            //转义开放状态
            String openStatus = MatchDataDictionaryKeyUtil.getKey(openType, openStateDic, dataMap.get("openType"));
            String fundName = fundInfoService.getFundNameByFundCode(dataMap.get("fundCode"), trustNo, tenant.getTenantName());
            entityList.add(FundOpenInfoEntity.builder()
                    .fundCode(dataMap.get("fundCode"))
                    .fundOpenDate(dataMap.get("openDate"))
                    .openType(openType)
                    .openStatus(openStatus)
                    .fundName(fundName)
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    private void processT0218Data(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastDay;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        loopNum = loopNum == 1 ? 30 : 365;
        for (int i = 0; i < loopNum; i++) {
            lastDay = localDate.minusDays(1);
            startDate = dateTimeFormatter.format(lastDay);
            String finalStartDate = startDate;
            String finalEndDate = startDate;
            try {
                List<String> bankAccoList = tgAccountBalanceInfoService.getBankAccoList(trustNo, tenant.getTenantName());
                if(CollectionUtils.isEmpty(bankAccoList)){
                    log.error("processT0218Data 无法获取参数bank_acco，中止");
                    return;
                }

                for (String bankAcco : bankAccoList) {
                    //1、封装请求参数
                    HashMap<String, Object> params = new HashMap<>();
                    int pageSize = 100;
                    String api = HaiTongConstants.TGACCOUNT_BALANCE_INFO;
                    List<JSONObject> objects = new ArrayList<>();
                    int pageNo = 0;
                    do {
                        pageNo++;
                        String requestNum = String.valueOf(pageSize);
                        String pageNoStr = String.valueOf(pageNo);
                        params.put("requestPageno", pageNoStr);
                        params.put("requestNum", requestNum);
                        params.put("date", finalStartDate);
                        params.put("bankAcco", bankAcco);
                        String jsonString = JSON.toJSONString(params);
                        //2、获取远端数据
                        Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                        if(CollectionUtils.isEmpty(stringObjectMap)){
                            log.error("processT0218Data 查询结果为空，终止查询");
                            break;
                        }
                        boolean result = (boolean) stringObjectMap.get("result");
                        if (result) {
                            objects = (List<JSONObject>) stringObjectMap.get("data");
                            String totalCount = (String) stringObjectMap.get("totalCount");
                            Integer totalCountInt = Integer.valueOf(totalCount);
                            if (!CollectionUtils.isEmpty(objects)) {
                                //3、封装成标准表的对象 //
                                List<TgAccountBalanceInfoEntity> entities = getTgAccountBalanceInfo(tenant, objects, trustNo);
                                //4、调用 basicservice 的保存数据接口
                                tgAccountBalanceInfoService.saveData(null, entities);
                            }
                            log.info("海通processT0218Data现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                            if (pageNo * pageSize > totalCountInt) {
                                log.info("海通processT0218Data查询入库结束");
                                break;
                            }
                        }
                    } while (objects != null && objects.size() == pageSize);
                }
            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processT0218Data:", e);
            }
            localDate = lastDay;
        }
    }

    public void processT0217Data(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastDay;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        loopNum = loopNum == 1 ? 30 : 365;
        for (int i = 0; i < loopNum; i++) {
            lastDay = localDate.minusDays(1);
            startDate = dateTimeFormatter.format(lastDay);
            String finalStartDate = startDate;
            String finalEndDate = startDate;
            try {
                //查询TGAccount_seq_info：account fund_code
                List<TgAccountSeqInfoEntity> accountAndFundCodes = tgAccountSeqInfoService.getFundCodeAndAccountList(trustNo,tenant.getTenantName());
                if(CollectionUtils.isEmpty(accountAndFundCodes)){
                    log.error("processT0217Data参数fundCode、account为空，无法查询");
                    return;
                }
                for (TgAccountSeqInfoEntity accountAndFundCode : accountAndFundCodes) {
                    //1、封装请求参数
                    HashMap<String, Object> params = new HashMap<>();
                    int pageSize = 100;
                    String api = HaiTongConstants.ACCOUNT_INFO;
                    List<JSONObject> objects = new ArrayList<>();
                    int pageNo = 0;
                    do {
                        pageNo++;
                        String requestNum = String.valueOf(pageSize);
                        String pageNoStr = String.valueOf(pageNo);
                        params.put("requestPageno", pageNoStr);
                        params.put("requestNum", requestNum);
                        params.put("date", finalStartDate);
                        params.put("fundCode", accountAndFundCode.getFundCode());
                        params.put("bankAcco", accountAndFundCode.getAccount());
                        String jsonString = JSON.toJSONString(params);
                        //2、获取远端数据
                        Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                        if(CollectionUtils.isEmpty(stringObjectMap)){
                            log.error("processT0217Data 查询结果为空，终止查询");
                            break;
                        }
                        boolean result = (boolean) stringObjectMap.get("result");
                        if (result) {
                            objects = (List<JSONObject>) stringObjectMap.get("data");
                            String totalCount = (String) stringObjectMap.get("totalCount");
                            Integer totalCountInt = Integer.valueOf(totalCount);
                            if (!CollectionUtils.isEmpty(objects)) {
                                //3、封装成标准表的对象 //
                                List<AccountInfoEntity> entities = getAccountInfoByT0217(tenant, objects, trustNo);
                                //4、调用 basicservice 的保存数据接口
                                accountInfoService.saveData(null, entities);

                                //3、封装成标准表的对象 //
                                List<TgAccountBalanceInfoEntity> entities1 = getTgAccountBalanceInfo(tenant, objects, trustNo);
                                //4、调用 basicservice 的保存数据接口
                                tgAccountBalanceInfoService.saveData(null, entities1);
                            }
                            log.info("海通processT0216Data现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                            if (pageNo * pageSize > totalCountInt) {
                                log.info("海通processT0216Data查询入库结束");
                                break;
                            }
                        }
                    } while (objects != null && objects.size() == pageSize);
                }
            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processT0216Data:", e);
            }
            localDate = lastDay;
        }
    }

    public List<TgAccountBalanceInfoEntity> getTgAccountBalanceInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        List<TgAccountBalanceInfoEntity> result = new ArrayList<>();

        try{
            log.info("getAccountInfoByT0214{}",JSON.toJSONString(remoteDatas));
            Map<String, String> currencyDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CURRENCY_SERVICE, trustNo);
            Map<String, String> bankCodeDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BANK_CODE_SERVICE, "海通TA");

            //2、封装数据
            Map<String, String> remoteDataMap;
            Date now = new Date();
            for (JSONObject remoteData : remoteDatas) {
                remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
                result.add(TgAccountBalanceInfoEntity.builder()
                        .currency(MatchDataDictionaryKeyUtil.getKey(currencyDir, remoteDataMap.get("curType")))
                        .bankAcco(remoteDataMap.get("bankAcco"))
                        .accoBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("acctBal")))
                        .updateDate(remoteDataMap.get("retTime"))
                        .trustNo(trustNo)
                        .admin(tenant.getTenantName())
                        .createTime(now)
                        .updateTime(now)
                        .build());
            }
            return result;
        }catch (Exception e){
            log.error("getAccountInfoByT0214异常{}",e);
        }
        return result;
    }

    private void processT0216Data(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastDay;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        loopNum = loopNum == 1 ? 30 : 365;
        for (int i = 0; i < loopNum; i++) {
            lastDay = localDate.minusDays(1);
            startDate = dateTimeFormatter.format(lastDay);
            String finalStartDate = startDate;
            String finalEndDate = startDate;

            List<String> bankAccoList = tgAccountSeqInfoService.getBankAccoList(trustNo,tenant.getTenantName());
            if(CollectionUtils.isEmpty(bankAccoList)){
                log.error("processT0216Data 入参为空，中止查询");
                break;
            }
            for (String s : bankAccoList) {
                try {
                    //1、封装请求参数
                    HashMap<String, Object> params = new HashMap<>();
                    int pageSize = 100;
                    String api = HaiTongConstants.QUERY_ACCOUNT_JOURNAL_ONLINE;
                    List<JSONObject> objects = new ArrayList<>();
                    int pageNo = 0;
                    do {
                        pageNo++;
                        String requestNum = String.valueOf(pageSize);
                        String pageNoStr = String.valueOf(pageNo);
                        params.put("requestPageno", pageNoStr);
                        params.put("requestNum", requestNum);
                        params.put("beginDate", finalStartDate);
                        params.put("endDate", finalEndDate);
                        params.put("bankAcco", s);
                        String jsonString = JSON.toJSONString(params);
                        //2、获取远端数据
                        Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                        if(CollectionUtils.isEmpty(stringObjectMap)){
                            log.error("processT0216Data 查询结果为空，终止查询");
                            break;
                        }
                        boolean result = (boolean) stringObjectMap.get("result");
                        if (result) {
                            objects = (List<JSONObject>) stringObjectMap.get("data");
                            String totalCount = (String) stringObjectMap.get("totalCount");
                            Integer totalCountInt = Integer.valueOf(totalCount);
                            if (!CollectionUtils.isEmpty(objects)) {
                                //3、封装成标准表的对象
                                List<TgAccountSeqInfoEntity> entities = getTgAccountSeqInfo(tenant, objects, trustNo);
                                log.info("海通processT0216Data封装数据为：{}", entities.size());
                                //4、调用 basicservice 的保存数据接口
                                tgAccountSeqInfoService.saveData(null, entities);
                            }
                            log.info("海通processT0216Data现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                            if (pageNo * pageSize > totalCountInt) {
                                log.info("海通processT0216Data查询入库结束");
                                break;
                            }
                        }
                    } while (objects != null && objects.size() == pageSize);

                } catch (Exception e) {
                    log.error("OutsourceHaiTongServiceImpl:processT0216Data:", e);
                }
                localDate = lastDay;
            }
        }
    }



    public void processT0214Data(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);
        try {
            //1、封装请求参数
            HashMap<String, Object> params = new HashMap<>();
            String api = HaiTongConstants.MJ_ACCOUNT_BALANCE_INFO;
            List<JSONObject> objects = new ArrayList<>();
            //2、获取远端数据
            String jsonString = JSON.toJSONString(params);
            Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO, jsonString, api, tenant, trustNo);
            if (CollectionUtils.isEmpty(stringObjectMap)) {
                log.error("processT0214Data 查询结果为空，终止查询");
            }
            boolean result = (boolean) stringObjectMap.get("result");
            if (result) {
                objects = (List<JSONObject>) stringObjectMap.get("data");
                if (!CollectionUtils.isEmpty(objects)) {
                    //3、封装成标准表的对象 //
                    List<AccountInfoEntity> entities = getAccountInfoByT0214(tenant, objects, trustNo);
                    //4、调用 basicservice 的保存数据接口
                    accountInfoService.saveData(null, entities);

                    //3、封装成标准表的对象 //
                    List<MjAccountBalanceInfoEntity> entities1 = getMJAccountBalanceInfoByT0214(tenant, objects, trustNo);
                    //4、调用 basicservice 的保存数据接口
                    mjAccountBalanceInfoService.saveData(null, entities1);
                }
            }
        } catch (Exception e) {
            log.error("OutsourceHaiTongServiceImpl:processT0214Data:", e);
        }
    }

    public List<MjAccountBalanceInfoEntity> getMJAccountBalanceInfoByT0214(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        List<MjAccountBalanceInfoEntity> result = new ArrayList<>();

        try{
            log.info("getAccountInfoByT0214{}",JSON.toJSONString(remoteDatas));
            Map<String, String> currencyDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CURRENCY_SERVICE, trustNo);
            Map<String, String> bankCodeDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BANK_CODE_SERVICE, "海通TA");

            //2、封装数据
            Map<String, String> remoteDataMap;
            Date now = new Date();
            for (JSONObject remoteData : remoteDatas) {
                String dateStr =(String) remoteData.get("date");
                if(StringUtils.isNotBlank(dateStr) && dateStr.length() == 8){
                    dateStr = dateStr.substring(0,4) + "-" + dateStr.substring(4,6) + "-" + dateStr.substring(6,8);
                    dateStr = dateStr + " 00:00:00";
                }else{
                    log.error("getMJAccountBalanceInfoByT0214时间为{}",dateStr);
                }

                remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
                result.add(MjAccountBalanceInfoEntity.builder()
                        .updateDate(dateStr)
                        .currency(MatchDataDictionaryKeyUtil.getKey(currencyDir, remoteDataMap.get("curType")))
                        .bankAcco(remoteDataMap.get("fundBankAcc"))
                        .accoBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("acctBal")))
                        .availableBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("availableBal")))
                        .accoTypeCode("ZJ002")
                        .trustNo(trustNo)
                        .admin(tenant.getTenantName())
                        .createTime(now)
                        .updateTime(now)
                        .build());
            }
            return result;
        }catch (Exception e){
            log.error("getAccountInfoByT0214异常{}",e);
        }
        return result;
    }

    public List<AccountInfoEntity> getAccountInfoByT0214(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        List<AccountInfoEntity> result = new ArrayList<>();

        try{
            log.info("getAccountInfoByT0214{}",JSON.toJSONString(remoteDatas));
            Map<String, String> currencyDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CURRENCY_SERVICE, trustNo);
            Map<String, String> bankCodeDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BANK_CODE_SERVICE, "海通TA");

            //2、封装数据
            Map<String, String> remoteDataMap;
            Date now = new Date();
            for (JSONObject remoteData : remoteDatas) {
                remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
                result.add(AccountInfoEntity.builder()
                        .fundCode(remoteDataMap.get("fundCode"))
                        .fundName(remoteDataMap.get("fundName"))
                        .bankCode(MatchDataDictionaryKeyUtil.getKey(bankCodeDic,remoteDataMap.get("bankNo")))
                        .branchBankName(remoteDataMap.get("bankName"))
                        .currency(MatchDataDictionaryKeyUtil.getKey(currencyDir, remoteDataMap.get("curType")))
                        .bankAcco(remoteDataMap.get("fundBankAcc"))
                        .nameInBank(remoteDataMap.get("bankAccName"))
                        .accoTypeCode("ZJ002")
                        .trustNo(trustNo)
                        .admin(tenant.getTenantName())
                        .createTime(now)
                        .updateTime(now)
                        .build());
            }
            return result;
        }catch (Exception e){
            log.error("getAccountInfoByT0214异常{}",e);
        }
        return result;
    }

    private List<AccountInfoEntity> getAccountInfoByT0217(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        List<AccountInfoEntity> result = new ArrayList<>();

        try{
            log.info("getAccountInfoByT0217{}",JSON.toJSONString(remoteDatas));
            Map<String, String> currencyDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CURRENCY_SERVICE, trustNo);
            Map<String, String> bankCodeDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BANK_CODE_SERVICE, "海通TA");

            //2、封装数据
            Map<String, String> remoteDataMap;
            Date now = new Date();
            for (JSONObject remoteData : remoteDatas) {
                remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
                result.add(AccountInfoEntity.builder()
                        .currency(MatchDataDictionaryKeyUtil.getKey(currencyDir, remoteDataMap.get("curType")))
                        .fundCode(remoteDataMap.get("fundCode"))
                        .fundName(remoteDataMap.get("fundName"))
                        .bankAcco(remoteDataMap.get("bankAcco"))
                        .nameInBank(remoteDataMap.get("accName"))
                        .branchBankName(remoteDataMap.get("openBankName"))
                        .accoTypeCode("ZJ001")
                        .trustNo(trustNo)
                        .admin(tenant.getTenantName())
                        .createTime(now)
                        .updateTime(now)
                        .build());
            }
            return result;
        }catch (Exception e){
            log.error("getAccountInfoByT0217异常{}",e);
        }
        return result;
    }

    private void processT0213Data(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);


        String startDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastDay;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        loopNum = loopNum == 1 ? 30 : 365;
        for (int i = 0; i < loopNum; i++) {
            lastDay = localDate.minusDays(1);
            startDate = dateTimeFormatter.format(lastDay);
            String finalStartDate = startDate;
            String finalEndDate = startDate;
            try {
                //1、封装请求参数
                HashMap<String, Object> params = new HashMap<>();
                int pageSize = 100;
                String api = HaiTongConstants.RAISING_ACCOUNT_FLOW;
                List<JSONObject> objects = new ArrayList<>();
                int pageNo = 0;
                do {
                    pageNo++;
                    String requestNum = String.valueOf(pageSize);
                    String pageNoStr = String.valueOf(pageNo);
                    params.put("requestPageno", pageNoStr);
                    params.put("requestNum", requestNum);
                    params.put("beginDate", finalStartDate);
                    params.put("endDate", finalEndDate);
                    String jsonString = JSON.toJSONString(params);
                    //2、获取远端数据
                    Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                    if(CollectionUtils.isEmpty(stringObjectMap)){
                        log.error("processT0213Data 查询结果为空，终止查询");
                        break;
                    }
                    boolean result = (boolean) stringObjectMap.get("result");
                    if (result) {
                        objects = (List<JSONObject>) stringObjectMap.get("data");
                        String totalCount = (String) stringObjectMap.get("totalCount");
                        Integer totalCountInt = Integer.valueOf(totalCount);
                        if (!CollectionUtils.isEmpty(objects)) {
                            //3、封装成标准表的对象
                            List<MjAccountSeqInfoEntity> entities = getMJAccountSeqInfo(tenant, objects, trustNo);
                            log.info("海通processT0213Data封装数据为：{}", entities.size());
                            //4、调用 basicservice 的保存数据接口
                            mjAccountSeqInfoService.saveData(null, entities);
                        }
                        log.info("海通processT0213Data现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                        if (pageNo * pageSize > totalCountInt) {
                            log.info("海通processT0213Data查询入库结束");
                            break;
                        }
                    }
                } while (objects != null && objects.size() == pageSize);

            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processT0213Data:", e);
            }
            localDate = lastDay;
        }
    }

    public List<MjAccountSeqInfoEntity> getMJAccountSeqInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {

        log.info("getMJAccountSeqInfo{}",JSON.toJSONString(remoteDatas));
        Map<String, String> paymentDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PAYMENT_DIRECTION_SERVICE, trustNo);

        //2、封装数据
        List<MjAccountSeqInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
            String directFlag = MatchDataDictionaryKeyUtil.getKey(paymentDir, remoteDataMap.get("directFlag"));
            String opAccount = "";
            String opAccountName = "";
            String opBankName = "";
            String account = "";
            String accountName = "";
            String bankName = "";
            if (StringUtils.isEmpty(directFlag)) {
                opAccount = remoteDataMap.get("outBankAcc");
                opAccountName = remoteDataMap.get("outAccName");
                opBankName = remoteDataMap.get("outOpenBank");
                account = remoteDataMap.get("inBankAcc");
                accountName = remoteDataMap.get("inAccName");
                bankName = remoteDataMap.get("inOpenBank");
            } else if(directFlag.contains("收")) {
                opAccount = remoteDataMap.get("outBankAcc");
                opAccountName = remoteDataMap.get("outAccName");
                opBankName = remoteDataMap.get("outOpenBank");
                account = remoteDataMap.get("inBankAcc");
                accountName = remoteDataMap.get("inAccName");
                bankName = remoteDataMap.get("inOpenBank");
            } else if (directFlag.contains("付")) {
                account = remoteDataMap.get("outBankAcc");
                accountName = remoteDataMap.get("outAccName");
                bankName = remoteDataMap.get("outOpenBank");
                opAccount = remoteDataMap.get("inBankAcc");
                opAccountName = remoteDataMap.get("inAccName");
                opBankName = remoteDataMap.get("inOpenBank");
            }

            String bankJour = remoteDataMap.get("bankJour");
            if(StringUtils.isNotBlank(bankJour) && bankJour.length()>32 ){
                bankJour = bankJour.substring(0,32);
            }
            //occurTime处理为HH:mm:ss
            String occurTime = remoteDataMap.get("occurTime");
            if (StringUtils.isNotBlank(occurTime)){
                SimpleDateFormat sdf = new SimpleDateFormat(TIME_PATTERN);
                try {
                    occurTime = DateUtil.formatTime(sdf.parse(occurTime));
                } catch (ParseException e) {
                    log.error("时间转化失败!", e);
                }

            }
            result.add(MjAccountSeqInfoEntity.builder()
                    .fundCode(remoteDataMap.get("fundCode"))
                    .fundName(remoteDataMap.get("fundName"))
                    .transferDate(remoteDataMap.get("occurDate"))
                    .transferTime(occurTime)
                    .opAccount(opAccount)
                    .opAccountName(opAccountName)
                    .opBankName(opBankName)
                    .account(account)
                    .accountName(accountName)
                    .bankName(bankName)
                    .transferInOut(directFlag)
                    .amount(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("occurAmt")))
                    .balance(BigDecimalUtil.obj2BigDecimal(remoteDataMap.get("acctBal")))
                    .summary(remoteDataMap.get("ftNote"))
                    .remark(remoteDataMap.get("bz"))
                    .remark(remoteDataMap.get("bz"))
                    .seqNo(bankJour)
                    .currency("156")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build());
        }
        return result;
    }

    private void processT0215Data(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastDay;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        loopNum = loopNum == 1 ? 30 : 365;
        for (int i = 0; i < loopNum; i++) {
            lastDay = localDate.minusDays(1);
            startDate = dateTimeFormatter.format(lastDay);
            String finalStartDate = startDate;
            String finalEndDate = startDate;
            try {
                //1、封装请求参数
                HashMap<String, Object> params = new HashMap<>();
                int pageSize = 100;
                String api = HaiTongConstants.QUERY_ACCOUNT_JOURNAL;
                List<JSONObject> objects = new ArrayList<>();
                int pageNo = 0;
                do {
                    pageNo++;
                    String requestNum = String.valueOf(pageSize);
                    String pageNoStr = String.valueOf(pageNo);
                    params.put("requestPageno", pageNoStr);
                    params.put("requestNum", requestNum);
                    params.put("beginDate", finalStartDate);
                    params.put("endDate", finalEndDate);
                    String jsonString = JSON.toJSONString(params);
                    //2、获取远端数据
                    Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                    if(CollectionUtils.isEmpty(stringObjectMap)){
                        log.error("processT0215Data 查询结果为空，终止查询");
                        break;
                    }
                    boolean result = (boolean) stringObjectMap.get("result");
                    if (result) {
                        objects = (List<JSONObject>) stringObjectMap.get("data");
                        String totalCount = (String) stringObjectMap.get("totalCount");
                        Integer totalCountInt = Integer.valueOf(totalCount);
                        if (!CollectionUtils.isEmpty(objects)) {
                            //3、封装成标准表的对象
                            List<TgAccountSeqInfoEntity> entities = getTgAccountSeqInfo(tenant, objects, trustNo);
                            log.info("海通processT0215Data封装数据为：{}", entities.size());
                            //4、调用 basicservice 的保存数据接口
                            tgAccountSeqInfoService.saveData(null, entities);
                        }
                        log.info("海通processT0215Data现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                        if (pageNo * pageSize > totalCountInt) {
                            log.info("海通processT0215Data查询入库结束");
                            break;
                        }
                    }
                } while (objects != null && objects.size() == pageSize);

            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processT0215Data:", e);
            }
            localDate = lastDay;
        }
    }

    public List<TgAccountSeqInfoEntity> getTgAccountSeqInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> currencyDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CURRENCY_SERVICE, trustNo);
        Map<String, String> paymentDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PAYMENT_DIRECTION_SERVICE, trustNo);

        log.info("getTgAccountSeqInfo{}",JSON.toJSONString(remoteDatas));

        //2、封装数据
        List<TgAccountSeqInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
            String occurTime = remoteDataMap.get("occurTime");
            String[] s = new String[2];
            if(StringUtils.isNotBlank(occurTime)){
                s = occurTime.split(" ");
            }
            log.info("t0215 occurTime={},s={}",occurTime,Arrays.toString(s));

            result.add(TgAccountSeqInfoEntity.builder()
                    .currency(MatchDataDictionaryKeyUtil.getKey(currencyDir, remoteDataMap.get("curType")))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .fundName(remoteDataMap.get("fundName"))
                    .transferInOut(MatchDataDictionaryKeyUtil.getKey(paymentDir, remoteDataMap.get("directFlag")))
                    .account(remoteDataMap.get("bankAcco"))
                    .accountName(remoteDataMap.get("accName"))
                    .bankName(remoteDataMap.get("openBankName"))
                    .opAccount(remoteDataMap.get("othBankAcco"))
                    .opAccountName(remoteDataMap.get("othAccName"))
                    .opBankName(remoteDataMap.get("othOpenBankName"))
                    .amount(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("occurAmt")))
                    .transferDate(s[0])
                    .transferTime(s[1])
                    .summary(remoteDataMap.get("bankNote"))
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build()
            );
        }
        return result;
    }

    //18 净值查询
    public void processFundNetValueData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        //参数来源 fund_info：fund_code
        List<String> fundCodeList = fundInfoService.getFundCodeList(tenant.getTrustNo(),tenant.getTenantName());

        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);
        for (String fundCode : fundCodeList) {
            log.info("processFundNetValueData_入参fundCode为{}",fundCode);
            String startDate;
            String endDate;
            LocalDate localDate = LocalDate.now();
            LocalDate lastMonth;
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            endDate = dateTimeFormatter.format(localDate);
            for (int i = 0; i < loopNum; i++) {
                lastMonth = localDate.minusMonths(1);
                startDate = dateTimeFormatter.format(lastMonth);
                String finalStartDate = startDate;
                String finalEndDate = endDate;
                try {
                    //1、封装请求参数
                    HashMap<String, Object> params = new HashMap<>();
                    int pageSize = 100;

                    String api = HaiTongConstants.FUND_NET_VALUE_INFO;
                    List<JSONObject> objects = new ArrayList<>();

                    int pageNo = 0;
                    do {
                        pageNo++;
                        String requestNum = String.valueOf(pageSize);
                        String pageNoStr = String.valueOf(pageNo);
                        params.put("fundCode", fundCode);
                        params.put("requestPageno", pageNoStr);
                        params.put("requestNum", requestNum);
                        params.put("netDateBegin", finalStartDate);
                        params.put("netDateEnd", finalEndDate);
                        String jsonString = JSON.toJSONString(params);
                        //2、获取远端数据
                        Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                        if(CollectionUtils.isEmpty(stringObjectMap)){
                            log.error("processFundNetValueData 查询结果为空，终止查询");
                            break;
                        }
                        boolean result = (boolean) stringObjectMap.get("result");
                        if (result) {
                            objects = (List<JSONObject>) stringObjectMap.get("data");
                            String totalCount = (String) stringObjectMap.get("totalCount");
                            Integer totalCountInt = Integer.valueOf(totalCount);
                            if (!CollectionUtils.isEmpty(objects)) {
                                //3、封装成标准表的对象 //
                                List<FundNetValueInfoEntity> entities = getFundNetValueInfo(tenant, objects, trustNo);
                                //4、调用 basicservice 的保存数据接口
                                fundNetValueInfoService.saveData(null, entities);
                            }
                            log.info("海通processFundNetValueData现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                            if (pageNo * pageSize > totalCountInt) {
                                log.info("海通processFundNetValueData查询入库结束");
                                break;
                            }
                        }
                    } while (objects != null && objects.size() == pageSize);

                } catch (Exception e) {
                    log.error("OutsourceHaiTongServiceImpl:processFundNetValueData:", e);
                }
                localDate = lastMonth;
                endDate = startDate;
            }
        }
    }

    /**
     * 邮件主题eg： 20221013通怡明曦2号私募证券投资基金估值表
     * @param tenant
     * @param trustNo
     * @param loopNum
     */
    public void processFundValueTableAndFundNetValueByEmail(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        log.info("processFundValueTableAndFundNetValueByEmail入参tenant={},trustNo={},loopNum={}",tenant,trustNo,loopNum);
        List<TenantEmailAuthorizationInfoEntity> tenantEmailAuthorizationInfoEntities = tenantEmailInfoService.queryByTenantName(tenant.getTenantName(), trustNo);
        for (TenantEmailAuthorizationInfoEntity tenantEmail : tenantEmailAuthorizationInfoEntities) {
            String purpose = EmailConfigPurposeEnum.ALL.getPurpose();
            log.info("processFundValueTableAndFundNetValueByEmail:ALL.getPurpose={},tenantEmail.getPurpose={}",purpose,tenantEmail.getPurpose());
            if(purpose.equals(tenantEmail.getPurpose())){
                log.info("processFundValueTableAndFundNetValueByEmail 配置为all,跳过");
                continue;
            }
            if (!ObjectUtils.isEmpty(tenantEmail)) {
                try {
                    //获取邮件
                    LocalDate localDate = LocalDate.now();
                    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
                    String startTime = dateTimeFormatter.format(localDate.minusMonths(loopNum));
                    log.info("过滤邮件时间:{}", startTime);
                    //拿到所有邮件
                    //Message[] weMessage = MailUtil.getWEMessage(tenantEmail.getEmailHost(), tenantEmail.getEmailAddress(), tenantEmail.getEmailSecret(), ZhongXinConstants.PROTOCOL);
                    Message[] weMessage = MailUtil.getMessageByTenantEmail(tenantEmail);
                    //快速筛选 方便测试
//                    log.info("updateTotalAsset_tenantEmail={}", JSON.toJSONString(tenantEmail));
//                    Message[] filterMessage = new Message[800];
//                    System.arraycopy(weMessage, weMessage.length - 2000, filterMessage, 0, 800);

                    //过滤符合条件的邮件
                    List<Message> messages = MailUtil.filterMessage(weMessage,
                            tenantEmail.getFromEmail(),
                            startTime,
                            tenantEmail.getEmailSubject(),
                            Boolean.TRUE);

                    //打印邮件相关信息 并且更新（ todo ）
                    if(!CollectionUtils.isEmpty(messages)){
                        log.info("processFundValueTableAndFundNetValueByEmail_拿到的messages数量为{}",messages.size());
                        String dirFilePath = tenantEmail.getDirFilePath();
                        if (StringUtils.isBlank(dirFilePath)) {
                            dirFilePath = mailNewUtils.getDefaultAttachmentParentPath(tenantEmail);
                        }
                        for (Message message : messages) {
                            MailUtil.printMailInfo(message, null,tenant);
                            if (StringUtils.isNotBlank(dirFilePath)) {
                                mailNewUtils.saveAttachment(message, dirFilePath);
                            }
                            // todo 处理邮件
                            try {
                                MailUtil re = new MailUtil((MimeMessage) message);
                                handleHaiTongEmailMessage(message, tenant, re.getSubject());
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }
                    }else{
                        log.error("海通processFundValueTableAndFundNetValueByEmail 过滤后messages信息为空");
                    }


                } catch (ParseException pe) {
                    pe.printStackTrace();
                    log.error("时间转化异常！", pe);
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                    log.error("分析邮件异常！", ioe);
                } catch (MessagingException me) {
                    me.printStackTrace();
                    log.error("获取邮件异常！", me);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("更新中信totalAsset异常！", e);
                }
            }
        }
    }

    public static final String NET_VALUE_TABLE = "估值表";

    public static final String START_ROW_FLAG = "科目代码";

    public static final String TOTAL_ASSERT_ROW = "资产类合计";

    public static final String TOTAL_ASSERT_ROW_WITH_COLON = "资产类合计:";

    //不含中文
    public static final Pattern pattern = Pattern.compile("[^\\u4e00-\\u9fa5]+");

    public static final String DEFAULT_PATTERN = "yyyyMMdd";

    /**
     * 更新totalAsset
     *
     * @param part
     * @throws MessagingException
     * @throws IOException
     */
    public void handleEmailMessage(Part part, TenantEscrowAuthorizationInfoDto tenant, String subject) throws MessagingException, IOException, ParseException {
        String fileName;
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            BodyPart mPart;
            for (int i = 0; i < mp.getCount(); i++) {
                try{
                    mPart = mp.getBodyPart(i);
                    fileName = mPart.getFileName();
                    // eg:SLK277_通怡青桐2号私募证券投资基金_2022-10-13估值表.xls
                    if ((fileName != null)) {
                        fileName = MailUtil.decodeText(fileName);

                        //保存文件
                        /*String parentPath = "D:\\temp\\";
                        File file = new File(parentPath);
                        file.mkdirs();
                        OutsourceZhongXinService.getFile(mPart.getInputStream(),parentPath+fileName);
                        */

                        log.info("temp:subject={}",subject);
                        //fileName =   new   String(fileName.getBytes(),"GB2312");
                        //ali String date = subject.substring(subject.indexOf("资产估值表_") + 6, subject.indexOf("_4级.xls"));
                        //String date = subject.substring(subject.indexOf("资产估值表_") + 6, subject.indexOf(".xls")==-1?subject.length():subject.indexOf(".xls"));
                        String date = StrUtil.getDateStrFromStringByPattern(subject, MailUtil.DATE_PATTERN);
                        log.info("fileName:{}", fileName);
                        //fundCode
                        String fundCode = fileName.substring(0, fileName.indexOf("_"));

                        //date
                        String suffixName = StringUtils.substringAfterLast(fileName, "_");
                        String fundNetDate = StringUtils.substringBefore(suffixName, NET_VALUE_TABLE);
                        String valueDate = fundNetDate.replace("-", "");

                        //valueDate = minusDays(valueDate,DEFAULT_PATTERN,1);

                        //fundName
                        String fundNameWithPreffix = StringUtils.substringBeforeLast(fileName, "_");
                        String fundName = StringUtils.substringAfter(fundNameWithPreffix, "_");

                        Workbook workbook = ExcelWriteUtil.getWorkbook(mPart.getInputStream());
                        Sheet sheetAt = workbook.getSheetAt(0);
                        boolean flag = false;
                        int rowNum = 0;
                        List<FundValueTableDataInfoEntity> entities = new ArrayList<>();
                        for (Row row : sheetAt) {
                            rowNum ++;
                            try{
                                if(Objects.isNull(row) || Objects.isNull(row.getCell(0))){
                                    flag = false;
                                    continue;
                                }
                                if(row.getCell(0).getCellTypeEnum().equals(CellType.STRING) && START_ROW_FLAG.equals(ExcelUtils.getStringValue(row.getCell(0)))){
                                    flag = true;
                                    continue;
                                }
                                //更新数据 fundValueDataInfo
                                if(flag){
                                    String cellx0 = ExcelUtils.getStringValue(row.getCell(0));
                                    boolean matches = pattern.matcher(cellx0).matches();
                                    if(!matches){
                                        log.info("该行第一个单元格内容为{},含有中文，跳过查询下一行",cellx0);
                                        flag = false;
                                        continue;
                                    }

                                    if(StringUtils.isBlank(cellx0)){
                                        log.info("该行第一个单元格内容为空,含有中文，跳过查询下一行",cellx0);
                                        flag = false;
                                        continue;
                                    }

                                    char keyChar = 'a';
                                    HashMap<Character,String> dataMap = new HashMap<>();
                                    for (int j = 0; j < 11; j++) {
                                        Cell cell = row.getCell(j);
                                        String stringValue = ExcelUtils.getStringValue(cell);
                                        dataMap.put(keyChar,stringValue);
                                        keyChar ++;
                                    }
                                    log.info("海通估值表邮件解析第{}行，拿到的内容{}",rowNum,JSON.toJSONString(dataMap));

                                    FundValueTableDataInfoEntity build = FundValueTableDataInfoEntity.builder()
                                            .fundCode(fundCode)
                                            .fundName(fundName)
                                            .valueDate(valueDate)
                                            .kmCode(StringUtils.isBlank(dataMap.get('a'))?null:dataMap.get('a'))
                                            .kmName(StringUtils.isBlank(dataMap.get('b'))?null:dataMap.get('b'))
                                            .currency("156")
                                            .amount(StringUtils.isBlank(dataMap.get('c'))?null:new BigDecimal(dataMap.get('c')))  //  c列
                                            .perCost(StringUtils.isBlank(dataMap.get('d'))?null:new BigDecimal(dataMap.get('d')))  // d列
                                            .portCost(StringUtils.isBlank(dataMap.get('e'))?null:new BigDecimal(dataMap.get('e')))  // e列
                                            .costBi(StringUtils.isBlank(dataMap.get('f'))?null:new BigDecimal(dataMap.get('f')))  // f列
                                            .vapPrice(StringUtils.isBlank(dataMap.get('g'))?null:new BigDecimal(dataMap.get('g')))  // g列
                                            .portMv(StringUtils.isBlank(dataMap.get('h'))?null:new BigDecimal(dataMap.get('h')))  // h列
                                            .mvBl(StringUtils.isBlank(dataMap.get('i'))?null:new BigDecimal(dataMap.get('i')))  // i列
                                            .portIv(StringUtils.isBlank(dataMap.get('j'))?null:new BigDecimal(dataMap.get('j')))  // j列
                                            .suspension(StringUtils.isBlank(dataMap.get('k'))?null:dataMap.get('k'))  // k列
                                            .trustNo("21")
                                            .admin(tenant.getTenantName())
                                            .updateTime(new Date())
                                            .build();

                                    log.info("拿到的fundValueTableDataInfoEntity为{}",JSON.toJSONString(build));

                                    entities.add(build);
                                    //fundValueTableDataInfoService.updateFundValueTabelEntity(build);
                                }
                                //更新数据 fundNetValueInfo 更新资产合计
                                /*if (ExcelUtils.getStringValue(row.getCell(0)).contains(TOTAL_ASSERT_ROW)) {
                                    Cell cell = row.getCell(7);
                                    String stringCellValue = ExcelUtils.getStringValue(cell);*/
                                if (row != null
                                        && row.getCell(0) != null
                                        && (row.getCell(0).getStringCellValue()).contains(TOTAL_ASSERT_ROW)) {
                                    //获取
                                    double numericCellValue = row.getCell(7).getNumericCellValue();
                                    log.info("admin : {}, fundCode：{}，netValueDate{}, 资产类合计值是：{}", tenant.getTenantName(), fundCode, valueDate, numericCellValue);
                                    //更新数据

                                    FundNetValueInfoEntity build = FundNetValueInfoEntity.builder()
                                            .totalAsset(BigDecimalUtil.obj2BigDecimalTrunToZero(numericCellValue))
                                            .updateTime(new Date())
                                            .createTime(new Date())
                                            .trustNo("21")
                                            .admin(tenant.getTenantName())
                                            .fundCode(fundCode)
                                            .netValueDate(valueDate)
                                            .build();

                                    log.info("海通更新资产合计字段{}",JSON.toJSONString(build));

                                    fundNetValueInfoService.updateTotalAsset(build);
                                }
                            }catch (Exception e){
                                log.error("海通估值表邮件解析第{}行异常,尝试解析下一行",rowNum,e);
                                continue;
                            }
                        }
                        if(!CollectionUtils.isEmpty(entities)){
                            log.info("从subject:{}中获取fundValueTableData 共计{}条",subject,entities.size());
                            fundValueTableDataInfoService.saveData(null,entities);
                        }else{
                            log.error("从subject:{}中未获得fundValueTableData",subject);
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    continue;
                }

            }
        }
    }

    public void handleHaiTongEmailMessage(Part part, TenantEscrowAuthorizationInfoDto tenant, String subject) throws MessagingException, IOException, ParseException {
        log.info("海通处理邮件 getTotalAsset tenant={} subject={}",JSON.toJSONString(tenant),subject);
        String fileName;
        Map<String, String> currencyDict = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CURRENCY_SERVICE, tenant.getTrustNo());//币种
        Map<String, String> typeOfFundValuation = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.TYPE_OF_FUND_VALUATION, tenant.getTrustNo());
        Map<String, String> fundValuationMap = typeOfFundValuationService.queryKeyValue();

        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            BodyPart mPart;
            for (int i = 0; i < mp.getCount(); i++) {
                try{
                    mPart = mp.getBodyPart(i);
                    fileName = mPart.getFileName();
                    if ((fileName != null)) {
                        fileName = MailUtil.decodeText(fileName);
                        HSSFWorkbook hssfWorkbook = new HSSFWorkbook(mPart.getInputStream());
                        HSSFSheet sheet = hssfWorkbook.getSheetAt(0);
                        HaitongEmailDto haitongEmailDto = parseExcelHaiTong(sheet, fileName, typeOfFundValuation, fundValuationMap);
                        log.info("haitongEmailDto:{}",haitongEmailDto);
                        FundNetValueInfoEntity fundNetValueInfo = haitongEmailDto.getFundNetValueInfoEntity();
                        fundNetValueInfo.setAdmin(tenant.getTenantName());
                        fundNetValueInfo.setTrustNo(tenant.getTrustNo());
                        fundNetValueInfo.setUpdateTime(new Date());
                        //更新资产合计
                        log.info("海通更新资产合计:{}",fundNetValueInfo);
                        fundNetValueInfoService.updateTotalAsset(fundNetValueInfo);
                        //更新估值表
                        List<FundValueTableDataInfoEntity> fundValueTableDataInfoList = haitongEmailDto.getFundValueTableDataInfoEntity();

                        if (!CollectionUtils.isEmpty(fundValueTableDataInfoList)){
                            for (FundValueTableDataInfoEntity entity: fundValueTableDataInfoList
                            ) {
                                entity.setAdmin(tenant.getTenantName());
                                entity.setTrustNo(tenant.getTrustNo());
                                entity.setCreateTime(new Date());
                                entity.setUpdateTime(new Date());
                            }
                        }
                        fundValueTableDataInfoService.saveData(null,fundValueTableDataInfoList);

                        // fundValuation
                        List<FundValuationEntity> fundValuationEntityList = haitongEmailDto.getFundValuationEntityList();
                        if (!CollectionUtils.isEmpty(fundValuationEntityList)){
                            for (FundValuationEntity entity: fundValuationEntityList
                            ) {
                                entity.setAdmin(tenant.getTenantName());
                                entity.setTrustNo(tenant.getTrustNo());
                                entity.setCreateTime(new Date());
                                entity.setUpdateTime(new Date());
                            }
                        }
                        fundValuationService.saveData(null, fundValuationEntityList);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 匹配yyyy-MM-dd格式时间
     */
    public static final String YEAR_MONTH_DAY_REGEX = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)$";

    /**
     * 海通邮件解析
     * @param
     * @param sheet
     * @param
     * @return
     */
    public HaitongEmailDto parseExcelHaiTong(HSSFSheet sheet, String fileName, Map<String, String> fundValuationDic, Map<String, String> keyValueMap) {
        String fundName = null;
        String fundCode = null;
        String fundValueDate = null;
        BigDecimal totalAsset = new BigDecimal(0);
        HaitongEmailDto result = new HaitongEmailDto();
        int LAST_ROW_OF_SUBJECT_CODE = outsourceZhongXinService.getLastRowOfSubjectCode(sheet);
        List<FundValueTableDataInfoEntity> fundValueTableDataInfoEntityList = new ArrayList<>();
        List<FundValuationEntity> fundValuationEntityList = new ArrayList<>();
        Pattern yyyyMMddPattern = Pattern.compile(YEAR_MONTH_DAY_REGEX);

        for (int rowNum=0; rowNum <=sheet.getLastRowNum(); rowNum++){
            HSSFRow sheetRow = sheet.getRow(rowNum);
            if (sheetRow == null){
                continue;
            }
            for (int cellNum = 0; cellNum <= sheetRow.getLastCellNum(); cellNum++) {
                HSSFCell cell = sheetRow.getCell(cellNum);
                if (cell == null){
                    continue;
                }
                //通过文件名获取基金编码,估值日期  SJV203_凌顶十一号私募证券投资基金_2023-01-31估值表
                Matcher matcher = yyyyMMddPattern.matcher(fileName);
                if (matcher.find()) {
                    fundValueDate = matcher.group().replaceAll("-", "");
                } else {
                    log.error("海通上游excel文件名格式变化fundValueDate无法解析，fundValueDate:{}", fileName);

                }
                if (fileName.contains("_")) {
                    String[] strings = fileName.trim().split("_");
                    fundCode = strings[0];
                    fundName = strings[1];
                } else {
                    log.error("海通上游excel文件名格式变化fundCode/fundName无法解析，fundCode:{}", fileName);
                }
                //获取资产合计
                if (TOTAL_ASSERT_ROW_WITH_COLON.equals(OutsourceZhongXinService.getValue(cell))) {
                    HSSFCell totalAssetCell = sheetRow.getCell(7);
                    if (totalAssetCell == null) {
                        log.error("海通上游excel格式变化,资产合计无法解析，fundName:{}", fundName);
                    }else {
                        double totalAssetDouble = totalAssetCell.getNumericCellValue();
                        totalAsset = BigDecimalUtil.obj2BigDecimalTrunToZero(totalAssetDouble);
                    }
                }
                //解析估值表数据 获取A列非中文字段
                if (cell.getColumnIndex() == 0
                        && !CellType.BLANK.equals(cell.getCellTypeEnum())
                        && !"".equals(OutsourceZhongXinService.getValue(cell))
                        && cell.getRowIndex() > LAST_ROW_OF_SUBJECT_CODE) {
                    String kmCode = OutsourceZhongXinService.getValue(cell);
                    String kmName = sheetRow.getCell(1) != null ? OutsourceZhongXinService.getValue(sheetRow.getCell(1)) : null;
                    BigDecimal amount = OutsourceZhongXinService.getBigDecimalFromCell(ExcelUtils.getStringValue(sheetRow.getCell(2)));
                    BigDecimal perCost = OutsourceZhongXinService.getBigDecimalFromCell(ExcelUtils.getStringValue(sheetRow.getCell(3)));
                    BigDecimal portCost = OutsourceZhongXinService.getBigDecimalFromCell(ExcelUtils.getStringValue(sheetRow.getCell(4)));
                    BigDecimal costBi = OutsourceZhongXinService.getBigDecimalFromCell(ExcelUtils.getStringValue(sheetRow.getCell(5)));
                    BigDecimal vapPrice = OutsourceZhongXinService.getBigDecimalFromCell(ExcelUtils.getStringValue(sheetRow.getCell(6)));
                    BigDecimal portMv = OutsourceZhongXinService.getBigDecimalFromCell(ExcelUtils.getStringValue(sheetRow.getCell(7)));
                    BigDecimal mvBl = OutsourceZhongXinService.getBigDecimalFromCell(ExcelUtils.getStringValue(sheetRow.getCell(8)));
                    BigDecimal portIv = OutsourceZhongXinService.getBigDecimalFromCell(ExcelUtils.getStringValue(sheetRow.getCell(9)));
                    String suspension = sheetRow.getCell(10) != null ? OutsourceZhongXinService.getValue(sheetRow.getCell(10)) : null;

                    FundValueTableDataInfoEntity entity = FundValueTableDataInfoEntity.builder()
                            .fundCode(fundCode)
                            .fundName(fundName)
                            .valueDate(fundValueDate)
                            .kmCode(kmCode)
                            .kmName(kmName)
                            .currency("156")
                            .amount(amount)
                            .perCost(perCost)
                            .portCost(portCost)
                            .costBi(costBi)
                            .vapPrice(vapPrice)
                            .portMv(portMv)
                            .mvBl(mvBl)
                            .portIv(portIv)
                            .suspension(suspension)
                            .build();
                    fundValueTableDataInfoEntityList.add(entity);
                    // 新增估值表
                    //获取估值表kmCode估值表
                    String targetKmCode = MatchDataDictionaryKeyUtil.getKey(fundValuationDic, kmCode);
                    String targetKmName = keyValueMap.get(targetKmCode);
                    if (StringUtils.isNotBlank(targetKmCode)) {
                        FundValuationEntity fundValuationEntity = FundValuationEntity.builder()
                                .fundCode(fundCode)
                                .fundName(fundName)
                                .valueDate(fundValueDate)
                                .kmCode(targetKmCode)
                                .kmName(targetKmName)
                                .currency("156")
                                .amount(amount)
                                .perCost(perCost)
                                .portCost(portCost)
                                .costBi(costBi)
                                .vapPrice(vapPrice)
                                .portMv(portMv)
                                .mvBl(mvBl)
                                .portIv(portIv)
                                .suspension(suspension)
                                .build();
                        fundValuationEntityList.add(fundValuationEntity);
                    }
                }
            }

        }
        FundNetValueInfoEntity fundNetValueInfo = FundNetValueInfoEntity.builder()
                .fundCode(fundCode)
                .totalAsset(totalAsset)
                .netValueDate(fundValueDate)
                .build();
        result.setFundNetValueInfoEntity(fundNetValueInfo);
        result.setFundValueTableDataInfoEntity(fundValueTableDataInfoEntityList);
        result.setFundValuationEntityList(fundValuationEntityList);
        return result;

    }
    private  String minusDays(String valueDate, String defaultPattern, int i) {
        log.info("minusDays:valueDate={},defaultPattern={},i={}",valueDate,defaultPattern,i);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(defaultPattern);
        LocalDate localDate = LocalDate.parse(valueDate,dateTimeFormatter );
        LocalDate localDate1 = localDate.minusDays(i);
        String format = dateTimeFormatter.format(localDate1);
        return format;
    }

    public void processFundFeeDataInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo, int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0; i < loopNum; i++) {
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            try {
                //1、封装请求参数
                HashMap<String, Object> params = new HashMap<>();
                int pageSize = 100;
                String api = HaiTongConstants.FUND_FEE_DATA_INFO;
                List<JSONObject> objects = new ArrayList<>();
                int pageNo = 0;
                do {
                    pageNo++;
                    String requestNum = String.valueOf(pageSize);
                    String pageNoStr = String.valueOf(pageNo);
                    params.put("requestPageno", pageNoStr);
                    params.put("requestNum", requestNum);
                    params.put("beginDate", finalStartDate);
                    params.put("endDate", finalEndDate);
                    String jsonString = JSON.toJSONString(params);
                    //2、获取远端数据
                    Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                    if(CollectionUtils.isEmpty(stringObjectMap)){
                        log.error("processFundFeeDataInfoData 查询结果为空，终止查询");
                        break;
                    }
                    boolean result = (boolean) stringObjectMap.get("result");
                    if (result) {
                        objects = (List<JSONObject>) stringObjectMap.get("data");
                        String totalCount = (String) stringObjectMap.get("totalCount");
                        Integer totalCountInt = Integer.valueOf(totalCount);
                        if (!CollectionUtils.isEmpty(objects)) {
                            //3、封装成标准表的对象
                            List<FundFeeDataInfoEntity> entities = getFundFeeDataInfo(tenant, objects, trustNo);
                            log.info("海通processFundFeeDataInfoData封装数据为：{}", entities.size());
                            //4、调用 basicservice 的保存数据接口
                            fundFeeDataInfoService.saveData(null, entities);
                        }
                        log.info("海通processFundFeeDataInfoData现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                        if (pageNo * pageSize > totalCountInt) {
                            break;
                        }
                    }
                } while (objects != null && objects.size() == pageSize);

            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processFundFeeDataInfoData:", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }

    public List<FundFeeDataInfoEntity> getFundFeeDataInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> objects, String trustNo) {
        //获取字典
        //封装数据
        List<FundFeeDataInfoEntity> entityList = new ArrayList<>();
        Map<String, String> remoteDataMap;
        for (JSONObject remoteData : objects){
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);
            //管理费
            entityList.add(FundFeeDataInfoEntity.builder()
                    .fundName(remoteDataMap.get("fundName"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .confirmDate(remoteDataMap.get("endDate"))
                    .fareDebit(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("managementFee")))
                    .fareUnpaid(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("managementFeeBal")))
                    .subjectCode("GLF")
                    .subjectName("管理费")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
            //外包服务费
            entityList.add(FundFeeDataInfoEntity.builder()
                    .fundName(remoteDataMap.get("fundName"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .confirmDate(remoteDataMap.get("endDate"))
                    .fareDebit(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("outsourceFee")))
                    .fareUnpaid(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("outsourceFeeBal")))
                    .subjectCode("WBF")
                    .subjectName("外包服务费")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
            //托管费
            entityList.add(FundFeeDataInfoEntity.builder()
                    .fundName(remoteDataMap.get("fundName"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .confirmDate(remoteDataMap.get("endDate"))
                    .fareDebit(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("custodianFee")))
                    .fareUnpaid(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("custodianFeeBal")))
                    .subjectCode("TGF")
                    .subjectName("托管费")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
            //销售服务费
            entityList.add(FundFeeDataInfoEntity.builder()
                    .fundName(remoteDataMap.get("fundName"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .confirmDate(remoteDataMap.get("endDate"))
                    .fareDebit(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("salesFee")))
                    .fareUnpaid(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("salesFeeBal")))
                    .subjectCode("XSF")
                    .subjectName("销售服务费")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
            //增值税
            entityList.add(FundFeeDataInfoEntity.builder()
                    .fundName(remoteDataMap.get("fundName"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .confirmDate(remoteDataMap.get("endDate"))
                    .fareDebit(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("payableValueAddedTax")))
                    .fareUnpaid(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("payableValueAddedTaxBal")))
                    .subjectCode("ZZS")
                    .subjectName("增值税")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
            //附加税
            entityList.add(FundFeeDataInfoEntity.builder()
                    .fundName(remoteDataMap.get("fundName"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .confirmDate(remoteDataMap.get("endDate"))
                    .fareDebit(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("payableSurtax")))
                    .fareUnpaid(BigDecimalUtil.obj2BigDecimalTrunToZero(remoteDataMap.get("payableSurtaxBal")))
                    .subjectCode("FJS")
                    .subjectName("附加税")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(new Date())
                    .updateTime(new Date())
                    .build());
        }
        return entityList;
    }

    //处理01.
    private void processFundInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo,int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        try {

            //1、封装请求参数
            HashMap<String, Object> params = new HashMap<>();
            int pageSize = 100;

            String api = HaiTongConstants.FUND_INFO_API;
            List<JSONObject> objects = new ArrayList<>();

            int pageNo = 0;
            do{
                pageNo++;
                String requestNum = String.valueOf(pageSize);
                String pageNoStr = String.valueOf(pageNo);
                params.put("requestNum",requestNum);
                params.put("requestPageno",pageNoStr);
                String jsonString = JSON.toJSONString(params);
                //2、获取远端数据
                Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                if(CollectionUtils.isEmpty(stringObjectMap)){
                    log.error("processFundInfoData 查询结果为空，终止查询");
                    break;
                }
                boolean result = (boolean)stringObjectMap.get("result");
                if(result){
                    objects = (List<JSONObject>) stringObjectMap.get("data");
                    String totalCount = (String) stringObjectMap.get("totalCount");
                    Integer totalCountInt = Integer.valueOf(totalCount);
                    if (!CollectionUtils.isEmpty(objects)) {
                        //3、封装成标准表的对象 //
                        List<FundInfoEntity> entities = getFundInfoData(tenant, objects, trustNo);
                        //4、调用 basicservice 的保存数据接口
                        fundInfoService.saveData(null, entities);
                    }
                    log.info("海通processFundInfoData现查询页为{}，页容量为{}，总数为{}",pageNo,pageSize,totalCountInt);
                    if(pageNo*pageSize>totalCountInt){
                        log.info("海通processFundInfoData查询入库结束");
                        break;
                    }
                }
            }while (objects!=null && objects.size() == pageSize);

        } catch (Exception e) {
            log.error("OutsourceHaiTongServiceImpl:processFundInfoData:", e);
        }
    }

    //处理02.
    public void processInvestorInfoAndInvestorBankInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo,int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        try {

            //1、封装请求参数
            HashMap<String, Object> params = new HashMap<>();
            int pageSize = 100;


            String api = HaiTongConstants.CUST_INFO_API;
            List<JSONObject> objects = new ArrayList<>();

            int pageNo = 0;
            do{
                pageNo++;
                String requestNum = String.valueOf(pageSize);
                String pageNoStr = String.valueOf(pageNo);
                params.put("requestNum",requestNum);
                params.put("requestPageno",pageNoStr);
                String jsonString = JSON.toJSONString(params);
                //2、获取远端数据
                Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                if(CollectionUtils.isEmpty(stringObjectMap)){
                    log.error("processInvestorInfoAndInvestorBankInfoData 查询结果为空，终止查询");
                    break;
                }
                boolean result = (boolean)stringObjectMap.get("result");
                if(result){
                    objects = (List<JSONObject>) stringObjectMap.get("data");
                    String totalCount = (String) stringObjectMap.get("totalCount");
                    Integer totalCountInt = Integer.valueOf(totalCount);
                    if (!CollectionUtils.isEmpty(objects)) {
                        //3、封装成标准表的对象 //
                        List<InvestorInfoEntity> entities = getInvestorInfoData(tenant, objects, trustNo);
                        //4、调用 basicservice 的保存数据接口
                        investorInfoService.saveData(null, entities);

                        List<InvestorBankInfoEntity> investorBankInfo = getInvestorBankInfo(tenant, objects, trustNo);
                        investorBankInfoService.saveData(null,investorBankInfo);

                    }
                    log.info(" 海通processInvestorInfoAndInvestorBankInfoData现查询页为{}，页容量为{}，总数为{}",pageNo,pageSize,totalCountInt);
                    if(pageNo*pageSize>totalCountInt){
                        log.info("海通processInvestorInfoAndInvestorBankInfoData查询入库结束");
                        break;
                    }
                }
            }while (objects!=null && objects.size() == pageSize);

        } catch (Exception e) {
            log.error("processInvestorInfoAndInvestorBankInfoData", e);
        }
    }

    //处理04.
    private void processCustShareInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo,int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        try {

            //1、封装请求参数
            HashMap<String, Object> params = new HashMap<>();
            List<CustShareInfoEntity> entityList = new ArrayList<>();
            int pageSize = 100;

            String api = HaiTongConstants.CUST_SHARE_INFO_API;
            List<JSONObject> objects = new ArrayList<>();

            int pageNo = 0;
            do{
                pageNo++;
                //2、获取远端数据
                String requestNum = String.valueOf(pageSize);
                String pageNoStr = String.valueOf(pageNo);
                params.put("requestNum",requestNum);
                params.put("requestPageno",pageNoStr);
                String jsonString = JSON.toJSONString(params);
                Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                if(CollectionUtils.isEmpty(stringObjectMap)){
                    log.error("processCustShareInfoData 查询结果为空，终止查询");
                    break;
                }
                boolean result = (boolean)stringObjectMap.get("result");
                if(result){
                    objects = (List<JSONObject>) stringObjectMap.get("data");
                    String totalCount = (String) stringObjectMap.get("totalCount");
                    Integer totalCountInt = Integer.valueOf(totalCount);
                    if (!CollectionUtils.isEmpty(objects)) {
                        //3、封装成标准表的对象 //
                        List<CustShareInfoEntity> entities = getCustShareInfo(tenant, objects, trustNo);
                        entityList.addAll(entities);
                    }
                    log.info("海通processCustShareInfoData现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                    if (pageNo * pageSize > totalCountInt) {
                        log.info("海通processFundInfoData查询入库结束");
                        break;
                    }
                }
            }while (objects!=null && objects.size() == pageSize);
            //4、调用 basicservice 的保存数据接口
            custShareInfoService.saveData(null, entityList);
        } catch (Exception e) {
            log.error("OutsourceHaiTongServiceImpl:processFundInfoData:", e);
        }
    }

    //处理09.
    private void processFundTradeInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo,int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0; i < loopNum; i++) {
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            try {
                //1、封装请求参数
                HashMap<String, Object> params = new HashMap<>();
                int pageSize = 100;


                String api = HaiTongConstants.FUND_TRADE_INFO_API;
                List<JSONObject> objects = new ArrayList<>();

                int pageNo = 0;
                do {
                    pageNo++;
                    String requestNum = String.valueOf(pageSize);
                    String pageNoStr = String.valueOf(pageNo);

                    params.put("requestPageno", pageNoStr);
                    params.put("requestNum", requestNum);
                    params.put("confDateBegin", finalStartDate);
                    params.put("confDateEnd", finalEndDate);
                    String jsonString = JSON.toJSONString(params);
                    //2、获取远端数据
                    Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                    if(CollectionUtils.isEmpty(stringObjectMap)){
                        log.error("processFundTradeInfoData 查询结果为空，终止查询");
                        break;
                    }
                    boolean result = (boolean) stringObjectMap.get("result");
                    if (result) {
                        objects = (List<JSONObject>) stringObjectMap.get("data");
                        String totalCount = (String) stringObjectMap.get("totalCount");
                        Integer totalCountInt = Integer.valueOf(totalCount);
                        if (!CollectionUtils.isEmpty(objects)) {
                            //3、封装成标准表的对象 //
                            List<FundTradeInfoEntity> entities = getFundTradeInfo(tenant, objects, trustNo);
                            //4、调用 basicservice 的保存数据接口
                            fundTradeInfoService.saveData(null, entities);
                        }
                        log.info("海通processFundTradeInfoData现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                        if (pageNo * pageSize > totalCountInt) {
                            log.info("海通processFundInfoData查询入库结束");
                            break;
                        }
                    }
                } while (objects != null && objects.size() == pageSize);

            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processFundInfoData:", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }

    //处理14
    private void processFundProfitInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo,int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0; i < loopNum; i++) {
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            try {
                //1、封装请求参数
                HashMap<String, Object> params = new HashMap<>();
                int pageSize = 100;


                String api = HaiTongConstants.FUND_PROFIT_INFO_API;
                List<JSONObject> objects = new ArrayList<>();

                int pageNo = 0;
                do {
                    pageNo++;
                    String pageNoStr = String.valueOf(pageNo);
                    String requestNum = String.valueOf(pageSize);
                    params.put("requestPageno", pageNoStr);
                    params.put("requestNum", requestNum);
                    params.put("confDateBegin", finalStartDate);
                    params.put("confDateEnd", finalEndDate);
                    String jsonString = JSON.toJSONString(params);
                    //2、获取远端数据
                    Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                    if(CollectionUtils.isEmpty(stringObjectMap)){
                        log.error("processFundProfitInfoData 查询结果为空，终止查询");
                        break;
                    }
                    boolean result = (boolean) stringObjectMap.get("result");
                    if (result) {
                        objects = (List<JSONObject>) stringObjectMap.get("data");
                        String totalCount = (String) stringObjectMap.get("totalCount");
                        Integer totalCountInt = Integer.valueOf(totalCount);
                        if (!CollectionUtils.isEmpty(objects)) {
                            //3、封装成标准表的对象 //
                            List<FundProfitInfoEntity> entities = getFundProfitInfo(tenant, objects, trustNo);
                            //4、调用 basicservice 的保存数据接口
                            fundProfitInfoService.saveData(null, entities);
                        }
                        log.info("海通processFundProfitInfoData现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                        if (pageNo * pageSize > totalCountInt) {
                            log.info("海通processFundProfitInfoData查询入库结束");
                            break;
                        }
                    }
                } while (objects != null && objects.size() == pageSize);

            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processFundProfitInfoData:", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }


    //处理15
    public void processCustShareDetailInfoData(TenantEscrowAuthorizationInfoDto tenant, String trustNo,int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        for (int i = 0; i < loopNum; i++) {
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
            String finalStartDate = startDate;
            String finalEndDate = endDate;
            try {
                //1、封装请求参数
                HashMap<String, Object> params = new HashMap<>();
                int pageSize = 100;


                String api = HaiTongConstants.CUST_SHARE_DETAIL_INFO;
                List<JSONObject> objects = new ArrayList<>();

                int pageNo = 0;
                do {
                    pageNo++;
                    String requestNum = String.valueOf(pageSize);
                    String pageNoStr = String.valueOf(pageNo);
                    params.put("requestPageno", pageNoStr);
                    params.put("requestNum", requestNum);
                    params.put("lastModifyBeg", finalStartDate);
                    params.put("lastModifyEnd", finalEndDate);
                    String jsonString = JSON.toJSONString(params);
                    //2、获取远端数据
                    Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                    if(CollectionUtils.isEmpty(stringObjectMap)){
                        log.error("processCustShareDetailInfoData 查询结果为空，终止查询");
                        break;
                    }
                    boolean result = (boolean) stringObjectMap.get("result");
                    if (result) {
                        objects = (List<JSONObject>) stringObjectMap.get("data");
                        String totalCount = (String) stringObjectMap.get("totalCount");
                        Integer totalCountInt = Integer.valueOf(totalCount);
                        if (!CollectionUtils.isEmpty(objects)) {
                            //3、封装成标准表的对象 //
                            List<CustShareDetailInfoEntity> entities = getCustShareDetailInfo(tenant, objects, trustNo);
                            //4、调用 basicservice 的保存数据接口
                            custShareDetailInfoService.saveData(null, entities);
                        }
                        log.info("海通processCustShareDetailInfoData现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
                        if (pageNo * pageSize > totalCountInt) {
                            log.info("海通processCustShareDetailInfoData查询入库结束");
                            break;
                        }
                    }
                } while (objects != null && objects.size() == pageSize);

            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processCustShareDetailInfoData:", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }


    //测试其它接口
    private void testOtherInterface(TenantEscrowAuthorizationInfoDto tenant, String trustNo,int loopNum) {
        HaitongAppSecretDTO haitongAppSecretDTO = getHaitongAppSecretDTO(tenant);

        String startDate;
        String endDate;
        LocalDate localDate = LocalDate.now();
        LocalDate lastMonth;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        endDate = dateTimeFormatter.format(localDate);
        String api = "";
        for (int i = 0; i < 7; i++) {
            HashMap<String, Object> params = new HashMap<>();

            if(i==0){
                api = HaiTongConstants.TEST_1;
                params.put("endDate","20220301");
                params.put("taAcco","123124");
                params.put("tradeAcco","1232134");
                params.put("beginDate","20220201");
            }else if(i==1){
                params.put("endDate","20220301");
                params.put("fundCode","SG685");
                params.put("beginDate","20220201");
                api = HaiTongConstants.TEST_2;
            }else if(i==2){
                params.put("confDateEnd","20220301");
                params.put("confDateBegin","20220201");
                api = HaiTongConstants.TEST_3;
            }else if(i==3){
                params.put("confDateEnd","20220301");
                params.put("confDateBegin","20220201");
                api = HaiTongConstants.TEST_4;
            }else if(i==4){
                params.put("confDateEnd","20220301");
                params.put("confDateBegin","20220201");
                api = HaiTongConstants.TEST_5;
            }else if(i==5){
                params.put("endDate","20220301");
                params.put("beginDate","20220201");
                api = HaiTongConstants.TEST_6;
            }else if(i==6){
                params.put("regDateEnd","20220301");
                params.put("regDateBeg","20220201");
                api = HaiTongConstants.TEST_7;
            }
            lastMonth = localDate.minusMonths(1);
            startDate = dateTimeFormatter.format(lastMonth);
//            String finalStartDate = startDate;
//            String finalEndDate = endDate;
            try {
                //1、封装请求参数
                int pageSize = 100;
                String requestNum = String.valueOf(pageSize);
                params.put("requestNum", requestNum);
//                params.put("lastModifyBeg", finalStartDate);
//                params.put("lastModifyEnd", finalEndDate);
                String jsonString = JSON.toJSONString(params);


                List<JSONObject> objects = new ArrayList<>();

//                int pageNo = 0;
//                do {
//                    pageNo++;
                //2、获取远端数据
                Map<String, Object> stringObjectMap = haiTongHttpUtil.sendMessage(haitongAppSecretDTO,jsonString, api, tenant, trustNo);
                if(CollectionUtils.isEmpty(stringObjectMap)){
                    log.error("testOtherInterface 查询结果为空，终止查询");
                    break;
                }
                System.err.println(i+" "+JSON.toJSONString(stringObjectMap));
//                    boolean result = (boolean) stringObjectMap.get("result");
//                    if (result) {
//                        objects = (List<JSONObject>) stringObjectMap.get("data");
//                        String totalCount = (String) stringObjectMap.get("totalCount");
//                        Integer totalCountInt = Integer.valueOf(totalCount);
//                        if (!CollectionUtils.isEmpty(objects)) {
//                            //3、封装成标准表的对象 //
//                            List<CustShareDetailInfoEntity> entities = getCustShareDetailInfo(tenant, objects, trustNo);
//                            //4、调用 basicservice 的保存数据接口
//                            custShareDetailInfoService.saveData(null, entities);
//                        }
//                        log.info("海通processCustShareDetailInfoData现查询页为{}，页容量为{}，总数为{}", pageNo, pageSize, totalCountInt);
//                        if (pageNo * pageSize > totalCountInt) {
//                            log.info("海通processCustShareDetailInfoData查询入库结束");
//                            break;
//                        }
//                    }
//                } while (objects != null && objects.size() == pageSize);

            } catch (Exception e) {
                log.error("OutsourceHaiTongServiceImpl:processCustShareDetailInfoData:", e);
            }
            localDate = lastMonth;
            endDate = startDate;
        }
    }

    //转换1.产品信息查询
    public List<FundInfoEntity> getFundInfoData(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> seviceModelDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.SERVICE_MODEL_SERVICE, trustNo);
        Map<String, String> taConfDaysDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.TA_TRANSACTION_CONFIRM_ATION_DAYS_SERVICE, trustNo);
        Map<String, String> fundTypeDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.FUND_TYPE_SERVICE, trustNo);
        Map<String, String> proDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PRODUCT_STATUS_SERVICE, trustNo);
        Map<String, String> privateFundType = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PRIVATE_FUND_TYPE_SERVICE, trustNo);


        //2、封装数据
        List<FundInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);

            String serviceMode = MatchDataDictionaryKeyUtil.getKey(seviceModelDir, remoteDataMap.get("serviceMode"));
            log.info("getFundInfoData_serviceMode_原值={},映射值={}",remoteDataMap.get("serviceMode"),serviceMode);

            String fundType = remoteDataMap.get("fundType");
            String fundTypeIn = MatchDataDictionaryKeyUtil.getKey(fundTypeDir, fundType);
            String peType = MatchDataDictionaryKeyUtil.getKey(privateFundType, remoteDataMap.get("fundType"));
            log.info("getFundInfoData_fundType_原值={}，映射值fundType={},peType={}",fundType,fundTypeIn,peType);

            String fundStatus = MatchDataDictionaryKeyUtil.getKey(proDir, remoteDataMap.get("fundStatus"));
            log.info("getFundInfoData_fundStatus_原值={}，映射值={}",remoteDataMap.get("fundStatus"),fundStatus);

            String createDate = remoteDataMap.get("establishDate");
            log.info("getFundInfoData_createDate="+createDate);

            String confDays = MatchDataDictionaryKeyUtil.getKey(taConfDaysDir, remoteDataMap.get("confDays"));
            log.info("getFundInfoData_confDays_原值={}，映射值={}",remoteDataMap.get("confDays"),confDays);

            result.add(FundInfoEntity.builder()
                    .fundCode(remoteDataMap.get("fundCode"))
                    .fundName(remoteDataMap.get("fundName"))
                    .serviceMode(serviceMode)
                    .fundType(fundTypeIn)
                    .peType(peType)
                    .fundStatus(fundStatus)
                    .createDate(createDate)
                    .confDays(confDays)
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build());
        }
        return result;
    }

    //转换2
    public List<InvestorInfoEntity> getInvestorInfoData(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> custTypeCsdcDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CUST_TYPE_CSDC_SERVICE, trustNo);
        Map<String, Map<String, String>> identityTypeCsdcDic = certificateCsdcService.queryCertificateWithDetail(trustNo);


        //2、封装数据
        List<InvestorInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);

            String key = MatchDataDictionaryKeyUtil.getKey(custTypeCsdcDic, remoteDataMap.get("custType"));
            log.info("getInvestorInfoData_custName原值为{},映射值为{}",remoteDataMap.get("custType"),key);

            String identityType = MatchDataDictionaryKeyUtil.getKey(key, identityTypeCsdcDic, remoteDataMap.get("certiType"));
            log.info("getInvestorInfoData_identityType原值为{},映射值为{}",remoteDataMap.get("certiType"),identityType);

            result.add(InvestorInfoEntity.builder()
                    .custName(remoteDataMap.get("custName"))
                    .fundAcco(remoteDataMap.get("fundAcco"))
                    .custType(key)
                    .identityType(identityType)
                    .identityNo(remoteDataMap.get("certiNo"))
                    .address(remoteDataMap.get("address"))
                    .mobileNo(remoteDataMap.get("tel"))
                    .zipCode(remoteDataMap.get("zipCode"))
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build());
        }
        return result;
    }

    //转换4
    public List<CustShareInfoEntity> getCustShareInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> sellerServiceDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.SELLER_SERVICE, "海通证券");

        Map<String, String> dividendDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.DIVIDEND_WAY_SERVICE, trustNo);


        //2、封装数据
        List<CustShareInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);

            String agencyNo = remoteDataMap.get("agencyNo");
            String agencyNo1 = MatchDataDictionaryKeyUtil.getKey(sellerServiceDir, agencyNo);
            log.info("getCustShareInfo_agencyNo原值={},映射值={}",agencyNo,agencyNo1);

            String bonusType = remoteDataMap.get("bonusType");

            String bonusMethod = MatchDataDictionaryKeyUtil.getKey(dividendDir, bonusType);
            log.info("getCustShareInfo_bonusMethod原值={},映射值={}",bonusType,bonusMethod);

            log.info("enableShares={}",remoteDataMap.get("enableShares"));
            log.info("lastHoldShares={}",remoteDataMap.get("realShares"));
            log.info("shareRatio={}",remoteDataMap.get("shareRatio"),remoteDataMap.get("shareRatio"));
            log.info("frozenShares={}",remoteDataMap.get("frozenShares"));
            log.info("income={}",remoteDataMap.get("income"));
            log.info("lastModify={}",remoteDataMap.get("lastModify"));
            //补充agency_name字段
            String agencyName = sellerService.queryAgencyName("海通证券",agencyNo);

            //修改shareRatio
            BigDecimal shareRatio = BigDecimalUtil.str2BigDecimal(remoteDataMap.get("shareRatio"), 6);
            BigDecimal shareRatioReal = null;
            if(shareRatio == null){
                log.error("海通getCustShareInfo为空");
            }else{
                shareRatioReal = shareRatio.multiply(new BigDecimal("100")).setScale(4, RoundingMode.HALF_DOWN);
            }
            //处理updateDate
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String updateDate = null;
            if (!StringUtils.isEmpty(remoteDataMap.get("lastModify"))) {
                try {
                    Date parse = sdf.parse(remoteDataMap.get("lastModify"));
                    updateDate = sdf1.format(parse);
                } catch (ParseException e) {
                    e.printStackTrace();
                    log.error("时间转化失败！", e);
                }
            }
            result.add(CustShareInfoEntity.builder()
                    .fundCode(remoteDataMap.get("fundCode"))
                    .fundName(remoteDataMap.get("fundName"))
                    .fundAcco(remoteDataMap.get("fundAcco"))
                    .tradeAcco(remoteDataMap.get("tradeAcco"))
                    .agencyNo(agencyNo1)
                    .enableShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("enableShares")))
                    .lastHoldShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("realShares")))
                    .shareRatio(shareRatioReal)
                    .netValueDate(remoteDataMap.get("busiDate"))
                    .frozenShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("frozenShares")))
                    .bonusMethod(bonusMethod)
                    .income(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("income")==null?"0":remoteDataMap.get("income")).setScale(2, RoundingMode.HALF_UP))
                    .updateDate(updateDate)
                    .agencyName(agencyName)
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build());
        }
        return result;
    }

    //转换9
    public List<FundTradeInfoEntity> getFundTradeInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> sellerServiceDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.SELLER_SERVICE, "海通证券");
        Map<String, String> taLaunchDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.TA_LAUNCH_FLAG_SERVICE, trustNo);
        Map<String, String> confirmDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CONFIRM_STATUS_SERVICE, trustNo);
        Map<String, String> dividendDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.DIVIDEND_WAY_SERVICE, trustNo);
        Map<String, String> businessDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BUSINESS_NAME_SERVICE, trustNo);

        //2、封装数据
        List<FundTradeInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);

            String agencyNo = remoteDataMap.get("agencyNo");
            String agencyNo1 = MatchDataDictionaryKeyUtil.getKey(sellerServiceDir, agencyNo);
            log.info("getFundTradeInfo_agencyNo原值={},映射值={}",agencyNo,agencyNo1);

            String taFlag = remoteDataMap.get("taFlag");
            String taFlag1 = MatchDataDictionaryKeyUtil.getKey(taLaunchDir, taFlag);
            log.info("getFundTradeInfo_taFlag原值={},映射值={}",taFlag,taFlag1);

            String confStatus = remoteDataMap.get("confStatus");
            String confirmStatus = MatchDataDictionaryKeyUtil.getKey(confirmDir, confStatus);
            log.info("getFundTradeInfo_confirmStatus原值={},映射值={}",confStatus,confirmStatus);

            String bonusType = remoteDataMap.get("bonusType");
            String bonusMethod = MatchDataDictionaryKeyUtil.getKey(dividendDir, bonusType);
            log.info("getFundTradeInfo_bonusMethod原值={},映射值={}",bonusType,bonusMethod);

            String busiFlag = remoteDataMap.get("busiFlag");
            String businessName = MatchDataDictionaryKeyUtil.getKey(businessDir, busiFlag);
            log.info("getFundTradeInfo_businessName原值={},映射值={}",busiFlag,businessName);

            log.info("confirmDate={}",remoteDataMap.get("confDate"));
            log.info("requestDate={}",remoteDataMap.get("applyDate"));
            log.info("getFundTradeInfo_applyBalance={}",remoteDataMap.get("balance"));
            log.info("getFundTradeInfo_netValue={}",remoteDataMap.get("netValue"));
            log.info("getFundTradeInfo_unShares={}",remoteDataMap.get("unShares"));
            log.info("getFundTradeInfo_unfrozenBalance={}",remoteDataMap.get("unfrozenBalance"));

            result.add(FundTradeInfoEntity.builder()
                    .confirmDate(remoteDataMap.get("confDate"))
                    .requestDate(remoteDataMap.get("applyDate"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .fundName(remoteDataMap.get("fundName"))
                    .agencyNo(agencyNo1)
                    .agencyName(remoteDataMap.get("agencyName"))
                    .fundAcco(remoteDataMap.get("fundAcco"))
                    .tradeAcco(remoteDataMap.get("tradeAcco"))
                    .taFlag(taFlag1)
                    .confirmStatus(confirmStatus)
                    .agio(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("agio"),4))
                    .bonusMethod(bonusMethod)
                    .applyBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("balance"),2))
                    .applyShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("shares"),2))
                    .netValue(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("netValue"),4))
                    .confirmBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("confBalance"),2))
                    .confirmShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("confShares"),2))
                    .tradeFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("tradeFare"),2))
                    .taFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("taFare"),2))
                    .stampTax(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("stampTax")))
                    .backFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("backFare")))
                    .breachFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("breachFare")))
                    .breachFareAgt(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("breachFare4Agt")))
                    .breachFareFund(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("breachFare4Fund")))
                    .profitBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("profitBalance")))
                    .profitBalanceAgt(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("profitBalance4Agt")))
                    .totalFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("totalFare")))
                    .agencyFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("agencyFare")))
                    .fundFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("fundFare")))
                    .registFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("registFare")))
                    .interest(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("interest")))
                    .interestTax(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("interestTax")))
                    .interestShare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("interestShare")))
                    .frozenBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("frozenBalance")))
                    .unfrozenBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("unfrozenBalance")))
                    .unShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("unShares")))
                    .confirmNavVol(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("netConfBalance")))
                    .cserialNo(remoteDataMap.get("cserialNo"))
                    .businessName(businessName)
                    .requestNo(remoteDataMap.get("originalNo"))
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build());
        }
        return result;
    }

    //转换13
    public List<InvestorBankInfoEntity> getInvestorBankInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> bankCodeDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BANK_CODE_SERVICE, "海通TA");
        Map<String, Map<String, String>> identityTypeCsdcDic = certificateCsdcService.queryCertificateWithDetail(trustNo);


        //2、封装数据
        List<InvestorBankInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);

            String bankNo = remoteDataMap.get("bankNo");

            String bankCode = MatchDataDictionaryKeyUtil.getKey(bankCodeDir, bankNo);
            log.info("getInvestorBankInfoData_bankCode原值为{},映射值为{}",bankNo,bankCode);

            result.add(InvestorBankInfoEntity.builder()
                    .fundAcco(remoteDataMap.get("fundAcco"))
                    .tradeAcco(remoteDataMap.get("tradeAcco"))
                    .bankCode(bankCode)
                    .bankNo(remoteDataMap.get("bankAcco"))
                    .branchBankName(remoteDataMap.get("openBankName"))
                    .nameInBank(remoteDataMap.get("nameInBank"))
                    .bankNoType("银行账号")
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build());
        }
        return result;
    }

    //转换14
    public List<FundProfitInfoEntity> getFundProfitInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> sellerServiceDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.SELLER_SERVICE, "海通证券");
//        Map<String, String> bankCodeDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BANK_CODE_SERVICE, "海通TA");
        Map<String, String> businessTypeDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.BUSINESS_NAME_SERVICE, trustNo);
        Map<String, String> handleDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.HANDLE_TYPE_SERVICE, trustNo);
//        Map<String, Map<String, String>> identityTypeCsdcDic = certificateCsdcService.queryCertificateWithDetail(trustNo);


        //2、封装数据
        List<FundProfitInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);

//            String bankNo = remoteDataMap.get("bankNo");
//            String bankCode = MatchDataDictionaryKeyUtil.getKey(bankCodeDir, bankNo);
//            log.info("getInvestorBankInfoData_bankCode原值为{},映射值为{}",bankNo,bankCode);
            String busiType = remoteDataMap.get("busiType");

            String businessName = MatchDataDictionaryKeyUtil.getKey(businessTypeDir, busiType);
            log.info("getFundProfitInfo_businessName原值={},映射值={}",busiType,businessName);

            String sortFlag = remoteDataMap.get("sortFlag");

            String sortFlag1 = MatchDataDictionaryKeyUtil.getKey(handleDir, sortFlag);
            log.info("getFundProfitInfo_sortFlag原值={},映射值={}",sortFlag,sortFlag1);

            String agencyNo = remoteDataMap.get("agencyNo");

            String agencyNo1 = MatchDataDictionaryKeyUtil.getKey(sellerServiceDir, agencyNo);
            log.info("getFundProfitInfo_agencyNo原值={},映射值={}",agencyNo,agencyNo1);

            log.info("getFundProfitInfo_dDate={}",remoteDataMap.get("dDate"));
            log.info("getFundProfitInfo_registDate={}",remoteDataMap.get("registDate"));
            log.info("getFundProfitInfo_confirmDate={}",remoteDataMap.get("confDate"));
            log.info("getFundProfitInfo_hold={}",remoteDataMap.get("hold"));

            //补充agencyName 字段
            String agencyName = sellerService.queryAgencyName("海通证券", agencyNo);

            result.add(FundProfitInfoEntity.builder()
                    .confirmDate(remoteDataMap.get("confDate"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .fundName(remoteDataMap.get("fundName"))
                    .agencyNo(agencyNo1)
                    .fundAcco(remoteDataMap.get("fundAcco"))
                    .tradeAcco(remoteDataMap.get("tradeAcco"))
                    .businessName(businessName)
                    .sortFlag(sortFlag1)
                    .requestDate(remoteDataMap.get("dDate"))
                    .registDate(remoteDataMap.get("registDate"))
                    .oriDate(remoteDataMap.get("dBeginDate"))
                    .holdDay(remoteDataMap.get("hold"))
                    .shares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("shares")))
                    .oriNav(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("oriNav"),4))
                    .oriTotalNav(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("oriTotalNav"),4))
                    .nav(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("nav"),4))
                    .totalNav(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("totalNav"),4))
                    .currRatio(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("currRatio"),4))
                    .yearRatio(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("yearRatio"),4))
                    .standardRatio(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("standardRatio"),4))
                    .returnFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("returnFare")))
                    .oriBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("oriBalance")))
                    .factBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("factBalance")))
                    .factShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("factShares")))
                    .bonusBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("bonusBalance")))
                    .income(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("income")))
                    .deductRatio(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("deductRatio"),4))
                    .valueAddedFare(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("valueAddedFare")))
                    .costPrice(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("costPrice")))
                    .totalUnitBonus(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("totalUnitBonus")))
                    .oriCserialNo(remoteDataMap.get("oriCserialNo"))
                    .cserialNo(remoteDataMap.get("cserialNo"))
                    .agencyName(agencyName)
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build());
        }
        return result;
    }

    //转换15
    public List<CustShareDetailInfoEntity> getCustShareDetailInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> sellerServiceDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.SELLER_SERVICE, "海通证券");
        Map<String, String> shareDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.SHARE_SOURCE_SERVICE, trustNo);


        //2、封装数据
        List<CustShareDetailInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);

            String agencyNo = remoteDataMap.get("agencyNo");

            String agencyNo1 = MatchDataDictionaryKeyUtil.getKey(sellerServiceDir, agencyNo);
            log.info("getCustShareDetailInfo_agencyNo原值={},映射值={}",agencyNo,agencyNo1);

            String sourceType = remoteDataMap.get("sourceType");
            String sourceType1 = MatchDataDictionaryKeyUtil.getKey(shareDir, sourceType);

            String oriSourceType = remoteDataMap.get("oriSourceType");
            String oriSource  = MatchDataDictionaryKeyUtil.getKey(shareDir, oriSourceType);

            log.info("getCustShareDetailInfo_sourceType原值={},映射值={},oriSource原值={}，映射值={}",sourceType,sourceType1,oriSourceType,oriSource);

            log.info("getCustShareDetailInfo_confirmDate={}",remoteDataMap.get("confDate"));
            log.info("getCustShareDetailInfo_registDate={}",remoteDataMap.get("registDate"));
            log.info("getCustShareDetailInfo_lastDeductDate={}",remoteDataMap.get("lastDeductDate"));

            //补充agencyName 字段
            String agencyName = sellerService.queryAgencyName("海通证券", agencyNo);


            result.add(CustShareDetailInfoEntity.builder()
                    .fundCode(remoteDataMap.get("fundCode"))
                    .fundName(remoteDataMap.get("fundName"))
                    .fundAcco(remoteDataMap.get("fundAcco"))
                    .tradeAcco(remoteDataMap.get("tradeAcco"))
                    .tradeAcco(remoteDataMap.get("tradeAcco"))
                    .agencyNo(agencyNo1)
                    .agencyName(agencyName)
                    .remainShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("realShares")))
                    .confirmDate(remoteDataMap.get("confDate"))
                    .registDate(remoteDataMap.get("registDate"))
                    .sourceType(sourceType1)
                    .oriSource(oriSource)
                    .oriNetValue(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("oriNetValue"),4))
                    .oriShares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("oriShares")))
                    .oriBalance(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("oriBalance")))
                    .lastDeductDate(remoteDataMap.get("lastDeductDate"))
                    .seqNo(RandomStrUtil.getRandomStr(32))
                    .agencyName(agencyName)
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .createTime(now)
                    .updateTime(now)
                    .build());
        }
        return result;
    }

    //转换18
    public List<FundNetValueInfoEntity> getFundNetValueInfo(TenantEscrowAuthorizationInfoDto tenant, List<JSONObject> remoteDatas, String trustNo) {
        //1、获取字典表数据
        Map<String, String> fundClassDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.FUND_CLASSIFICATION_LOGO_SERVICE, tenant.getTrustNo());

        log.info("getFundNetValueInfo拿到的数据为{}",JSON.toJSONString(remoteDatas));

        //2、封装数据
        List<FundNetValueInfoEntity> result = new ArrayList<>();
        Map<String, String> remoteDataMap;
        Date now = new Date();
        for (JSONObject remoteData : remoteDatas) {
            remoteDataMap = JSONObject.toJavaObject(remoteData, Map.class);

            String fundLevel = remoteDataMap.get("fundLevel");
            String fundLevelMaped = MatchDataDictionaryKeyUtil.getKey(fundClassDir, fundLevel);
            log.info("getFundNetValueInfo:基金等级原值：{}，映射后值{}",fundLevel,fundLevelMaped);

            result.add(FundNetValueInfoEntity.builder()
                    .netValueDate(remoteDataMap.get("netDate"))
                    .fundCode(remoteDataMap.get("fundCode"))
                    .fundName(remoteDataMap.get("fundName"))
                    .totalAsset(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("totalAssets"),2))
                    .shares(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("assetShares"),2))
                    .assetValue(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("assetNet"),2))
                    .netValue(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("netAssetVal"),4))
                    .totalNetValue(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("totalAssetVal"),4))
                    .ettFundIncome(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("ettFundIncome"),2))
                    .sevenDayRate(BigDecimalUtil.str2BigDecimal(remoteDataMap.get("sevenDayRate"),4))
                    .fundLevel(fundLevelMaped)
                    .trustNo(trustNo)
                    .admin(tenant.getTenantName())
                    .currency("156")
                    .createTime(now)
                    .updateTime(now)
                    .build()
            );
        }
        return result;
    }

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

    @Override
    public R initLaterSingleTenantData(String versionStr, TenantEscrowAuthorizationInfoDto tenant) {
        log.info("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;
//          Integer loopNum = CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
//        Integer loopNum = 48;
        try {
            switch (versionStr) {
                case CustodyContants.R_PT_S_CUSTODY_3_2_7:
//                    processT0213Data(tenant, trustNo, loopNum);
//                    log.info("管理人{}海通募集户流水更新完成!", tenant.getTenantName());
                    processT0215Data(tenant, trustNo, loopNum);
                    processT0216Data(tenant, trustNo, loopNum);
                    log.info("管理人{}海通托管户流水更新完成!", tenant.getTenantName());
                    break;
            }
        } catch (Exception e){
            log.error("海通流水表更新失败!", e);
        }
        return null;
    }

    @Override
    public R initByAppointedTrustNoAndMouth(TenantEscrowAuthorizationInfoDto tenant, int mouth) {
        log.info("initByAppointedTrustNoAndMouth_tenant={},mouth={}",JSON.toJSONString(tenant),mouth);
        getDataFromHaiTong(tenant,mouth);
        return R.ok();
    }

    public HaiTongConstants getHaiTongConstantsFromTenant(TenantEscrowAuthorizationInfoDto tenant){
        HaiTongConstants haiTongConstants = new HaiTongConstants();
        String appSecret = tenant.getAppSecret();
        haiTongConstants.setPropertyFromJsonHaiTong(appSecret);
        String appKey = tenant.getAppKey();
        if (StringUtils.isNotBlank(appKey) && appKey.equals(haiTongConstants.clientId)) {
            log.info("getHaiTongConstantsFromTenant 返回内容{}",JSON.toJSONString(haiTongConstants));
            return haiTongConstants;
        }
        log.error("海通appkey与appSecret不匹配,appkey为{}，appSecret为{}",appKey,appSecret);
        throw new IllegalArgumentException("appkey与appSecret不匹配");
    }

    public void initTenantDataBy305Patch02(TenantEscrowAuthorizationInfoDto tenant,String trustNo,Integer loopNum){
        log.info("318patch01海通更新fundOpenInfo开始");
        outsourceHaiTongService.processFundValueTableAndFundNetValueByEmail(tenant, trustNo, loopNum);
        log.info("18patch01海通更新fundOpenInfo结束");

    }

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

    @Override
    public R updateSingleData20min(TenantEscrowAuthorizationInfoDto tenant) {
        try {
            log.info("*****************海通托管数据每半小时更新开始************************");
            String trustNo = tenant.getTrustNo();//42
            Integer loopTime = CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
            //mjAccount_seq_info
            processT0213Data(tenant, trustNo, loopTime);
            // account_info+MJAccount_balance_info
            processT0214Data(tenant, trustNo, loopTime);
            //TGAccount_seq_info
            processT0216Data(tenant, trustNo, loopTime);
            //TGAccount_balance_info
            processT0218Data(tenant, trustNo, loopTime);
            log.info("******************海通托管数据每半小时更新结束***********************");
            return R.ok("海通托管数据每半小时更新完成！");
        } catch (Exception e) {
            log.error("海通托管数据每半小时更新异常！", e);
            return R.ok("海通托管数据每半小时更新失败！");
        }
    }

    @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) {

        if(!CollectionUtils.isEmpty(tenants)){
            for (TenantEscrowAuthorizationInfoDto tenant : tenants) {
                try{
                    log.info("海通定时更新净值数据开始,授权信息为{}",JSON.toJSONString(tenant));
                    outsourceHaiTongService.processFundNetValueData(tenant,tenant.getTrustNo(),1);
                    log.info("处理邮件解析FundValueTableInfo和FundNetValueInfo表的数据");
                    processFundValueTableAndFundNetValueByEmail(tenant,tenant.getTrustNo(),1);
                    log.info("海通定时更新净值数据结束,授权信息为{}",JSON.toJSONString(tenant));
                }catch (Exception e){
                    log.error("海通定时更新净值数据异常,授权信息为{}",JSON.toJSONString(tenant),e);
                }
            }
        }
        return R.ok();
    }

    @Override
    public R updateSingleNetValueData(TenantEscrowAuthorizationInfoDto tenant) {
        try{
            log.info("海通每天8点,12点,20点更新净值数据开始,授权信息为{}",JSON.toJSONString(tenant));
            outsourceHaiTongService.processFundNetValueData(tenant,tenant.getTrustNo(),1);
            log.info("处理邮件解析FundValueTableInfo和FundNetValueInfo表的数据");
            processFundValueTableAndFundNetValueByEmail(tenant,tenant.getTrustNo(),1);
            log.info("海通每天8点,12点,20点更新净值数据结束,授权信息为{}",JSON.toJSONString(tenant));
        }catch (Exception e){
            log.error("海通每天8点,12点,20点更新净值数据异常,授权信息为{}",JSON.toJSONString(tenant),e);
        }
        return R.ok();
    }

    @Override
    public DubboResult updateMJBalanceData(TenantEscrowAuthorizationInfoDto tenant) {
        try {
            String trustNo = tenant.getTrustNo();
            int loopTime = CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
            // account_info+MJAccount_balance_info
            processT0214Data(tenant, trustNo, loopTime);
            return DubboResult.newSuccess();
        } catch (Exception e) {
            log.error("手动更新募集户余额失败", e);
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, "手动更新募集户余额失败" + e.getMessage());
        }
    }

    @Override
    public DubboResult updateMJSeqData(TenantEscrowAuthorizationInfoDto tenant) {
        try {
            String trustNo = tenant.getTrustNo();
            int loopTime = CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
            // mjAccount_seq_info
            processT0213Data(tenant, trustNo, loopTime);
            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();
            int loopTime = CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
            // TGAccount_balance_info
            processT0218Data(tenant, trustNo, loopTime);
            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();
            int loopTime = CustodyContants.UPDATE_BY_MONTH_DAILY_LOOP_TIME;
            // TGAccount_seq_info
            processT0216Data(tenant, trustNo, loopTime);
            return DubboResult.newSuccess();
        } catch (Exception e) {
            log.error("手动更新托管户流水失败", e);
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, "手动更新托管户流水失败" + e.getMessage());
        }
    }
}
