package com.yd.api.practitioner.service.impl;

import com.github.pagehelper.PageHelper;
import com.yd.api.customer.service.CustomerService;
import com.yd.api.customer.vo.register.RegisterRequestVO;
import com.yd.api.customer.vo.register.RegisterResponseVO;
import com.yd.api.practitioner.vo.login.CanSeeSalaryListResponseVO;
import com.yd.api.practitioner.vo.payscale.PayScaleInfo;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsActionsUpdateResponseVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsQueryResponseVO;
import com.yd.api.practitioner.vo.login.PractitionerLoginBasicInfo;
import com.yd.api.practitioner.vo.login.PractitionerLoginRequestVO;
import com.yd.api.practitioner.vo.login.PractitionerLoginResponseVO;
import com.yd.api.practitioner.vo.media.MediaGetReqVO;
import com.yd.api.practitioner.vo.media.MediaGetRespVO;
import com.yd.api.practitioner.vo.opportunity.*;
import com.yd.api.practitioner.vo.rank.AclCustomerFortuneStatistics;
import com.yd.api.practitioner.vo.rank.PractitionerRankRequestVO;
import com.yd.api.practitioner.vo.rank.PractitionerRankResponseVO;
import com.yd.api.practitioner.vo.rank.PractitionerInfoForAchievement;
import com.yd.api.practitioner.vo.recruit.*;
import com.yd.api.practitioner.vo.salestarget.*;
import com.yd.api.practitioner.vo.setting.*;
import com.yd.api.practitioner.vo.subordinate.SubordinateSystemMemberInfo;
import com.yd.api.practitioner.vo.subordinate.SubordinateSystemMemberQueryRequestVO;
import com.yd.api.practitioner.vo.subordinate.SubordinateSystemMemberQueryResponseVO;
import com.yd.api.practitioner.vo.subordinate.SubordinateSystemStatisticInfo;
import com.yd.api.result.CommonResult;
import com.yd.dal.entity.customer.*;
import com.yd.dal.entity.marketing.*;
import com.yd.dal.entity.meta.*;
import com.yd.dal.entity.marketing.MktLeadsAssignedTrack;
import com.yd.dal.entity.marketing.MktLeadsAssigneds;
import com.yd.dal.entity.marketing.MktLeadsGoals;
import com.yd.dal.entity.marketing.MktLeadsPool;
import com.yd.dal.entity.practitioner.opportunity.OwnOpportunityInfo;
import com.yd.dal.entity.order.PoOrder;
import com.yd.dal.entity.practitioner.opportunity.PlayerSalesActivityInfo;
import com.yd.dal.entity.survey.SurveyCustomerAnswers;
import com.yd.dal.entity.user.AclUser;
import com.yd.dal.service.customer.*;
import com.yd.dal.service.marketing.*;
import com.yd.dal.service.marketing.MktLeadsAssignedTrackDALService;
import com.yd.dal.service.marketing.MktLeadsAssignedsDALService;
import com.yd.dal.service.marketing.MktLeadsGoalsDALService;
import com.yd.dal.service.meta.*;
import com.yd.dal.service.order.PoOrderDALService;
import com.yd.dal.service.survey.SurveyCustomerAnswersDALService;
import com.yd.dal.service.user.AclUserDALService;
import com.yd.dal.entity.customer.practitioner.*;
import com.yd.dal.service.meta.MdCodeDALService;
import com.yd.dal.service.meta.MdDropOptionsDALService;
import com.yd.rmi.ali.mail.service.MailService;
import com.yd.rmi.ali.oss.service.OssService;
import com.yd.rmi.cache.SystemConfigService;
import com.yd.rmi.n22.policy.pojo.policydetail.PolicyDetailQueryRequestBody;
import com.yd.rmi.n22.policy.pojo.policydetail.PolicyDetailQueryResponseVO;
import com.yd.rmi.n22.policy.pojo.policylist.PolicyInfoN22;
import com.yd.rmi.n22.policy.pojo.policylist.PolicyListQueryRequestBody;
import com.yd.rmi.n22.policy.service.N22PolicyService;
import com.yd.rmi.n22.salary.pojo.SalaryDetails;
import com.yd.rmi.n22.salary.pojo.SalaryDetailsSearchRequestBody;
import com.yd.rmi.n22.salary.pojo.SalaryDetailsSearchResponseVO;
import com.yd.rmi.n22.salary.service.N22SalaryService;
import com.yd.rmi.n22.staff.pojo.GetStaffNewRequestBody;
import com.yd.rmi.n22.staff.pojo.GetStaffNewResponseVO;
import com.yd.rmi.n22.staff.pojo.Staff;
import com.yd.rmi.n22.staff.service.N22StaffService;
import com.yd.rmi.tencent.wechat.service.WechatService;
import com.yd.rmi.tencent.wechat.vo.WeChatInfoByENV;
import com.yd.rmi.tencent.wechatinterf.pojo.ticket.TicketRequest;
import com.yd.rmi.tencent.wechatinterf.pojo.token.TokenRequest;
import com.yd.util.CommonUtil;
import com.yd.util.HttpUtil;
import com.yd.util.config.ZHBErrorConfig;
import org.apache.commons.beanutils.BeanPropertyValueEqualsPredicate;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.common.base.Strings;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

@Service("practitionerService")
public class PractitionerServiceImpl implements com.yd.api.practitioner.service.PractitionerService {

    @Autowired
    private AclPractitionerDALService aclPractitionerDALService;
    @Autowired
    private MdCodeDALService mdCodeDALService;
    @Autowired
    private AclFileUploadDALService aclFileUploadDALService;
    @Autowired
    private AclPractitionerSubordinateSystemDALService aclPractitionerSubordinateSystemDALService;
    @Autowired
    private AclCustomerLogDALService aclCustomerLogDALService;
    @Autowired
    private OssService ossService;
    @Autowired
    private WechatService wechatService;
    @Autowired
    private AclCustomerShareDALService aclCustomerShareDALService;
    @Autowired
    private PoOrderDALService poOrderDALService;
    @Autowired
    private AclCustomerDALService aclCustomerDALService;
    @Autowired
    private MdMkCampaignDALService mdMkCampaignDALService;
    @Autowired
    private MktLeadsAssignedsDALService mktLeadsAssignedsDALService;
    @Autowired
    private ObjectCollectionTaggedDALService objectCollectionTaggedDALService;
    @Autowired
    private MktLeadsAssignedTrackDALService mktLeadsAssignedTrackDALService;
    @Autowired
    private MdTagDALService mdTagDALService;
    @Autowired
    private AclCustomerMembershipDALService aclCustomerMembershipDALService;
    @Autowired
    private SurveyCustomerAnswersDALService surveyCustomerAnswersDALService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private AclPractitionerPotentialDALService aclPractitionerPotentialDALService;
    @Autowired
    private AclPractitionerPotentialAssignedTrackDALService aclPractitionerPotentialAssignedTrackDALService;
    @Autowired
    private MktLeadsPoolDALService mktLeadsPoolDALService;
    @Autowired
    private MdDropOptionsDALService mdDropOptionsDALService;
    @Autowired
    private AclUserDALService aclUserDALService;
    @Autowired
    private AclPractitionerPotentialAssignedsDALService aclPractitionerPotentialAssignedsDALService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private MktLeadsGoalsDALService mktLeadsGoalsDALService;
    @Autowired
    private MdDropMasterDALService mdDropMasterDALService;
    @Autowired
    private MdGoalsCalculateExpressionService mdGoalsCalculateExpressionService;
    @Autowired
    private MktLeadsGoalsActionsDALService mktLeadsGoalsActionsDALService;
    @Autowired
    private AclPractitionerSettingDALService aclpractitionersettingDALService;
    @Autowired
    private AclCustomerFortuneDALService aclCustomerFortuneDALService;
    @Autowired
    private AclPractitionerPotentialGoalsDALService aclPractitionerPotentialGoalsDALService;
    @Autowired
    private MdGoalsCalculateExpressionDALService mdGoalsCalculateExpressionDALService;
    @Autowired
    private AclPractitionerPotentialGoalsActionsDALService aclPractitionerPotentialGoalsActionsDALService;
    @Autowired
    private MktLeadsExpertRequestDALService mktLeadsExpertRequestDALService;
    @Autowired
    private MktLeadsExpertAssignDALService mktLeadsExpertAssignDALService;
    @Autowired
    private MailService mailService;
    @Autowired
    private N22StaffService n22StaffService;
    @Autowired
    private N22SalaryService n22SalaryService;
    @Autowired
    private N22PolicyService n22PolicyService;

    @Override
    public PractitionerLoginResponseVO practitionerLogin(PractitionerLoginRequestVO requestVO) {
        PractitionerLoginResponseVO responseVO = new PractitionerLoginResponseVO();
        String mobileNo = requestVO.getMobileNo();
        //1、校验入参，电话号码不能为空
        if (Strings.isNullOrEmpty(mobileNo)) {
            String[] params = {"mobileNo"};
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("610001", params)));
            return responseVO;
        }
        //2、检查是否在ag_acl_customer表中存在该用户，如果不存在就注册，然后直接抛错，该用户未注册为经纪人
        PractitionerInfo practitionerInfo = aclPractitionerDALService.findPractitionerInfoByLogin(mobileNo);
        if(practitionerInfo != null){
            Long practitionerType = practitionerInfo.getPractitionerType();
            //处理特殊人员
            boolean isSpecial = false;
            String mobileSpecialStr = mdCodeDALService.findCodeByType("special_practitioner_mobile");
            if(!Strings.isNullOrEmpty(mobileSpecialStr)){
                List<String> mobileSpecials = Arrays.asList(mobileSpecialStr.split(","));
                isSpecial = mobileSpecials.contains(mobileNo);
            }
//            if(28L == practitionerType || isSpecial){//只有寿险的经纪人和注册为经纪人的员工才能登录
            PractitionerBasicInfo practitionerBasicInfo = aclPractitionerDALService.findByMobileNoE(mobileNo);
            Long practitionerId = practitionerInfo.getPractitionerId();
            Long customerId = practitionerInfo.getCustomerId();
            AclCustomer customer = aclCustomerDALService.findById(customerId);
            PractitionerLoginBasicInfo basicInfo = new PractitionerLoginBasicInfo();
            BeanUtils.copyProperties(practitionerInfo,basicInfo);
            //获取头像
            Integer targetType = 1, targetUseFor = 1;
            CustomerFileUpload fileUpload = aclFileUploadDALService.findFilePathInfo(targetType,targetUseFor,practitionerId);
            String imagePath = (fileUpload != null) ? fileUpload.getFilePath() : null;
            basicInfo.setHeadImagePath(imagePath);
            //获取二维码
            targetUseFor = 9;
            fileUpload = aclFileUploadDALService.findFilePathInfo(targetType,targetUseFor,practitionerId);
            String qrCodePath = (fileUpload != null) ? fileUpload.getFilePath() : null;
            basicInfo.setQrCodePath(qrCodePath);
            //获取体系信息
            Long subordinateId = practitionerInfo.getSubordinateId();
            if(subordinateId != null){
                PractitionerSubordinateInfo subordinateInfo = aclPractitionerSubordinateSystemDALService.findSubordinateInfo(subordinateId);
                if(subordinateInfo != null){
                    basicInfo.setSubordinateName(subordinateInfo.getSubordinateName());
                    basicInfo.setSubordinateLeader(subordinateInfo.getSubordinateLeader());
                }
            }
            if(practitionerBasicInfo != null){
                responseVO.setPractitionerIdEG(practitionerBasicInfo.getPractitionerId());
            }
            //获取用户的登录次数
            List<AclCustomerLog> customerLogList = aclCustomerLogDALService.findLogInfoByCustomerId(customerId);
            int logTimes = (customerLogList.isEmpty()) ? 0 : customerLogList.size();
            //保存用户的登录记录
            aclCustomerLogDALService.saveCustomerLog(customerId,2);
            getOpenIdUrl(responseVO,customer);
            responseVO.setCustomerId(customerId);
            responseVO.setPractitionerId(practitionerId);
            responseVO.setPractitionerTypeId(practitionerType);
            responseVO.setPractitionerBasicInfo(basicInfo);
            responseVO.setLoginTimes(logTimes);
            responseVO.setCanSeeSalaryList(practitionerInfo.getCanSeeSalaryList());
            responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
//            }
        }else{
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830001")));
        }
        return responseVO;
    }

    private void getOpenIdUrl(PractitionerLoginResponseVO responseVO, AclCustomer customer) {
        String openId = customer.getYdWechatOpenid();
        if(Strings.isNullOrEmpty(openId)) {
            WeChatInfoByENV weChatInfo = wechatService.getWeChatInfoByENV("YDBJ", false);
            String appId = weChatInfo.getAppId(), secret = weChatInfo.getSecret();
            if (!Strings.isNullOrEmpty(appId) && !Strings.isNullOrEmpty(secret)) {
                try {
                    String info = appId+","+customer.getId();
                    String redirectUri = mdCodeDALService.findCodeByType("FilePathPrefix")+"ydapi/getOpenId?info=" + info;
                    redirectUri = URLEncoder.encode(redirectUri, "UTF-8");
                    String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"
                            + "appid=" + appId
                            + "&redirect_uri=" + redirectUri
                            + "&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
                    responseVO.setGetOpenIdUrl(url);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    @Override
    public PractitionerRankResponseVO practitionerRank(PractitionerRankRequestVO requestVO) {
        PractitionerRankResponseVO responseVO = new PractitionerRankResponseVO();
        String mobileNo = requestVO.getMobileNo();
        Integer type = requestVO.getType();
        Integer time = requestVO.getTime();
        Integer platform = requestVO.getPlatform();
        type = (type == null) ? 1 : type;//默认：保费
        time = (time == null) ? 1 : time;//默认：本月
        platform = (platform == null) ? 1 : platform;
        if (!Strings.isNullOrEmpty(mobileNo)) {
            //查询该手机号码的经纪人id，是否存在
            Map<Integer, PractitionerBasicInfo> practitionerBasicInfoMap = getPractitionerBasicInfo(mobileNo);
            if (!practitionerBasicInfoMap.isEmpty()) {
                PractitionerBasicInfo practitionerBasicInfo = practitionerBasicInfoMap.get(platform);
                Long practitionerTypeId = null;
                if (platform == 1) {
                    practitionerTypeId = practitionerBasicInfo.getPractitionerTypeId();
                } else {
                    PractitionerBasicInfo practitionerBasicInfoYD = practitionerBasicInfoMap.get(1);
                    if (practitionerBasicInfoYD != null) {
                        practitionerTypeId = practitionerBasicInfoYD.getPractitionerTypeId();
                    }
                }
                if (practitionerBasicInfo != null && practitionerTypeId != null) {
                    String practitionerId = practitionerBasicInfo.getPractitionerId();
                    if (!Strings.isNullOrEmpty(practitionerId)) {
                        List<PractitionerRankInfo> rankInfoList = getPractitionerRankInfo(time, platform, practitionerTypeId);
                        //按照指定类型排序
                        getPractitionerRankResult(responseVO, rankInfoList, type, practitionerBasicInfoMap, time, platform, practitionerTypeId);
                        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
                    }
                }
            } else {
                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830001"))); //该经纪人不存在
            }
        } else {
            String[] param = {"mobileNo"};
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("610001", param)));
        }
        return responseVO;
    }

    private List<PractitionerRankInfo> getPractitionerRankInfo(Integer time, Integer platform,Long practitionerTypeId) {
        List<PractitionerRankInfo> rankInfoList = new ArrayList<>();
        if(platform == 1){
            rankInfoList = aclPractitionerDALService.getPractitionerRankInfoForOnline(time,practitionerTypeId);
            //特殊人员处理
            String mobileSpecialStr = mdCodeDALService.findCodeByType("special_practitioner_mobile");
            if(!Strings.isNullOrEmpty(mobileSpecialStr)){
                List<String> mobileSpecials = Arrays.asList(mobileSpecialStr.split(","));
                List<PractitionerRankInfo> rankInfoListSpecials = aclPractitionerDALService.getPractitionerRankInfoForSpecials(mobileSpecials,time);
                rankInfoList.addAll(rankInfoListSpecials);
            }
        }else{
            rankInfoList = aclPractitionerDALService.getPractitionerRankInfoForOffline(time);

            // 调用N22接口查寿险
//            try {
//                rankInfoList = this.getPractitionerRankInfoFromN22(time);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
        }
        return rankInfoList;
    }

    private List<PractitionerRankInfo> getPractitionerRankInfoFromN22(Integer time) throws Exception {
        // 根据查询时间范围获取查询开始时间和结束时间
        String startTime;
        String endTime;
        if (Integer.valueOf("1") == time) {
            startTime = CommonUtil.getBeginDayOfMonth();
            endTime = CommonUtil.getEndDayOfMonth();
        } else if (Integer.valueOf("3") == time) {
            startTime = CommonUtil.getStartOrEndDayOfQuarter(true);
            endTime = CommonUtil.getStartOrEndDayOfQuarter(false);
        } else {
            startTime = CommonUtil.getBeginDayOfYear();
            endTime = CommonUtil.getEndDayOfYear();
        }
        // 循环查询每个经纪人的数据
        List<AclPractitioner> list = aclPractitionerDALService.queryAllLifePractitioner();
        List<PractitionerRankInfo> rankInfoList = new ArrayList<>();
        for (AclPractitioner practitioner : list) {
            PractitionerRankInfo rankInfo = this.queryPersonalRankInfoFromN22(practitioner.getMobileNo(), startTime, endTime);
            if (rankInfo != null) {
                rankInfoList.add(rankInfo);
            }
        }

        return rankInfoList;
    }

    private PractitionerRankInfo queryPersonalRankInfoFromN22(String mobileNo,  String startTime, String endTime) throws Exception {
        // 1.根据手机号查询经纪人在N22系统的Agent_id
        GetStaffNewRequestBody getStaffNewRequestBody = new GetStaffNewRequestBody();
        getStaffNewRequestBody.setMobile(mobileNo);
        GetStaffNewResponseVO resp = n22StaffService.getStaffNew(getStaffNewRequestBody);

        if ("未查询到该坐席".equals(resp.getResponseHead().getMessage())){
            return null;
        }
        if (!"查询成功".equals(resp.getResponseHead().getMessage())){
            throw new Exception("查询N22的Agent_id错误");
        }
        List<Staff> staffList = resp.getResponseBody().getStaff();
        if (staffList.size() == 0) {
            throw new Exception("查询N22的经纪人错误");
        }
        Staff staff = staffList.get(0);
        String agent_id = staff.getAgent_id();

        // 2.根据Agent_id当前经纪人的佣金明细
        SalaryDetailsSearchRequestBody salaryDetailsSearchRequestBody = new SalaryDetailsSearchRequestBody();
        salaryDetailsSearchRequestBody.setLoginName(agent_id);
        salaryDetailsSearchRequestBody.setSearchType("1");
        salaryDetailsSearchRequestBody.setCheckStatus("1");
        salaryDetailsSearchRequestBody.setStartDate(startTime);
        salaryDetailsSearchRequestBody.setEndDate(endTime);
        SalaryDetailsSearchResponseVO salaryDetailsSearchResponseVO = n22SalaryService.salaryDetailsSearch(salaryDetailsSearchRequestBody);

        if (!"查询成功".equals(salaryDetailsSearchResponseVO.getResponseHead().getMessage())){
            throw new Exception( "查询N22佣金明细列表错误");
        }
        List<SalaryDetails> salaryDetailsList = salaryDetailsSearchResponseVO.getResponseBody().getSalaryDetailsLIST();

        // 3.按年月分组
        Map<String, List<SalaryDetails>> group = n22SalaryService.groupByYearmonth(salaryDetailsList);

        // 4.统计FYC,FYP,count
        PractitionerRankInfo rankInfo = null;
        for (String key : group.keySet()) {

            System.out.println("Key = " + key);
            List<SalaryDetails> list = group.get(key);

            // 计算每组FYC,FYP,count
            rankInfo = this.getFypAndFycAndCount(list);

        }

        return rankInfo;
    }

    private Double getFyp(String policyNo) throws Exception{

        // 请求参数
        PolicyDetailQueryRequestBody policyInfoRequestBody = new PolicyDetailQueryRequestBody();
        policyInfoRequestBody.setPolicyNo(policyNo);

        PolicyDetailQueryResponseVO policyDetailQueryResponseVO = n22PolicyService.policyInfo(policyInfoRequestBody);

        if (!"查询成功".equals(policyDetailQueryResponseVO.getResponseHead().getMessage())){
            throw new Exception("查询N22经纪人保单详情错误");
        }
        Double premium = policyDetailQueryResponseVO.getResponseBody().getPremium();

        return premium;

    }

    private PractitionerRankInfo getFypAndFycAndCount(List<SalaryDetails> list) throws Exception {

        Integer count = 0;
        Double fyc = 0D;
        Double fyp = 0D;
        // 判断list中是否存在保单佣金
        boolean isFYCExist = false;
        for (SalaryDetails s : list) {
            // 1.计算FYC
            if ("FYC".equals(s.getSalaryName())) {
                fyc = BigDecimal.valueOf(s.getCommission())
                        .add(BigDecimal.valueOf(fyc))
                        .doubleValue();
                count = count + 1;
                isFYCExist = true;
            }
        }

        if (!isFYCExist) {
            return null;
        }

        // FYP
        Double premium = 0D;
        for (SalaryDetails s : list) {
            // 2.调用N22保单接口获取每个保单的保费
            if ("FYC".equals(s.getSalaryName())) {
                premium = this.getFyp(s.getAppl_No());

                fyp = BigDecimal.valueOf(premium)
                        .add(BigDecimal.valueOf(fyp))
                        .doubleValue();
            }
        }

        PractitionerRankInfo rankInfo = new PractitionerRankInfo();
        rankInfo.setCount(count);
        rankInfo.setFyp(fyp);
        rankInfo.setFyc(fyc);
        rankInfo.setName(list.get(0).getStaffName());
        rankInfo.setSpcDivName(list.get(0).getRoleGroupDescription());

        return rankInfo;
    }

    private Map<Integer,PractitionerBasicInfo> getPractitionerBasicInfo(String mobileNo) {
        Map<Integer,PractitionerBasicInfo> practitionerBasicInfoMap = new HashMap<>();
        PractitionerBasicInfo practitionerBasicInfo1 = aclPractitionerDALService.getPractitionerBasicInfoForOnline(mobileNo);
        if(practitionerBasicInfo1 != null){
            Long practitionerId = practitionerBasicInfo1.getPractitionerIdForOnline();
            if(practitionerId != null){
                practitionerBasicInfo1.setPractitionerId(practitionerId.toString());
                practitionerBasicInfoMap.put(1,practitionerBasicInfo1);
            }
        }
        PractitionerBasicInfo practitionerBasicInfo2 = aclPractitionerDALService.getPractitionerBasicInfoForOffline(mobileNo);
        practitionerBasicInfoMap.put(2,practitionerBasicInfo2);
        return practitionerBasicInfoMap;
    }

    private void getPractitionerRankResult(PractitionerRankResponseVO responseVO, List<PractitionerRankInfo> rankInfoList, Integer type, Map<Integer,PractitionerBasicInfo> practitionerBasicInfoMap,Integer time,Integer platform,Long practitionerTypeId) {
        PractitionerInfoForAchievement practitionerInfo = new PractitionerInfoForAchievement(0D,0D,0);
        List<AclCustomerFortuneStatistics> rankList = new ArrayList<>();
        String practitionerId = practitionerBasicInfoMap.get(platform).getPractitionerId();
        if(!rankInfoList.isEmpty()){
            //排序---1-保费，2-佣金，3-件数
            if(2 == type){
                rankInfoList.sort(Comparator.comparingDouble(PractitionerRankInfo::getFyc).reversed());
            }else if(3 == type){
                rankInfoList.sort(Comparator.comparingInt(PractitionerRankInfo::getCount).reversed());
            }else{
                rankInfoList.sort(Comparator.comparingDouble(PractitionerRankInfo::getFyp).reversed());
            }
            AclCustomerFortuneStatistics fortuneStatistics;
            int rank = 1;
            Long practitionerIdForOnLine;
            String practitionerIdItem;
            for(PractitionerRankInfo practitionerItem : rankInfoList){
                //更新对象里面的内容，将PractitionerIdForOnLine里的信息赋值到PractitionerId
                practitionerIdForOnLine = practitionerItem.getPractitionerIdForOnLine();
                if(practitionerIdForOnLine != null){
                    practitionerItem.setPractitionerId(practitionerIdForOnLine.toString());
                }
                practitionerIdItem = practitionerItem.getPractitionerId();
                if(rank <= 10){//排名
                    fortuneStatistics = new AclCustomerFortuneStatistics();
                    BeanUtils.copyProperties(practitionerItem,fortuneStatistics);
                    fortuneStatistics.setSubordinateSystemName(practitionerItem.getSpcDivName());
                    fortuneStatistics.setRank(rank);
                    rankList.add(fortuneStatistics);
                }
                if(practitionerId.equals(practitionerIdItem)){//赋值
                    BeanUtils.copyProperties(practitionerItem,practitionerInfo);
                    practitionerInfo.setRank(rank);
                    if(rank > 10){
                        break;
                    }
                }
                rank ++;
            }
        }
        disposalPractitionerInfo(practitionerInfo,practitionerBasicInfoMap,time,platform);
        responseVO.setPractitionerInfo(practitionerInfo);
        if(practitionerTypeId == 28){
            responseVO.setRank(rankList);
        }
    }

    private void disposalPractitionerInfo(PractitionerInfoForAchievement practitionerInfo, Map<Integer,PractitionerBasicInfo> practitionerBasicInfoMap, Integer time, Integer platform) {
        Double fyc = practitionerInfo.getFyc();
        PractitionerRankInfo practitionerRankInfo = null;
        Double fycOther;
        PractitionerBasicInfo practitionerBasicInfoYD = practitionerBasicInfoMap.get(1);
        if(practitionerBasicInfoYD != null){
            String practitionerIdYD = practitionerBasicInfoYD.getPractitionerId();
            if(!Strings.isNullOrEmpty(practitionerIdYD)){
                Long practitionerId = Long.parseLong(practitionerIdYD);
                if(platform == 1){
                    PractitionerBasicInfo practitionerBasicInfoEG = practitionerBasicInfoMap.get(2);
                    if(practitionerBasicInfoEG != null){
                        String practitionerIdEG = practitionerBasicInfoEG.getPractitionerId();
                        if(!Strings.isNullOrEmpty(practitionerIdEG)){
                            practitionerRankInfo = aclPractitionerDALService.getPractitionerRankInfoByPractitionerIdEG(practitionerIdEG,time);
                        }
                    }
                }else{
                    practitionerRankInfo = aclPractitionerDALService.getPractitionerRankInfoByPractitionerIdYD(practitionerId,time);
                }
                fycOther = practitionerRankInfo != null ? practitionerRankInfo.getFyc() : 0D;
                Double fycSum = CommonUtil.doubleFormat(fyc+fycOther,2);
                if(fycSum != 0){
                    Double completeRate = getCompletionRate(practitionerId,null,fycSum,time);
                    practitionerInfo.setCompletionRate(completeRate);
                }
            }
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public SettingQueryResponseVO settingQuery(SettingQueryRequestVO requestVO) {
        SettingQueryResponseVO responseVO = new SettingQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();//入参经纪人id
        //需要查询的信息 1.自我介绍 2.我的设置 3.头像 4.个人微信二位码 5.生活照
        //1.2均在ag_acl_practitioner表中查询
        AclPractitioner practitioner = aclPractitionerDALService.findPractitionerById(practitionerId);
        String bioIntro = practitioner.getBioIntro();//经纪人个人介绍
        Integer isMobileShow = practitioner.getIsMobileShow();
        Integer isNameShow = practitioner.getIsNameShow();
        //3.4.5在ag_acl_file_upload中查询
        //target_type 1=从业人员practioner表, 2=员工user表,  3=客户customer表, 4=渠道客户channel表
        //target_use_for 文件用途 1=头像 2=生活照 3=证照 4=毕业证书 5=营业登记证 6.咨询定制方案 7.客户身份证正面照片 8.客户身份证反面照片 9.个人微信二维码
        //查询ag_acl_file_upload中isActive=1&&target_type=1&&target_id=practitionerId的信息
        AclFileUpload fileUpload = new AclFileUpload();
        fileUpload.setIsActive(1);
        fileUpload.setTargetType(1);
        fileUpload.setTargetId(practitionerId);
        List<AclFileUpload> fileUploads = aclFileUploadDALService.findByAclFileUpload(fileUpload);
        //筛选出头像
        BeanPropertyValueEqualsPredicate predicateClause  = new BeanPropertyValueEqualsPredicate("targetUseFor",1);
        List<AclFileUpload> headImgs = (List<AclFileUpload>) CollectionUtils.select(fileUploads,predicateClause);
        //头像至多一张
        String headImgUrl = null;
        if (!headImgs.isEmpty()){
            headImgUrl = headImgs.get(0).getFilePath();
        }
        //筛选出生活照
        predicateClause  = new BeanPropertyValueEqualsPredicate("targetUseFor",2);
        List<AclFileUpload> lifeImgs = (List<AclFileUpload>) CollectionUtils.select(fileUploads,predicateClause);
        List<LifeImg> lifeImgUrls = new ArrayList<>();
        for (AclFileUpload lifeImg: lifeImgs){
            LifeImg info = new LifeImg();
            info.setId(lifeImg.getId());
            info.setLifeImgUrl(lifeImg.getFilePath());
            lifeImgUrls.add(info);
        }
        //筛选出二维码
        predicateClause  = new BeanPropertyValueEqualsPredicate("targetUseFor",9);
        List<AclFileUpload> wxQRImgs = (List<AclFileUpload>) CollectionUtils.select(fileUploads,predicateClause);
        String wxQRImgUrl = null;
        if (!wxQRImgs.isEmpty()){
            wxQRImgUrl = wxQRImgs.get(0).getFilePath();
        }
        //返回参数
        responseVO.setPractitionerId(practitionerId);
        responseVO.setBioIntro(bioIntro);
        responseVO.setIsMobileShow(isMobileShow);
        responseVO.setIsNameShow(isNameShow);
        responseVO.setHeadImgUrl(headImgUrl);
        responseVO.setLifeImgUrls(lifeImgUrls);
        responseVO.setWxQRImgUrl(wxQRImgUrl);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    public ImgDeleteResponseVO imgDelete(ImgDeleteRequestVO requestVO) {
        ImgDeleteResponseVO responseVO = new ImgDeleteResponseVO();
        Long fileId = requestVO.getFileId();
        AclFileUpload fileUpload = new AclFileUpload();
        fileUpload.setId(fileId);
        fileUpload.setIsActive(0);
        aclFileUploadDALService.updateFileUpload(fileUpload);
        responseVO.setPractitionerId(requestVO.getPractitionerId());
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    @Transactional
    public SettingSaveResponseVO settingSave(SettingSaveRequestVO requestVO) throws Exception {
        SettingSaveResponseVO responseVO = new SettingSaveResponseVO();
        //入参判断
        CommonResult commonResult = paramCheck(requestVO);
        if (!commonResult.isSuccess()){
            responseVO.setCommonResult(commonResult);
            return responseVO;
        }
        //保存经纪人自我介绍及设置
        practitionerMySettingSave(requestVO);
        String settingSave = requestVO.getSettingSave();
        if (settingSave.equalsIgnoreCase("img")){
            String message;
            //保存头像
            message = practitionerHeadImgSave(requestVO);
            if (!CommonUtil.isNullOrBlank(message)){
                responseVO.setCommonResult(new CommonResult(false,message));
                return responseVO;
            }
            //保存生活照
            message = practitionerLifeImgSave(requestVO);
            if (!CommonUtil.isNullOrBlank(message)){
                responseVO.setCommonResult(new CommonResult(false,message));
                return responseVO;
            }
            //保存二维码
            message = practitionerWXQRImgSave(requestVO);
            if (!CommonUtil.isNullOrBlank(message)){
                responseVO.setCommonResult(new CommonResult(false,message));
                return responseVO;
            }

        }
        responseVO.setCommonResult(commonResult);
        return responseVO;
    }

    @Override
    public MediaGetRespVO mediaGet(MediaGetReqVO requestVO) {
        MediaGetRespVO mediaGetRespVO=new MediaGetRespVO();
        String message=ZHBErrorConfig.getErrorInfo("800000");
        String mediaId = requestVO.getMediaId();
        String accessToken = wechatService.obtainToken(new TokenRequest());
        System.out.println("accessToken:"+accessToken);
        TicketRequest ticketRequest = new TicketRequest();
        ticketRequest.setAccessToken(accessToken);
        String jsapiTicket = wechatService.obtainTicket(ticketRequest);
        System.out.println("jsapiTicket:"+jsapiTicket);
        String ImgUrl= "https://api.weixin.qq.com/cgi-bin/media/get?access_token="+accessToken+"&media_id="+mediaId;
        String scale = requestVO.getScale();
        //判断上传尺寸是否符合要求
        if(!CommonUtil.isNullOrBlank(scale)){
            Map<String,Object> input = HttpUtil.getInput(ImgUrl);
            if (!(boolean)input.get("success")){
                mediaGetRespVO.setCommonResult(new CommonResult(false, (String)input.get("message")));
                return mediaGetRespVO;
            }
            InputStream inputStream = (InputStream) input.get("is");
            //判断图像尺寸
            Image img = null;
            try {
                img = ImageIO.read(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
                mediaGetRespVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830003")));
                return mediaGetRespVO;
            }else {
                double width = img.getWidth(null);
                double height = img.getHeight(null);
                double value =height/width;
                double scaleDouble = Double.parseDouble(scale);
                if (value !=scaleDouble) {
                    if (scaleDouble == 1){
                        //上传头像尺寸比例为1:1
                        mediaGetRespVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830005")));
                        return mediaGetRespVO;
                    }else if(scaleDouble ==0.75) {
                        mediaGetRespVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830004")));
                        return mediaGetRespVO;
                    }
                }
            }
        }
//		System.out.println("ImgUrl:"+ImgUrl);
        mediaGetRespVO.setImgUrl(ImgUrl);
        mediaGetRespVO.setCommonResult(new CommonResult(true, message));
        return mediaGetRespVO;
    }

    @Override
    public OwnOpportunityQueryResponseVO ownOpportunityQuery(OwnOpportunityQueryRequestVO requestVO) {
        //查询自己的商机列表
        OwnOpportunityQueryResponseVO responseVO = new OwnOpportunityQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        //经纪人查询通过自己分享成为自己商机的客户
        AclPractitioner practitioner = aclPractitionerDALService.findPractitionerById(practitionerId);
        Long customerId = practitioner.getCustomerId();
        //查询自己的分享码，仅银盾服务产品
        List<AclCustomerShare> aclCustomerShareList = aclCustomerShareDALService.findByCustomerIdAndInsurerId(customerId,888L);
        List<String> customerShareCodes = new ArrayList<>();
        for ( AclCustomerShare aclCustomerShare:aclCustomerShareList ) {
            customerShareCodes.add(aclCustomerShare.getShareCode());
        }
        //此map存放customerId及订单id
        Map<Long,Long> opportunityDateMap = new HashMap<>();
        if (!customerShareCodes.isEmpty()){
            //通过shareCodeId查询成交的订单
            List<PoOrder> poOrderList = poOrderDALService.findByStatusAndShareCodeInGroupByCustomerId(3,customerShareCodes);
            //便利order，查询商机客户，及服务订单id
            for (PoOrder poOrder:poOrderList) {
                if (poOrder.getCustomerId().longValue() == customerId.longValue()){
                    continue;
                }
                opportunityDateMap.put(poOrder.getCustomerId(), poOrder.getId());
            }
        }
        List<OwnOpportunityInfo> ownOpportunityInfos = aclPractitionerDALService.ownOpportunityQuery(practitionerId);
        for (OwnOpportunityInfo info : ownOpportunityInfos){
            info.setOrderId(opportunityDateMap.get(info.getOpportunityId()));
        }
        responseVO.setOwnOpportunityInfos(ownOpportunityInfos);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    public OwnOpportunityDetailQueryResponseVO ownOpportunityDetailQuery(OwnOpportunityDetailQueryRequestVO requestVO) {
        OwnOpportunityDetailQueryResponseVO responseVO = new OwnOpportunityDetailQueryResponseVO();
        //商机客户基本信息
        OpportunityBasicInformationInfo basicInformationInfo = getOpportunityBasicInformation(requestVO);
        //调查问卷答案，咨询服务
        OpportunityConsultationInfo opportunityConsultationInfo = getOpportunityConsultation(requestVO);
        //商机跟进ag_survey_analysis_sales_record表差字段
        OpportunityRecordSituationInfo opportunityRecordSituationInfo = new OpportunityRecordSituationInfo();
        List<OpportunityRecordInfo> opportunityRecordInfos = getOpportunityRecords(requestVO);
        if (!opportunityRecordInfos.isEmpty()){
            opportunityRecordSituationInfo.setStatus(getRecordStatus(opportunityRecordInfos));
            opportunityRecordSituationInfo.setOpportunityRecordInfos(opportunityRecordInfos);
            //商机得分详情
            OpportunityScore opportunityScore = getOpportunityScore(opportunityRecordInfos);
            responseVO.setOpportunityScore(opportunityScore);
        }

        responseVO.setOpportunityRecordSituationInfo(opportunityRecordSituationInfo);
        responseVO.setOpportunityBasicInformationInfo(basicInformationInfo);
        responseVO.setOpportunityConsultationInfo(opportunityConsultationInfo);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    private Long getRecordStatus(List<OpportunityRecordInfo> opportunityRecordInfos) {
        Long mdDropOptionId = opportunityRecordInfos.get(0).getMdDropOptionId();
        List<MdDropOptions> mdDropOptions = mdDropOptionsDALService.findByDropMasterCode("bizchance_promotion_action");
        ConcurrentMap<String,Long> optionCodeToId = new ConcurrentHashMap<>();
        for (MdDropOptions info : mdDropOptions){
            optionCodeToId.put(info.getDropOptionCode(),info.getId());
        }
        Long refusedId = optionCodeToId.get("refused");
        if (mdDropOptionId.equals(refusedId)){
            return 1L;
        }
        return 0L;
    }

    private OpportunityScore getOpportunityScore(List<OpportunityRecordInfo> opportunityRecordInfos) {
        OpportunityScore opportunityScore = new OpportunityScore();
        Integer scoreDay = 0;
        Integer scoreWeek = 0;
        Integer scoreMonth = 0;
        Integer scoreYear = 0;
        Integer scoreTotal = 0;
        for (OpportunityRecordInfo info:opportunityRecordInfos){
            //总分数
            scoreTotal += info.getTrackScore();
            if (CommonUtil.isThisYear(info.getNoticeDate())){
                //本年分数
                scoreYear += info.getTrackScore();
                if (CommonUtil.isThisMonth(info.getNoticeDate())){
                    //本月分数
                    scoreMonth += info.getTrackScore();
                    if (CommonUtil.isToday(info.getNoticeDate())){
                        //今日分数
                        scoreDay += info.getTrackScore();
                    }
                }
            }
            if (CommonUtil.isThisWeek(info.getNoticeDate())){
                //本周分数
                scoreWeek += info.getTrackScore();
            }
        }
        opportunityScore.setScoreDay(scoreDay);
        opportunityScore.setScoreWeek(scoreWeek);
        opportunityScore.setScoreMonth(scoreMonth);
        opportunityScore.setScoreYear(scoreYear);
        opportunityScore.setScoreTotal(scoreTotal);
        return opportunityScore;
    }

    /**
     * 商机客户基本信息
     */
    private OpportunityBasicInformationInfo getOpportunityBasicInformation(OwnOpportunityDetailQueryRequestVO requestVO) {
        OpportunityBasicInformationInfo info = new OpportunityBasicInformationInfo();
        Long customerId = requestVO.getOpportunityId();
        Long practitionerId = requestVO.getPractitionerId();
        AclCustomer customer = aclCustomerDALService.findByCustomerId(customerId);
        info.setOpportunityId(customerId);
        info.setName(customer.getName());
        info.setAge(customer.getAge());
        info.setGender(customer.getGender());
        info.setMobileNo(customer.getMobileNo());
        info.setWeChat(customer.getWechatNo());
        info.setOtherContacts(customer.getOtherContacts());
        info.setZodiacTypeId(customer.getZodiacTypeId());
        if (!CommonUtil.isNullOrZero(customer.getZodiacTypeId())){
            MdDropOptions mdDropOption = mdDropOptionsDALService.findByDropOptionId(Long.valueOf(customer.getZodiacTypeId()));
            info.setZodiacType(mdDropOption.getDropOptionName());
        }
        info.setBloodTypeId(customer.getBloodTypeId());
        if (!CommonUtil.isNullOrZero(customer.getBloodTypeId())){
            MdDropOptions mdDropOption = mdDropOptionsDALService.findByDropOptionId(Long.valueOf(customer.getBloodTypeId()));
            info.setBloodType(mdDropOption.getDropOptionName());
        }
        String mktCampaign = customer.getMktCampaign();
        MktLeadsPool pool = mktLeadsPoolDALService.findByCustomerId(customerId);
        if (pool != null) {
            Integer sourceFrom = pool.getSourceFrom();
            String campaign = pool.getMktCampaign();
            if (!CommonUtil.isNullOrZero(sourceFrom)) {
                MdDropOptions dropOption = mdDropOptionsDALService.findByDropOptionId(Long.valueOf(sourceFrom));
                info.setSourceChannel(dropOption.getDropOptionName());
            } else if (!CommonUtil.isNullOrBlank(campaign)) {
                MdMkCampaign mdMkCampaign = mdMkCampaignDALService.findByMktCampaignId(Long.valueOf(campaign));
                info.setSourceChannel(mdMkCampaign.getName());
            }
        }

        info.setAddress(customer.getAddress());
        MktLeadsAssignedTrack mktLeadsAssignedTrack = new MktLeadsAssignedTrack();
        mktLeadsAssignedTrack.setPractitionerId(practitionerId);
        mktLeadsAssignedTrack.setCustomerId(customerId);
        PageHelper.orderBy("created_at DESC");
        List<MktLeadsAssignedTrack> mktLeadsAssignedTracks = mktLeadsAssignedTrackDALService.findByMktLeadsAssignedTrack(mktLeadsAssignedTrack);
        Long opportunityDropOptionId = 0L;
        if (!mktLeadsAssignedTracks.isEmpty()){
            opportunityDropOptionId = mktLeadsAssignedTracks.get(0).getMdDropOptionId();
        }
        info.setMdDropOptionId(opportunityDropOptionId);
        if (!CommonUtil.isNullOrZero(opportunityDropOptionId)){
            MdDropOptions mdDropOption = mdDropOptionsDALService.findByDropOptionId(opportunityDropOptionId);
            info.setMdDropOptionName(mdDropOption.getDropOptionName());
        }
        MktLeadsAssigneds mktLeadsAssigneds = new MktLeadsAssigneds();
        mktLeadsAssigneds.setCustomerId(customerId);
        mktLeadsAssigneds.setAssignedPractitionerId(practitionerId);
        List<MktLeadsAssigneds>  mktLeadsAssignedsList =mktLeadsAssignedsDALService.findByMktLeadsAssigneds(mktLeadsAssigneds);
        mktLeadsAssigneds = mktLeadsAssignedsList.get(0);
        info.setFyc(mktLeadsAssigneds.getFyc());
        info.setFyp(mktLeadsAssigneds.getFyp());
        info.setPieces(mktLeadsAssigneds.getPieces());
        info.setRemark(mktLeadsAssigneds.getRemark());
        info.setTimeToClose(CommonUtil.dateParseString(mktLeadsAssigneds.getTimeToClose(),"yyyy-MM-dd"));
        info.setOpportunityDate(CommonUtil.dateParseString(mktLeadsAssigneds.getCreatedAt(),"yyyy-MM-dd HH:mm:ss"));
        info.setOpportunityCustomerTags(OpportunityCustomerTags(customerId));

        //查询此商机是否有申请专家
        info.setExpertType(0L);
        MktLeadsExpertRequest mktLeadsExpertRequest = mktLeadsExpertRequestDALService.findByCustomerId(mktLeadsAssigneds.getCustomerId());
        if (mktLeadsExpertRequest != null){
            //有申请专家  查询是否指派专家
            info.setExpertType(1L);
            Long mktLeadsExpertRequestId = mktLeadsExpertRequest.getId();
            MktLeadsExpertAssign mktLeadsExpertAssign = mktLeadsExpertAssignDALService.findByLeadsExpertRequestId(mktLeadsExpertRequestId);
            if (mktLeadsExpertAssign != null){
                //以指派专家
                info.setExpertType(2L);
                Long expertPractitionerId = mktLeadsExpertAssign.getExpertPractitionerId();
                AclPractitioner expertPractitioner = aclPractitionerDALService.findById(expertPractitionerId);
                info.setExpertPractitionerId(expertPractitionerId);
                info.setExpertPractitionerName(expertPractitioner.getName());
            }
        }

        return info;
    }

    /**
     * 客户标签查询
     */
    private List<OpportunityCustomerTag> OpportunityCustomerTags(Long customerId) {
        List<OpportunityCustomerTag> tags = new ArrayList<>();
        ObjectCollectionTagged objectCollectionTagged = new ObjectCollectionTagged();
        objectCollectionTagged.setIsActive(1);
        objectCollectionTagged.setTaggedObjectType(4);
        objectCollectionTagged.setTaggedObjectId(customerId);
        List<ObjectCollectionTagged> taggeds = objectCollectionTaggedDALService.findByObjectCollectionTagged(objectCollectionTagged);
        List<Long> tagIds = new ArrayList<>();
        for (ObjectCollectionTagged tagged: taggeds) {
            tagIds.add(Long.valueOf(tagged.getMdTagId()));
        }
        if (!tagIds.isEmpty()){
            List<MdTag> mdTags = mdTagDALService.findByTagIdIn(tagIds);
            for (MdTag mdTag:mdTags) {
                OpportunityCustomerTag tag = new OpportunityCustomerTag();
                tag.setTagId(mdTag.getId());
                tag.setTagName(mdTag.getTagName());
                tags.add(tag);
            }
        }
        return tags;
    }

    /**
     * 调查问卷答案，咨询服务
     */
    private OpportunityConsultationInfo getOpportunityConsultation(OwnOpportunityDetailQueryRequestVO requestVO) {
        OpportunityConsultationInfo info = new OpportunityConsultationInfo();
        Long orderId = requestVO.getOrderId();
        if (CommonUtil.isNullOrZero(orderId)){
            return info;
        }
        info.setOrderId(orderId);
        PoOrder poOrder = poOrderDALService.findByOrderId(requestVO.getOrderId());
        Long planId = poOrder.getPlanId();
        if (planId==453L||planId==464L) {
            info.setIsCompletedQuestionnaire(3L);
        }else {
            AclCustomerMembership membership = aclCustomerMembershipDALService.findByOrderId(requestVO.getOrderId());
            info.setIsCompletedQuestionnaire( (membership.getApproveDate() != null) ? 3L : 1L);
        }
        info.setOpportunitySurveyAnswersList(findSurveyAnswers(requestVO));
        return info;
    }

    /**
     * 问卷答案
     */
    @SuppressWarnings("unchecked")
    private List<OpportunitySurveyAnswers> findSurveyAnswers(OwnOpportunityDetailQueryRequestVO requestVO) {
        Long customerId = requestVO.getOpportunityId();
        Long orderId = requestVO.getOrderId();
        SurveyCustomerAnswers surveyCustomerAnswersQuery=new SurveyCustomerAnswers();
        surveyCustomerAnswersQuery.setOrderId(orderId);
        surveyCustomerAnswersQuery.setCustomerId(customerId);
        List<SurveyCustomerAnswers> surveyCustomerAnswersList = surveyCustomerAnswersDALService.findByObjGroupByOrderBy(surveyCustomerAnswersQuery,null,null);
        List<SurveyCustomerAnswers> surveyQuestionsList = surveyCustomerAnswersDALService.findByObjGroupByOrderBy(surveyCustomerAnswersQuery,"question_name","id");
        List<OpportunitySurveyAnswers> req=new ArrayList<>();
        for (SurveyCustomerAnswers surveyQuestions : surveyQuestionsList) {
            String questionName = surveyQuestions.getQuestionName();
            BeanPropertyValueEqualsPredicate predicateClause = new BeanPropertyValueEqualsPredicate( "questionName", questionName);
            List<SurveyCustomerAnswers> mainRisks = (List<SurveyCustomerAnswers>) CollectionUtils.select(surveyCustomerAnswersList, predicateClause);
            OpportunitySurveyAnswers surveyAnswers=new OpportunitySurveyAnswers();
            surveyAnswers.setQuestionName(surveyQuestions.getQuestionName());
            List<String> optionNameList=new ArrayList<>();
            for (SurveyCustomerAnswers surveyCustomerAnswers : mainRisks) {
                if (surveyCustomerAnswers.getOptionName() != null) {
                    optionNameList.add(surveyCustomerAnswers.getOptionName());
                }
                if (surveyCustomerAnswers.getCustomerInput() != null){
                    optionNameList.add(surveyCustomerAnswers.getCustomerInput());
                }
            }
            surveyAnswers.setOptionName(optionNameList);
            req.add(surveyAnswers);
        }
        return req;
    }

    @SuppressWarnings("unchecked")
    private List<OpportunityRecordInfo> getOpportunityRecords(OwnOpportunityDetailQueryRequestVO requestVO) {
        Long practitionerId = requestVO.getPractitionerId();
        Long customerId = requestVO.getOpportunityId();
        List<OpportunityRecordInfo> infos = new ArrayList<>();
        MktLeadsAssignedTrack mktLeadsAssignedTrack = new MktLeadsAssignedTrack();
        mktLeadsAssignedTrack.setPractitionerId(practitionerId);
        mktLeadsAssignedTrack.setCustomerId(customerId);
        PageHelper.orderBy("track_time DESC , created_at DESC , updated_at DESC");
        List<MktLeadsAssignedTrack> mktLeadsAssignedTracks = mktLeadsAssignedTrackDALService.findByMktLeadsAssignedTrack(mktLeadsAssignedTrack);
        List<MdDropOptions> dropOptionsList = mdDropOptionsDALService.findByDropMasterCode("bizchance_promotion_action");
        for (MktLeadsAssignedTrack track : mktLeadsAssignedTracks) {
            OpportunityRecordInfo info = new OpportunityRecordInfo();
            CommonUtil.simpleObjectCopy(track, info);
            info.setOpportunityId(track.getCustomerId());
            info.setNoticeDate(CommonUtil.dateParseString(track.getTrackTime(), "yyyy-MM-dd"));
            BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("id", track.getMdDropOptionId());
            List<MdDropOptions> select = (List<MdDropOptions>)CollectionUtils.select(dropOptionsList, predicate);
            if (!select.isEmpty()){
                info.setMdDropOptionName(select.get(0).getDropOptionName());
            }
            infos.add(info);
        }
        return infos;
    }

    @Override
    public RecruitResponseVO recruit(RecruitRequestVO requestVO) {
        RecruitResponseVO responseVO = new RecruitResponseVO();
        String name = requestVO.getName();
        String mobileNo = requestVO.getMobileNo();
        Long practitionerId = requestVO.getPractitionerId();
        if(!Strings.isNullOrEmpty(name) && !Strings.isNullOrEmpty(mobileNo) && practitionerId != null){
            if(mobileNo.length() != 11 || mobileNo.startsWith("1")){
                RegisterRequestVO register = new RegisterRequestVO();
                register.setMobileNo(mobileNo);
                register.setName(name);
                //将增员对象进行注册
                RegisterResponseVO registerResp = customerService.register(register);
                Long customerId = registerResp.getCustomerId();
                //判断是否已经为银盾经纪人
                AclPractitioner practitioner = aclPractitionerDALService.findByCustomerIdIsActive(customerId,1);
                if(practitioner == null){
                    //判断该增员是否已存在
                    Long potentialId = requestVO.getPotentialId();
                    String timeToOnboarding = requestVO.getTimeToOnboarding();
                    List<AclPractitionerPotential> practitionerPotentialList = aclPractitionerPotentialDALService.findByMobileNo(mobileNo,1);
                    if(potentialId != null || practitionerPotentialList.isEmpty()){
                        String remark = requestVO.getRemark();
                        AclPractitionerPotential practitionerPotential = new AclPractitionerPotential();
                        BeanUtils.copyProperties(requestVO,practitionerPotential);
                        practitionerPotential.setCustomerId(customerId);
                        practitionerPotential.setPractitionerAssignedIds(practitionerId.toString());
                        practitionerPotential.setIsActive(1);
                        if(potentialId != null){
                            practitionerPotential.setId(potentialId);
                            practitionerPotential.setUpdatedAt(new Date());
                            practitionerPotential.setUpdatedBy(practitionerId);
                            practitionerPotential.setUpdaterType(2);
                            aclPractitionerPotentialDALService.update(practitionerPotential);
                            //更新该经纪人的备注
                            updateRecruitRemark(potentialId,practitionerId,remark,timeToOnboarding);
                        }else{
                            practitionerPotential.setCreatedAt(new Date());
                            practitionerPotential.setCreatedBy(practitionerId);
                            practitionerPotential.setCreatorType(2);
                            aclPractitionerPotentialDALService.save(practitionerPotential);
                            potentialId = practitionerPotential.getId();
                            //如果已经分配团队长，则在追踪表中增加记录
                            List<Long> practitionerPotentialIdList = new ArrayList<>();
                            practitionerPotentialIdList.add(potentialId);
                            addPractitionerPotentialTrack(practitionerPotentialIdList, practitionerId,remark,timeToOnboarding);
                        }
                        responseVO.setPotentialCustomerId(customerId);
                        responseVO.setPotentialId(potentialId);
                        responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
                    }else{
                        responseVO.setPotentialCustomerId(customerId);
                        responseVO.setPotentialId(practitionerPotentialList.get(0).getId());
                        responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("830011")));
                    }
                }else{
                    responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("830010")));
                }
            }else{
                String [] paras = {mobileNo};
                responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("630001",paras)));
            }
        }else{
            String [] paras = {"name,mobileNo,practitionerId"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }

    /**
     * 更新经纪人对增员对备注
     * @param potentialId 增员id
     * @param practitionerId 团队长id
     * @param remark 备注
     */
    private void updateRecruitRemark(Long potentialId, Long practitionerId, String remark,String timeToOnboarding) {
        if(potentialId != null && practitionerId != null && !Strings.isNullOrEmpty(remark)){
            List<AclPractitionerPotentialAssigneds> assignedsList = aclPractitionerPotentialAssignedsDALService.findByPotentialIdAndPractitionerId(potentialId,practitionerId);
            if(assignedsList != null && !assignedsList.isEmpty()){
                AclPractitionerPotentialAssigneds assigneds = assignedsList.get(0);
                assigneds.setRemark(remark);
                assigneds.setTimeToOnboarding(CommonUtil.stringParseDate(timeToOnboarding,"yyyy-MM-dd"));
                aclPractitionerPotentialAssignedsDALService.update(assigneds);
            }
        }
    }

    private void addPractitionerPotentialTrack(List<Long> practitionerPotentialIdList, Long practitionerId,String remark,String timeToOnboarding) {
        if (practitionerId != null && !practitionerPotentialIdList.isEmpty()) {
            List<AclPractitionerPotentialAssignedTrack> potentialAssignedTrackList = new ArrayList<>();
            AclPractitionerPotentialAssignedTrack potentialAssignedTrack;
            List<AclPractitionerPotentialAssigneds> potentialAssignedsList = new ArrayList<>();
            AclPractitionerPotentialAssigneds potentialAssigneds;
            Long trackStatusId = 107L;
            Integer trackScore = 2;
            List<MdDropOptions> optionsList = mdDropOptionsDALService.findByMasterCodeAndOrderId("team_building_track",1);
            if(optionsList != null && !optionsList.isEmpty()){
                MdDropOptions options = optionsList.get(0);
                trackStatusId = options.getId();
                trackScore = options.getDropOptionScore();
            }
            for (Long potentialId : practitionerPotentialIdList) {
                potentialAssignedTrack = new AclPractitionerPotentialAssignedTrack();
                potentialAssignedTrack.setPractitionerPotentialId(potentialId);
                potentialAssignedTrack.setPractitionerAssignedId(practitionerId);
                potentialAssignedTrack.setTrackStatusId(trackStatusId);//待跟进
                potentialAssignedTrack.setIsActive(1);
                potentialAssignedTrack.setIsLasted(1);
                potentialAssignedTrack.setCreatedAt(new Date());
                potentialAssignedTrack.setCreatedBy(practitionerId);
                potentialAssignedTrack.setCreatorType(2);
                potentialAssignedTrack.setTrackScore(trackScore);
                potentialAssignedTrack.setTrackTime(new Date());
                potentialAssignedTrack.setNotice(remark);
                potentialAssignedTrackList.add(potentialAssignedTrack);

                potentialAssigneds = new AclPractitionerPotentialAssigneds();
                potentialAssigneds.setAssignedPractitionerId(practitionerId);
                potentialAssigneds.setPractitionerPotentialId(potentialId);
                potentialAssigneds.setTimeToOnboarding(CommonUtil.stringParseDate(timeToOnboarding,"yyyy-MM-dd"));
                potentialAssigneds.setRemark(remark);
                potentialAssigneds.setIsActive(1);
                potentialAssigneds.setCreatedAt(new Date());
                potentialAssigneds.setCreatedBy(practitionerId);
                potentialAssigneds.setCreatorType(2);
                potentialAssignedsList.add(potentialAssigneds);

            }
            aclPractitionerPotentialAssignedTrackDALService.saveAll(potentialAssignedTrackList);
            aclPractitionerPotentialAssignedsDALService.saveAll(potentialAssignedsList);
        }
    }

    @Override
    @Transactional
    public AddRecruitTrackResponseVO addRecruitTrack(AddRecruitTrackRequestVO requestVO) {
        AddRecruitTrackResponseVO responseVO = new AddRecruitTrackResponseVO();
        Long trackStatusId = requestVO.getTrackStatusId();
        Long practitionerId = requestVO.getPractitionerId();
        Long potentialId = requestVO.getPotentialId();
        String trackTime = requestVO.getTrackTime();
        if(trackStatusId != null && practitionerId != null && potentialId != null && !Strings.isNullOrEmpty(trackTime)){
            Date trackTimeDate = CommonUtil.stringParseDate(trackTime,"yyyy-MM-dd");
            AclPractitionerPotentialAssignedTrack assignedTrack = new AclPractitionerPotentialAssignedTrack();
            List<AclPractitionerPotentialAssignedTrack> assignedTrackIsLastedList = aclPractitionerPotentialAssignedTrackDALService.findByPotentialIdAndIsLasted(potentialId,1);
            //1、更新最新的状态
            if(assignedTrackIsLastedList != null && !assignedTrackIsLastedList.isEmpty()){
                List<AclPractitionerPotentialAssignedTrack> assignedTrackUpdateList = new ArrayList<>();
                for(AclPractitionerPotentialAssignedTrack item : assignedTrackIsLastedList){
                    item.setIsLasted(0);
                    item.setUpdatedBy(practitionerId);
                    item.setUpdaterType(2);
                    item.setUpdatedAt(new Date());
                    assignedTrackUpdateList.add(item);
                }
                aclPractitionerPotentialAssignedTrackDALService.updateAll(assignedTrackUpdateList);
            }
            //2、查询团队长对该增员所有增员状态
            List<AclPractitionerPotentialAssignedTrack> assignedTrackList = aclPractitionerPotentialAssignedTrackDALService.findByPractitionerIdAndPotentialIdAndTrackStatusId(practitionerId,potentialId,trackStatusId,trackTimeDate);
            if(assignedTrackList == null || assignedTrackList.isEmpty()){//3、如果没有，获取增员状态对应的分值，
                MdDropOptions options = mdDropOptionsDALService.findById(trackStatusId);
                assignedTrack.setTrackScore(options.getDropOptionScore());
                assignedTrack.setPractitionerAssignedId(practitionerId);
                assignedTrack.setPractitionerPotentialId(potentialId);
                assignedTrack.setTrackStatusId(trackStatusId);
                assignedTrack.setNotice(requestVO.getNotice());
                assignedTrack.setTrackTime(trackTimeDate);
                assignedTrack.setIsActive(1);
                assignedTrack.setIsLasted(1);
                assignedTrack.setCreatorType(2);
                assignedTrack.setCreatedBy(practitionerId);
                assignedTrack.setCreatedAt(new Date());
                aclPractitionerPotentialAssignedTrackDALService.save(assignedTrack);
                responseVO.setTrackId(assignedTrack.getId());
            }else{
                assignedTrack = assignedTrackList.get(0);
                assignedTrack.setNotice(requestVO.getNotice());
                assignedTrack.setIsLasted(1);
                assignedTrack.setUpdatedAt(new Date());
                assignedTrack.setUpdatedBy(practitionerId);
                assignedTrack.setUpdaterType(2);
                aclPractitionerPotentialAssignedTrackDALService.update(assignedTrack);
            }
            responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
        }else{
            String [] paras = {"trackStatusId,practitionerId,potentialId,trackTime"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }

    @Override
    public RecruitTrackQueryResponseVO recruitTrackQuery(RecruitTrackQueryRequestVO requestVO) {
        RecruitTrackQueryResponseVO responseVO = new RecruitTrackQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        Long potentialId = requestVO.getPotentialId();
        if(potentialId != null && practitionerId != null){
            List<AclPractitionerPotentialAssignedTrack> assignedTrackList = aclPractitionerPotentialAssignedTrackDALService.findByPractitionerIdAndPotentialId(practitionerId,potentialId);
            if(assignedTrackList != null && !assignedTrackList.isEmpty()){
                Map<Integer,Map<Long,String>> nameMap = getOperateName(assignedTrackList);
                Map<Long,String> userMap = nameMap.get(1);
                Map<Long,String> practitionerMap = nameMap.get(2);
                Map<Long,String> trackStatusMap = new HashMap<>();
                List<MdDropOptions> dropOptionsList = mdDropOptionsDALService.findByMasterCode("team_building_track");
                dropOptionsList.forEach(i->trackStatusMap.put(i.getId(),i.getDropOptionName()));
                List<RecruitTrackInfo> recruitTrackInfoList = new ArrayList<>();
                RecruitTrackInfo recruitTrack;
                Long operateUserId,trackStatusId;
                Integer operateUserType;
                String operateUserName;
                for(AclPractitionerPotentialAssignedTrack item : assignedTrackList){
                    operateUserId = item.getCreatedBy();
                    trackStatusId = item.getTrackStatusId();
                    operateUserType = item.getCreatorType();
                    operateUserName = (operateUserType == 1) ? userMap.get(operateUserId) : practitionerMap.get(operateUserId);
                    recruitTrack = new RecruitTrackInfo();
                    recruitTrack.setTrackId(item.getId());
                    recruitTrack.setNotice(item.getNotice());
                    recruitTrack.setOperateUserId(operateUserId);
                    recruitTrack.setOperateUserName(operateUserName);
                    recruitTrack.setTrackStatusId(trackStatusId);
                    recruitTrack.setTrackStatus(trackStatusMap.get(trackStatusId));
                    recruitTrack.setCreateAt(CommonUtil.dateParseString(item.getCreatedAt(),"yyyy-MM-dd HH:mm:ss"));
                    recruitTrack.setTrackTime(CommonUtil.dateParseString(item.getTrackTime(),"yyyy-MM-dd"));
                    recruitTrackInfoList.add(recruitTrack);
                    responseVO.setRecruitTrackInfoList(recruitTrackInfoList);
                    responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
                }
            }else{
                responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("820001")));
            }
        }else{
            String [] paras = {"practitionerId,potentialId"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }

    private Map<Integer, Map<Long, String>> getOperateName(List<AclPractitionerPotentialAssignedTrack> assignedTrackList) {
        Map<Integer, Map<Long, String>> nameMap = new HashMap<>();
        Map<Long, String> practitionerMap = new HashMap<>();
        Map<Long, String> userMap = new HashMap<>();
        Set<Long> practitionerIdSet = new HashSet<>();
        Set<Long> userIdSet = new HashSet<>();
        for(AclPractitionerPotentialAssignedTrack item : assignedTrackList){
            if(item.getCreatorType() == 2){
                practitionerIdSet.add(item.getCreatedBy());
            }else{
                userIdSet.add(item.getCreatedBy());
            }
        }
        List<Long> practitionerIdList = new ArrayList<>(practitionerIdSet);
        List<Long> userIdList = new ArrayList<>(userIdSet);
        if(!practitionerIdList.isEmpty()){
            List<AclPractitioner> practitionerList = aclPractitionerDALService.findByIds(practitionerIdList);
            practitionerList.forEach(i->practitionerMap.put(i.getId(),i.getName()));
        }
        if(!userIdList.isEmpty()){
            List<AclUser> userList = aclUserDALService.findByIds(userIdList);
            userList.forEach(i->userMap.put(i.getId(),i.getName()));
        }
        nameMap.put(1,userMap);
        nameMap.put(2,practitionerMap);
        return nameMap;
    }

    @Override
    public RecruitListResponseVO recruitListQuery(RecruitListRequestVO requestVO) {
        RecruitListResponseVO responseVO = new RecruitListResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        if(practitionerId != null){
            Integer status = requestVO.getStatus();
            //1、获取用户数据
            List<PractitionerPotentialInfo> practitionerPotentialInfoList = aclPractitionerPotentialDALService.findByPractitionerIdAndLasted(practitionerId);
            if(practitionerPotentialInfoList != null && !practitionerPotentialInfoList.isEmpty()){
                List<MdDropOptions> trackStatusList = mdDropOptionsDALService.findByMasterCode("team_building_track");
                Map<Integer,Long> trackStatusInfo = getTrackStatusInfo(trackStatusList);
                Long firstTrackStatusId = trackStatusInfo.get(1);
                Long LastStatusId = trackStatusInfo.get(2);
                Map<Long,String> trackStatusMap = new HashMap<>();
                trackStatusList.forEach(i->trackStatusMap.put(i.getId(),i.getDropOptionName()));
                List<MdDropOptions> recruitSourceList = mdDropOptionsDALService.findByMasterCode("team_building_source");
                Map<Long,String> recruitSourceMap = new HashMap<>();
                recruitSourceList.forEach(i->recruitSourceMap.put(i.getId(),i.getDropOptionName()));
                List<PractitionerPotentialInfo> potentialInfoList = new ArrayList<>();
                Long trackStatusId;
                List<AclPractitionerPotentialAssigneds> assignedsList = aclPractitionerPotentialAssignedsDALService.findByPractitionerId(practitionerId);
                Map<Long,String> remarkMap = new HashMap<>();
                assignedsList.forEach(i->remarkMap.put(i.getPractitionerPotentialId(),i.getRemark()));
                List<Long> potentialIdList = new ArrayList<>(remarkMap.keySet());
                List<AclPractitionerPotentialAssigneds> assigneds = aclPractitionerPotentialAssignedsDALService.findByPractitionerIdAndPotentialIdList(practitionerId,potentialIdList);
                Map<Long,Date> timeToOnBoardingMap = new HashMap<>();
                assigneds.forEach(i->timeToOnBoardingMap.put(i.getPractitionerPotentialId(),i.getTimeToOnboarding()));
                //待开发   --查询预计报聘时间
                for(PractitionerPotentialInfo item : practitionerPotentialInfoList){
                    trackStatusId = item.getTrackStatusId();
                    if(status != null){
                        if(status == 1 && trackStatusId.longValue() == firstTrackStatusId){
                            getResponseMessage(potentialInfoList,trackStatusMap,recruitSourceMap,item,remarkMap,timeToOnBoardingMap);
                        }else if(status == 3 && trackStatusId.longValue() == LastStatusId){
                            getResponseMessage(potentialInfoList,trackStatusMap,recruitSourceMap,item,remarkMap,timeToOnBoardingMap);
                        }else if(status == 2 && trackStatusId.longValue() != LastStatusId && trackStatusId.longValue() != firstTrackStatusId){
                            getResponseMessage(potentialInfoList,trackStatusMap,recruitSourceMap,item,remarkMap,timeToOnBoardingMap);
                        }
                    }else{
                        getResponseMessage(potentialInfoList,trackStatusMap,recruitSourceMap,item,remarkMap,timeToOnBoardingMap);
                    }
                }
                potentialInfoList.sort((o1, o2) -> o2.getUpdateAt().compareTo(o1.getUpdateAt()));
                responseVO.setPractitionerPotentialInfoList(potentialInfoList);
                responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
            }else{
                responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("820001")));
            }
        }else{
            String [] paras = {"practitionerId"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }


    private void getResponseMessage(List<PractitionerPotentialInfo> potentialInfoList, Map<Long, String> trackStatusMap,Map<Long,String> recruitSourceMap, PractitionerPotentialInfo item,Map<Long,String> remarkMap,Map<Long,Date> timeToOnBoardingMap) {
        PractitionerPotentialInfo potentialInfo = new PractitionerPotentialInfo();
        BeanUtils.copyProperties(item,potentialInfo);
        potentialInfo.setRemark(remarkMap.get(item.getPotentialId()));
        potentialInfo.setTrackStatus(trackStatusMap.get(item.getTrackStatusId()));
        potentialInfo.setResourceDropMasterName(recruitSourceMap.get(item.getResourceDropMasterId()));
        potentialInfo.setTimeToOnboarding(CommonUtil.dateParseString(timeToOnBoardingMap.get(item.getPotentialId()),"yyyy-MM-dd"));
        potentialInfo.setUpdateAt(item.getUpdateAt());
        potentialInfoList.add(potentialInfo);
    }

    private Map<Integer,Long> getTrackStatusInfo(List<MdDropOptions> trackStatusList) {
        Map<Integer,Long> trackStatusInfo = new HashMap<>();
        Long firstTrackStatusId = null ,LastStatusId = null,id;
        Integer orderId,min = null,max = null;
        for(MdDropOptions item : trackStatusList){
            id = item.getId();
            orderId = item.getDropOptionOrder();
            if(orderId < 50){
                if(firstTrackStatusId == null){
                    firstTrackStatusId = LastStatusId = id;
                    min = max = orderId;
                }else{
                    if(orderId < min){
                        firstTrackStatusId = id;
                        min = orderId;
                    }else if(orderId > max){
                        LastStatusId = id;
                        max = orderId;
                    }
                }
            }
        }
        trackStatusInfo.put(1,firstTrackStatusId);
        trackStatusInfo.put(2,LastStatusId);
        return trackStatusInfo;
    }

    @Override
    public OwnOpportunityBasicInformationSaveResponseVO ownOpportunityBasicInformationSave(OwnOpportunityBasicInformationSaveRequestVO requestVO) {
        OwnOpportunityBasicInformationSaveResponseVO resp = new OwnOpportunityBasicInformationSaveResponseVO();
        Long leadsAssignedId = requestVO.getLeadsAssignedId();
        Long customerId = requestVO.getOpportunityId();
        if (CommonUtil.isNullOrZero(leadsAssignedId)){
            //判断是否为经纪人自己创建商机
            CommonResult commonResult = isCreateOpportunity(requestVO);
            if (!commonResult.isSuccess()){
                resp.setCommonResult(commonResult);
                return resp;
            }
            customerId = requestVO.getOpportunityId();
        }

        //保存基础信息
        saveCustomerInfo(customerId,requestVO);
        //保存/激活新的标签
        saveCustomerTag(customerId,requestVO.getOpportunityCustomerTags());
        //更新预设值
        saveLeadsAssigneds(requestVO);
        resp.setLeadsAssignedId(requestVO.getLeadsAssignedId());
        resp.setOpportunityId(customerId);
        resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return resp;
    }

    private CommonResult isCreateOpportunity(OwnOpportunityBasicInformationSaveRequestVO requestVO) {
        Long customerId;
        //当指派id为null时,认为是保存新的商机
        //校验商机号码,手机号码对应的customer是否存在
        String mobileNo = requestVO.getMobileNo();
        AclCustomer aclCustomer = aclCustomerDALService.findByMobileNo(mobileNo);
        Long mdMkCampaignId = systemConfigService.getMdMkCampaignId("leadaddedbypractioner");

        //判断是否通过手机号码找到客户
        if (aclCustomer!=null){
            MktLeadsAssigneds mktLeadsAssigneds = new MktLeadsAssigneds();
            mktLeadsAssigneds.setCustomerId(aclCustomer.getId());
            List<MktLeadsAssigneds> mktLeadsAssignedsList = mktLeadsAssignedsDALService.findByMktLeadsAssigneds(mktLeadsAssigneds);
            if (!mktLeadsAssignedsList.isEmpty()){
                MktLeadsAssignedTrack leadsAssignedTrack = mktLeadsAssignedTrackDALService.findByListNotesForCustomerId(aclCustomer.getId());
                Long mdDropOptionId = leadsAssignedTrack.getMdDropOptionId();
                //判断最后一条跟进状态是否为失败,是失败则无需判断经纪人id和之前是否一致
                MdDropOptions mdDropOption = mdDropOptionsDALService.findById(mdDropOptionId);
                if (!"refused".equalsIgnoreCase(mdDropOption.getDropOptionCode())){
                    //跳出错误
                    return new CommonResult(false,ZHBErrorConfig.getErrorInfo("830014"));
                }
            }
        }else {
            //此人为第一次进来
            //帮其经行注册
            aclCustomer = new AclCustomer();
            aclCustomer.setRole(2);//1= Staff 2=Customer 3=Partner
            aclCustomer.setAccountId(createAccountId(mobileNo));
            aclCustomer.setLogin(mobileNo);
            aclCustomer.setMobileNo(mobileNo);
            aclCustomer.setCusLevel(1);
            aclCustomer.setName(requestVO.getName());
            aclCustomer.setIsActive(1);
            aclCustomer.setRoleId(3L);
            aclCustomer.setWithdrawType(0);
            aclCustomer.setCreatedAt(new Date());
            aclCustomer.setCreatedBy(-1L);
            aclCustomer.setUpdatedAt(new Date());
            aclCustomer.setUpdatedBy(-1L);
            aclCustomer.setChannelReferralRateId(3L);
            aclCustomer.setMktCampaign(String.valueOf(mdMkCampaignId));
            aclCustomerDALService.save(aclCustomer);
        }
        customerId = aclCustomer.getId();
        //查询此customer是否在pool中
        MktLeadsPool pool = mktLeadsPoolDALService.findByCustomerId(customerId);
        if (pool == null){
            //线索池为空时,保存线索池
            pool = new MktLeadsPool();
            pool.setMktCampaign(String.valueOf(mdMkCampaignId));
            pool.setCustomerId(customerId);
            pool.setHasAssigned(1);
            pool.setSourceFrom(requestVO.getSourceFrom());
            pool.setIsActive(1);
            pool.setAddedAt(new Date());
            pool.setAddedBy(requestVO.getAssignedPractitionerId());
            pool.setAdderType(2);
            mktLeadsPoolDALService.save(pool);
        }
        //保存至指派表
        MktLeadsAssigneds assigneds = new MktLeadsAssigneds();
        assigneds.setAssignedPractitionerId(requestVO.getAssignedPractitionerId());
        assigneds.setCustomerId(customerId);
        assigneds.setIsActive(1);
        assigneds.setCreatedAt(new Date());
        assigneds.setCreatedBy(-1L);
        assigneds.setUpdatedAt(new Date());
        assigneds.setUpdatedBy(-1L);
        mktLeadsAssignedsDALService.save(assigneds);
        //更新跟进表初始值
        String mdDropOptionsId = systemConfigService.getSingleConfigValue("OpportunityToBeFollowedUp");
        MdDropOptions mdDropOptions = mdDropOptionsDALService.findById(Long.valueOf(mdDropOptionsId));
        MktLeadsAssignedTrack leadsAssignedTrack = new MktLeadsAssignedTrack();
        leadsAssignedTrack.setSalesNotice("获得此商机,"+CommonUtil.dateParseString(new Date(),"yyyy-MM-dd HH:mm:ss"));
        leadsAssignedTrack.setTrackScore(mdDropOptions.getDropOptionScore());
        leadsAssignedTrack.setIsActive(1);
        leadsAssignedTrack.setCreatedAt(new Date());
        leadsAssignedTrack.setCreatedBy(requestVO.getAssignedPractitionerId());
        leadsAssignedTrack.setUpdatedAt(new Date());
        leadsAssignedTrack.setUpdatedBy(requestVO.getAssignedPractitionerId());
        leadsAssignedTrack.setPractitionerId(requestVO.getAssignedPractitionerId());
        leadsAssignedTrack.setCustomerId(customerId);
        leadsAssignedTrack.setMdDropOptionId(Long.valueOf(mdDropOptionsId));
        leadsAssignedTrack.setLeadsAssignedId(assigneds.getId());
        leadsAssignedTrack.setTrackTime(new Date());
        leadsAssignedTrack.setCreatorType(2);
        leadsAssignedTrack.setUpdatorType(2);
        mktLeadsAssignedTrackDALService.saveTrack(leadsAssignedTrack);
        requestVO.setOpportunityId(customerId);
        requestVO.setLeadsAssignedId(assigneds.getId());
        return new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000"));
    }

    private String createAccountId(String mobileNo) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String sub = null;
        if(mobileNo != null && !"".equals(mobileNo)){
            sub = mobileNo.substring(mobileNo.length()-6);
        }
        return "C_"+sub+"_"+sdf.format(new Date());
    }

    private void saveCustomerInfo(Long customerId, OwnOpportunityBasicInformationSaveRequestVO requestVO) {
        AclCustomer customer = aclCustomerDALService.findById(customerId);
        String mobileNo = customer.getMobileNo();
        String idNo = customer.getIdNo();
        customer.setMobileNo(mobileNo);
        customer.setIdNo(idNo);
        customer.setName(requestVO.getName());
        customer.setBirthDate(CommonUtil.stringParseDate(requestVO.getBirthDate(),"yyyy-MM-dd"));
        customer.setGender(requestVO.getGender());
        customer.setAddress(requestVO.getAddress());
        customer.setAge(requestVO.getAge());
        customer.setWechatNo(requestVO.getWeChat());
        customer.setOtherContacts(requestVO.getOtherContacts());
        customer.setZodiacTypeId(requestVO.getZodiacTypeId());
        customer.setBloodTypeId(requestVO.getBloodTypeId());
        aclCustomerDALService.update(customer);
    }

    private void saveLeadsAssigneds(OwnOpportunityBasicInformationSaveRequestVO requestVO) {
        Long leadsAssignedId = requestVO.getLeadsAssignedId();
        MktLeadsAssigneds mktLeadsAssigneds = mktLeadsAssignedsDALService.findByLeadsAssignedId(leadsAssignedId);
        mktLeadsAssigneds.setFyc(requestVO.getFyc());
        mktLeadsAssigneds.setFyp(requestVO.getFyp());
        mktLeadsAssigneds.setPieces(requestVO.getPieces());
        mktLeadsAssigneds.setTimeToClose(CommonUtil.stringParseDate(requestVO.getTimeToClose(),"yyyy-MM-dd"));
        mktLeadsAssigneds.setRemark(requestVO.getRemark());
        mktLeadsAssignedsDALService.updateMktLeadsAssigneds(mktLeadsAssigneds);
    }

    private void saveCustomerTag(Long customerId ,List<OpportunityCustomerTag> opportunityCustomerTags) {
        //保存标签
        //此人的原有标签全部至0
        ObjectCollectionTagged tagged = new ObjectCollectionTagged();
        tagged.setTaggedObjectType(4);
        tagged.setTaggedObjectId(customerId);
        List<ObjectCollectionTagged> taggedList = objectCollectionTaggedDALService.findByObjectCollectionTagged(tagged);
        for (ObjectCollectionTagged tag:taggedList) {
            tag.setIsActive(0);
            objectCollectionTaggedDALService.updateObjectCollectionTagged(tag);
        }
        for (OpportunityCustomerTag tag:opportunityCustomerTags) {
            tagged = new ObjectCollectionTagged();
            tagged.setTaggedObjectType(4);
            tagged.setTaggedObjectId(customerId);
            tagged.setMdTagId(tag.getTagId().intValue());
            List<ObjectCollectionTagged> taggeds = objectCollectionTaggedDALService.findByObjectCollectionTagged(tagged);
            if (taggeds.isEmpty()){
                //保存
                tagged.setIsActive(1);
                tagged.setRecommendOrder(1);
                tagged.setDisplayOrder(1);
                tagged.setCreatedBy(-1L);
                tagged.setCreatedAt(new Date());
                tagged.setUpdatedBy(-1L);
                tagged.setUpdatedAt(new Date());
                objectCollectionTaggedDALService.saveObjectCollectionTagged(tagged);
            }else {
                //更新
                tagged = taggeds.get(0);
                tagged.setIsActive(1);
                tagged.setUpdatedBy(-1L);
                tagged.setUpdatedAt(new Date());
                objectCollectionTaggedDALService.updateObjectCollectionTagged(tagged);
            }
        }
    }

    @Override
    public OwnOpportunityRecordSaveResponseVO ownOpportunityRecordSave(OwnOpportunityRecordSaveRequestVO requestVO) {
        OwnOpportunityRecordSaveResponseVO resp = new OwnOpportunityRecordSaveResponseVO();
        CommonResult commonResult = check(requestVO);
        if (!commonResult.isSuccess()){
            resp.setCommonResult(commonResult);
            return resp;
        }

        MktLeadsAssignedTrack track = new MktLeadsAssignedTrack();
        CommonUtil.simpleObjectCopy(requestVO,track);
        track.setCustomerId(requestVO.getOpportunityId());
        track.setTrackTime(CommonUtil.stringParseDate(requestVO.getNoticeDate()+" 00:00:00", "yyyy-MM-dd HH:mm:ss"));
        track.setCreatedBy(requestVO.getPractitionerId());
        track.setCreatedAt(new Date());
        track.setCreatorType(2);
        track.setUpdatedBy(requestVO.getPractitionerId());
        track.setUpdatorType(2);
        track.setUpdatedAt(new Date());
        MdDropOptions dropOtions = mdDropOptionsDALService.findByDropOptionId(requestVO.getMdDropOptionId());
        track.setTrackScore(dropOtions.getDropOptionScore());
        if (CommonUtil.isNullOrZero(requestVO.getId())){
            //保存
            mktLeadsAssignedTrackDALService.saveTrack(track);
        }else {
            //更新
            mktLeadsAssignedTrackDALService.updateTrack(track);
        }
        resp.setOpportunityId(requestVO.getOpportunityId());
        resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return resp;
    }

    @Override
    public OpportunityStatisticsResponseVO opportunityStatistics(OpportunityStatisticsRequestVO requestVO) {
        OpportunityStatisticsResponseVO resp = new OpportunityStatisticsResponseVO();
        //计算商机得分 今天,本周,本月
        MktLeadsAssignedTrack mktLeadsAssignedTrack = new MktLeadsAssignedTrack();
        mktLeadsAssignedTrack.setPractitionerId(requestVO.getPractitionerId());
        PageHelper.orderBy("track_time DESC");
        List<MktLeadsAssignedTrack> mktLeadsAssignedTracks = mktLeadsAssignedTrackDALService.findByMktLeadsAssignedTrack(mktLeadsAssignedTrack);
        Integer scoreDay = 0;
        Integer scoreWeek = 0;
        Integer scoreMonth = 0;
        for (MktLeadsAssignedTrack info : mktLeadsAssignedTracks){
            boolean isStatistics = false;
            String time = CommonUtil.dateParseString(info.getTrackTime(), "yyyy-MM-dd");
            if (!CommonUtil.isNullOrBlank(time)){
                if (CommonUtil.isThisMonth(time)){
                    scoreMonth += info.getTrackScore();
                    if (CommonUtil.isToday(time)){
                        scoreDay += info.getTrackScore();
                    }
                    isStatistics = true;
                }
                if (CommonUtil.isThisWeek(time)){
                    scoreWeek += info.getTrackScore();
                    isStatistics = true;
                }
                //既不属于月也不属于周跳出
                if (!isStatistics){
                    break;
                }
            }
        }
        //计算新增商机个数
        List<MktLeadsAssigneds> mktLeadsAssigneds = mktLeadsAssignedsDALService.findByPractitionerIdAndThisWeek(requestVO.getPractitionerId());
        //计算经纪人目标得分
        MktLeadsGoalsActions mktLeadsGoalsActions = new MktLeadsGoalsActions();
        mktLeadsGoalsActions.setPractitionerId(requestVO.getPractitionerId());
        //当前年份
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        mktLeadsGoalsActions.setCurrentYear(year);
        mktLeadsGoalsActions.setIsActive(1);
        List<MktLeadsGoalsActions> leadsGoalsActions = mktLeadsGoalsActionsDALService.findByMktLeadsGoalsActions(mktLeadsGoalsActions);
        if (!leadsGoalsActions.isEmpty()){
            List<MdDropOptions> mdDropOptionsList = mdDropOptionsDALService.findByDropMasterCode("bizchance_promotion_action");
            ConcurrentMap<Long,Integer> optionScoreMap = new ConcurrentHashMap<>();
            for (MdDropOptions info : mdDropOptionsList){
                optionScoreMap.put(info.getId(),info.getDropOptionScore());
            }
            int targetScoreMonth = 0;
            for (MktLeadsGoalsActions info : leadsGoalsActions){
                Long leadsActionId = info.getLeadsActionId();
                Integer singleScore = optionScoreMap.get(leadsActionId);
                targetScoreMonth += singleScore * info.getActionStandards();
            }
            Double achievementRateMonth = BigDecimal.valueOf(scoreMonth)
                    .divide(BigDecimal.valueOf(targetScoreMonth),4,BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
            Double achievementRateWeek = BigDecimal.valueOf(scoreWeek)
                    .divide(BigDecimal.valueOf(targetScoreMonth),4,BigDecimal.ROUND_HALF_UP)
                    .multiply(BigDecimal.valueOf(12))
                    .divide(BigDecimal.valueOf(52),4,BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
            resp.setAchievementRateMonth(achievementRateMonth);
            resp.setAchievementRateWeek(achievementRateWeek);
        }
        resp.setScoreDay(scoreDay);
        resp.setScoreWeek(scoreWeek);
        resp.setScoreMonth(scoreMonth);
        resp.setAddOpportunityNum(mktLeadsAssigneds.size());
        resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return resp;
    }

    @Override
    @Transactional
    public SalesTargetSaveResponseVO salesTargetSave(SalesTargetSaveRequestVO requestVO) {
        SalesTargetSaveResponseVO responseVO = new SalesTargetSaveResponseVO();
        //经纪人id
        Long practitionerId = requestVO.getPractitionerId();
        //当前年份
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        Integer goalsType = requestVO.getGoalsType();
        //初始化之前数据  全部修改为不启用
        initializationAction(practitionerId,year,goalsType);
        AclPractitionerSubordinateSystem subordinate = new AclPractitionerSubordinateSystem();
        if (goalsType == 2){
            //查询经纪人所在团队
            List<AclPractitionerSubordinateSystem> subordinates = aclPractitionerSubordinateSystemDALService.findByOwnerPractitionerId(practitionerId);
            if (subordinates.isEmpty()){
                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830016")));
                return responseVO;
            }
            subordinate = subordinates.get(0);
        }//else {
//            subordinate = aclPractitionerSubordinateSystemDALService.findByPractitionerId(practitionerId);
//            if (subordinate == null){
//                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830018")));
//                return responseVO;
//            }
//        }
        //保存年目标
        Date date = new Date();
        saveYearGoal(requestVO,practitionerId,date,year,goalsType,subordinate);

        //保存月目标
        List<SalesTargetMonth> salesTargetMonths = requestVO.getSalesTargetMonths();
        for(SalesTargetMonth info: salesTargetMonths){
            saveMonthGoal(info,practitionerId,date,year,goalsType,subordinate);
        }

        //经纪人保存/团队不需保存
        if (goalsType==1){
            //保存经纪人商机活动量均分
            MdDropMaster mdDropMaster = mdDropMasterDALService.findByScenarioCode("bizchance_promotion_action");
            Long masterId = mdDropMaster.getId();
            //查询出所有计算公式
            //件数  年总
            Integer pieces = requestVO.getPieces();
            int piecesMonth = BigDecimal.valueOf(pieces).divide(BigDecimal.valueOf(12),0, BigDecimal.ROUND_UP).intValue();
            System.out.println("piecesMonth:"+piecesMonth);
            ScriptEngine jScriptEngine=new ScriptEngineManager().getEngineByName("JavaScript");
            List<MdGoalsCalculateExpression> list = mdGoalsCalculateExpressionService.findByMasterId(masterId);
            List<SalesTargetActions> salesTargetActionsList = new ArrayList<>();
            for (MdGoalsCalculateExpression info : list){
                //保存经纪人商机活动量分摊细化设置  ag_mkt_leads_goals_actions
                SalesTargetActions salesTargetAction = saveLeadsGoalsActions(info,jScriptEngine,year,piecesMonth,practitionerId,date,goalsType);
                salesTargetActionsList.add(salesTargetAction);
            }
            responseVO.setSalesTargetActions(salesTargetActionsList);
        }

        BeanUtils.copyProperties(requestVO,responseVO);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }
    @Override
    @Transactional
    public PotentialGoalsSettingResponseVO potentialGoalsSetting(PotentialGoalsSettingRequestVO requestVO) {
        PotentialGoalsSettingResponseVO responseVO = new PotentialGoalsSettingResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        Integer numberRecruitsYear = requestVO.getNumberRecruitsYear();
        Integer numberMDRTYear = requestVO.getNumberMDRTYear();
        List<RecruitGoalForMonth> recruitGoalForMonthList = requestVO.getRecruitGoalForMonthList();
        if(practitionerId != null && numberMDRTYear != null && numberRecruitsYear != null && !recruitGoalForMonthList.isEmpty()){
            Integer month,numberRecruits,numberMDRT;
            int numberRecruits1=0,numberMDRT1=0,numberRecruits2=0,numberMDRT2=0,numberRecruits3=0,numberMDRT3=0,numberRecruits4=0,numberMDRT4=0;
            Calendar calendar = Calendar.getInstance();
            Integer currentYear = calendar.get(Calendar.YEAR);
            Date version = new Date();
            List<AclPractitionerPotentialGoals> potentialGoalsUpdateList = new ArrayList<>();
            List<AclPractitionerPotentialGoals> potentialGoalsOld = aclPractitionerPotentialGoalsDALService.findByPractitionerAndCurrentYear(practitionerId,currentYear);
            if(potentialGoalsOld != null && !potentialGoalsOld.isEmpty()){
                for(AclPractitionerPotentialGoals item : potentialGoalsOld){
                    item.setUpdatedAt(new Date());
                    item.setUpdatedBy(practitionerId);
                    item.setIsActive(0);
                    potentialGoalsUpdateList.add(item);
                }
                aclPractitionerPotentialGoalsDALService.updateList(potentialGoalsUpdateList);
            }
            //1、统计全年
            List<AclPractitionerPotentialGoals> potentialGoalsList = new ArrayList<>();
            getPotentialGoalsList(potentialGoalsList,practitionerId,1,1,numberRecruitsYear,numberMDRTYear,currentYear,version);
            //2、统计每个月
            for(RecruitGoalForMonth item : recruitGoalForMonthList){
                month = item.getMonth();
                numberRecruits = item.getNumberRecruits();
                numberMDRT = item.getNumberMDRT();
                if(month < 4){
                    numberRecruits1 = numberRecruits1 + numberRecruits;
                    numberMDRT1 = numberMDRT1 + numberMDRT;
                }else if(month < 7){
                    numberRecruits2 = numberRecruits2 + numberRecruits;
                    numberMDRT2 = numberMDRT2 + numberMDRT;
                }else if(month < 10){
                    numberRecruits3 = numberRecruits3 + numberRecruits;
                    numberMDRT3 = numberMDRT3 + numberMDRT;
                }else {
                    numberRecruits4 = numberRecruits4 + numberRecruits;
                    numberMDRT4 = numberMDRT4 + numberMDRT;
                }
                getPotentialGoalsList(potentialGoalsList,practitionerId,3,month,numberRecruits,numberMDRT,currentYear,version);
            }
            //3、统计每个季度 -- 1-2-3，4-5-6，7-8-9，10-11-12
            getPotentialGoalsList(potentialGoalsList,practitionerId,2,1,numberRecruits1,numberMDRT1,currentYear,version);
            getPotentialGoalsList(potentialGoalsList,practitionerId,2,2,numberRecruits2,numberMDRT2,currentYear,version);
            getPotentialGoalsList(potentialGoalsList,practitionerId,2,3,numberRecruits3,numberMDRT3,currentYear,version);
            getPotentialGoalsList(potentialGoalsList,practitionerId,2,4,numberRecruits4,numberMDRT4,currentYear,version);
            aclPractitionerPotentialGoalsDALService.saveAll(potentialGoalsList);
            //4、根据年度总目标计算年度活动量M
            savePotentialActions(practitionerId,numberRecruitsYear,currentYear,version);
            responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
        }else{
            String [] paras = {"practitionerId,numberMDRTYear,numberRecruitsYear,recruitGoalForMonthList"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }

    @Override
    public SalesTargetQueryResponseVO salesTargetQuery(SalesTargetQueryRequestVO requestVO) {
        SalesTargetQueryResponseVO responseVO = new SalesTargetQueryResponseVO();
        //经纪人id
        Long practitionerId = requestVO.getPractitionerId();
        //当前年份
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        Integer goalsType = requestVO.getGoalsType();
        //通过is_active = 1  经纪人id 和 目标所属年度 去查询ag_mkt_leads_goals/ag_mkt_leads_goals_actions
        MktLeadsGoals mktLeadsGoals = new MktLeadsGoals();
        mktLeadsGoals.setIsActive(1);
        mktLeadsGoals.setPractitionerId(practitionerId);
        mktLeadsGoals.setCurrentYear(year);
        mktLeadsGoals.setGoalsType(goalsType);
        AclPractitionerSubordinateSystem subordinateSystem = new AclPractitionerSubordinateSystem();
        if (goalsType == 2){
            List<AclPractitionerSubordinateSystem> subordinateSystems = aclPractitionerSubordinateSystemDALService.findByOwnerPractitionerId(practitionerId);
            if (subordinateSystems.isEmpty()){
                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830017")));
                return responseVO;
            }
            subordinateSystem = subordinateSystems.get(0);
        }//else {
//            subordinateSystem = aclPractitionerSubordinateSystemDALService.findByPractitionerId(practitionerId);
//            if (subordinateSystem == null){
//                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830018")));
//                return responseVO;
//            }
//        }
        mktLeadsGoals.setSubordinateSystemId(subordinateSystem.getId());
        List<MktLeadsGoals> mktLeadsGoalsList = mktLeadsGoalsDALService.findByMktLeadsGoals(mktLeadsGoals);
        List<SalesTargetMonth> salesTargetMonthList = new ArrayList<>();
        for (MktLeadsGoals info :mktLeadsGoalsList){
            Integer statisticTimeUnit = info.getStatisticTimeUnit();
            if (statisticTimeUnit==1){//年
                responseVO.setPremium(info.getPremium());
                responseVO.setCommission(info.getCommission());
                responseVO.setPieces(info.getPieces());
                responseVO.setPieceAveragePremium(info.getPieceAveragePremium());
            }else if (statisticTimeUnit==3){//月
                SalesTargetMonth salesTargetMonth = new SalesTargetMonth();
                salesTargetMonth.setCommission(info.getCommission());
                salesTargetMonth.setMonthNum(info.getSeqTime());
                salesTargetMonth.setPieceAveragePremium(info.getPieceAveragePremium());
                salesTargetMonth.setPieces(info.getPieces());
                salesTargetMonth.setPremium(info.getPremium());
                salesTargetMonthList.add(salesTargetMonth);
            }
        }

        MktLeadsGoalsActions mktLeadsGoalsActions = new MktLeadsGoalsActions();
        mktLeadsGoalsActions.setIsActive(1);
        mktLeadsGoalsActions.setPractitionerId(practitionerId);
        mktLeadsGoalsActions.setCurrentYear(year);
        mktLeadsGoalsActions.setGoalsType(goalsType);
        List<MktLeadsGoalsActions> mktLeadsGoalsActionsList = mktLeadsGoalsActionsDALService.findByMktLeadsGoalsActions(mktLeadsGoalsActions);
        List<SalesTargetActions> salesTargetActions = new ArrayList<>();
        for (MktLeadsGoalsActions info : mktLeadsGoalsActionsList){
            SalesTargetActions salesTargetAction = new SalesTargetActions();
            salesTargetAction.setStatisticTimeUnit(3);
            salesTargetAction.setActionStandards(info.getActionStandards());
            salesTargetAction.setLeadsActionId(info.getLeadsActionId());
            salesTargetAction.setLeadsActionName(info.getLeadsActionName());
            salesTargetActions.add(salesTargetAction);
        }

        responseVO.setPractitionerId(practitionerId);
        responseVO.setSalesTargetMonths(salesTargetMonthList);
        responseVO.setSalesTargetActions(salesTargetActions);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    public SalesTargetMonthSaveResponseVO salesTargetMonthSave(SalesTargetMonthSaveRequestVO requestVO) {
        SalesTargetMonthSaveResponseVO responseVO = new SalesTargetMonthSaveResponseVO();
        //经纪人id
        Long practitionerId = requestVO.getPractitionerId();
        //当前年份
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        Integer goalsType = requestVO.getGoalsType();
        mktLeadsGoalsActionsDALService.updateIsActiveIsNull(practitionerId,year,goalsType);
        List<SalesTargetActions> salesTargetActionsList = requestVO.getSalesTargetActionsList();
        Date date = new Date();
        MktLeadsGoalsActions mktLeadsGoalsActions;
        for (SalesTargetActions info : salesTargetActionsList){
            mktLeadsGoalsActions = new MktLeadsGoalsActions();
            mktLeadsGoalsActions.setPractitionerId(practitionerId);
            mktLeadsGoalsActions.setGoalsType(goalsType);
            mktLeadsGoalsActions.setCurrentYear(year);
            mktLeadsGoalsActions.setStatisticTimeUnit(3);
            mktLeadsGoalsActions.setLeadsActionId(info.getLeadsActionId());
            mktLeadsGoalsActions.setLeadsActionName(info.getLeadsActionName());
            mktLeadsGoalsActions.setActionStandards(info.getActionStandards());
            mktLeadsGoalsActions.setCurrentVersion(date);
            mktLeadsGoalsActions.setIsActive(1);
            mktLeadsGoalsActions.setCreatedAt(new Date());
            mktLeadsGoalsActions.setCreatedBy(practitionerId);
            mktLeadsGoalsActions.setUpdatedAt(new Date());
            mktLeadsGoalsActions.setUpdatedBy(practitionerId);
            mktLeadsGoalsActionsDALService.save(mktLeadsGoalsActions);
        }
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }
    @Override
    public PotentialGoalsQueryResponseVO potentialGoalsQuery(PotentialGoalsQueryRequestVO requestVO) {
        PotentialGoalsQueryResponseVO responseVO = new PotentialGoalsQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        if(practitionerId != null){
            Calendar calendar = Calendar.getInstance();
            Integer currentYear = calendar.get(Calendar.YEAR);
            List<Integer> timeTypeList = Arrays.asList(1,3);
            List<AclPractitionerPotentialGoals> potentialGoalsList = aclPractitionerPotentialGoalsDALService.findByPractitionerAndCurrentYearAndTimeUnit(practitionerId,currentYear,timeTypeList);
            List<RecruitGoalForMonth> recruitGoalForMonthList = new ArrayList<>();
            if(potentialGoalsList != null && !potentialGoalsList.isEmpty()){
                RecruitGoalForMonth recruitGoalForMonth;
                for(AclPractitionerPotentialGoals item : potentialGoalsList){
                    if(item.getStatisticTimeUnit() == 1){
                        responseVO.setNumberRecruitsYear(item.getNumberRecruits());
                        responseVO.setNumberMDRTYear(item.getNumberMdrt());
                    }else{
                        recruitGoalForMonth = new RecruitGoalForMonth();
                        recruitGoalForMonth.setMonth(item.getSeqTime());
                        recruitGoalForMonth.setNumberMDRT(item.getNumberMdrt());
                        recruitGoalForMonth.setNumberRecruits(item.getNumberRecruits());
                        recruitGoalForMonthList.add(recruitGoalForMonth);
                    }
                }
            }
            responseVO.setRecruitGoalForMonthList(recruitGoalForMonthList);
            responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
        }else{
            String [] paras = {"practitionerId"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }

    @Override
    public TeamActionsAverageQueryResponseVO teamScoreAverageQuery(TeamActionsAverageQueryRequestVO requestVO) {
        TeamActionsAverageQueryResponseVO responseVO = new TeamActionsAverageQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        //该团队长下团队所有经纪人信息
        List<Long> practitionerIds = this.getPractitionerIdList(practitionerId,1);
        //团队经纪人个数
        BigDecimal practitionerNum = BigDecimal.valueOf(practitionerIds.size());

        //查询此团队经纪人所有得跟进状态
        List<MdDropOptions> mdDropOptions = mdDropOptionsDALService.findByDropMasterCode("bizchance_promotion_action");
        ConcurrentMap<String,Long> optionCodeToId = new ConcurrentHashMap<>();
        for (MdDropOptions info : mdDropOptions){
            optionCodeToId.put(info.getDropOptionCode(),info.getId());
        }
        //查询其团队天,周,月总分
        HashMap<String,BigDecimal> totalStatistics = mktLeadsAssignedTrackDALService.totalStatisticsForTeam(practitionerIds);
        Double scoreDayAverage = 0D;
        Double scoreWeekAverage= 0D;
        Double scoreMonthAverage= 0D;
        if (totalStatistics != null){
            //总分除以人数得到均分
            scoreDayAverage = getScoreAverage(totalStatistics.get("scoreToday"),practitionerNum);
            scoreWeekAverage= getScoreAverage(totalStatistics.get("scoreWeek"),practitionerNum);
            scoreMonthAverage= getScoreAverage(totalStatistics.get("scoreMonth"),practitionerNum);
        }

        //拿到商机跟踪,失败id
        Long refusedId = optionCodeToId.get("refused");
        //计算此团队一周增加的商机数 ag_mkt_leads_assigneds
        Integer opportunitiesNum = mktLeadsAssignedsDALService.countPractitionerIdsAndThisWeek(practitionerIds,refusedId);
        //计算年/季/月  首年保费(premium)/佣金(commission)/件数(pieces)  均取至指派表ag_mkt_leads_assigneds
        HashMap<String,BigDecimal> performanceForecast = mktLeadsAssignedsDALService.performanceForecastForTeam(practitionerIds,refusedId);

        List<MktLeadsGoals> leadsGoals = getYearTeamGoals(practitionerId);
        ConcurrentHashMap<String,Double> achievementRateMap = new ConcurrentHashMap<>();
        if (!leadsGoals.isEmpty()&&performanceForecast != null){
            //计算完成率
            achievementRateMap = getAchievementRate(leadsGoals,performanceForecast);
        }

        responseVO.setScoreDayAverage(scoreDayAverage);
        responseVO.setScoreWeekAverage(scoreWeekAverage);
        responseVO.setScoreMonthAverage(scoreMonthAverage);
        responseVO.setOpportunitiesNum(opportunitiesNum);
        if (performanceForecast != null){
            responseVO.setPremiumMonth(CommonUtil.isNullOrZero(performanceForecast.get("totalFYPMonth"))?0:performanceForecast.get("totalFYPMonth").doubleValue());
            responseVO.setCommissionMonth(CommonUtil.isNullOrZero(performanceForecast.get("totalFYCMonth"))?0:performanceForecast.get("totalFYCMonth").doubleValue());
            responseVO.setPiecesMonth(CommonUtil.isNullOrZero(performanceForecast.get("totalPiecesMonth"))?0:performanceForecast.get("totalPiecesMonth").doubleValue());
            responseVO.setPremiumQuarter(CommonUtil.isNullOrZero(performanceForecast.get("totalFYPQuarter"))?0:performanceForecast.get("totalFYPQuarter").doubleValue());
            responseVO.setCommissionQuarter(CommonUtil.isNullOrZero(performanceForecast.get("totalFYCQuarter"))?0:performanceForecast.get("totalFYCQuarter").doubleValue());
            responseVO.setPiecesQuarter(CommonUtil.isNullOrZero(performanceForecast.get("totalPiecesQuarter"))?0:performanceForecast.get("totalPiecesQuarter").doubleValue());
            responseVO.setPremiumYear(CommonUtil.isNullOrZero(performanceForecast.get("totalFYPYear"))?0:performanceForecast.get("totalFYPYear").doubleValue());
            responseVO.setCommissionYear(CommonUtil.isNullOrZero(performanceForecast.get("totalFYCYear"))?0:performanceForecast.get("totalFYCYear").doubleValue());
            responseVO.setPiecesYear(CommonUtil.isNullOrZero(performanceForecast.get("totalPiecesYear"))?0:performanceForecast.get("totalPiecesYear").doubleValue());
        }
        responseVO.setAchievementRateYear(CommonUtil.isNullOrZero(achievementRateMap.get("achievementRateYear"))?0D: achievementRateMap.get("achievementRateYear"));
        responseVO.setAchievementRateQuarter(CommonUtil.isNullOrZero(achievementRateMap.get("achievementRateQuarter"))?0D:achievementRateMap.get("achievementRateQuarter"));
        responseVO.setAchievementRateMonth(CommonUtil.isNullOrZero(achievementRateMap.get("achievementRateMonth"))?0D:achievementRateMap.get("achievementRateMonth"));
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    public List<Long> getPractitionerIdList(Long practitionerId,Integer isActive) {
        List<Long> practitionerIdList = new ArrayList<>();
        practitionerIdList.add(practitionerId);

        // 判断当前经纪人是否为团队长
        int count = aclPractitionerDALService.isTeamLeader(practitionerId);
        if (count > 0) {
            List<Long> practitionerIdList1 = aclPractitionerDALService.queryTeamAllPractitionerId(practitionerId,isActive);
            practitionerIdList.addAll(practitionerIdList1);
        } else {
            List<Long> practitionerIdList2 = aclPractitionerDALService.queryMentoredByPractitionerId(practitionerId);
            practitionerIdList.addAll(practitionerIdList2);
        }
        
        practitionerIdList = practitionerIdList.stream().distinct().collect(Collectors.toList());
        return practitionerIdList;
    }

    @Override
    public CanSeeSalaryListResponseVO canSeeSalaryList(Long practitionerId) {
        CanSeeSalaryListResponseVO responseVO = new CanSeeSalaryListResponseVO();
        AclPractitioner aclPractitioner = aclPractitionerDALService.findById(practitionerId);
        responseVO.setCanSeeSalaryList(aclPractitioner.getCanSeeSalaryList());
        responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @Override
    public PotentialGoalsActionsQueryResponseVO potentialGoalsActionsQuery(PotentialGoalsActionsQueryRequestVO requestVO) {
        PotentialGoalsActionsQueryResponseVO responseVO = new PotentialGoalsActionsQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        if(practitionerId != null){
            Calendar calendar = Calendar.getInstance();
            Integer currentYear = calendar.get(Calendar.YEAR);
            List<PotentialGoalsActionsInfo> goalsActionsInfoList = new ArrayList<>();
            List<AclPractitionerPotentialGoalsActions> goalsActionsList = aclPractitionerPotentialGoalsActionsDALService.findByPractitionerIdAndCurrentYearAndIsActiveAndTimeUnit(practitionerId,currentYear,1,3);
            if(goalsActionsList != null && !goalsActionsList.isEmpty()){
                PotentialGoalsActionsInfo goalsActionsInfo;
                for(AclPractitionerPotentialGoalsActions item : goalsActionsList){
                    goalsActionsInfo = new PotentialGoalsActionsInfo();
                    BeanUtils.copyProperties(item,goalsActionsInfo);
                    goalsActionsInfoList.add(goalsActionsInfo);
                }
                responseVO.setGoalsActionsInfoList(goalsActionsInfoList);
            }
            responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
        }else{
            String [] paras = {"practitionerId"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }

    @Override
    public PlayerSalesActivityQueryResponseVO playerSalesActivityQuery(PlayerSalesActivityQueryRequestVO requestVO) {
        PlayerSalesActivityQueryResponseVO responseVO = new PlayerSalesActivityQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        MdDropOptions mdDropOptions = mdDropOptionsDALService.selectByMasterCodeAndOptionsCode("bizchance_promotion_action","refused");
        List<PlayerSalesActivityInfo> playerSalesActivityInfos = aclPractitionerDALService.playerSalesActivityQuery(practitionerId,mdDropOptions.getId());
        //计算完成率
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        //通过团队长经纪人id查询出团队所有人设置的目标
        List<MktLeadsGoalsActions> mktLeadsGoalsActions = mktLeadsGoalsActionsDALService.findTeamGoalsMonth(practitionerId,year);
        List<MdDropOptions> mdDropOptionsList = mdDropOptionsDALService.findByDropMasterCode("bizchance_promotion_action");
        ConcurrentHashMap<Long , Integer> optionsIdToScore = new ConcurrentHashMap<>();
        for (MdDropOptions info : mdDropOptionsList){
            optionsIdToScore.put(info.getId(),info.getDropOptionScore());
        }
        for (PlayerSalesActivityInfo info : playerSalesActivityInfos){
            //总分数
            int predictionScore = 0;
            for (MktLeadsGoalsActions actions : mktLeadsGoalsActions){
                if (info.getPractitionerId().equals(actions.getPractitionerId())){
                    predictionScore += actions.getActionStandards() * optionsIdToScore.get(actions.getLeadsActionId());
                }
            }
            if (!CommonUtil.isNullOrZero(predictionScore)){
                BigDecimal achievementRateMonth =  info.getScoreMonth().divide(BigDecimal.valueOf(predictionScore),4,BigDecimal.ROUND_HALF_UP);
                info.setAchievementRateMonth(achievementRateMonth.doubleValue());
            }
        }
        responseVO.setPlayerSalesActivityInfo(playerSalesActivityInfos);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }
    @Override
    public PotentialGoalsActionsUpdateResponseVO potentialGoalsActionsUpdate(PotentialGoalsActionsUpdateRequestVO requestVO) {
        PotentialGoalsActionsUpdateResponseVO responseVO = new PotentialGoalsActionsUpdateResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        List<PotentialGoalsActionsInfo> goalsActionsInfoList = requestVO.getGoalsActionsInfoList();
        if(practitionerId != null && !goalsActionsInfoList.isEmpty()){
            Calendar calendar = Calendar.getInstance();
            Integer currentYear = calendar.get(Calendar.YEAR);
            Date version = new Date();
            //1、更新旧数据
            updateOldDataForGoalsActions(practitionerId,currentYear);
            //2、保存数据
            int result;
            Long potentialActionId;
            String potentialActionName;
            List<AclPractitionerPotentialGoalsActions> potentialGoalsActionsList = new ArrayList<>();
            for(PotentialGoalsActionsInfo item : goalsActionsInfoList){
                result = item.getActionStandards();
                potentialActionId = item.getPotentialActionId();
                potentialActionName = item.getPotentialActionName();
                savePotentialGoalsActions(potentialGoalsActionsList,practitionerId,currentYear,potentialActionId,potentialActionName,result,version);
            }
            aclPractitionerPotentialGoalsActionsDALService.saveAll(potentialGoalsActionsList);
            responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
        }else{
            String [] paras = {"practitionerId,goalsActionsInfoList"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }

    @Override
    public SalesPerformanceForecastListQueryResponseVO salesPerformanceForecastListQuery(SalesPerformanceForecastListQueryRequestVO requestVO) {
        SalesPerformanceForecastListQueryResponseVO responseVO = new SalesPerformanceForecastListQueryResponseVO();
        List<SalesPerformanceForecastInfo> infos = new ArrayList<>();
        //通过团队长经纪人id,查询此团队所有经纪人id
        Long practitionerId = requestVO.getPractitionerId();
        List<AclPractitioner> practitioners = aclPractitionerDALService.findByIds(this.getPractitionerIdList(practitionerId,1));
        if (practitioners.isEmpty()){
            responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            return responseVO;
        }
        List<Long> practitionerIds = new ArrayList<>();
        ConcurrentHashMap<Long,String> practitionerIdToName = new ConcurrentHashMap<>();
        for (AclPractitioner aclPractitioner : practitioners){
            practitionerIds.add(aclPractitioner.getId());
            practitionerIdToName.put(aclPractitioner.getId(),aclPractitioner.getName());
        }
        //通过团队所有经纪人id,去查询自己的预测值
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        List<MktLeadsGoals> mktLeadsGoals = mktLeadsGoalsDALService.selectByPractitionerIds(practitionerIds,year);
        //查询词团队所有经纪人的商机预测值
        MdDropOptions mdDropOptions = mdDropOptionsDALService.selectByMasterCodeAndOptionsCode("bizchance_promotion_action","refused");
        List<MktLeadsAssigneds> mktLeadsAssigneds = mktLeadsAssignedsDALService.selectByPractitionerIdRemoveRefused(practitionerIds,mdDropOptions.getId());

        String time = requestVO.getTime();
        if ("M".equalsIgnoreCase(time)){
            //月度
            int month = cal.get(Calendar.MONTH) + 1;
            infos = getMouthPerformanceForecast(practitionerIds,mktLeadsGoals,mktLeadsAssigneds,practitionerIdToName,month);
        }else if ("Q".equalsIgnoreCase(time)){
            //季度
            int month = cal.get(Calendar.MONTH) + 1;
            infos = getQuarterPerformanceForecast(practitionerIds,mktLeadsGoals,mktLeadsAssigneds,practitionerIdToName,month);
        }else if ("Y".equalsIgnoreCase(time)){
            //年
            infos = getYearPerformanceForecast(practitionerIds,mktLeadsGoals,mktLeadsAssigneds,practitionerIdToName);
        }

        responseVO.setSalesPerformanceForecastInfos(infos);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    @SuppressWarnings("unchecked")
    private List<SalesPerformanceForecastInfo> getYearPerformanceForecast(List<Long> practitionerIds, List<MktLeadsGoals> mktLeadsGoals, List<MktLeadsAssigneds> mktLeadsAssigneds, ConcurrentHashMap<Long, String> practitionerIdToName) {
        List<SalesPerformanceForecastInfo> infos = new ArrayList<>();
        for (Long praId : practitionerIds) {
            SalesPerformanceForecastInfo info = new SalesPerformanceForecastInfo();
            BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("practitionerId", praId);
            List<MktLeadsGoals> mktLeadsGoalsList = (List<MktLeadsGoals>) CollectionUtils.select(mktLeadsGoals, predicate);
            if (mktLeadsGoalsList.isEmpty()){
                info.setPractitionerId(praId);
                info.setName(practitionerIdToName.get(praId));
                infos.add(info);
                continue;
            }
            //总预测值
            BigDecimal quarterGoal = BigDecimal.ZERO;
            for (MktLeadsGoals leadsGoals : mktLeadsGoalsList) {
                if (leadsGoals.getStatisticTimeUnit() == 1) {
                    quarterGoal = quarterGoal.add(BigDecimal.valueOf(leadsGoals.getCommission()));
                }
            }

            //商机累加值
            predicate = new BeanPropertyValueEqualsPredicate("assignedPractitionerId", praId);
            List<MktLeadsAssigneds> mktLeadsAssignedsList = (List<MktLeadsAssigneds>)CollectionUtils.select(mktLeadsAssigneds,predicate);

            BigDecimal defaultCommission = BigDecimal.ZERO;
            BigDecimal defaultPremium = BigDecimal.ZERO;
            Integer defaultPieces = 0;
            for (MktLeadsAssigneds leadsAssigneds: mktLeadsAssignedsList) {
                String timeToClose = CommonUtil.dateParseString(leadsAssigneds.getTimeToClose(), "yyyy-MM-dd");
                if (CommonUtil.isNullOrBlank(timeToClose)){
                    continue;
                }
                if (CommonUtil.isThisYear(timeToClose)){
                    defaultPieces += leadsAssigneds.getPieces();
                    defaultCommission = defaultCommission.add(leadsAssigneds.getFyc());
                    defaultPremium = defaultPremium.add(leadsAssigneds.getFyp());
                }
            }
            Double achievementRate = defaultCommission.divide(quarterGoal,4,BigDecimal.ROUND_HALF_UP).doubleValue();
            info.setPractitionerId(praId);
            info.setName(practitionerIdToName.get(praId));
            info.setPieces(defaultPieces);
            info.setPremium(defaultPremium.doubleValue());
            info.setCommission(defaultCommission.doubleValue());
            info.setAchievementRate(achievementRate);
            infos.add(info);
        }
        return infos;
    }

    @SuppressWarnings("unchecked")
    private List<SalesPerformanceForecastInfo> getQuarterPerformanceForecast(List<Long> practitionerIds, List<MktLeadsGoals> mktLeadsGoals, List<MktLeadsAssigneds> mktLeadsAssigneds, ConcurrentHashMap<Long, String> practitionerIdToName, int month) {
        List<SalesPerformanceForecastInfo> infos = new ArrayList<>();
        for (Long praId : practitionerIds) {
            SalesPerformanceForecastInfo info = new SalesPerformanceForecastInfo();
            BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("practitionerId", praId);
            List<MktLeadsGoals> mktLeadsGoalsList = (List<MktLeadsGoals>) CollectionUtils.select(mktLeadsGoals, predicate);
            if (mktLeadsGoalsList.isEmpty()){
                info.setPractitionerId(praId);
                info.setName(practitionerIdToName.get(praId));
                infos.add(info);
                continue;
            }
            Integer[] quarter = new Integer[]{};
            if (month == 1 || month == 2 || month == 3) {
                quarter = new Integer[]{1, 2, 3};
            } else if (month == 4 || month == 5 || month == 6) {
                quarter = new Integer[]{4, 5, 6};
            } else if (month == 7 || month == 8 || month == 9) {
                quarter = new Integer[]{7, 8, 9};
            } else if (month == 10 || month == 11 || month == 12) {
                quarter = new Integer[]{10, 11, 12};
            }
            //总预测值
            BigDecimal quarterGoal = BigDecimal.ZERO;
            for (MktLeadsGoals leadsGoals : mktLeadsGoalsList) {
                if (leadsGoals.getStatisticTimeUnit() == 3) {
                    //月目标
                    //判断是否为本季度
                    Integer monthNum = leadsGoals.getSeqTime();
                    if (Arrays.asList(quarter).contains(monthNum)) {
                        quarterGoal = quarterGoal.add(BigDecimal.valueOf(leadsGoals.getCommission()));
                    }
                }
            }

            //商机累加值
            predicate = new BeanPropertyValueEqualsPredicate("assignedPractitionerId", praId);
            List<MktLeadsAssigneds> mktLeadsAssignedsList = (List<MktLeadsAssigneds>)CollectionUtils.select(mktLeadsAssigneds,predicate);

            BigDecimal defaultCommission = BigDecimal.ZERO;
            BigDecimal defaultPremium = BigDecimal.ZERO;
            Integer defaultPieces = 0;
            for (MktLeadsAssigneds leadsAssigneds: mktLeadsAssignedsList) {
                String timeToClose = CommonUtil.dateParseString(leadsAssigneds.getTimeToClose(), "yyyy-MM-dd");
                if (CommonUtil.isNullOrBlank(timeToClose)){
                    continue;
                }
                Calendar c = Calendar.getInstance();
                c.setTime(leadsAssigneds.getTimeToClose());
                int timeToCloseMonth = c.get(Calendar.MONTH)+1;
                if (Arrays.asList(quarter).contains(timeToCloseMonth)){
                    defaultPieces += leadsAssigneds.getPieces();
                    defaultCommission = defaultCommission.add(leadsAssigneds.getFyc());
                    defaultPremium = defaultPremium.add(leadsAssigneds.getFyp());
                }
            }
            Double achievementRate = defaultCommission.divide(quarterGoal,4,BigDecimal.ROUND_HALF_UP).doubleValue();
            info.setPractitionerId(praId);
            info.setName(practitionerIdToName.get(praId));
            info.setPieces(defaultPieces);
            info.setPremium(defaultPremium.doubleValue());
            info.setCommission(defaultCommission.doubleValue());
            info.setAchievementRate(achievementRate);
            infos.add(info);
        }
        return infos;
    }

    @SuppressWarnings("unchecked")
    private List<SalesPerformanceForecastInfo> getMouthPerformanceForecast(List<Long> practitionerIds, List<MktLeadsGoals> mktLeadsGoals, List<MktLeadsAssigneds> mktLeadsAssigneds, ConcurrentHashMap<Long, String> practitionerIdToName, int month) {
        List<SalesPerformanceForecastInfo> infos = new ArrayList<>();
        for (Long praId : practitionerIds){
            SalesPerformanceForecastInfo info = new SalesPerformanceForecastInfo();
            BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("practitionerId", praId);
            List<MktLeadsGoals> mktLeadsGoalsList = (List<MktLeadsGoals>)CollectionUtils.select(mktLeadsGoals,predicate);
            predicate = new BeanPropertyValueEqualsPredicate("seqTime", month);
            mktLeadsGoalsList = (List<MktLeadsGoals>)CollectionUtils.select(mktLeadsGoalsList,predicate);
            //筛选此经纪人的所有指派信息
            predicate = new BeanPropertyValueEqualsPredicate("assignedPractitionerId", praId);
            List<MktLeadsAssigneds> mktLeadsAssignedsList = (List<MktLeadsAssigneds>)CollectionUtils.select(mktLeadsAssigneds,predicate);

            BigDecimal defaultCommission = BigDecimal.ZERO;
            BigDecimal defaultPremium = BigDecimal.ZERO;
            Integer defaultPieces = 0;
            for (MktLeadsAssigneds leadsAssigneds : mktLeadsAssignedsList){
                String timeToClose = CommonUtil.dateParseString(leadsAssigneds.getTimeToClose(), "yyyy-MM-dd");
                if (CommonUtil.isNullOrBlank(timeToClose)){
                    continue;
                }
                if (CommonUtil.isThisMonth(timeToClose)){
                    defaultPieces += leadsAssigneds.getPieces();
                    defaultCommission = defaultCommission.add(leadsAssigneds.getFyc());
                    defaultPremium = defaultPremium.add(leadsAssigneds.getFyp());
                }
            }
            info.setPractitionerId(praId);
            info.setName(practitionerIdToName.get(praId));
            info.setPieces(defaultPieces);
            info.setPremium(defaultPremium.doubleValue());
            info.setCommission(defaultCommission.doubleValue());
            if (!mktLeadsGoalsList.isEmpty()){
                MktLeadsGoals leadsGoals = mktLeadsGoalsList.get(0);
                Double achievementRate = defaultCommission.divide(BigDecimal.valueOf(leadsGoals.getCommission()),4,BigDecimal.ROUND_HALF_UP).doubleValue();
                info.setAchievementRate(achievementRate);
            }
            infos.add(info);
        }
        return infos;
    }


    private ConcurrentHashMap<String, Double> getAchievementRate(List<MktLeadsGoals> leadsGoals,HashMap<String,BigDecimal> performanceForecast) {
        ConcurrentHashMap<String, Double> achievementRateMap = new ConcurrentHashMap<>();
        //获取当前月份
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH)+1;
        //查询这个月所在季度是那几个月
        Integer[] quarter =  new Integer[]{};
        if (month == 1 || month == 2 || month == 3){
            quarter = new Integer[]{1, 2, 3};
        }else if (month == 4 || month == 5 || month == 6){
            quarter = new Integer[]{4, 5, 6};
        }else if (month == 7 || month == 8 || month == 9){
            quarter = new Integer[]{7, 8, 9};
        }else if (month == 10 || month == 11 || month == 12){
            quarter = new Integer[]{10, 11, 12};
        }

        Double yearGoal = 0D;
        Double quarterGoal = 0D;
        Double monthGoal = 0D;
        for (MktLeadsGoals info : leadsGoals){
            if (info.getStatisticTimeUnit()==1){
                //年目标
                yearGoal = info.getCommission();
            }else if (info.getStatisticTimeUnit() == 3){
                //月目标
                //判断是否为本季度
                Integer monthNum = info.getSeqTime();
                if (Arrays.asList(quarter).contains(monthNum)){
                    quarterGoal += info.getCommission();
                    if (month == info.getSeqTime()){
                        monthGoal = info.getCommission();
                    }
                }
            }
        }

        //年完成率
        if (!CommonUtil.isNullOrZero(performanceForecast.get("totalFYCYear"))){
            Double achievementRateYear = performanceForecast.get("totalFYCYear")
                    .multiply(BigDecimal.valueOf(100))
                    .divide(BigDecimal.valueOf(yearGoal),2,BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
            achievementRateMap.put("achievementRateYear",achievementRateYear);
        }
        //季完成率
        if (!CommonUtil.isNullOrZero(performanceForecast.get("totalFYCQuarter"))){
            Double achievementRateQuarter = performanceForecast.get("totalFYCQuarter")
                    .multiply(BigDecimal.valueOf(100))
                    .divide(BigDecimal.valueOf(quarterGoal),2,BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
            achievementRateMap.put("achievementRateQuarter",achievementRateQuarter);
        }
        //月完成率
        if (!CommonUtil.isNullOrZero(performanceForecast.get("totalFYCMonth"))){
            Double achievementRateMonth = performanceForecast.get("totalFYCMonth")
                    .multiply(BigDecimal.valueOf(100))
                    .divide(BigDecimal.valueOf(monthGoal),2,BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
            achievementRateMap.put("achievementRateMonth",achievementRateMonth);
        }
        return achievementRateMap;
    }

    private List<MktLeadsGoals> getYearTeamGoals(Long practitionerId) {
        //查询团队长设置的月/季/年  FYC目标  ag_mkt_leads_goals
        MktLeadsGoals mktLeadsGoals = new MktLeadsGoals();
        mktLeadsGoals.setIsActive(1);//是否启用
        mktLeadsGoals.setPractitionerId(practitionerId);//团队长经纪人id
        mktLeadsGoals.setGoalsType(2);//目标类型：1：经纪人指标，2:团队指标
        //当前年份
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        mktLeadsGoals.setCurrentYear(year);
        List<AclPractitionerSubordinateSystem> subordinateSystems = aclPractitionerSubordinateSystemDALService.findByOwnerPractitionerId(practitionerId);
        if (!subordinateSystems.isEmpty()){
            AclPractitionerSubordinateSystem subordinateSystem = subordinateSystems.get(0);
            mktLeadsGoals.setSubordinateSystemId(subordinateSystem.getId());
        }
        return mktLeadsGoalsDALService.findByMktLeadsGoals(mktLeadsGoals);
    }

    /**
     * 通过总分计算平均分  保留两位小数
     * @param total 总分
     * @param practitionerNum 人数
     * @return 均分
     */
    private Double getScoreAverage(BigDecimal total, BigDecimal practitionerNum) {
        double scoreAverage = 0D;
        if (!CommonUtil.isNullOrZero(total)){
            scoreAverage = total
                    .divide(practitionerNum,2,BigDecimal.ROUND_HALF_UP)
                    .doubleValue();
        }
        return scoreAverage;
    }

    private void initializationAction(Long practitionerId, int year,Integer goalsType) {
        //通过经纪人id 和 目标所属年度 去查询ag_mkt_leads_goals/ag_mkt_leads_goals_actions  并将is_active = 0
        mktLeadsGoalsDALService.updateIsActiveIsNull(practitionerId,year,goalsType);
        mktLeadsGoalsActionsDALService.updateIsActiveIsNull(practitionerId,year,goalsType);
    }

    private SalesTargetActions saveLeadsGoalsActions(MdGoalsCalculateExpression info, ScriptEngine jScriptEngine, int year, int piecesMonth, Long practitionerId , Date date,Integer goalsType) {
        Long dropOptionId = info.getActionId();
        String dropOptionName = info.getDropOptionName();
        String calculateScriptExpression = info.getCalculateScriptExpression();
//            System.out.println("calculateScriptExpression:"+calculateScriptExpression);
        Integer actionStandards = null;
        String replaceAll = calculateScriptExpression.replaceAll("num", String.valueOf(piecesMonth));
        System.out.println(replaceAll);
        try {
            actionStandards = (Integer) jScriptEngine.eval(replaceAll);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        //保存信息至ag_mkt_leads_goals_actions
        MktLeadsGoalsActions mktLeadsGoalsActions = new MktLeadsGoalsActions();
        mktLeadsGoalsActions.setPractitionerId(practitionerId);
        mktLeadsGoalsActions.setCurrentYear(year);
        mktLeadsGoalsActions.setStatisticTimeUnit(3);
        mktLeadsGoalsActions.setGoalsType(goalsType);
        mktLeadsGoalsActions.setLeadsActionId(dropOptionId);
        mktLeadsGoalsActions.setLeadsActionName(dropOptionName);
        mktLeadsGoalsActions.setActionStandards(actionStandards);
        mktLeadsGoalsActions.setCurrentVersion(date);
        mktLeadsGoalsActions.setIsActive(1);
        mktLeadsGoalsActions.setCreatedAt(new Date());
        mktLeadsGoalsActions.setCreatedBy(practitionerId);
        mktLeadsGoalsActions.setUpdatedAt(new Date());
        mktLeadsGoalsActions.setUpdatedBy(practitionerId);
        mktLeadsGoalsActionsDALService.save(mktLeadsGoalsActions);
        SalesTargetActions salesTargetAction = new SalesTargetActions();
        salesTargetAction.setStatisticTimeUnit(3);
        salesTargetAction.setActionStandards(actionStandards);
        salesTargetAction.setLeadsActionId(dropOptionId);
        salesTargetAction.setLeadsActionName(dropOptionName);
        return salesTargetAction;
    }

    /**
     * 保存月度商机目标
     * @param info 入参
     * @param practitionerId 经纪人id
     * @param date 版本号
     * @param year 当前年份
     */
    private void saveMonthGoal(SalesTargetMonth info, Long practitionerId, Date date,int year,Integer goalsType,AclPractitionerSubordinateSystem subordinate) {
        MktLeadsGoals mktLeadsGoals = new MktLeadsGoals();
        mktLeadsGoals.setPractitionerId(practitionerId);
        mktLeadsGoals.setPremium(info.getPremium());
        mktLeadsGoals.setCommission(info.getCommission());
        mktLeadsGoals.setGoalsType(goalsType);
        mktLeadsGoals.setSubordinateSystemId(subordinate.getId());
        mktLeadsGoals.setSubordinateSystemName(subordinate.getName());
        mktLeadsGoals.setPieces(info.getPieces());
        mktLeadsGoals.setPieceAveragePremium(info.getPieceAveragePremium());
        mktLeadsGoals.setCurrentYear(year);
        mktLeadsGoals.setStatisticTimeUnit(3);
        mktLeadsGoals.setSeqTime(info.getMonthNum());
        mktLeadsGoals.setCurrentVersion(date);
        mktLeadsGoals.setCreatedAt(new Date());
        mktLeadsGoals.setCreatedBy(practitionerId);
        mktLeadsGoals.setUpdatedAt(new Date());
        mktLeadsGoals.setUpdatedBy(practitionerId);
        mktLeadsGoals.setIsActive(1);
        mktLeadsGoalsDALService.saveMktLeadsGoals(mktLeadsGoals);
    }

    /**
     * 保存商机年目标
     * @param requestVO 入参
     * @param practitionerId 经纪人id
     * @param date 版本号
     * @param year 当前年份
     */
    private void saveYearGoal(SalesTargetSaveRequestVO requestVO,Long practitionerId,Date date,int year,Integer goalsType,AclPractitionerSubordinateSystem subordinate) {
        Double premium = requestVO.getPremium();
        Double commission = requestVO.getCommission();
        Integer pieces = requestVO.getPieces();
        Double pieceAveragePremium = requestVO.getPieceAveragePremium();
        MktLeadsGoals mktLeadsGoals = new MktLeadsGoals();
        mktLeadsGoals.setPractitionerId(practitionerId);
        mktLeadsGoals.setGoalsType(goalsType);
        mktLeadsGoals.setSubordinateSystemId(subordinate.getId());
        mktLeadsGoals.setSubordinateSystemName(subordinate.getName());
        mktLeadsGoals.setPremium(premium);
        mktLeadsGoals.setCommission(commission);
        mktLeadsGoals.setPieces(pieces);
        mktLeadsGoals.setPieceAveragePremium(pieceAveragePremium);
        mktLeadsGoals.setCurrentYear(year);
        mktLeadsGoals.setSeqTime(year);
        mktLeadsGoals.setStatisticTimeUnit(1);
        mktLeadsGoals.setCurrentVersion(date);
        mktLeadsGoals.setCreatedAt(new Date());
        mktLeadsGoals.setCreatedBy(practitionerId);
        mktLeadsGoals.setUpdatedAt(new Date());
        mktLeadsGoals.setUpdatedBy(practitionerId);
        mktLeadsGoals.setIsActive(1);
        mktLeadsGoalsDALService.saveMktLeadsGoals(mktLeadsGoals);
    }
    @Override
    public SubordinateSystemMemberQueryResponseVO subordinateSystemMemberQuery(SubordinateSystemMemberQueryRequestVO requestVO) {
        SubordinateSystemMemberQueryResponseVO responseVO = new SubordinateSystemMemberQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        if(practitionerId != null){
            Integer time = requestVO.getTime();
            time = (time == null) ? 1 : time;
            String mobileNo = aclPractitionerDALService.findMobileNoByPractitionerId(practitionerId);
            double fypSum = 0D,fycSum = 0D;
            int countSum = 0;
            SubordinateSystemStatisticInfo statisticInfo = new SubordinateSystemStatisticInfo();
            Map<String,SubordinateSystemMemberInfo> memberInfoMap = new HashMap<>();
            //银盾保险在线
            getMemberInfoForOnLine(memberInfoMap,practitionerId,time);
            //eGolden
            getMemberInfoForEGolden(memberInfoMap,practitionerId,time);
            //20210303增加逻辑,已离职经纪人没有数据不显示
            //查询这个团队已离职经纪人电话
            List<String> leaveOfficeList = aclPractitionerDALService.findLeaveOfficeByPractitionerId(practitionerId);
            for (String m : leaveOfficeList) {
                SubordinateSystemMemberInfo subordinateSystemMemberInfo = memberInfoMap.get(m);
                if (CommonUtil.isNullOrZero(subordinateSystemMemberInfo.getCount())){
                    memberInfoMap.remove(m);
                }
            }
            //查询出来的结果按照fyp进行排序
            List<SubordinateSystemMemberInfo> memberInfoList = new ArrayList<>(memberInfoMap.values());
            memberInfoList.sort(Comparator.comparingDouble(SubordinateSystemMemberInfo::getFyp));
            Collections.reverse(memberInfoList);
            for(SubordinateSystemMemberInfo item : memberInfoList){
                fypSum += item.getFyp();
                fycSum += item.getFyc();
                countSum += item.getCount();
            }
            statisticInfo.setCount(countSum);
            statisticInfo.setFyc(CommonUtil.doubleFormat(fycSum,2));
            statisticInfo.setFyp(CommonUtil.doubleFormat(fypSum,2));

            // 查看经纪人所在的体系
            AclPractitionerSubordinateSystem subordinateSystem = aclPractitionerSubordinateSystemDALService.findByPractitionerId(practitionerId);
            if (subordinateSystem != null) {
                Long subordinateSystemId = subordinateSystem.getId();
                statisticInfo.setCompletionRate(getCompletionRate(null,subordinateSystemId,fycSum,time));
                responseVO.setId(subordinateSystemId);
                responseVO.setSubordinateSystemName(subordinateSystem.getName());
                responseVO.setContactName(subordinateSystem.getContactName());
                responseVO.setContactNo(subordinateSystem.getContactNo());
                responseVO.setRemark(subordinateSystem.getRemark());
            }
            responseVO.setStatisticInfo(statisticInfo);
            responseVO.setMemberInfoList(memberInfoList);
            responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        }else{
            String[] params = {"practitionerId"};
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("610001", params)));
        }
        return responseVO;
    }

    /**
     * EGolden中的体系成员成员或被辅导人信息
     * @param memberInfoMap
     * @param practitionerId
     * @param time
     */
    private void getMemberInfoForEGolden(Map<String, SubordinateSystemMemberInfo> memberInfoMap, Long practitionerId, Integer time) {
        List<AclPractitioner> practitionerList = aclPractitionerDALService.findByIds(this.getPractitionerIdList(practitionerId,null));
        List<String> mobileNoList = new ArrayList<>();
        for(AclPractitioner item : practitionerList){
            mobileNoList.add(item.getMobileNo());
        }
        System.out.println("看看手机号");
        System.out.println(mobileNoList);
        List<SubordinateSystemMemberInfoE> subordinateSystemMemberInfoEList = aclPractitionerSubordinateSystemDALService.findStatisticsEBymobileList(mobileNoList, time);
        System.out.println("看看根据手机号查询的EGolden");
        System.out.println(subordinateSystemMemberInfoEList);

        if(!subordinateSystemMemberInfoEList.isEmpty()){
            String mobileNoForMember;
            SubordinateSystemMemberInfo memberInfo;
            Double fyp, fyc;
            Integer count;
            //4、根据id查询出所有的成员的fyc和fyp
            for(SubordinateSystemMemberInfoE item : subordinateSystemMemberInfoEList){
                mobileNoForMember = getMobileNo(item.getMobileNo());
                if(memberInfoMap.containsKey(mobileNoForMember)){
                    memberInfo = memberInfoMap.get(mobileNoForMember);
                    fyp = memberInfo.getFyp();
                    fyc = memberInfo.getFyc();
                    count = memberInfo.getCount();
                    memberInfo.setFyc(CommonUtil.doubleFormat(fyc + item.getFyc(),2));
                    memberInfo.setFyp(CommonUtil.doubleFormat(fyp + item.getFyp(),2));
                    memberInfo.setCount(count + item.getCount());
                }else{
                    memberInfo = new SubordinateSystemMemberInfo();
                    BeanUtils.copyProperties(item,memberInfo);
                    memberInfoMap.put(mobileNoForMember,memberInfo);
                }
            }
        }
    }

    /**
     * EGolden体系中的成员信息
     * @param memberInfoMap 成员类型
     * @param mobileNo 团队长手机号码
     * @param time 时间
     */
    private void getMemberInfoForEGolden(Map<String, SubordinateSystemMemberInfo> memberInfoMap, String mobileNo, Integer time) {
        if(!Strings.isNullOrEmpty(mobileNo) && mobileNo.length() == 11){
            //1、通过手机号码查询用户
            PractitionerBasicInfo practitionerBasicInfo = aclPractitionerDALService.findByMobileNoE(mobileNo);
            //2、判断该用户是否是为团队长
            if(practitionerBasicInfo != null){
                String practitionerId = practitionerBasicInfo.getPractitionerId();
                if(!Strings.isNullOrEmpty(practitionerId)){
                    PractitionerSubordinateInfo subordinateInfo = aclPractitionerSubordinateSystemDALService.findByOwnerE(practitionerId);
                    if(subordinateInfo != null){
                        //3、通过团队长编号查询出该团队下的所有成员
                        String subordinateIdForEGolden = subordinateInfo.getSubordinateCode();
                        List<SubordinateSystemMemberInfoE> subordinateSystemMemberInfoEList = aclPractitionerSubordinateSystemDALService.findStatisticsE(subordinateIdForEGolden,time);
                        if(!subordinateSystemMemberInfoEList.isEmpty()){
                            String mobileNoForMember;
                            SubordinateSystemMemberInfo memberInfo;
                            Double fyp, fyc;
                            Integer count;
                            //4、根据id查询出所有的成员的fyc和fyp
                            for(SubordinateSystemMemberInfoE item : subordinateSystemMemberInfoEList){
                                mobileNoForMember = getMobileNo(item.getMobileNo());
                                if(memberInfoMap.containsKey(mobileNoForMember)){
                                    memberInfo = memberInfoMap.get(mobileNoForMember);
                                    fyp = memberInfo.getFyp();
                                    fyc = memberInfo.getFyc();
                                    count = memberInfo.getCount();
                                    memberInfo.setFyc(CommonUtil.doubleFormat(fyc + item.getFyc(),2));
                                    memberInfo.setFyp(CommonUtil.doubleFormat(fyp + item.getFyp(),2));
                                    memberInfo.setCount(count + item.getCount());
                                }else{
                                    memberInfo = new SubordinateSystemMemberInfo();
                                    BeanUtils.copyProperties(item,memberInfo);
                                    memberInfoMap.put(mobileNoForMember,memberInfo);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取EGOlden中的手机号码
     * @param mobileNo 手机号码
     * @return 校验后的手机号码
     */
    private String getMobileNo(String mobileNo) {
        if(!Strings.isNullOrEmpty(mobileNo) && mobileNo.length() > 11){
            if(mobileNo.contains(" ")){
               String[] mobiles =  mobileNo.split(" ");
               return mobiles[1];
            }
        }
        return mobileNo;
    }

    /**
     * 银盾在线查询体系中的成员信息
     * @param memberInfoMap  成员类型
     * @param practitionerId
     * @param time 时间
     */
    private void getMemberInfoForOnLine(Map<String,SubordinateSystemMemberInfo> memberInfoMap, Long practitionerId, Integer time) {
        //1、查询该团队长所在体系的所有成员
        List<AclPractitioner> practitionerList = aclPractitionerDALService.findByIds(this.getPractitionerIdList(practitionerId,null));
        if(!practitionerList.isEmpty() && practitionerList.get(0) != null){
            Map<Long,Long> customerMap = new HashMap<>();
            Map<Long,String> practitionerIdMobileNoMap = new HashMap<>();
            List<Long> practitionerIds = new ArrayList<>();
            List<Long> customerIds = new ArrayList<>();
            for(AclPractitioner item : practitionerList){
                practitionerIds.add(item.getId());
                customerIds.add(item.getCustomerId());
                customerMap.put(item.getCustomerId(),item.getId());
            }
            //2、查询该体系下经纪人的财富订单统计
            List<AclCustomerFortuneStatistics> customerFortuneStatistics = aclCustomerFortuneDALService.findBypractitionerIds(practitionerIds, time);
            Map<Long,AclCustomerFortuneStatistics> customerFortuneStatisticsMap = new HashMap<>();
            customerFortuneStatistics.forEach(i->customerFortuneStatisticsMap.put(i.getPractitionerId(),i));
            //3、获取所有成员的级别
            List<AclPractitionerSetting> practitionerSettings = aclpractitionersettingDALService.findByPractitionerIdList(practitionerIds);
            Map<Long,Long> practitionerSettingMap = new HashMap<>();
            practitionerSettings.forEach(i->practitionerSettingMap.put(i.getPractitionerId(),i.getPractitionerLevel()));
            //4、获取所有经纪人登记的基础信息
            List<MdDropOptions> practitionerLevelInfo = mdDropOptionsDALService.findByDropMasterCode("practitioner_level");//5L
            Map<Long,String> levelInfoNameMap= new HashMap<>() ,levelInfoCodeMap = new HashMap<>();
            practitionerLevelInfo.forEach(i->levelInfoNameMap.put(i.getId(),i.getDropOptionName()));
            practitionerLevelInfo.forEach(i->levelInfoCodeMap.put(i.getId(),i.getDropOptionCode()));
            //5、查询所以经纪人手机号码
            List<AclCustomer> customerList = aclCustomerDALService.findByIds(customerIds);
            customerList.forEach(i->practitionerIdMobileNoMap.put(customerMap.get(i.getId()),i.getMobileNo()));
//            for(AclCustomer item : customerList){
//                practitionerIdMobileNoMap.put(customerMap.get(item.getId()),item.getMobileNo());
//            }
            SubordinateSystemMemberInfo memberInfo;
            Long practitionerIdForMember,practitionerLevelId;
            AclCustomerFortuneStatistics customerFortuneStatisticsItem;
            for(AclPractitioner practitioner : practitionerList){
                double fyp = 0D,fyc = 0D;
                int count = 0;
                practitionerIdForMember = practitioner.getId();
                practitionerLevelId = practitionerSettingMap.get(practitionerIdForMember);
                memberInfo = new SubordinateSystemMemberInfo();
                memberInfo.setPractitionerId(practitionerIdForMember);
                memberInfo.setName(practitioner.getName());
                memberInfo.setLevelCode(levelInfoCodeMap.get(practitionerLevelId));
                memberInfo.setLevelName(levelInfoNameMap.get(practitionerLevelId));
                if(customerFortuneStatisticsMap.containsKey(practitionerIdForMember)){
                    customerFortuneStatisticsItem = customerFortuneStatisticsMap.get(practitionerIdForMember);
                    fyc = customerFortuneStatisticsItem.getFyc();
                    fyp = customerFortuneStatisticsItem.getFyp();
                    count = customerFortuneStatisticsItem.getCount();
                }
                memberInfo.setFyc(CommonUtil.doubleFormat(fyc,2));
                memberInfo.setFyp(CommonUtil.doubleFormat(fyp,2));
                memberInfo.setCount(count);
                memberInfoMap.put(practitionerIdMobileNoMap.get(practitionerIdForMember),memberInfo);
            }
        }
    }

    /**
     * 获取完成率
     * @param practitionerId 经纪人Id
     * @param subordinateSystemId 团队长ID
     * @param fycSum  总的FYC
     * @param time 时间
     * @return 完成率
     */
    private Double getCompletionRate(Long practitionerId,Long subordinateSystemId, Double fycSum,Integer time) {
        if((practitionerId != null || subordinateSystemId != null) && fycSum != null && time != null && fycSum > 0){
            List<MktLeadsGoals> leadsGoals;
            Double goalsPremium = null;
            if(time == 2){
                if(practitionerId != null){
                    leadsGoals = mktLeadsGoalsDALService.findByTypeAndTimeUnitAndPractitionerId(1,1,practitionerId);
                }else{
                    leadsGoals = mktLeadsGoalsDALService.findByTypeAndTimeUnitAndSubordinateSystemId(2,1,subordinateSystemId);
                }
                goalsPremium = (leadsGoals != null && leadsGoals.size() > 0) ? leadsGoals.get(0).getCommission() : null;
            }else{
                if(practitionerId != null){
                    leadsGoals = mktLeadsGoalsDALService.findByTypeAndTimeUnitAndPractitionerId(1,3,practitionerId);
                }else{
                    leadsGoals = mktLeadsGoalsDALService.findByTypeAndTimeUnitAndSubordinateSystemId(2,3,subordinateSystemId);
                }
                Calendar calendar = Calendar.getInstance();
                int month = calendar.get(Calendar.MONTH)+1;
                List<Integer> monthList = getMonthListForQuarter(month);
                for(MktLeadsGoals item : leadsGoals){
                    if(time == 1){//月份
                        if(item.getSeqTime() == month){
                            goalsPremium = item.getCommission();
                            break;
                        }
                    }else{//季度
                        if(monthList.contains(item.getSeqTime())){
                            goalsPremium = (goalsPremium == null) ? item.getCommission() : goalsPremium + item.getCommission();
                        }
                    }
                }
            }
            if(goalsPremium != null && goalsPremium > 0){
                BigDecimal fycBigDecimal = new BigDecimal(fycSum),goalsBigDecimal = new BigDecimal(goalsPremium);
                return CommonUtil.doubleFormat(fycBigDecimal.divide(goalsBigDecimal,4,BigDecimal.ROUND_HALF_UP).doubleValue() * 100,2);
            }
        }
        return 0D;
    }

    private List<Integer> getMonthListForQuarter(int month) {
        if (month < 4) {
            return Arrays.asList(1, 2, 3);
        } else if (month < 7) {
            return Arrays.asList(4, 5, 6);
        } else if (month < 10) {
            return Arrays.asList(7, 8, 9);
        } else {
            return Arrays.asList(10, 11, 12);
        }
    }
    @Override
    public PotentialActivityQueryResponseVO potentialActivityQuery(PotentialActivityQueryRequestVO requestVO) {
        PotentialActivityQueryResponseVO responseVO = new PotentialActivityQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        if(practitionerId != null){
            List<AclPractitionerPotentialAssignedTrack> assignedTrackList = aclPractitionerPotentialAssignedTrackDALService.findScoreByPractitionerIdAndDate(practitionerId,"month");
            int activityForToday = 0,activityForWeek = 0,activityForMonth = 0,activityForQuarter = 0;
            Set<Long> succeedRecruitSet = new HashSet<>();
            if(assignedTrackList != null && !assignedTrackList.isEmpty()){
                Integer trackScore;
                Date trackTime;
                Long trackStatusId;
                Calendar calendar = Calendar.getInstance();
                //获取增员成功id
                List<MdDropOptions> optionsList = mdDropOptionsDALService.findByMasterCodeAndOptionsCode("team_building_track","7");
                long trackSucceedId = (optionsList != null && !optionsList.isEmpty()) ? optionsList.get(0).getId() : 113L;
                Date todayStartDate = getTimeStartDate(calendar,"today");//本天的开始时间
                Date weekStartDate = getTimeStartDate(calendar,"week");//本周的开始时间
                Date monthStartDate = getTimeStartDate(calendar,"month");//本月的开始时间
//              Date quarterStartDate = getTimeStartDate(calendar,"quarter"); //本季的开始时间
                for(AclPractitionerPotentialAssignedTrack item : assignedTrackList){
                    trackStatusId = item.getTrackStatusId();
                    trackScore = item.getTrackScore();
                    trackTime = item.getTrackTime();
                    if(trackStatusId != null && trackSucceedId == trackStatusId && item.getIsLasted() == 1){
                        succeedRecruitSet.add(item.getId());
                    }
                    if(trackScore != null && trackScore != 0){
                        if(!trackTime.before(todayStartDate)){
                            activityForToday += trackScore;
                            activityForWeek += trackScore;
                            activityForMonth += trackScore;
                            activityForQuarter += trackScore;
                        }else if(!trackTime.before(weekStartDate)){
                            activityForWeek += trackScore;
                            activityForMonth += trackScore;
                            activityForQuarter += trackScore;
                        }else if(!trackTime.before(monthStartDate)){
                            activityForMonth += trackScore;
                            activityForQuarter += trackScore;
                        }else{
                            activityForQuarter += trackScore;
                        }
                    }
                }
            }
            responseVO.setActivityForToday(activityForToday);
            responseVO.setActivityForWeek(activityForWeek);
            responseVO.setActivityForMonth(activityForMonth);
            responseVO.setActivityForQuarter(activityForQuarter);
            responseVO.setRecruitSucceed(succeedRecruitSet.size());
            responseVO.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
        }else{
            String [] paras = {"practitionerId"};
            responseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610002",paras)));
        }
        return responseVO;
    }

    @Override
    public SalesScoreDetailQueryResponseVO salesScoreDetailQuery(SalesScoreDetailQueryRequestVO requestVO) {
        SalesScoreDetailQueryResponseVO responseVO = new SalesScoreDetailQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        String time = requestVO.getTime();
        //根据经纪人id及时间范围统计跟进状态次数
        List<SalesScoreDetail> salesScoreDetails = mktLeadsAssignedTrackDALService.getSalesScoreDetailByPractitionerId(practitionerId,time);
        responseVO.setSalesScoreDetails(salesScoreDetails);
        responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        return responseVO;
    }

    private Date getTimeStartDate(Calendar calendar, String time) {
        if(calendar != null){
            switch (time) {
                case "today":
                    calendar.set(Calendar.HOUR_OF_DAY, 0);
                    calendar.set(Calendar.SECOND, 0);
                    calendar.set(Calendar.MINUTE, 0);
                    calendar.set(Calendar.MILLISECOND, 0);
                    return calendar.getTime();
                case "week":
                    calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
                    calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
                    return calendar.getTime();
                case "month":
                    calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
                    calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
                    return calendar.getTime();
                default:
                    int currentMonth = calendar.get(Calendar.MONTH) + 1;
                    SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        if (currentMonth <= 3)
                            calendar.set(Calendar.MONTH, 0);
                        else if (currentMonth <= 6)
                            calendar.set(Calendar.MONTH, 3);
                        else if (currentMonth <= 9)
                            calendar.set(Calendar.MONTH, 4);
                        else if (currentMonth <= 12)
                            calendar.set(Calendar.MONTH, 9);
                        calendar.set(Calendar.DATE, 1);
                        return longSdf.parse(shortSdf.format(calendar.getTime()) + " 00:00:00");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
            }
        }
        return null;
    }

    private void savePotentialGoalsActions(List<AclPractitionerPotentialGoalsActions> potentialGoalsActionsList, Long practitionerId, Integer currentYear, Long potentialActionId, String potentialActionName, int result, Date version) {
        //月
        savePotentialGoalsActionsDetail(potentialGoalsActionsList,practitionerId,currentYear,3,potentialActionId,potentialActionName,result,version);
        //季度
        result = result*3;
        savePotentialGoalsActionsDetail(potentialGoalsActionsList,practitionerId,currentYear,2,potentialActionId,potentialActionName,result,version);
        //周
        result = result*4;
        result = result%52 == 0 ? (result/52) : (result/52)+1;
        savePotentialGoalsActionsDetail(potentialGoalsActionsList,practitionerId,currentYear,4,potentialActionId,potentialActionName,result,version);
    }

    /**
     * 计算活动量
     * @param numberRecruitsYear 年目标
     */
    private void savePotentialActions(Long practitionerId,Integer numberRecruitsYear,Integer currentYear,Date version) {
        if(numberRecruitsYear != null){
            //清空就逻辑
            updateOldDataForGoalsActions(practitionerId,currentYear);
            //1、获取所有的逻辑
            List<MdGoalsCalculateExpression> calculateExpressionList = mdGoalsCalculateExpressionDALService.findByMasterCodeAndIsActive("team_building_track",1);
            if(calculateExpressionList != null && !calculateExpressionList.isEmpty()){
                try {
                    ScriptEngine jScriptEngine=new ScriptEngineManager().getEngineByName("JavaScript");
                    int a = numberRecruitsYear%12 == 0 ? (numberRecruitsYear/12) : (numberRecruitsYear/12)+1;
                    String expression;
                    int result;
                    Long potentialActionId;
                    String potentialActionName;
                    List<AclPractitionerPotentialGoalsActions> potentialGoalsActionsList = new ArrayList<>();
                    for(MdGoalsCalculateExpression item :  calculateExpressionList){
                        expression = item.getCalculateScriptExpression();
                        if(!Strings.isNullOrEmpty(expression)){
                            expression = expression.replaceAll("num",String.valueOf(a));
                            result = (int) jScriptEngine.eval(expression);
                            potentialActionId = item.getActionId();
                            potentialActionName = item.getDropOptionName();
                            savePotentialGoalsActions(potentialGoalsActionsList,practitionerId,currentYear,potentialActionId,potentialActionName,result,version);
                        }
                    }
                    aclPractitionerPotentialGoalsActionsDALService.saveAll(potentialGoalsActionsList);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    private void updateOldDataForGoalsActions(Long practitionerId, Integer currentYear) {
        List<AclPractitionerPotentialGoalsActions> potentialGoalsActionsListUpdate = new ArrayList<>();
        List<AclPractitionerPotentialGoalsActions> potentialGoalsActionsListOld = aclPractitionerPotentialGoalsActionsDALService.findByPractitionerIdAndCurrentYearAndIsActive(practitionerId,currentYear,1);
        if(potentialGoalsActionsListOld != null && !potentialGoalsActionsListOld.isEmpty()){
            for(AclPractitionerPotentialGoalsActions item : potentialGoalsActionsListOld){
                item.setIsActive(0);
                item.setUpdatedAt(new Date());
                item.setUpdatedBy(practitionerId);
                potentialGoalsActionsListUpdate.add(item);
            }
            aclPractitionerPotentialGoalsActionsDALService.updateAll(potentialGoalsActionsListUpdate);
        }
    }

    private void savePotentialGoalsActionsDetail(List<AclPractitionerPotentialGoalsActions> potentialGoalsActionsList, Long practitionerId, Integer currentYear, Integer timeUnit, Long potentialActionId, String potentialActionName, int result, Date version) {
        AclPractitionerPotentialGoalsActions potentialGoalsActions = new AclPractitionerPotentialGoalsActions();
        potentialGoalsActions.setPractitionerId(practitionerId);
        potentialGoalsActions.setCurrentYear(currentYear);
        potentialGoalsActions.setStatisticTimeUnit(timeUnit);
        potentialGoalsActions.setPotentialActionId(potentialActionId);
        potentialGoalsActions.setPotentialActionName(potentialActionName);
        potentialGoalsActions.setActionStandards(result);
        potentialGoalsActions.setCurrentVersion(version);
        potentialGoalsActions.setIsActive(1);
        potentialGoalsActions.setCreatedAt(new Date());
        potentialGoalsActions.setCreatedBy(practitionerId);
        potentialGoalsActionsList.add(potentialGoalsActions);
    }

    /**
     * 生成保存列表
     * @param potentialGoalsList 列表
     * @param practitionerId 经纪人id
     * @param timeType 时间类型
     * @param seq 序号
     * @param numberRecruitsYear 年目标
     * @param numberMDRTYear MDRT年目标
     */
    private void getPotentialGoalsList(List<AclPractitionerPotentialGoals> potentialGoalsList, Long practitionerId, Integer timeType, Integer seq, Integer numberRecruitsYear, Integer numberMDRTYear,Integer currentYear,Date version) {
        AclPractitionerPotentialGoals potentialGoals = new AclPractitionerPotentialGoals();
        potentialGoals.setPractitionerId(practitionerId);
        potentialGoals.setCurrentYear(currentYear);
        potentialGoals.setStatisticTimeUnit(timeType);
        potentialGoals.setSeqTime(seq);
        potentialGoals.setNumberRecruits(numberRecruitsYear);
        potentialGoals.setNumberMdrt(numberMDRTYear);
        potentialGoals.setCurrentVersion(version);
        potentialGoals.setIsActive(1);
        potentialGoals.setCreatedAt(new Date());
        potentialGoals.setCreatedBy(practitionerId);
        potentialGoalsList.add(potentialGoals);
    }

    private CommonResult check(OwnOpportunityRecordSaveRequestVO requestVO) {
        String noticeDate = requestVO.getNoticeDate();
        if (CommonUtil.isNullOrBlank(noticeDate)){
            return new CommonResult(false, ZHBErrorConfig.getErrorInfo("830012"));
        }
        String salesNotice = requestVO.getSalesNotice();
        if (CommonUtil.isNullOrBlank(salesNotice)){
            return new CommonResult(false, ZHBErrorConfig.getErrorInfo("830013"));
        }
        //判断此经纪人当天是否已为此商机经行了此项跟进
        if (CommonUtil.isNullOrZero(requestVO.getId())){
            MktLeadsAssignedTrack mktLeadsAssignedTrack = new MktLeadsAssignedTrack();
            mktLeadsAssignedTrack.setPractitionerId(requestVO.getPractitionerId());
            mktLeadsAssignedTrack.setCustomerId(requestVO.getOpportunityId());
            mktLeadsAssignedTrack.setLeadsAssignedId(requestVO.getLeadsAssignedId());
            mktLeadsAssignedTrack.setMdDropOptionId(requestVO.getMdDropOptionId());
            List<MktLeadsAssignedTrack> trackList = mktLeadsAssignedTrackDALService.findByTrackTimeForNew(mktLeadsAssignedTrack);
            if (!trackList.isEmpty()){
                return new CommonResult(false, ZHBErrorConfig.getErrorInfo("830015"));
            }
        }
        return new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000"));
    }

    private CommonResult paramCheck(SettingSaveRequestVO requestVO) {
        //检查入参判断
        Long practitionerId = requestVO.getPractitionerId();
        if (CommonUtil.isNullOrZero(practitionerId)){
            String[] params = {"practitionerId"};
            return new CommonResult(false, ZHBErrorConfig.getErrorInfo("610001",params));
        }
        //生活照至多三张
        List<String> lifeImgUrls = requestVO.getLifeImgUrls();
        if (lifeImgUrls != null){
            if (!lifeImgUrls.isEmpty()){
                AclFileUpload aclFileUpload = new AclFileUpload();
                aclFileUpload.setTargetType(1);
                aclFileUpload.setTargetId(practitionerId);
                aclFileUpload.setTargetUseFor(2);
                aclFileUpload.setIsActive(1);
                List<AclFileUpload> fileUploads = aclFileUploadDALService.findByAclFileUpload(aclFileUpload);
                if (!fileUploads.isEmpty()){
                    int size = lifeImgUrls.size()+fileUploads.size();
                    if (size>=4){
                        return new CommonResult(false, ZHBErrorConfig.getErrorInfo("830006"));
                    }
                }
            }
        }
        return new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000"));
    }

    private void practitionerMySettingSave(SettingSaveRequestVO requestVO) {
        //修改个人设置，个人介绍
        String settingSave = requestVO.getSettingSave();
        if (settingSave.equalsIgnoreCase("isShow")||settingSave.equalsIgnoreCase("intro")){
            Long practitionerId = requestVO.getPractitionerId();
            AclPractitioner practitioner = aclPractitionerDALService.findPractitionerById(practitionerId);
            if (settingSave.equalsIgnoreCase("intro")){
                practitioner.setBioIntro(requestVO.getBioIntro());
            }else if (settingSave.equalsIgnoreCase("isShow")){
                practitioner.setIsNameShow(requestVO.getIsNameShow());
                practitioner.setIsMobileShow(requestVO.getIsMobileShow());
            }
            aclPractitionerDALService.updatePractitioner(practitioner);
        }
    }

    private String practitionerHeadImgSave(SettingSaveRequestVO requestVO) throws Exception {
        String headImgUrl = requestVO.getHeadImgUrl();
        if (CommonUtil.isNullOrBlank(headImgUrl)){
            //如果头像没有地址，则认为没有上传
            return null;
        }
        //上传图片
        return uploadImage(headImgUrl,requestVO.getPractitionerId(),1);
    }

    private String practitionerLifeImgSave(SettingSaveRequestVO requestVO) throws Exception {
        List<String> lifeImgUrls = requestVO.getLifeImgUrls();
        StringBuilder message = new StringBuilder(" ");
        int i = 1;
        for (String lifeImgUrl: lifeImgUrls){
            String resp = uploadImage(lifeImgUrl, requestVO.getPractitionerId(), 2);
            if (!CommonUtil.isNullOrBlank(resp)){
                message.append(i).append(",");
            }
            i++;
        }
        if (!CommonUtil.isNullOrBlank(message.toString())){
            return "此次上传第"+message+"张图片尺寸不符合要求!!";
        }
        return null;
    }

    private String practitionerWXQRImgSave(SettingSaveRequestVO requestVO) throws Exception{
        String wxQRImgUrl = requestVO.getWxQRImgUrl();
        if (CommonUtil.isNullOrBlank(wxQRImgUrl)){
            //如果头像没有地址，则认为没有上传
            return null;
        }
        //上传图片
        return uploadImage(wxQRImgUrl,requestVO.getPractitionerId(),9);
    }

    private String uploadImage(String headImgUrl, Long practitionerId,Integer targetUseFor) throws Exception{
        Map<String, Object> input = HttpUtil.getInput(headImgUrl);
        if (!(boolean)input.get("success")){
            if (targetUseFor==1){
                //地址转流失败
                return ZHBErrorConfig.getErrorInfo("830007");
            }else if(targetUseFor==2){
                return ZHBErrorConfig.getErrorInfo("830008");
            }else if(targetUseFor==9){
                return ZHBErrorConfig.getErrorInfo("830009");
            }
        }
        //获取头像流
        InputStream inputStream = (InputStream) input.get("is");
        //判断图像尺寸
        BufferedImage img = ImageIO.read(inputStream);
        if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
            return ZHBErrorConfig.getErrorInfo("830003");
        }
//        else {
//            double width = img.getWidth(null);
//            double height = img.getHeight(null);
//            double value =height/width;
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(img, "jpg", os);
            inputStream = new ByteArrayInputStream(os.toByteArray());
//            if (value !=1&&(targetUseFor == 1 || targetUseFor == 9)){
//                //上传头像尺寸比例为1:1
//                return ZHBErrorConfig.getErrorInfo("830005");
//            }else if(value !=0.75 && targetUseFor == 2){
//                return ZHBErrorConfig.getErrorInfo("830004");
//            }
//        }
        //上传图片至阿里云
        String prefix = "broker/"+practitionerId+"/";
        String originalFilename = generateKey(targetUseFor);
        String key = prefix + originalFilename;
        String putFileToOss = ossService.putFileToOss(null,key,inputStream);
        //将之前头像设置为不启用
        if (targetUseFor==1||targetUseFor==9){
            updateImgOld(practitionerId,targetUseFor);
        }
        //保存到数据库
        AclPractitioner practitioner = aclPractitionerDALService.findPractitionerById(practitionerId);
        AclFileUpload aclFileUpload = new AclFileUpload();
        aclFileUpload.setTargetType(1);
        aclFileUpload.setTargetId(practitioner.getId());
        String practitionerCode = practitioner.getPractitionerCode();
        aclFileUpload.setTargetNo(practitionerCode);
        aclFileUpload.setFileType("jpg");
        aclFileUpload.setFileName(originalFilename);
        aclFileUpload.setFilePath(putFileToOss);
        aclFileUpload.setTargetUseFor(targetUseFor);
        aclFileUpload.setFileSize(String.valueOf(inputStream.available()));
        aclFileUpload.setOssKey(key);
        aclFileUpload.setIsActive(1);
        aclFileUpload.setUploadedAt(new Date());
        aclFileUpload.setUploadedBy(-1L);
        aclFileUpload.setTargetSeq(getTargetSeq(practitioner.getId(),targetUseFor));
        aclFileUploadDALService.saveFileUpload(aclFileUpload);
        return null;
    }
    private String generateKey(int targetUseFor) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
        return targetUseFor+sdf.format(new Date()) + CommonUtil.getRandomNum(3)+".jpg";
    }

    private void updateImgOld(Long practitionerId, int targetUseFor) {
        AclFileUpload aclFileUpload = new AclFileUpload();
        aclFileUpload.setTargetId(practitionerId);
        aclFileUpload.setTargetType(1);
        aclFileUpload.setIsActive(1);
        aclFileUpload.setTargetUseFor(targetUseFor);
        List<AclFileUpload> uploads = aclFileUploadDALService.findByAclFileUpload(aclFileUpload);
        if (!uploads.isEmpty()){
            for (AclFileUpload fileUpload :uploads){
                fileUpload.setIsActive(0);
                aclFileUploadDALService.updateFileUpload(fileUpload);
            }
        }
    }

    private Integer getTargetSeq(Long practitionerId, Integer targetUseFor) {
        AclFileUpload aclFileUpload = new AclFileUpload();
        aclFileUpload.setTargetType(1);
        aclFileUpload.setTargetId(practitionerId);
        aclFileUpload.setTargetUseFor(targetUseFor);
        List<AclFileUpload> aclFileUploadList = aclFileUploadDALService.findByAclFileUpload(aclFileUpload);
        return aclFileUploadList.size()+1;
    }

    @Override
    public ApplyForExpertSupportResponseVO applyForExpertSupport(ApplyForExpertSupportRequestVO requestVO) {
        ApplyForExpertSupportResponseVO resp = new ApplyForExpertSupportResponseVO();
        //判断此商机专家支持是否已经申请
        MktLeadsExpertRequest isExpertRequest = mktLeadsExpertRequestDALService.findByCustomerId(requestVO.getOpportunityId());
        if (isExpertRequest != null){
            resp.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("830019")));
            return resp;
        }
        //申请专家支持
        //保存ag_mkt_leads_expert_request
        MktLeadsExpertRequest mktLeadsExpertRequest = new MktLeadsExpertRequest();
        mktLeadsExpertRequest.setLeadsAssignedId(requestVO.getLeadsAssignedId());
        mktLeadsExpertRequest.setCustomerId(requestVO.getOpportunityId());
        mktLeadsExpertRequest.setIsActive(1);
        mktLeadsExpertRequest.setCreatedAt(new Date());
        mktLeadsExpertRequest.setUpdatedAt(new Date());
        mktLeadsExpertRequest.setCreatedBy(requestVO.getPractitionerId());
        mktLeadsExpertRequest.setUpdatedBy(requestVO.getPractitionerId());
        mktLeadsExpertRequestDALService.save(mktLeadsExpertRequest);

        //查询商机所属经纪人的信息
        AclPractitioner aclPractitioner = aclPractitionerDALService.findPractitionerByLeadsAssignedId(requestVO.getLeadsAssignedId());
        //发邮件
        //发送邮件给客服，同步跟进
        String toAddress = systemConfigService.getSingleConfigValue("ApplyForExpertSupportToAddress");
        String ccAddress = systemConfigService.getSingleConfigValue("ApplyForExpertSupportCCAddresses");
        List<String> ccList = new ArrayList<>();
        for (String address :ccAddress.split(",")){
            ccList.add(address);
        }
        String[] ccAddresses = ccList.toArray(new String[ccList.size()]);
        ccList.toArray(ccAddresses);
        String subject = "申请专家支持";
        String messageText = "尊敬的管理员，您好!";
        messageText += "寿险经纪人【"+aclPractitioner.getName()+"】，电话{"+aclPractitioner.getMobileNo()+"}申请了专家支持，请在AGMS及时处理并分配专家进行支持。谢谢!";

        mailService.sysNotify(toAddress,ccAddresses,subject,messageText);

        resp.setCommonResult(new CommonResult(true,ZHBErrorConfig.getErrorInfo("800000")));
        return resp;
    }
}
