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

import static java.util.stream.Collectors.toList;

import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

import javax.imageio.ImageIO;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.beanutils.BeanPropertyValueEqualsPredicate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.google.common.base.Strings;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.libs.pdf.PDFTemplate;
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.PractitionerIdRequestVO;
import com.yd.api.practitioner.vo.businessCard.Certificate;
import com.yd.api.practitioner.vo.businessCard.PractitionerApplyEmailRequestVO;
import com.yd.api.practitioner.vo.businessCard.PractitionerBusinessCardRequestVO;
import com.yd.api.practitioner.vo.businessCard.PractitionerBusinessCardResponseVO;
import com.yd.api.practitioner.vo.commitment.QueryCommitmentByPractitionerIdResponseVO;
import com.yd.api.practitioner.vo.commitment.SignCommitmentRequestVO;
import com.yd.api.practitioner.vo.informed.QueryInformedSheetByIdResponseVO;
import com.yd.api.practitioner.vo.informed.QueryInformedSheetListRequestVO;
import com.yd.api.practitioner.vo.informed.QueryInformedSheetListResponseVO;
import com.yd.api.practitioner.vo.informed.SaveInformedSheetRequestVO;
import com.yd.api.practitioner.vo.informed.SignInformedSheetRequestVO;
import com.yd.api.practitioner.vo.informed.UpdateInformedSheetByIdRequestVO;
import com.yd.api.practitioner.vo.login.CanSeeSalaryListResponseVO;
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.ApplyForExpertSupportRequestVO;
import com.yd.api.practitioner.vo.opportunity.ApplyForExpertSupportResponseVO;
import com.yd.api.practitioner.vo.opportunity.OpportunityBasicInformationInfo;
import com.yd.api.practitioner.vo.opportunity.OpportunityConsultationInfo;
import com.yd.api.practitioner.vo.opportunity.OpportunityCustomerTag;
import com.yd.api.practitioner.vo.opportunity.OpportunityDeleteRequestVO;
import com.yd.api.practitioner.vo.opportunity.OpportunityRecordInfo;
import com.yd.api.practitioner.vo.opportunity.OpportunityRecordSituationInfo;
import com.yd.api.practitioner.vo.opportunity.OpportunityScore;
import com.yd.api.practitioner.vo.opportunity.OpportunityStatisticsRequestVO;
import com.yd.api.practitioner.vo.opportunity.OpportunityStatisticsResponseVO;
import com.yd.api.practitioner.vo.opportunity.OpportunitySurveyAnswers;
import com.yd.api.practitioner.vo.opportunity.OwnOpportunityBasicInformationSaveRequestVO;
import com.yd.api.practitioner.vo.opportunity.OwnOpportunityBasicInformationSaveResponseVO;
import com.yd.api.practitioner.vo.opportunity.OwnOpportunityDetailQueryRequestVO;
import com.yd.api.practitioner.vo.opportunity.OwnOpportunityDetailQueryResponseVO;
import com.yd.api.practitioner.vo.opportunity.OwnOpportunityQueryRequestVO;
import com.yd.api.practitioner.vo.opportunity.OwnOpportunityQueryResponseVO;
import com.yd.api.practitioner.vo.opportunity.OwnOpportunityRecordSaveRequestVO;
import com.yd.api.practitioner.vo.opportunity.OwnOpportunityRecordSaveResponseVO;
import com.yd.api.practitioner.vo.opportunity.PlayerSalesActivityQueryRequestVO;
import com.yd.api.practitioner.vo.opportunity.PlayerSalesActivityQueryResponseVO;
import com.yd.api.practitioner.vo.opportunity.SalesPerformanceForecastInfo;
import com.yd.api.practitioner.vo.opportunity.SalesPerformanceForecastListQueryRequestVO;
import com.yd.api.practitioner.vo.opportunity.SalesPerformanceForecastListQueryResponseVO;
import com.yd.api.practitioner.vo.opportunity.SalesScoreDetail;
import com.yd.api.practitioner.vo.opportunity.SalesScoreDetailQueryRequestVO;
import com.yd.api.practitioner.vo.opportunity.SalesScoreDetailQueryResponseVO;
import com.yd.api.practitioner.vo.practitionerCustomer.CustomerHolder;
import com.yd.api.practitioner.vo.practitionerCustomer.QueryCustomerHolderListResponesVO;
import com.yd.api.practitioner.vo.practitionerCustomer.QueryCustomerInsuredListRequestVO;
import com.yd.api.practitioner.vo.practitionerCustomer.QueryCustomerInsuredListResponesVO;
import com.yd.api.practitioner.vo.practitionerCustomer.QueryPolicyListByHolderCustomerIdRequestVO;
import com.yd.api.practitioner.vo.practitionerCustomer.QueryPolicyListByHolderCustomerIdResponesVO;
import com.yd.api.practitioner.vo.rank.AclCustomerFortuneStatistics;
import com.yd.api.practitioner.vo.rank.PractitionerInfoForAchievement;
import com.yd.api.practitioner.vo.rank.PractitionerRankRequestVO;
import com.yd.api.practitioner.vo.rank.PractitionerRankResponseVO;
import com.yd.api.practitioner.vo.recruit.AddRecruitTrackRequestVO;
import com.yd.api.practitioner.vo.recruit.AddRecruitTrackResponseVO;
import com.yd.api.practitioner.vo.recruit.PotentialActivityQueryRequestVO;
import com.yd.api.practitioner.vo.recruit.PotentialActivityQueryResponseVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsActionsInfo;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsActionsQueryRequestVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsActionsQueryResponseVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsActionsUpdateRequestVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsActionsUpdateResponseVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsQueryRequestVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsQueryResponseVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsSettingRequestVO;
import com.yd.api.practitioner.vo.recruit.PotentialGoalsSettingResponseVO;
import com.yd.api.practitioner.vo.recruit.PractitionerPotentialInfo;
import com.yd.api.practitioner.vo.recruit.RecruitGoalForMonth;
import com.yd.api.practitioner.vo.recruit.RecruitListRequestVO;
import com.yd.api.practitioner.vo.recruit.RecruitListResponseVO;
import com.yd.api.practitioner.vo.recruit.RecruitRequestVO;
import com.yd.api.practitioner.vo.recruit.RecruitResponseVO;
import com.yd.api.practitioner.vo.recruit.RecruitTrackInfo;
import com.yd.api.practitioner.vo.recruit.RecruitTrackQueryRequestVO;
import com.yd.api.practitioner.vo.recruit.RecruitTrackQueryResponseVO;
import com.yd.api.practitioner.vo.salestarget.SalesTargetActions;
import com.yd.api.practitioner.vo.salestarget.SalesTargetMonth;
import com.yd.api.practitioner.vo.salestarget.SalesTargetMonthSaveRequestVO;
import com.yd.api.practitioner.vo.salestarget.SalesTargetMonthSaveResponseVO;
import com.yd.api.practitioner.vo.salestarget.SalesTargetQueryRequestVO;
import com.yd.api.practitioner.vo.salestarget.SalesTargetQueryResponseVO;
import com.yd.api.practitioner.vo.salestarget.SalesTargetSaveRequestVO;
import com.yd.api.practitioner.vo.salestarget.SalesTargetSaveResponseVO;
import com.yd.api.practitioner.vo.salestarget.TeamActionsAverageQueryRequestVO;
import com.yd.api.practitioner.vo.salestarget.TeamActionsAverageQueryResponseVO;
import com.yd.api.practitioner.vo.setting.ImgDeleteRequestVO;
import com.yd.api.practitioner.vo.setting.ImgDeleteResponseVO;
import com.yd.api.practitioner.vo.setting.LifeImg;
import com.yd.api.practitioner.vo.setting.SettingQueryRequestVO;
import com.yd.api.practitioner.vo.setting.SettingQueryResponseVO;
import com.yd.api.practitioner.vo.setting.SettingSaveRequestVO;
import com.yd.api.practitioner.vo.setting.SettingSaveResponseVO;
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.practitioner.vo.unionSales.SignUnionSalesRequestVO;
import com.yd.api.practitioner.vo.unionSales.UnionSalesPractitionerInfo;
import com.yd.api.result.CommonResult;
import com.yd.api.result.CommonResultIDResponseVO;
import com.yd.api.result.CommonResultResponseVO;
import com.yd.api.result.IDRequestVO;
import com.yd.dal.entity.customer.AclCustomer;
import com.yd.dal.entity.customer.AclCustomerLog;
import com.yd.dal.entity.customer.AclCustomerMembership;
import com.yd.dal.entity.customer.AclCustomerShare;
import com.yd.dal.entity.customer.AclFileUpload;
import com.yd.dal.entity.customer.AclPractitioner;
import com.yd.dal.entity.customer.AclPractitionerPotential;
import com.yd.dal.entity.customer.AclPractitionerPotentialAssignedTrack;
import com.yd.dal.entity.customer.AclPractitionerPotentialAssigneds;
import com.yd.dal.entity.customer.AclPractitionerPotentialGoals;
import com.yd.dal.entity.customer.AclPractitionerPotentialGoalsActions;
import com.yd.dal.entity.customer.AclPractitionerSetting;
import com.yd.dal.entity.customer.AclPractitionerSubordinateSystem;
import com.yd.dal.entity.customer.AgPoInformed;
import com.yd.dal.entity.customer.CustomerFileUpload;
import com.yd.dal.entity.customer.practitioner.PractitionerBasicInfo;
import com.yd.dal.entity.customer.practitioner.PractitionerInfo;
import com.yd.dal.entity.customer.practitioner.PractitionerRankInfo;
import com.yd.dal.entity.customer.practitioner.PractitionerSubordinateInfo;
import com.yd.dal.entity.customer.practitioner.SubordinateSystemMemberInfoE;
import com.yd.dal.entity.marketing.MktLeadsAssignedTrack;
import com.yd.dal.entity.marketing.MktLeadsAssigneds;
import com.yd.dal.entity.marketing.MktLeadsExpertAssign;
import com.yd.dal.entity.marketing.MktLeadsExpertRequest;
import com.yd.dal.entity.marketing.MktLeadsGoals;
import com.yd.dal.entity.marketing.MktLeadsGoalsActions;
import com.yd.dal.entity.marketing.MktLeadsPool;
import com.yd.dal.entity.meta.MdDropMaster;
import com.yd.dal.entity.meta.MdDropOptions;
import com.yd.dal.entity.meta.MdGoalsCalculateExpression;
import com.yd.dal.entity.meta.MdMkCampaign;
import com.yd.dal.entity.meta.MdTag;
import com.yd.dal.entity.meta.ObjectCollectionTagged;
import com.yd.dal.entity.order.CustomerPolicyInfo;
import com.yd.dal.entity.order.PoOrder;
import com.yd.dal.entity.practitioner.opportunity.OwnOpportunityInfo;
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.mapper.customer.AclPolicyholderMapper;
import com.yd.dal.mapper.customer.AgPoInformedMapper;
import com.yd.dal.mapper.marketing.MktLeadsAssignedsMapper;
import com.yd.dal.service.agms.AgmsDashboardDALService;
import com.yd.dal.service.customer.AclCustomerDALService;
import com.yd.dal.service.customer.AclCustomerFortuneDALService;
import com.yd.dal.service.customer.AclCustomerLogDALService;
import com.yd.dal.service.customer.AclCustomerMembershipDALService;
import com.yd.dal.service.customer.AclCustomerShareDALService;
import com.yd.dal.service.customer.AclFileUploadDALService;
import com.yd.dal.service.customer.AclPractitionerDALService;
import com.yd.dal.service.customer.AclPractitionerPotentialAssignedTrackDALService;
import com.yd.dal.service.customer.AclPractitionerPotentialAssignedsDALService;
import com.yd.dal.service.customer.AclPractitionerPotentialDALService;
import com.yd.dal.service.customer.AclPractitionerPotentialGoalsActionsDALService;
import com.yd.dal.service.customer.AclPractitionerPotentialGoalsDALService;
import com.yd.dal.service.customer.AclPractitionerSettingDALService;
import com.yd.dal.service.customer.AclPractitionerSubordinateSystemDALService;
import com.yd.dal.service.marketing.MktLeadsAssignedTrackDALService;
import com.yd.dal.service.marketing.MktLeadsAssignedsDALService;
import com.yd.dal.service.marketing.MktLeadsExpertAssignDALService;
import com.yd.dal.service.marketing.MktLeadsExpertRequestDALService;
import com.yd.dal.service.marketing.MktLeadsGoalsActionsDALService;
import com.yd.dal.service.marketing.MktLeadsGoalsDALService;
import com.yd.dal.service.marketing.MktLeadsPoolDALService;
import com.yd.dal.service.meta.MdCodeDALService;
import com.yd.dal.service.meta.MdDropMasterDALService;
import com.yd.dal.service.meta.MdDropOptionsDALService;
import com.yd.dal.service.meta.MdGoalsCalculateExpressionDALService;
import com.yd.dal.service.meta.MdGoalsCalculateExpressionService;
import com.yd.dal.service.meta.MdMkCampaignDALService;
import com.yd.dal.service.meta.MdTagDALService;
import com.yd.dal.service.meta.ObjectCollectionTaggedDALService;
import com.yd.dal.service.order.PoOrderDALService;
import com.yd.dal.service.survey.SurveyCustomerAnswersDALService;
import com.yd.dal.service.user.AclUserDALService;
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.salary.pojo.Achieve;
import com.yd.rmi.n22.salary.pojo.SearchStaffAchievementRequestBody;
import com.yd.rmi.n22.salary.pojo.SearchStaffAchievementResponseVO;
import com.yd.rmi.n22.salary.service.N22SalaryService;
import com.yd.rmi.n22.staff.pojo.MyStaff;
import com.yd.rmi.n22.staff.pojo.MyStaffSearchRequestBody;
import com.yd.rmi.n22.staff.pojo.MyStaffSearchResponseVO;
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.PDFConfiguration;
import com.yd.util.config.ZHBErrorConfig;
import com.yd.util.deshandler.DESTypeHandler;

@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 AgmsDashboardDALService agmsDashboardDALService;
    @Autowired
    private AclPolicyholderMapper aclPolicyholderMapper;
    @Autowired
    private AgPoInformedMapper informedMapper;
    @Autowired
    private MktLeadsAssignedsMapper mktLeadsAssignedsMapper;

    @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){//只有寿险的经纪人和注册为经纪人的员工才能登录

            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());
                }
            }

            //获取用户的登录次数
            List<AclCustomerLog> customerLogList = aclCustomerLogDALService.findLogInfoByCustomerId(customerId);
            int logTimes = (customerLogList.isEmpty()) ? 0 : customerLogList.size();
            //保存用户的登录记录
            requestVO.setMessage(ZHBErrorConfig.getErrorInfo("800000"));
            requestVO.setName(customer.getName());
            Long loginLogId = aclCustomerLogDALService.saveCustomerLog(customerId, 2, requestVO);
            getOpenIdUrl(responseVO, customer);
            responseVO.setCustomerId(customerId);
            responseVO.setPractitionerId(practitionerId);
            responseVO.setPractitionerTypeId(practitionerType);
            responseVO.setPractitionerBasicInfo(basicInfo);
            responseVO.setLoginTimes(logTimes);
            responseVO.setCanSeeSalaryList(practitionerInfo.getCanSeeSalaryList());
            responseVO.setLoginLogId(loginLogId);
            responseVO.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
//            }
        } else {
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("830001")));
            requestVO.setMessage(ZHBErrorConfig.getErrorInfo("800000"));
            requestVO.setMobileNo(mobileNo);
            Long loginLogId = aclCustomerLogDALService.saveCustomerLog(null, 2, requestVO);
            responseVO.setLoginLogId(loginLogId);

        }
        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(1);
                Long practitionerTypeId = null;
                if (null == practitionerBasicInfo) {
                    responseVO.setCommonResult(new CommonResult(false, "该经纪人不存在"));
                    return responseVO;
                }
                practitionerTypeId = practitionerBasicInfo.getPractitionerTypeId();

//                PractitionerBasicInfo practitionerBasicInfo = practitionerBasicInfoMap.get(platform);
                if (practitionerBasicInfo != null && practitionerTypeId != null) {
                    String practitionerId = practitionerBasicInfo.getPractitionerId();
                    if (!Strings.isNullOrEmpty(practitionerId)) {
                        List<PractitionerRankInfo> rankInfoList = getPractitionerRankInfo(requestVO, practitionerTypeId, practitionerId,type,practitionerBasicInfo);
//                        //按照指定类型排序并获取前10个元素
//                        rankInfoList = this.sortByTypeAndGetElement(rankInfoList, type, practitionerBasicInfo);
                        //按照指定类型排序
                        getPractitionerRankResult(responseVO, rankInfoList, type, practitionerBasicInfoMap, time, platform, practitionerTypeId);
//                        //过滤掉业绩是0的元素
//                        removeZero(responseVO);

                        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)));
        }
        if (Integer.valueOf("1").equals(requestVO.getIsPersonal())) {
            List<AclCustomerFortuneStatistics> list = responseVO.getRank();
            for (AclCustomerFortuneStatistics item : list) {
                item.setName("***");
                item.setFyp(999D);
                item.setFyc(999D);
                item.setCount(999);
            }
        }
        return responseVO;
    }

    private void removeZero(PractitionerRankResponseVO responseVO) {
        List<AclCustomerFortuneStatistics> rank = responseVO.getRank();
        List<String> stringList = rank.stream().map(AclCustomerFortuneStatistics::getName)
                .collect(Collectors.toList());
        long count = stringList.stream().distinct().count();
        if (stringList.size() != count) {
            System.out.println("有重复元素");
            // 有重复元素
            rank.remove(rank.size() - 1);
        }
        // 过滤掉销售业绩是0的元素
        List<AclCustomerFortuneStatistics> resultList = rank.stream()
                .filter((AclCustomerFortuneStatistics i) -> !Integer.valueOf("0").equals(i.getCount()))
                .collect(toList());

        responseVO.setRank(resultList);
    }

    private List<PractitionerRankInfo> sortByTypeAndGetElement(List<PractitionerRankInfo> rankInfoList, Integer type, PractitionerBasicInfo practitionerBasicInfo) {

        String name = practitionerBasicInfo.getName();
        // 获取本人的数据
        BeanPropertyValueEqualsPredicate predicate = new BeanPropertyValueEqualsPredicate("name", name);
        List<PractitionerRankInfo> list = (List<PractitionerRankInfo>) CollectionUtils.select(rankInfoList, predicate);
        PractitionerRankInfo info = null;
        if (CollectionUtils.isNotEmpty(list)) {
            info = list.get(0);
            info.setPractitionerId(practitionerBasicInfo.getPractitionerId());
        }

        // 过滤掉销售业绩是0的元素
        rankInfoList = rankInfoList.stream()
                .filter((PractitionerRankInfo i) -> !Integer.valueOf("0").equals(i.getCount()))
                .collect(Collectors.toList());

        // 排序---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());
        }

        // 集合元素过多，只获取排序后的前10个元素
        List<PractitionerRankInfo> subList = rankInfoList;
        if (rankInfoList != null && rankInfoList.size() > 10) {
            subList = rankInfoList.subList(0, 10);
        }

        System.out.println("看看截取后的集合个数");
        System.out.println(subList.size());


        if (null != info) {
            subList.add(info);
        }
        return subList;
    }

    private List<PractitionerRankInfo> getPractitionerRankInfo(PractitionerRankRequestVO requestVO, Long practitionerTypeId, String practitionerId,Integer type,PractitionerBasicInfo practitionerBasicInfo) {
        Integer time = requestVO.getTime();
//        Integer isPersonal = requestVO.getIsPersonal();
        Integer platform = requestVO.getPlatform();
        time = (time == null) ? 1 : time;//默认：本月
        platform = (platform == null) ? 1 : platform;

        List<PractitionerRankInfo> rankInfoList = new ArrayList<>();
//        if (platform == 1) {
        	List<String> mobileSpecials = new ArrayList<String>();
            String mobileSpecialStr = mdCodeDALService.findCodeByType("special_practitioner_mobile");
            if (!Strings.isNullOrEmpty(mobileSpecialStr)) {
            	mobileSpecials = Arrays.asList(mobileSpecialStr.split(","));
            }else{
            	mobileSpecials.add(practitionerId);
            }
            rankInfoList = aclPractitionerDALService.getPractitionerRankInfoForOnline(time, practitionerTypeId,platform,type,mobileSpecials);
        	List<PractitionerRankInfo> practitionerRankInfo = aclPractitionerDALService.getPractitionerRankInfo(time, practitionerTypeId,platform,type,Integer.valueOf(practitionerId));
        	PractitionerRankInfo info = null;
            if (CollectionUtils.isNotEmpty(practitionerRankInfo) && practitionerRankInfo.get(0) != null) {
                info = practitionerRankInfo.get(0);
                info.setPractitionerId(practitionerId);
                rankInfoList.add(info);
            }else{
                info = new PractitionerRankInfo();
                info.setPractitionerId(practitionerId);
                info.setPractitionerIdForOnLine(Long.valueOf(practitionerId));
                info.setCustomerId(practitionerBasicInfo.getCustomerId());
                info.setName(practitionerBasicInfo.getName());
                info.setTitleCode(practitionerBasicInfo.getTitleCode());
                info.setTitleName(practitionerBasicInfo.getTitleName());
                info.setSpcDivName(practitionerBasicInfo.getSpcDivName());
                info.setCount(0);
                info.setFyp(0D);
                info.setFyc(0D);
                rankInfoList.add(info);
            }
//        } else {
//            rankInfoList = aclPractitionerDALService.getPractitionerRankInfoForOffline(time);
//            // 调用N22接口查寿险
//            try {
//                rankInfoList = this.getPractitionerRankInfoFromN22(time, isPersonal, practitionerId);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//        //特殊人员处理
//        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,platform);
//            rankInfoList.addAll(rankInfoListSpecials);
//        }
        return rankInfoList;
    }

    private List<PractitionerRankInfo> getPractitionerRankInfoFromN22(Integer time, Integer isPersonal, String loginName) 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<PractitionerRankInfo> rankInfoList = this.queryN22RankInfoList(loginName, isPersonal, startTime, endTime);

        return rankInfoList;
    }

    private List<PractitionerRankInfo> queryN22RankInfoList(String loginName, Integer isPersonal, String startTime, String endTime) throws Exception {

        // 1.根据Agent_id当前经纪人的佣金明细
        SearchStaffAchievementRequestBody searchStaffAchievementRequestBody = new SearchStaffAchievementRequestBody();
        if (Integer.valueOf("0").equals(isPersonal)) {
            searchStaffAchievementRequestBody.setAgent_id(loginName);
        }
        searchStaffAchievementRequestBody.setSearchtype("1");
        searchStaffAchievementRequestBody.setIsdown("0");
        searchStaffAchievementRequestBody.setPolicystatus("201");
        searchStaffAchievementRequestBody.setIssuedatestart(startTime);
        searchStaffAchievementRequestBody.setIssuedateend(endTime);
        SearchStaffAchievementResponseVO searchStaffAchievementResponseVO = n22SalaryService.searchStaffAchievement(searchStaffAchievementRequestBody);

        if (!"查询成功".equals(searchStaffAchievementResponseVO.getResponseHead().getMessage())) {
            throw new Exception("N22寿险业绩统计查询错误");
        }
        List<Achieve> achieveList = searchStaffAchievementResponseVO.getResponseBody().getAchieveList();

        // 2.组装返回报文
        List<PractitionerRankInfo> rankInfoList = new ArrayList<>();
        List<String> nameList = new ArrayList<>();
        PractitionerRankInfo rankInfo = null;
        for (Achieve achieve : achieveList) {

            rankInfo = new PractitionerRankInfo();
            rankInfo.setCount(achieve.getSucNumber());
            rankInfo.setFyp(achieve.getFYP());
            rankInfo.setFyc(achieve.getFYC());
            rankInfo.setName(achieve.getDescription());

            rankInfoList.add(rankInfo);
            // 获取nameList
            nameList.add(achieve.getDescription());
        }

        // 3.根据姓名查询经纪人所属体系名称
        List<PractitionerInfo> practitionerInfoList = aclPractitionerDALService.findPractitionerInfoByNameList(nameList);
        for (PractitionerRankInfo rankInfo1 : rankInfoList) {
            for (PractitionerInfo practitionerInfo : practitionerInfoList) {
                if (rankInfo1.getName().equals(practitionerInfo.getName())) {
                    rankInfo1.setSpcDivName(practitionerInfo.getSubsystem());
                }
            }
        }

        return rankInfoList;
    }

    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);

//        //N22查询经纪人信息接口
//        PractitionerBasicInfo practitionerBasicInfo2 = this.queryN22PractitionerBasicInfo(mobileNo);
//        practitionerBasicInfoMap.put(2, practitionerBasicInfo2);
        return practitionerBasicInfoMap;
    }

    private PractitionerBasicInfo queryN22PractitionerBasicInfo(String mobileNo) {
        Staff staff = n22StaffService.queryN22StaffByMobileNo(mobileNo);
        if (staff != null) {
            PractitionerBasicInfo practitionerBasicInfo = new PractitionerBasicInfo();
            practitionerBasicInfo.setPractitionerId(staff.getAgent_id());
            practitionerBasicInfo.setName(staff.getStaffname());

            return practitionerBasicInfo;
        }

        return null;
    }

    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(1).getPractitionerId();
        if (!rankInfoList.isEmpty()) {
            AclCustomerFortuneStatistics fortuneStatistics;
            int rank = 1;
            Long practitionerIdForOnLine;
            String practitionerIdItem;
            boolean boole = true;
            for (PractitionerRankInfo practitionerItem : rankInfoList) {
                //更新对象里面的内容，将PractitionerIdForOnLine里的信息赋值到PractitionerId
                practitionerIdForOnLine = practitionerItem.getPractitionerIdForOnLine();
                if (practitionerIdForOnLine != null) {
                    practitionerItem.setPractitionerId(practitionerIdForOnLine.toString());
                }
                practitionerIdItem = practitionerItem.getPractitionerId();
                if (rank <= 10) {//排名
                	if(practitionerId.equals(practitionerIdItem)){
                		if(!boole) continue;
                		if(boole) boole = false;
                	}
                    fortuneStatistics = new AclCustomerFortuneStatistics();
                    BeanUtils.copyProperties(practitionerItem, fortuneStatistics); 
                    fortuneStatistics.setPractitionerId(practitionerIdForOnLine);
                    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);
//                practitionerRankInfo = aclPractitionerDALService.getPractitionerRankInfoByPractitionerIdYD(practitionerId, time, platform);
//                if (platform == 1) {
//                    PractitionerBasicInfo practitionerBasicInfoEG = practitionerBasicInfoMap.get(2);
//                    if (practitionerBasicInfoEG != null) {
//                        String practitionerIdEG = practitionerBasicInfoEG.getPractitionerId();
//                        if (!Strings.isNullOrEmpty(practitionerIdEG)) {
////                          practitionerRankInfo = aclPractitionerDALService.getPractitionerRankInfoByPractitionerIdEG(practitionerIdEG, time);
//                            practitionerRankInfo = this.getPractitionerRankInfoByPractitionerIdEG(practitionerIdEG, time);
//                        }
//                    }
//                } else {
//                    practitionerRankInfo = aclPractitionerDALService.getPractitionerRankInfoByPractitionerIdYD(practitionerId, time, platform);
//                }
//                fycOther = practitionerRankInfo != null ? practitionerRankInfo.getFyc() : 0D;
//                Double fycSum = CommonUtil.doubleFormat(fyc + fycOther, 2);
                if (fyc != 0) {
                	SubordinateSystemStatisticInfo statisticInfo = new SubordinateSystemStatisticInfo();
                    getCompletionRate(statisticInfo,practitionerId, null, fyc, time);
                    practitionerInfo.setCompletionRate(statisticInfo.getCompletionRate());
                }
            }
        }
    }

    private PractitionerRankInfo getPractitionerRankInfoByPractitionerIdEG(String loginName, Integer time) {
        List<Achieve> achieveList = agmsDashboardDALService.queryN22FYC(time, 0, loginName);

        PractitionerRankInfo rankInfo = null;
        for (Achieve achieve : achieveList) {

            rankInfo = new PractitionerRankInfo();
            rankInfo.setFyc(achieve.getFYC());
            rankInfo.setName(achieve.getDescription());

        }

        return rankInfo;
    }

    @Override
    @SuppressWarnings("unchecked")
    public SettingQueryResponseVO settingQuery(SettingQueryRequestVO requestVO) {
        SettingQueryResponseVO responseVO = new SettingQueryResponseVO();
        Long practitionerId = requestVO.getPractitionerId();//入参经纪人id
        //等保调整
        List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
        if (null == findByObjSortable) {
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
            return responseVO;
        }
        //需要查询的信息 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.setBioIntroTwo(practitioner.getBioIntroTwo());
        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();
        //等保调整
        List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
        if (null == findByObjSortable) {
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
            return responseVO;
        }
        //经纪人查询通过自己分享成为自己商机的客户
        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);
        String customerName = customer.getName();
        info.setName(customerName);
        info.setAge(customer.getAge());
        info.setBirthDate(CommonUtil.dateParseString(customer.getBirthDate(),"yyyy-MM-dd"));
        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);
        mktLeadsAssignedTrack.setIsActive(1);
        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);
        mktLeadsAssigneds.setIsActive(1);
        List<MktLeadsAssigneds> mktLeadsAssignedsList = mktLeadsAssignedsDALService.findByMktLeadsAssigneds(mktLeadsAssigneds);
        mktLeadsAssigneds = mktLeadsAssignedsList.get(0);
        String leadsAssignedsCustomerName = mktLeadsAssigneds.getCustomerName();
        if (customerName != null && leadsAssignedsCustomerName != null) {
            if (!customerName.equals(leadsAssignedsCustomerName)) {
                info.setName(leadsAssignedsCustomerName);
            }
        }
        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.setStatus(track.getInformedStatus());
            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) {
            //等保调整
            List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
            if (null == findByObjSortable) {
                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
                return responseVO;
            }
            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 assignedPractitionerId = requestVO.getAssignedPractitionerId();
        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());
            mktLeadsAssigneds.setIsActive(1);
            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())) {
                    //获取最新track对应的leads
                    for (MktLeadsAssigneds item : mktLeadsAssignedsList) {
                        if (item.getId().equals(leadsAssignedTrack.getLeadsAssignedId())) {
                            //跳出错误
                            if (item.getAssignedPractitionerId().equals(assignedPractitionerId)) {
                                return new CommonResult(false, "该商机已存在");
                            } else {
                                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();
        //等保调整
        List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
        if (null == findByObjSortable) {
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
            return responseVO;
        }
        //当前年份
        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(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 QueryCustomerHolderListResponesVO queryCustomerHolderList(Long practitionerId) {
        QueryCustomerHolderListResponesVO resp = new QueryCustomerHolderListResponesVO();
        resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("820001")));

        if (practitionerId != null) {
            AclPractitioner practitioner = aclPractitionerDALService.findById(practitionerId);
            if (practitioner != null) {
                Long customerId = practitioner.getCustomerId();
                List<CustomerPolicyInfo> policyInfos = poOrderDALService.findPolicyInfoByCustomerId(customerId, null);
                List<Long> vehiclePolicyOrderIdList = poOrderDALService.findVehiclePolicyInfoByCustomerId(customerId);
                List<Long> orderIdList = new ArrayList<>();
                for (CustomerPolicyInfo policyInfo : policyInfos) {
                    orderIdList.add(policyInfo.getOrderId());
                }
                orderIdList.addAll(vehiclePolicyOrderIdList);
                if (CollectionUtils.isNotEmpty(orderIdList)) {
                    List<CustomerHolder> list = aclPolicyholderMapper.queryThisPractitiionerAllPolicyHolderList(orderIdList);
                    // 如果姓名，出生日期为空就去查ag_acl_policyholder表的记录
                    this.completeCustomerHolder(list, 2);

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

    @Override
    public QueryCustomerInsuredListResponesVO queryCustomerInsuredList(QueryCustomerInsuredListRequestVO requestVO) {
        QueryCustomerInsuredListResponesVO resp = new QueryCustomerInsuredListResponesVO();
        resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("820001")));
        if (requestVO != null) {
            List<CustomerHolder> list = aclPolicyholderMapper.queryInsuredListByHolderCustomerId(requestVO);
            // 如果姓名，出生日期为空就去查ag_acl_policyholder表的记录
            this.completeCustomerHolder(list, 3);

            resp.setList(list);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        }
        return resp;
    }

    private void completeCustomerHolder(List<CustomerHolder> list, int holderType) {
        CustomerHolder info;
        for (CustomerHolder holder : list) {
            if (holder.getName() == null || holder.getBirthDate() == null) {
                info = aclPolicyholderMapper.queryUsefulInfo(holder.getCustomerId(), holderType);
                if (info != null) {
                    BeanUtils.copyProperties(info, holder);
                }
            }
        }
    }

    @Override
    public QueryPolicyListByHolderCustomerIdResponesVO queryPolicyListByHolderCustomerId(QueryPolicyListByHolderCustomerIdRequestVO requestVO) {
        QueryPolicyListByHolderCustomerIdResponesVO resp = new QueryPolicyListByHolderCustomerIdResponesVO();
        resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("820001")));

        if (requestVO != null) {
            List<CustomerPolicyInfo> policyInfos = aclPolicyholderMapper.queryPolicyListByHolderCustomerId(requestVO);

            resp.setList(policyInfos);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        }
        return resp;
    }

    @Override
    public List<Long> getPractitionerIdBySidList(Long sId, String systemType, Integer isActive) {
        List<Long> practitionerIdList = new ArrayList<>();
        List<AclPractitioner> aclPractitionerList = aclPractitionerDALService.findBySubordinateSystemId(sId, systemType);
        if (null != aclPractitionerList) {
            practitionerIdList = aclPractitionerList.stream().map(AclPractitioner::getId).collect(Collectors.toList());
        }
        return practitionerIdList;
    }

    @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<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
        if (null == findByObjSortable) {
            responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
            return responseVO;
        }
        List<Long> practitionerIdList = this.getPractitionerIdList(practitionerId, 1);
        List<AclPractitioner> practitionerRaises = aclPractitionerDALService.findPractitionerByRaise(practitionerId);
        if(practitionerRaises != null && practitionerRaises.size() > 0){
        	for(AclPractitioner practitioner : practitionerRaises){
		        if (null != practitioner && null != practitioner.getRaiseId()) {
		            practitionerIdList.add(practitioner.getId());
		            List<Long> practitionerRaiseIdList = this.getPractitionerIdList(practitioner.getId(), null);
		            practitionerIdList.addAll(practitionerRaiseIdList);
		        }
        	}
        }
        List<AclPractitioner> practitioners = aclPractitionerDALService.findByIds(practitionerIdList);
        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 = 0D;
            if(quarterGoal.compareTo(BigDecimal.ZERO)!=0){
            	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 = 0D;
            if(quarterGoal.compareTo(BigDecimal.ZERO)!=0){
            	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;
//            if (!mktLeadsGoalsList.isEmpty()) {
//                MktLeadsGoals leadsGoals = mktLeadsGoalsList.get(0);
//                defaultCommission = new BigDecimal(leadsGoals.getCommission());
//                defaultPremium = new BigDecimal(leadsGoals.getPremium());
//                defaultPieces = leadsGoals.getPieces();
//            }
            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 = 0D;
                if(leadsGoals.getCommission() != null && leadsGoals.getCommission() > 0){
                	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")) && !CommonUtil.isNullOrZero(yearGoal)) {
            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")) && !CommonUtil.isNullOrZero(quarterGoal)) {
            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")) && !CommonUtil.isNullOrZero(monthGoal)) {
            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) {
            //等保调整
            List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
            if (null == findByObjSortable) {
                responseVO.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
                return responseVO;
            }
            Integer time = requestVO.getTime();
            time = (time == null) ? 1 : time;
            PageHelper.clearPage();//偶然遇到了这个问题，同一个查询结果一会是10个（预期），一会是真实个数（刷新/重启应用就又变成真实个数）  查看日志，发现了问题：结果为10个时查询SQL自动加上了Limit 10
//            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);
            //N22
//            try {
//                this.getMemberInfoFromN22(memberInfoMap, practitionerId, time, mobileNo);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
            //20210303增加逻辑,已离职经纪人没有数据不显示
            //查询这个团队已离职经纪人电话
            List<String> leaveOfficeList = aclPractitionerDALService.findLeaveOfficeByPractitionerId(practitionerId);
            for (String m : leaveOfficeList) {
                SubordinateSystemMemberInfo subordinateSystemMemberInfo = memberInfoMap.get(m);
                if (null != subordinateSystemMemberInfo && CommonUtil.isNullOrZero(subordinateSystemMemberInfo.getCount())) {
                    memberInfoMap.remove(m);
                }
            }
            //查询出来的结果按照【sortType 排序类型(1:FYP;2:FYC;3:件数;4:目标FYC,不传默认1:FYP)】进行排序
            List<SubordinateSystemMemberInfo> memberInfoList = new ArrayList<>(memberInfoMap.values());
            if("2".equals(requestVO.getSortType())){
                memberInfoList.sort(Comparator.comparingDouble(SubordinateSystemMemberInfo::getFyc));
            }else if("3".equals(requestVO.getSortType())){
                memberInfoList.sort(Comparator.comparingDouble(SubordinateSystemMemberInfo::getCount));
            }else if("4".equals(requestVO.getSortType())){
                memberInfoList.sort(Comparator.comparingDouble(SubordinateSystemMemberInfo::getTargetFyc));
            }else{
                memberInfoList.sort(Comparator.comparingDouble(SubordinateSystemMemberInfo::getFyp));
            }
            Collections.reverse(memberInfoList);

            Double targetFyc = 0D;//目标FYP
            Double targetFyp = 0D;//目标FYC,目标件数
            Integer targetCount = 0;//目标件数
            for (SubordinateSystemMemberInfo item : memberInfoList) {
                fypSum += item.getFyp();
                fycSum += item.getFyc();
                countSum += item.getCount();
                targetFyc += item.getTargetFyc();
                targetFyp += item.getTargetFyp();
                targetCount += item.getTargetCount();
            }
            statisticInfo.setCount(countSum);
            statisticInfo.setFyc(CommonUtil.doubleFormat(fycSum, 2));
            statisticInfo.setFyp(CommonUtil.doubleFormat(fypSum, 2));
            statisticInfo.setTargetFyc(CommonUtil.doubleFormat(targetFyc, 2));
    		statisticInfo.setTargetFyp(CommonUtil.doubleFormat(targetFyp, 2));
    		statisticInfo.setTargetCount(targetCount);
            if (targetFyc != null && targetFyc > 0) {
                BigDecimal fycBigDecimal = new BigDecimal(fycSum), goalsBigDecimal = new BigDecimal(targetFyc);
				statisticInfo.setCompletionRate(CommonUtil.doubleFormat(fycBigDecimal.divide(goalsBigDecimal, 4, BigDecimal.ROUND_HALF_UP).doubleValue() * 100, 2));
            }else{
            	statisticInfo.setCompletionRate(0D);
            }

            // 查看经纪人所在的体系
            AclPractitionerSubordinateSystem subordinateSystem = aclPractitionerSubordinateSystemDALService.findByPractitionerId(practitionerId);
            if (subordinateSystem != null) {
                Long subordinateSystemId = subordinateSystem.getId();
//                getCompletionRate(statisticInfo,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;
    }

    private void getMemberInfoFromN22(Map<String, SubordinateSystemMemberInfo> memberInfoMap, Long practitionerId, Integer time, String mobileNo) throws Exception {

        // 1.查询N22我管的人
        Staff staff = n22StaffService.queryN22StaffByMobileNo(mobileNo);

        MyStaffSearchRequestBody myStaffSearchRequestBody = new MyStaffSearchRequestBody();
        myStaffSearchRequestBody.setLoginName(staff.getAgent_id());
        MyStaffSearchResponseVO myStaffSearchResponseVO = n22StaffService.myStaffSearch(myStaffSearchRequestBody);
        if (!"查询成功".equals(myStaffSearchResponseVO.getResponseHead().getMessage())) {
            throw new Exception("N22查询我管的人错误");
        }

        if (myStaffSearchResponseVO.getResponseBody() == null || CollectionUtils.isEmpty(myStaffSearchResponseVO.getResponseBody().getStaffArray())) {
            throw new Exception("N22未查询到我管的人");
        }
        List<MyStaff> staffArray = myStaffSearchResponseVO.getResponseBody().getStaffArray();

        List<String> loginNameList = new ArrayList<>();
        for (MyStaff myStaff : staffArray) {
            loginNameList.add(myStaff.getManage_LoginName());
        }

        System.out.println(loginNameList);

        // 2.根据Agent_id当前经纪人的佣金明细
        // 2.1.根据查询时间范围获取查询开始时间和结束时间
        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();
        }
        SearchStaffAchievementRequestBody searchStaffAchievementRequestBody = new SearchStaffAchievementRequestBody();
        searchStaffAchievementRequestBody.setSearchtype("1");
        searchStaffAchievementRequestBody.setIsdown("0");
        searchStaffAchievementRequestBody.setPolicystatus("201");
        searchStaffAchievementRequestBody.setIssuedatestart(startTime);
        searchStaffAchievementRequestBody.setIssuedateend(endTime);
        // 2.2.根据loginName循环查询N22业绩接口
        List<SubordinateSystemMemberInfoE> subordinateSystemMemberInfoEList = new ArrayList<>();
        SubordinateSystemMemberInfoE info = null;
        Achieve achieve = null;
        List<String> mobileList = new ArrayList<>();
        for (String loginName : loginNameList) {

            searchStaffAchievementRequestBody.setAgent_id(loginName);
            SearchStaffAchievementResponseVO searchStaffAchievementResponseVO = n22SalaryService.searchStaffAchievement(searchStaffAchievementRequestBody);

            if (!"查询成功".equals(searchStaffAchievementResponseVO.getResponseHead().getMessage())) {
                throw new Exception(searchStaffAchievementResponseVO.getResponseHead().getMessage());
            }
            List<Achieve> resultList = searchStaffAchievementResponseVO.getResponseBody().getAchieveList();

            if (CollectionUtils.isNotEmpty(resultList)) {

                achieve = resultList.get(0);

                info = new SubordinateSystemMemberInfoE();

                info.setCount(achieve.getSucNumber());
                info.setFyp(achieve.getFYP());
                info.setFyc(achieve.getFYC());
                info.setName(achieve.getDescription());
                info.setLoginName(loginName);
                // 查询N22的电话号码
                Staff staff1 = n22StaffService.queryN22StaffByLoginName(loginName);
                if (staff1 != null) {
                    info.setMobileNo(staff1.getMobile());
                    mobileList.add(staff1.getMobile());
                }

                subordinateSystemMemberInfoEList.add(info);
            }
        }

        // 3.通过姓名查询手机号
        List<PractitionerInfo> practitionerInfoListAll = aclPractitionerDALService.findPractitionerInfoByMobileList(mobileList);
        // 判断当前经纪人是否为团队长
        List<PractitionerInfo> practitionerInfoList = new ArrayList<>();
        int iCount = aclPractitionerDALService.isTeamLeader(practitionerId);
        if (iCount == 0) {
            //如果登录人员不是团队长，则过滤的辅导人不是当前登录人员的数据
            for (PractitionerInfo item : practitionerInfoListAll) {
                if (null != practitionerId && null != item.getMentorId() && practitionerId.equals(item.getMentorId())) {
                    practitionerInfoList.add(item);
                }
            }
        } else {
            practitionerInfoList = practitionerInfoListAll;
        }
        for (SubordinateSystemMemberInfoE infoE : subordinateSystemMemberInfoEList) {
            for (PractitionerInfo item : practitionerInfoList) {
                if (infoE.getMobileNo().equals(item.getMobileNo())) {
                    BeanUtils.copyProperties(item, infoE);
                }
            }
        }
        //过滤掉经纪人为空的，说明不是当前经纪人辅导的人
        List<SubordinateSystemMemberInfoE> subordinateSystemMemberInfoELista = new ArrayList<>();
        for (SubordinateSystemMemberInfoE infoE : subordinateSystemMemberInfoEList) {
            if (null != infoE.getPractitionerId()) {
                subordinateSystemMemberInfoELista.add(infoE);
            }
        }
        subordinateSystemMemberInfoEList = subordinateSystemMemberInfoELista;


        System.out.println("看看根据手机号查询的N22");
        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 = 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 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<Long> practitionerIdList = this.getPractitionerIdList(practitionerId, null);
        List<AclPractitioner> practitionerRaises = aclPractitionerDALService.findPractitionerByRaise(practitionerId);
        if(practitionerRaises != null && practitionerRaises.size() > 0){
        	for(AclPractitioner practitionerRaise : practitionerRaises){
		        if (null != practitionerRaise && null != practitionerRaise.getRaiseId()) {
		            practitionerIdList.add(practitionerRaise.getId());
		            List<Long> practitionerRaiseIdList = this.getPractitionerIdList(practitionerRaise.getId(), null);
		            practitionerIdList.addAll(practitionerRaiseIdList);
		        }
        	}
        }
        List<AclPractitioner> practitionerList = aclPractitionerDALService.findByIds(practitionerIdList);
        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());
//            }
            //6、查询该体系下经纪人设置的目标
            List<AclCustomerFortuneStatistics> customerTarget = aclCustomerFortuneDALService.findTargetBypractitionerIds(practitionerIds, time);
            Map<Long, AclCustomerFortuneStatistics> customerTargetMap = new HashMap<>();
            customerTarget.forEach(i -> customerTargetMap.put(i.getPractitionerId(), i));
            SubordinateSystemMemberInfo memberInfo;
            Long practitionerIdForMember, practitionerLevelId;
            AclCustomerFortuneStatistics customerFortuneStatisticsItem;
            for (AclPractitioner practitioner : practitionerList) {
                double fyp = 0D, fyc = 0D;
                int count = 0;
                double targetFyc = 0D;
                double targetFyp = 0D;
                int targetCount = 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 = Double.valueOf(customerFortuneStatisticsItem.getFyc());
                    fyp = Double.valueOf(customerFortuneStatisticsItem.getFyp());
                    count = Integer.valueOf(customerFortuneStatisticsItem.getCount());
                }
                if (customerTargetMap.containsKey(practitionerIdForMember)) {
                    customerFortuneStatisticsItem = customerTargetMap.get(practitionerIdForMember);
                    targetFyc = Double.valueOf(customerFortuneStatisticsItem.getTargetFyc());
                    targetFyp = Double.valueOf(customerFortuneStatisticsItem.getTargetFyp());
                    targetCount = Integer.valueOf(customerFortuneStatisticsItem.getTargetCount());
                }
                memberInfo.setFyc(CommonUtil.doubleFormat(fyc, 2));
                memberInfo.setFyp(CommonUtil.doubleFormat(fyp, 2));
                memberInfo.setCount(count);
                memberInfo.setTargetFyc(CommonUtil.doubleFormat(targetFyc, 2));
                memberInfo.setTargetFyp(CommonUtil.doubleFormat(targetFyp, 2));
                memberInfo.setTargetCount(targetCount);
                if (targetFyc > 0) {
                    BigDecimal fycBigDecimal = new BigDecimal(fyc), goalsBigDecimal = new BigDecimal(targetFyc);
                    memberInfo.setCompletionRate(CommonUtil.doubleFormat(fycBigDecimal.divide(goalsBigDecimal, 4, BigDecimal.ROUND_HALF_UP).doubleValue() * 100, 2));
                }else{
                	memberInfo.setCompletionRate(0D);
                }
                memberInfoMap.put(practitionerIdMobileNoMap.get(practitionerIdForMember), memberInfo);
            }
        }
    }

    /**
     * 获取完成率
     *
     * @param practitionerId      经纪人Id
     * @param subordinateSystemId 团队长ID
     * @param fycSum              总的FYC
     * @param time                时间
     * @return 完成率
     */
	@SuppressWarnings("unchecked")
    private void getCompletionRate(SubordinateSystemStatisticInfo statisticInfo,Long practitionerId, Long subordinateSystemId, Double fycSum, Integer time) {
		statisticInfo.setTargetFyc(0D);
		statisticInfo.setTargetFyp(0D);
		statisticInfo.setTargetCount(0);
    	statisticInfo.setCompletionRate(0D);
		if ((practitionerId != null || subordinateSystemId != null) && fycSum != null && time != null && fycSum > 0) {
            List<MktLeadsGoals> leadsGoals;
            Double goalsPremium = null;
            if (time == 2 || time == 4) {
                if (practitionerId != null) {
                    leadsGoals = mktLeadsGoalsDALService.findByTypeAndTimeUnitAndPractitionerId(1, 1, practitionerId);
                } else {
                    leadsGoals = mktLeadsGoalsDALService.findByTypeAndTimeUnitAndSubordinateSystemId(2, 1, subordinateSystemId);
                }
                if(leadsGoals != null && leadsGoals.size() > 0){
                    Calendar calendar = Calendar.getInstance();
                    int year = calendar.get(Calendar.YEAR);
                    if (time == 4) {
                    	year = year - 1;
                    }
                	for (MktLeadsGoals mktLeadsGoals : leadsGoals) {
						if(mktLeadsGoals.getCurrentYear() != null && mktLeadsGoals.getCurrentYear().intValue() == year){
							goalsPremium =  mktLeadsGoals.getCommission();
							statisticInfo.setTargetFyc(mktLeadsGoals.getCommission());
							statisticInfo.setTargetFyp(mktLeadsGoals.getPremium());
							statisticInfo.setTargetCount(mktLeadsGoals.getPieces());
							break;
						}
					}
                }
            } 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;
                BeanPropertyValueEqualsPredicate predicateClause = new BeanPropertyValueEqualsPredicate("currentYear", calendar.get(Calendar.YEAR));
                leadsGoals = (List<MktLeadsGoals>)CollectionUtils.select(leadsGoals, predicateClause);
                List<Integer> monthList = getMonthListForQuarter(month);
                for (MktLeadsGoals item : leadsGoals) {
                    if (time == 1) {//月份
                        if (item.getSeqTime() == month) {
                            goalsPremium = item.getCommission();
							statisticInfo.setTargetFyc(item.getCommission());
							statisticInfo.setTargetFyp(item.getPremium());
							statisticInfo.setTargetCount(item.getPieces());
                            break;
                        }
                    } else {//季度
                        if (monthList.contains(item.getSeqTime())) {
                            goalsPremium = (goalsPremium == null) ? item.getCommission() : goalsPremium + item.getCommission();
                            if(statisticInfo.getTargetFyc() != null){
    							statisticInfo.setTargetFyc(item.getCommission() + statisticInfo.getTargetFyc());
                            }
                            if(statisticInfo.getTargetFyp() != null){
    							statisticInfo.setTargetFyp(item.getPremium() + statisticInfo.getTargetFyp());
                            }
                            if(statisticInfo.getTargetCount() != null){
    							statisticInfo.setTargetCount(item.getPieces() + statisticInfo.getTargetCount());
                            }
							
                        }
                    }
                }
            }
            if (goalsPremium != null && goalsPremium > 0) {
                BigDecimal fycBigDecimal = new BigDecimal(fycSum), goalsBigDecimal = new BigDecimal(goalsPremium);
				statisticInfo.setCompletionRate(CommonUtil.doubleFormat(fycBigDecimal.divide(goalsBigDecimal, 4, BigDecimal.ROUND_HALF_UP).doubleValue() * 100, 2));
            }
        }
	}
	
    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.setBioIntroTwo(requestVO.getBioIntroTwo());
            } 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;
    }

    @Override
    public CommonResultIDResponseVO saveInformedSheet(SaveInformedSheetRequestVO requestVO) {
        CommonResultIDResponseVO resp = new CommonResultIDResponseVO();
        try {
            // 先判断传入的客户姓名和客户电话与传入的customerId是否一致
            AclCustomer oldCustomer = aclCustomerDALService.findById(requestVO.getCustomerId());
            String newName = requestVO.getCustomerName();
            String newMobile = requestVO.getCustomerMobile();
            // 查询客户是否存在
            AclCustomer customerParams = new AclCustomer();
            customerParams.setMobileNo(newMobile);
            customerParams.setRole(2);
            customerParams.setIsActive(1);
            List<AclCustomer> customerList = aclCustomerDALService.findByObj(customerParams);
            AclCustomer newerCustomer = null;
            if (CollectionUtils.isNotEmpty(customerList)) {
                newerCustomer = customerList.get(0);
            } else {
                //此人为第一次进来
                //帮其进行注册
                newerCustomer = new AclCustomer();
                newerCustomer.setRole(2);//1= Staff 2=Customer 3=Partner
                newerCustomer.setAccountId(createAccountId(newMobile));
                newerCustomer.setLogin(newMobile);
                newerCustomer.setMobileNo(newMobile);
                newerCustomer.setCusLevel(1);
                newerCustomer.setName(newName);
                newerCustomer.setIsActive(1);
                newerCustomer.setRoleId(3L);
                newerCustomer.setWithdrawType(0);
                newerCustomer.setCreatedAt(new Date());
                newerCustomer.setCreatedBy(-1L);
                newerCustomer.setUpdatedAt(new Date());
                newerCustomer.setUpdatedBy(-1L);
                newerCustomer.setChannelReferralRateId(3L);

                Long mdMkCampaignId = systemConfigService.getMdMkCampaignId("leadaddedbypractioner");
                newerCustomer.setMktCampaign(String.valueOf(mdMkCampaignId));
                aclCustomerDALService.save(newerCustomer);

                Long newerCustomerId = newerCustomer.getId();
                //查询此customer是否在pool中
                MktLeadsPool pool = mktLeadsPoolDALService.findByCustomerId(newerCustomerId);
                if (pool == null) {
                    //线索池为空时,保存线索池
                    pool = new MktLeadsPool();
                    pool.setMktCampaign(String.valueOf(mdMkCampaignId));
                    pool.setCustomerId(newerCustomerId);
                    pool.setHasAssigned(1);
                    pool.setIsActive(1);
                    pool.setAddedAt(new Date());
                    pool.setAddedBy(requestVO.getPractitionerId());
                    pool.setAdderType(2);
                    mktLeadsPoolDALService.save(pool);
                }
            }
            if (!newMobile.equals(oldCustomer.getMobileNo()) || !newName.equals(oldCustomer.getName())) {// 如果电话不一样，就更新商机的电话
                MktLeadsAssigneds mktLeadsAssigneds = new MktLeadsAssigneds();
                mktLeadsAssigneds.setId(requestVO.getLeadsAssignedId());
                mktLeadsAssigneds.setCustomerMobile(newMobile);
                mktLeadsAssigneds.setCustomerName(newName);
                mktLeadsAssigneds.setCustomerId(newerCustomer.getId());
                mktLeadsAssignedsMapper.updateByPrimaryKeySelective(mktLeadsAssigneds);
            }
            // 数据库实体
            AgPoInformed informed = new AgPoInformed();
            informed.setCustomerName(newName);
            informed.setCustomerMobile(newMobile);
            informed.setPractitionerId(requestVO.getPractitionerId());
            informed.setLeadsId(requestVO.getLeadsAssignedId());
            informed.setCustomerId(newerCustomer.getId());
            informed.setStatus("0");
            informed.setIsActive(1);

            Date curDate = new Date();
            informed.setCreatedAt(curDate);
            informed.setUpdatedAt(curDate);

            Long loginId = requestVO.getLoginId();
            informed.setCreatedBy(loginId);
            informed.setUpdatedBy(loginId);

            informedMapper.insertSelective(informed);

            // 商机更新一条告知书待签署的记录
            MktLeadsAssignedTrack track = new MktLeadsAssignedTrack();
            track.setInformedId(informed.getId());
            track.setPractitionerId(requestVO.getPractitionerId());
            track.setCustomerId(newerCustomer.getId());// 商机的id还是得用旧的customerId
            track.setLeadsAssignedId(requestVO.getLeadsAssignedId());
            track.setInformedStatus("0");
            track.setInformedOssPath("https://yindun-images.oss-cn-shanghai-finance-1-pub.aliyuncs.com/ElectronicNotice/ElectronicNotice.pdf");
            track.setSalesNotice("客户告知书发送成功");
            track.setTrackTime(curDate);
            track.setCreatedBy(loginId);
            track.setCreatedAt(new Date());
            track.setCreatorType(1);
            track.setUpdatedBy(loginId);
            track.setUpdatorType(1);
            track.setUpdatedAt(new Date());
            MdDropOptions dropOption = systemConfigService.getDropOption("bizchance_promotion_action", "customerNotice_0");
            track.setMdDropOptionId(dropOption.getId());
            track.setTrackScore(dropOption.getDropOptionScore());
            //保存
            mktLeadsAssignedTrackDALService.saveTrack(track);
            //更新所有商机状态
            mktLeadsAssignedTrackDALService.updateCustomerIdByLeadsAssignedId(newerCustomer.getId(), requestVO.getLeadsAssignedId());

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            resp.setId(informed.getId());
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public QueryInformedSheetByIdResponseVO queryInformedSheetById(IDRequestVO requestVO) {
        QueryInformedSheetByIdResponseVO resp = new QueryInformedSheetByIdResponseVO();
        try {
            AgPoInformed informed = informedMapper.selectByPrimaryKey(requestVO.getId());

            resp.setInformed(informed);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public CommonResultIDResponseVO updateInformedSheetById(UpdateInformedSheetByIdRequestVO requestVO) {
        CommonResultIDResponseVO resp = new CommonResultIDResponseVO();
        try {
            String policyNo = requestVO.getPolicyNo();
            List<PoOrder> orderList = poOrderDALService.findByPolicyNo(policyNo);
            if (CollectionUtils.isEmpty(orderList)) {
                resp.setCommonResult(new CommonResult(false, "保单号不存在"));
                return resp;
            }

            AgPoInformed informed = informedMapper.selectByPrimaryKey(requestVO.getId());
            // 删除旧保单号关联的客户告知书保单附件
            if (informed.getPolicyNo() != null) {
                informedMapper.deletePoPolicyOfflineUploadByPolicyNo(informed.getPolicyNo());
            }
            // 更新保单号
            informed.setPolicyNo(policyNo);
            informed.setUpdatedBy(requestVO.getLoginId());
            informed.setUpdatedAt(new Date());
            informedMapper.updateByPrimaryKeySelective(informed);
            // 新保单号新增客户告知书到保单附件
            informedMapper.insertInformedSheet(informed);

            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
            resp.setId(informed.getId());
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public  CommonResultResponseVO deleteInformedSheetById(IDRequestVO requestVO){
    	CommonResultResponseVO resp = new CommonResultResponseVO();
    	if (requestVO == null || requestVO.getId() == null) {
            resp.setCommonResult(new CommonResult(false, "客户告知书ID不能为空"));
            return resp;
        }
	    try {
            AgPoInformed informed = informedMapper.selectByPrimaryKey(requestVO.getId());
            if(informed != null){
            	if(Strings.isNullOrEmpty(informed.getPolicyNo())){
            		informedMapper.deleteByPrimaryKey(requestVO.getId());
            	}else{
                    resp.setCommonResult(new CommonResult(false, "客户告知书已经关联保单号,不能删除"));
                    return resp;
            	}
            }else{
                resp.setCommonResult(new CommonResult(false, "根据客户告知书ID查询不到数据"));
                return resp;
            }
	        resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
	    } catch (Exception e) {
	        e.printStackTrace();
	        resp.setCommonResult(new CommonResult(false, e.getMessage()));
	    }
	    return resp;
    }

    @Override
    public CommonResultIDResponseVO signInformedSheet(SignInformedSheetRequestVO requestVO) {
        CommonResultIDResponseVO resp = new CommonResultIDResponseVO();
        Long id = requestVO.getId();
        String imgStr = requestVO.getImgStr();
        try {
            AgPoInformed dbData = informedMapper.selectByPrimaryKey(id);
            if (dbData != null && "1".equals(dbData.getStatus())) {
                resp.setCommonResult(new CommonResult(false, "不可重复签署"));
                return resp;
            }
            if (StringUtils.isBlank(imgStr)) {
                resp.setCommonResult(new CommonResult(false, "file不可为空"));
                return resp;
            }
            if (imgStr.indexOf("data:image/png;") != -1) {
                imgStr = imgStr.replace("data:image/png;base64,", "");
            }

            byte[] fileBytes = Base64.getDecoder().decode(imgStr);
            InputStream inputStream = new ByteArrayInputStream(fileBytes);

            // 上传签名图片至阿里云
            StringBuffer fileName = new StringBuffer();
            fileName.append("InformedSheet/").append(id).append("/");
            String originalFilename = generateKey(10);
            String key = fileName.append(originalFilename).append(".png").toString();
            String putFileToOss = ossService.putFileToOss(null, key, inputStream);

            // 更新
            AgPoInformed informed = informedMapper.selectByPrimaryKey(requestVO.getId());
            informed.setId(id);
            informed.setSignOssPath(putFileToOss);

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date curDate = new Date();
            String signDate = format.format(curDate);
            informed.setInformedNo(this.getNextInformedNo());
            informed.setSignDate(signDate);
            informed.setStatus("1");
            informedMapper.updateByPrimaryKeySelective(informed);

            // 商机更新一条告知书已签署的记录
            MktLeadsAssignedTrack track = new MktLeadsAssignedTrack();
            track.setPractitionerId(informed.getPractitionerId());
            track.setLeadsAssignedId(informed.getLeadsId());
            track.setInformedId(id);
            track.setInformedStatus("1");
            track.setCustomerId(informed.getCustomerId());
            track.setSalesNotice("客户告知书签署成功");
            track.setTrackTime(curDate);
            track.setCreatedBy(-1L);
            track.setCreatedAt(curDate);
            track.setCreatorType(1);
            track.setUpdatedBy(-1L);
            track.setUpdatorType(1);
            track.setUpdatedAt(new Date());
            MdDropOptions dropOption = systemConfigService.getDropOption("bizchance_promotion_action", "customerNotice_1");
            track.setMdDropOptionId(dropOption.getId());
            track.setTrackScore(dropOption.getDropOptionScore());
            //保存
            mktLeadsAssignedTrackDALService.saveTrack(track);

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

            // 生成pdf
            new Thread(new Runnable() {

                @Override
                public void run() {
                    if (informed != null) {
                        Long informedId = informed.getId();

                        String templatePDF = PDFConfiguration.getProperty("informed.pdf.template");
                        //模板文件生成临时文件目录
                        String tmpPathPDF = PDFConfiguration.getProperty("informed.pdf.temp.path");

                        //PDF模板输出结果文件
                        String templateResultPDF = tmpPathPDF + informedId + "-signedInformed.pdf";

                        //填充数据
                        Map<String, String> initDatas = new HashMap<>();
                        Map<String, String> initImages = new HashMap<>();

                        //下载图片
                        String signPicture = this.getImgTolocal(tmpPathPDF, "sign.png", informed.getSignOssPath());
                        initImages.put("p_name", signPicture);
                        String pDate = informed.getSignDate();
                        initDatas.put("p_date", pDate);
                        initDatas.put("p_informedNo", informed.getInformedNo());
                        initDatas.put("p_customerName", informed.getCustomerName());

                        //按模板填充数据生成结果PDF
                        PDFTemplate.generatePDF(templatePDF, templateResultPDF, initDatas, initImages);
                        try {

                            //上传至oss    ossService
                            String ossPath = putContractFileToOSS("informed", templateResultPDF, informedId);

                            informed.setInformedOssPath(ossPath);
                            informedMapper.updateByPrimaryKeySelective(informed);

                            //更新track
                            mktLeadsAssignedTrackDALService.updateInformedOssPathByInformedId(ossPath, informedId);

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }

                private String getImgTolocal(String localDirectory, String filename, String imgUrl) {
                    Map<String, Object> input = HttpUtil.getInput(imgUrl);
                    if (!(boolean) input.get("success")) {
                        return null;
                    }
                    //获取头像流
                    InputStream inputStream = (InputStream) input.get("is");
                    if (null == inputStream) {
                        return null;
                    }

                    String filePath = localDirectory + filename;
                    byte[] data = new byte[1024];
                    int len = 0;
                    FileOutputStream fileOutputStream = null;
                    try {
                        fileOutputStream = new FileOutputStream(filePath);
                        while ((len = inputStream.read(data)) != -1) {
                            fileOutputStream.write(data, 0, len);

                        }

                        return filePath;

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } finally {

                        if (inputStream != null) {
                            try {
                                inputStream.close();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        if (fileOutputStream != null) {
                            try {
                                fileOutputStream.close();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                    return null;
                }

            }).start();

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, "保存失败"));
        }
        return resp;
    }

    private String getNextInformedNo() {
        return informedMapper.getNextInformedNo();
    }

    @Override
    public QueryInformedSheetListResponseVO queryInformedSheetList(QueryInformedSheetListRequestVO requestVO) {
        QueryInformedSheetListResponseVO resp = new QueryInformedSheetListResponseVO();
        try {
            AgPoInformed informed = new AgPoInformed();
            BeanUtils.copyProperties(requestVO, informed);
            List<AgPoInformed> list = informedMapper.selectByRecord(informed);

            resp.setList(list);
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    private String putContractFileToOSS(String businessType, String file, Long recordId) throws Exception {
        StringBuffer directory = new StringBuffer();
        directory.append(businessType).append("/").append(recordId).append("/");

        File tempFile = new File(file.trim());

        //数据源不存在
        if (!tempFile.exists()) {
            throw new RuntimeException("目标文件地址不存在!");
        }
        //非文件类型
        if (!tempFile.isFile()) {
            throw new RuntimeException("目标文件不是文件类型!");
        }
        InputStream is = null;
        String ossPath = null;
        try {
            is = new BufferedInputStream(new FileInputStream(tempFile));//读取数据源

            String fileName = tempFile.getName();
            String key = directory.append(fileName).toString();
            ossPath = ossService.putFileToOss(null, key, is);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return ossPath;
    }

    @Override
    public CommonResultIDResponseVO signCommitment(SignCommitmentRequestVO requestVO) {
        CommonResultIDResponseVO resp = new CommonResultIDResponseVO();
        resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        String practitionerName = requestVO.getPractitionerName();
        Long practitionerId = requestVO.getPractitionerId();
        String imgStr = requestVO.getImgStr();
        try {
            // 附件文件
            AclFileUpload aclFileUpload = aclFileUploadDALService.findByTargetIdAndRemark(1, practitionerId, "承诺书");
            if (aclFileUpload != null) {
                resp.setCommonResult(new CommonResult(false, "不可重复签署"));
                return resp;
            }
            if (StringUtils.isBlank(imgStr)) {
                resp.setCommonResult(new CommonResult(false, "file不可为空"));
                return resp;
            }
            if (imgStr.indexOf("data:image/png;") != -1) {
                imgStr = imgStr.replace("data:image/png;base64,", "");
            }

            byte[] fileBytes = Base64.getDecoder().decode(imgStr);
            InputStream inputStream = new ByteArrayInputStream(fileBytes);

            String templatePDF = PDFConfiguration.getProperty("commitment.pdf.template");
            //模板文件生成临时文件目录
            String tmpPathPDF = PDFConfiguration.getProperty("commitment.pdf.temp.path");

            //PDF模板输出结果文件
            String templateResultPDF = tmpPathPDF + "signedCommitment.pdf";

            //下载签名图片
            String signPicture = this.getImgStrFilePath(tmpPathPDF, "sign.png", inputStream);

            //填充数据
            Map<String, String> initDatas = new HashMap<>();
            initDatas.put("p_date", CommonUtil.dateParseString(new Date(), "yyyy-MM-dd"));
            initDatas.put("p_customerName", practitionerName);

            Map<String, String> initImages = new HashMap<>();
            initImages.put("p_name", signPicture);

            //按模板填充数据生成结果PDF
            PDFTemplate.generatePDF(templatePDF, templateResultPDF, initDatas, initImages);

            //上传至oss    ossService
            String ossPath = this.putContractFileToOSS("commitment", templateResultPDF, practitionerId);
            //加入文件附件
            AclFileUpload fileUpload = new AclFileUpload();
            fileUpload.setTargetType(1);
            fileUpload.setTargetId(practitionerId);
            fileUpload.setTargetNo(practitionerId + "-signedCommitment.pdf");
            fileUpload.setTargetUseFor(11);
            fileUpload.setFileName(practitionerId + "-signedCommitment.pdf");
            fileUpload.setFileType("PDF");
            fileUpload.setFilePath(ossPath);
            fileUpload.setFileSize(String.valueOf(fileBytes.length));
            fileUpload.setRemark("承诺书");
            aclFileUploadDALService.saveFileUpload(fileUpload);

            try {
				//发送邮件给客服，同步跟进
				String toAddress = systemConfigService.getSingleConfigValue("ContinuationRateSupportToAddress");
				String ccAddress = systemConfigService.getSingleConfigValue("ContinuationRateSupportCCAddresses");
				AclPractitioner aclPractitioner = aclPractitionerDALService.findById(practitionerId);
				if(aclPractitioner != null){
				    String subject = "经纪人【"+practitionerName+"】已签署品质承诺书";
				    String messageText = "尊敬的银盾运营同事： </br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ";
				    boolean boole = false;
				  	if(aclPractitioner.getS3Id() != null){
						AclPractitionerSubordinateSystem subordinateInfo = aclPractitionerSubordinateSystemDALService.findById(aclPractitioner.getS3Id());
				        if (subordinateInfo != null) {
				        	messageText += subordinateInfo.getName() + "纵队-";
				        	boole = false;
				        }
					}
					if(aclPractitioner.getS2Id() != null){
						AclPractitionerSubordinateSystem subordinateInfo = aclPractitionerSubordinateSystemDALService.findById(aclPractitioner.getS2Id());
				        if (subordinateInfo != null) {
				        	messageText += subordinateInfo.getName() + "体系-";
				        	boole = false;
				        }
					}
					if(aclPractitioner.getS1Id() != null){
						AclPractitionerSubordinateSystem subordinateInfo = aclPractitionerSubordinateSystemDALService.findById(aclPractitioner.getS1Id());
				        if (subordinateInfo != null) {
				        	messageText += subordinateInfo.getName() + "分部";
				        	boole = true;
				        }
					}
					if(!boole){
						messageText = messageText.substring(0,messageText.length()-1);
					}
				    messageText += "的经纪人【"+practitionerName+"】已签署品质承诺书，请至 “AGMS后台>经纪人管理>上传文件-列表” 进行查看，并安排后续相关工作，谢谢！";
				    mailService.sysNotify(toAddress, ccAddress.split(","), subject, messageText);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    @Override
    public QueryCommitmentByPractitionerIdResponseVO queryCommitmentByPractitionerId(PractitionerIdRequestVO requestVO) {
        QueryCommitmentByPractitionerIdResponseVO resp = new QueryCommitmentByPractitionerIdResponseVO();
        resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        Long practitionerId = requestVO.getPractitionerId();
        try {
            // 附件文件
            AclFileUpload aclFileUpload = aclFileUploadDALService.findByTargetIdAndRemark(1, practitionerId, "承诺书");
            if (aclFileUpload != null) {
                resp.setFileOssPath(aclFileUpload.getFilePath());
                return resp;
            }
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }

    private String getImgStrFilePath(String localDirectory, String filename, InputStream inputStream) {
        //头像流
        if (null == inputStream) {
            return null;
        }

        String filePath = localDirectory + filename;
        byte[] data = new byte[1024];
        int len = 0;
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(filePath);
            while ((len = inputStream.read(data)) != -1) {
                fileOutputStream.write(data, 0, len);

            }
            return filePath;

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 经纪人联合销售签名
     * @param SignUnionSalesRequestVO
     * @return CommonResultIDResponseVO
     * @author Yan Wenyang
     */
    @SuppressWarnings("unchecked")
    public CommonResultIDResponseVO signUnionSales(SignUnionSalesRequestVO requestVO) {
        CommonResultIDResponseVO resp = new CommonResultIDResponseVO();
        resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));

        Long unionSalesPractitionerId = requestVO.getUnionSalesPractitionerId();
        Long unionSalesId = requestVO.getUnionSalesId();
        String imgStr = requestVO.getImgStr();
        Long practitionerId = requestVO.getPractitionerId();
        if (unionSalesPractitionerId  == null) {
            resp.setCommonResult(new CommonResult(false, "联合销售经纪人不可为空"));
            return resp;
        }
        if (unionSalesId == null) {
            resp.setCommonResult(new CommonResult(false, "联合销售ID不可为空"));
            return resp;
        }
        if (practitionerId == null) {
            resp.setCommonResult(new CommonResult(false, "经纪人ID不可为空"));
            return resp;
        }
        if (StringUtils.isBlank(imgStr)) {
            resp.setCommonResult(new CommonResult(false, "file不可为空"));
            return resp;
        }
        try {
        	UnionSalesPractitionerInfo unionSalesPractitionerInfo = null;
            List<UnionSalesPractitionerInfo> unionSalesPractitioners = aclPractitionerDALService.findUnionSalesPractitionerByUnionSalesId(unionSalesId, unionSalesPractitionerId);
            if(unionSalesPractitioners != null && unionSalesPractitioners.size() > 0){
                BeanPropertyValueEqualsPredicate predicateClause = new BeanPropertyValueEqualsPredicate("id", unionSalesPractitionerId);
                List<UnionSalesPractitionerInfo> unionSalesPractitionerInfos = (List<UnionSalesPractitionerInfo>)CollectionUtils.select(unionSalesPractitioners, predicateClause);
                if(unionSalesPractitionerInfos != null && unionSalesPractitionerInfos.size() > 0){
                	unionSalesPractitionerInfo = unionSalesPractitionerInfos.get(0);
                }
            }
            if (unionSalesPractitionerInfo == null) {
                resp.setCommonResult(new CommonResult(false, "联合销售经纪人不存在"));
                return resp;
            }else if(unionSalesPractitionerInfo.getPractitionerId().longValue() != practitionerId.longValue()) {
                resp.setCommonResult(new CommonResult(false, "联合销售经纪人ID 与经纪人不匹配"));
                return resp;
            }else if(unionSalesPractitionerInfo.getSignStatus() != null && "3".equals(unionSalesPractitionerInfo.getSignStatus())) {
                resp.setCommonResult(new CommonResult(false, "不可重复签署"));
                return resp;
            }
            if (imgStr.indexOf("data:image/png;") != -1) {
                imgStr = imgStr.replace("data:image/png;base64,", "");
            }

            byte[] imgBytes = Base64.getDecoder().decode(imgStr);

            String logoPath = PDFConfiguration.getProperty("unionSales.pdf.template");
            //模板文件生成临时文件目录
            String tmpPathPDF = PDFConfiguration.getProperty("unionSales.pdf.temp.path");
            
            //PDF模板输出结果文件
            String savePath = tmpPathPDF + "signedUnionSales.pdf";

            InputStream inputStream = new ByteArrayInputStream(imgBytes);
            //下载签名图片
            String signPicture = this.getImgStrFilePath(tmpPathPDF, "signUnionSales.png", inputStream);
            
            //生成最终版本的pdf
    		Map<String,Object> retMap = generateFinalPdf(logoPath, savePath, signPicture, unionSalesPractitioners,unionSalesPractitionerInfo);
            
            //上传至oss ossService
            String ossPath = this.putContractFileToOSS("unionSales", savePath, unionSalesId);
            String ossPathImg = this.putContractFileToOSS("unionSales", signPicture, unionSalesPractitionerId);

            int singX = 0;
            int singY = 0;
            if(retMap.get("signX") != null){
            	singX = (int)retMap.get("signX");
    		}
    		if(retMap.get("signY") != null){
            	singY = (int)retMap.get("signY");
    		}
    		String signStatus = "2";
    		if(retMap.get("signStatus") != null){
    			signStatus = (String)retMap.get("signStatus");
    		}
    		if(!"1".equals(signStatus)){
        		aclPractitionerDALService.updateUnionSalesPractitioner(unionSalesPractitionerId, ossPathImg, singX, singY, "3");
        		aclPractitionerDALService.updateUnionSales(unionSalesId, ossPath, signStatus);
    		}else{
                resp.setCommonResult(new CommonResult(false, "签署失败,请联系管理人员!"));
    		}
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCommonResult(new CommonResult(false, e.getMessage()));
        }
        return resp;
    }
        
    /**
     * 生成最终版本的pdf
     * @param logoPaht logo图片路径
     * @param savePath 最终版本的pdf生成路径
     * @param signPicture 签名图片
     * @param unionSalesPractitioners 动态组拼PDF数据集合对象
     * @param unionSalesPractitioner 
     * @param void
     * @author Yan Wenyang
     */
    public static Map<String,Object> generateFinalPdf(String logoPath,String savePath,String signPicture, List<UnionSalesPractitionerInfo> unionSalesPractitioners,UnionSalesPractitionerInfo unionSalesPractitioner) {
		Document document = new Document();
		PdfWriter writer = null;
		Map<String,Object> retMap = new HashMap<String,Object>();
		FileOutputStream out = null;
        try {
        	out = new FileOutputStream(savePath);
			writer = PdfWriter.getInstance(document, out);
			document.open();
	        
			generatePdfChunk(document, logoPath, unionSalesPractitioners, "1", unionSalesPractitioner);
			
			//动态生成PDF表格
			Paragraph paragraph = generatePdfTable(unionSalesPractitioners);
			document.add(paragraph);
			
			generatePdfChunk(document, logoPath, unionSalesPractitioners, "2", unionSalesPractitioner);
			
			//动态把图片插入PDF中
			if(unionSalesPractitioners != null && unionSalesPractitioners.size() > 0){
				String salesSignUlr = unionSalesPractitioners.get(0).getSalesSignUlr();
				if(!StringUtils.isBlank(salesSignUlr)){
					for (int i= 0; i< unionSalesPractitioners.size(); i++) {
						UnionSalesPractitionerInfo unionSalesPractitionerInfo = unionSalesPractitioners.get(i);
						if(unionSalesPractitionerInfo != null && !StringUtils.isBlank(unionSalesPractitionerInfo.getSignUlr()) 
								&& "3".equals(unionSalesPractitionerInfo.getSignStatus())){
							InputStream inputStream = null;
							ByteArrayOutputStream baos = null;
							try {
								Map<String, Object> input = HttpUtil.getInput(unionSalesPractitionerInfo.getSignUlr());
								if (!(boolean) input.get("success")) {
									continue;
								}
								inputStream = (InputStream) input.get("is");
								if (null == inputStream) {
									continue;
								}
								baos = new ByteArrayOutputStream();
								byte buff[] = new byte[1024];
								int len = 0;
								while ((len = inputStream.read(buff)) != -1) {
								    baos.write(buff, 0, len);
								}
								baos.flush();
								com.itextpdf.text.Image jpg = com.itextpdf.text.Image.getInstance(baos.toByteArray());
								
								jpg.scaleToFit(100, 100);
								jpg.setAbsolutePosition(unionSalesPractitionerInfo.getSignX(), unionSalesPractitionerInfo.getSignY());
								jpg.setAlignment(com.itextpdf.text.Image.ALIGN_CENTER);
								document.add(jpg);
							} catch (Exception e) {
								e.printStackTrace();
							}finally {
								if(baos != null){
									baos.close();
								}
								if(inputStream != null){
									inputStream.close();
								}
							}
						}
					}
				}
				 
				int signCount = unionSalesPractitioners.get(0).getSignCount();
				int count = unionSalesPractitioners.size();
				int x = 150;
				int y = 405;
				if(count > 1){
					y = y - 10*count;
					if(count/3 >= 1){
						y = y - count/3*15;
					}
				}
				if(signCount > 0){
					y = y - signCount*70;
				}
				com.itextpdf.text.Image jpg = com.itextpdf.text.Image.getInstance(signPicture);
				jpg.scaleToFit(100, 100);
				jpg.setAbsolutePosition(x, y);
				jpg.setAlignment(com.itextpdf.text.Image.ALIGN_CENTER);
				document.add(jpg);
				
				retMap.put("signX", x);
				retMap.put("signY", y);
				String signStatus = "2";
				if(signCount+1 >= unionSalesPractitioners.size()){
					signStatus = "3";
				}
				retMap.put("signStatus", signStatus);
            }
		} catch (Exception e) {
			retMap.put("signStatus", "1");
			e.printStackTrace();
		}finally {
			try {
				if(document != null){
					document.close();
				}
				if(out != null){
					out.close();
				}
				if(writer != null){
					writer.close();
				}
			} catch (IOException e) {
				retMap.put("signStatus", "1");
				e.printStackTrace();
			}
		}
		//多个PDF合并功能
//		String[] filePaths = {filePath,filePathTemp};
//		if(!mergePdfFiles(filePaths, savePath, -1)){
//			retMap.put("signStatus", "1");
//		}
        return retMap;
    }
    
    /**
     * 多个PDF合并功能
     * @param filePaths 多个PDF的路径
     * @param savePath 生成的新PDF路径
     * @param pages 第几页合并(-1为最后一页)
     * @return boolean 成功返回true,失败返回false
     * @author Yan Wenyang
     */
    public static boolean mergePdfFiles(String[] filePaths,String savePath,int pages){
    	Document retDocument = null;
    	PdfReader pdfReader = null;
		PdfCopy copy = null;
		boolean boole = true;
        try {
        	if(filePaths != null && filePaths.length > 0){
        		pdfReader = new PdfReader(filePaths[0]);
		    	retDocument = new Document(pdfReader.getPageSize(1));
				copy = new PdfCopy(retDocument, new FileOutputStream(savePath));
				retDocument.open();
				PdfImportedPage page;
				for (int i = 0; i < filePaths.length; i++){
					PdfReader reader = null;
				    try {
						reader = new PdfReader(filePaths[i]);
						int n = reader.getNumberOfPages();
						for (int j = 1; j <= n; j++){
							//页数为1，一页一页复制
							retDocument.newPage();
							page = copy.getImportedPage(reader, j);
							copy.addPage(page);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}finally {
						if(reader != null){
							reader.close();
						}
					}
				}
        	}
		} catch (Exception e) {
			boole = false;
			e.printStackTrace();
		}finally {
			try {
				if(copy != null){
					copy.close();
				}
				if(retDocument != null){
					retDocument.close();
				}
				if(pdfReader != null){
					pdfReader.close();
				}
			} catch (Exception e) {
				boole = false;
				e.printStackTrace();
			}
		}
        return boole;
    }

    /**
     * 动态生成PDF
     * @param document Document对象
     * @param logoPath logo图片路径
     * @param object 动态组拼PDF数据集合对象
     * @param type 操作对象
     * @param unionSalesPractitioner 当前经纪人签署信息
     * @return void
     * @author Yan Wenyang
     */
    @SuppressWarnings("unchecked")
    public static void generatePdfChunk(Document document,String logoPath, Object object,String type,UnionSalesPractitionerInfo unionSalesPractitioner) throws Exception {
    	//添加段落
    	Paragraph preface = new Paragraph();
        BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        com.itextpdf.text.Font fontChinese = new com.itextpdf.text.Font(bfChinese, 15.5F, com.itextpdf.text.Font.NORMAL);

    	if(object != null){
  	        List<UnionSalesPractitionerInfo> unionSalesPractitioners = (List<UnionSalesPractitionerInfo>)object;
  	        UnionSalesPractitionerInfo unionSalesPractitionerInfo = unionSalesPractitioners.get(0);
	    	if("1".equals(type)){
	    		//1. 生成logo图片
				com.itextpdf.text.Image jpgLogo = com.itextpdf.text.Image.getInstance(logoPath);
				jpgLogo.scaleToFit(150, 150);
				jpgLogo.setAbsolutePosition(90, 800);
				jpgLogo.setAlignment(com.itextpdf.text.Image.ALIGN_CENTER);
				document.add(jpgLogo);
				
				//2. 横线
		        LineSeparator line = new LineSeparator(0.5f,80,BaseColor.BLACK,Element.ALIGN_CENTER,-10f);
		        Paragraph paragraphLine = new Paragraph();
		        paragraphLine.add(new Chunk(line));
		        document.add(line);
		        
		        //3. 正文
	    		preface = new Paragraph();
	    		preface.add(new Phrase("银盾经纪人联合销售确认书", fontChinese));
	    		preface.setAlignment(Element.ALIGN_CENTER);
	    		preface.setSpacingBefore(20f); //设置段落上空白
	    		preface.setSpacingAfter(10f); //设置段落下空白
	    		document.add(preface);
	    		
	            fontChinese = new com.itextpdf.text.Font(bfChinese, 10.5F, com.itextpdf.text.Font.NORMAL);
	    		preface = new Paragraph();
	    		preface.add(new Phrase("以下保单经纪人同意进行联合销售，并对佣金分配比例和业绩分配比例约定如下：", fontChinese));
	    		preface.setAlignment(Element.ALIGN_CENTER);
	    		preface.setSpacingBefore(10f); //设置段落上空白
	    		preface.setSpacingAfter(10f); //设置段落下空白
	    		document.add(preface);
	    		
	    		preface = new Paragraph();
	    		preface.add(new Phrase("保单信息", fontChinese));
	    		preface.setAlignment(Element.ALIGN_CENTER);
	    		preface.setSpacingBefore(10f); //设置段落上空白
	    		preface.setSpacingAfter(10f); //设置段落下空白
	    		document.add(preface);
			
	    		preface = new Paragraph();
				preface.add(new Phrase("保险公司：", fontChinese));
				preface.add(new Phrase(unionSalesPractitionerInfo.getInsurerName(), fontChinese));
	    		preface.setSpacingBefore(10f); //设置段落上空白
				preface.setIndentationLeft(50);
				preface.setIndentationRight(50);
	    		document.add(preface);

	    		preface = new Paragraph();
				preface.add(new Phrase("产品名称：", fontChinese));
				preface.add(new Phrase(unionSalesPractitionerInfo.getProductName(), fontChinese));
	    		preface.setSpacingBefore(10f); //设置段落上空白
				preface.setIndentationLeft(50);
				preface.setIndentationRight(50);
	    		document.add(preface);

	    		preface = new Paragraph();
				preface.add(new Phrase("投保单号： ", fontChinese));
				preface.add(new Phrase(unionSalesPractitionerInfo.getProposalNo(), fontChinese));
	    		preface.setSpacingBefore(10f); //设置段落上空白
				preface.setIndentationLeft(50);
				preface.setIndentationRight(50);
	    		document.add(preface);

	    		preface = new Paragraph();
				preface.add(new Phrase("保单号：     ", fontChinese));
				preface.add(new Phrase(unionSalesPractitionerInfo.getPolicyNo(), fontChinese));
	    		preface.setSpacingBefore(10f); //设置段落上空白
				preface.setIndentationLeft(50);
				preface.setIndentationRight(50);
	    		document.add(preface);

	    		preface = new Paragraph();
				preface.add(new Phrase("投保人：   ", fontChinese));
				preface.add(new Phrase(unionSalesPractitionerInfo.getPolicyholderName(), fontChinese));
	    		preface.setSpacingBefore(10f); //设置段落上空白
	    		preface.setSpacingAfter(10f); //设置段落下空白
				preface.setIndentationLeft(50);
				preface.setIndentationRight(50);
	    		document.add(preface);
	    	}else{
	            fontChinese = new com.itextpdf.text.Font(bfChinese, 10.5F, com.itextpdf.text.Font.NORMAL);
	    		preface = new Paragraph();
				preface.add(new Phrase("※本人已详细阅读以上联合销售的内容，同意上述约定并承诺执行。", fontChinese));
				preface.setIndentationLeft(50);
				preface.setIndentationRight(50);
	    		document.add(preface);
	    		
	    		//5. 动态已签经纪人信息
	    		for (int i= 0; i< unionSalesPractitioners.size(); i++) {
		            unionSalesPractitionerInfo = unionSalesPractitioners.get(i);
		            if(unionSalesPractitionerInfo != null && !StringUtils.isBlank(unionSalesPractitionerInfo.getSignUlr()) 
							&& "3".equals(unionSalesPractitionerInfo.getSignStatus())){
			    		preface = new Paragraph();
						preface.add(new Phrase("经纪人：   ", fontChinese));
						preface.add(new Phrase(unionSalesPractitionerInfo.getPractitionerName(), fontChinese));
			    		preface.setSpacingBefore(10f); //设置段落上空白
			    		preface.setSpacingAfter(10f); //设置段落下空白
						preface.setIndentationLeft(50);
						preface.setIndentationRight(50);
			    		document.add(preface);
	
			    		preface = new Paragraph();
						preface.add(new Phrase("经纪人亲签：   ", fontChinese));
						preface.add(new Phrase("                                                       日期：", fontChinese));
						preface.add(new Phrase(unionSalesPractitionerInfo.getSignDate(), fontChinese));
			    		preface.setSpacingBefore(10f); //设置段落上空白
			    		preface.setSpacingAfter(10f); //设置段落下空白
						preface.setIndentationLeft(50);
						preface.setIndentationRight(50);
			    		document.add(preface);
		            }
		        }

	    		//6. 当前签署经纪人信息
	    		if(unionSalesPractitioner != null){
		    		preface = new Paragraph();
					preface.add(new Phrase("经纪人：   ", fontChinese));
					preface.add(new Phrase(unionSalesPractitioner.getPractitionerName(), fontChinese));
		    		preface.setSpacingBefore(10f); //设置段落上空白
		    		preface.setSpacingAfter(10f); //设置段落下空白
					preface.setIndentationLeft(50);
					preface.setIndentationRight(50);
		    		document.add(preface);

		    		preface = new Paragraph();
					preface.add(new Phrase("经纪人亲签：   ", fontChinese));
					preface.add(new Phrase("                                                       日期：", fontChinese));
					preface.add(new Phrase(CommonUtil.dateParseString(new Date(), "yyyy-MM-dd HH:mm:ss"), fontChinese));
		    		preface.setSpacingBefore(10f); //设置段落上空白
		    		preface.setSpacingAfter(10f); //设置段落下空白
					preface.setIndentationLeft(50);
					preface.setIndentationRight(50);
		    		document.add(preface);
	    		}
	    	}
	    }
    }
    
    /**
     * 动态生成PDF表格
     * @param object 动态组排PDF数据集合对象
     * @return Paragraph
     * @author Yan Wenyang
     */
    @SuppressWarnings("unchecked")
    public static Paragraph generatePdfTable(Object object) throws Exception {
        BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        com.itextpdf.text.Font fontChinese = new com.itextpdf.text.Font(bfChinese, 10F, com.itextpdf.text.Font.NORMAL);
        Paragraph ret = new Paragraph();
        PdfPTable tableBox = new PdfPTable(3);
        tableBox.setWidths(new float[] { 0.4f, 0.3f, 0.3f});//每个单元格占多宽
        tableBox.setWidthPercentage(80f);
        //创建表格格式及内容
        tableBox.addCell(getCell(new Phrase("经纪人", fontChinese), 1, 1));
        tableBox.addCell(getCell(new Phrase("分佣分配比例", fontChinese), 1, 1));
        tableBox.addCell(getCell(new Phrase("业绩分配比例", fontChinese), 1, 1));
        if(object != null){
	        //遍历查询出的结果
	        List<UnionSalesPractitionerInfo> unionSalesPractitioners = (List<UnionSalesPractitionerInfo>)object;
	        for (int i= 0; i< unionSalesPractitioners.size(); i++) {
	            UnionSalesPractitionerInfo unionSalesPractitionerInfo = unionSalesPractitioners.get(i);
	            if(unionSalesPractitionerInfo != null){
		            tableBox.addCell(getCell(new Phrase(unionSalesPractitionerInfo.getPractitionerName(), fontChinese), 1, 1));
		            tableBox.addCell(getCell(new Phrase(unionSalesPractitionerInfo.getCommissionRate().toString() +"%", fontChinese), 1, 1));
		            tableBox.addCell(getCell(new Phrase(unionSalesPractitionerInfo.getAchievementsRate().toString() +"%", fontChinese), 1, 1));
	            }
	        }
        }
        ret.add(tableBox);
        return ret;
    }
    
    /**
     * 每个cell的格式，合并单元格情况
     * @param phrase
     * @param colSpan
     * @param rowSpan
     * @return PdfPCell
     * @author Yan Wenyang
     */
    public static PdfPCell getCell(Phrase phrase, int colSpan, int rowSpan) {
    	PdfPCell cells = new PdfPCell(phrase);
        cells.setUseAscender(true);
        cells.setMinimumHeight(20f);
        cells.setHorizontalAlignment(1);
        cells.setVerticalAlignment(5);
        cells.setColspan(colSpan);
        cells.setRowspan(rowSpan);
        cells.setNoWrap(false);
        return cells;
    }

    /**
     * 逻辑删除商机
     * @param OpportunityDeleteRequestVO
     * @return CommonResultIDResponseVO
     * @author Yan Wenyang
     */
    public CommonResultIDResponseVO updateOpportunity(OpportunityDeleteRequestVO requestVO){
        CommonResultIDResponseVO resp = new CommonResultIDResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        if (practitionerId == null) {
            resp.setCommonResult(new CommonResult(false, "经纪人ID不可为空"));
            return resp;
        }
        if (requestVO.getOpportunityId() == null) {
            resp.setCommonResult(new CommonResult(false, "商机ID不可为空"));
            return resp;
        }
        //等保调整
        List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
        if (null == findByObjSortable) {
        	resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
            return resp;
        }
        resp.setId(requestVO.getOpportunityId());
        resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        
        //物理删除需要更新的表
//      SELECT t.id, t.customer_id, t.* FROM ag_mkt_leads_assigneds t WHERE t.id ='219' AND t.is_active ='1';;
//      SELECT t.* FROM ag_mkt_leads_pool t WHERE t.customer_id ='29397' AND t.is_active ='1';
//      SELECT t.* FROM ag_mkt_leads_assigned_track t WHERE t.leads_assigned_id ='219' AND t.is_active ='1';;
//      SELECT t.* FROM ag_mkt_leads_expert_request t WHERE t.leads_assigned_id ='219' AND t.is_active ='1';;
//      SELECT t.* FROM ag_mkt_leads_expert_assign t WHERE t.leads_expert_request_id='19' AND t.is_active ='1';;
        MktLeadsAssigneds mktLeadsAssigneds = mktLeadsAssignedsDALService.findByLeadsAssignedId(requestVO.getOpportunityId());
        if(mktLeadsAssigneds != null && mktLeadsAssigneds.getIsActive() != null && mktLeadsAssigneds.getIsActive().intValue() == 1){
            mktLeadsAssigneds.setIsActive(0);
            mktLeadsAssigneds.setUpdatedAt(new Date());
            mktLeadsAssigneds.setUpdatedBy(requestVO.getPractitionerId());
            mktLeadsAssignedsDALService.updateMktLeadsAssigneds(mktLeadsAssigneds);

            MktLeadsPool pool = mktLeadsPoolDALService.findByCustomerId(mktLeadsAssigneds.getCustomerId());
            if (pool != null) {
            	pool.setIsActive(0);
            	mktLeadsPoolDALService.updateMktLeadsAssigneds(pool);
            }
            
            MktLeadsAssignedTrack mktLeadsAssignedTrack = new MktLeadsAssignedTrack();
            mktLeadsAssignedTrack.setLeadsAssignedId(mktLeadsAssigneds.getId());
            mktLeadsAssignedTrack.setIsActive(1);
            List<MktLeadsAssignedTrack> mktLeadsAssignedTracks = mktLeadsAssignedTrackDALService.findByMktLeadsAssignedTrack(mktLeadsAssignedTrack);
            if(mktLeadsAssignedTracks != null && mktLeadsAssignedTracks.size() > 0 ){
            	for (MktLeadsAssignedTrack item : mktLeadsAssignedTracks) {
            		item.setIsActive(0);
            		item.setUpdatedAt(new Date());
            		item.setUpdatedBy(requestVO.getPractitionerId());
                    mktLeadsAssignedTrackDALService.updateTrack(item);
				}
            }

            //判断此商机专家支持是否已经申请
            MktLeadsExpertRequest isExpertRequest = mktLeadsExpertRequestDALService.findByLeadsAssignedId(mktLeadsAssigneds.getId());
            if(isExpertRequest != null){
	            //有申请专家  查询是否指派专家
	            MktLeadsExpertAssign mktLeadsExpertAssign = mktLeadsExpertAssignDALService.findByLeadsExpertRequestId(isExpertRequest.getId());
	            if (mktLeadsExpertAssign != null) {
	            	mktLeadsExpertAssign.setIsActive(0);
	            	mktLeadsExpertAssign.setUpdatedAt(new Date());
	            	mktLeadsExpertAssign.setUpdatedBy(requestVO.getPractitionerId());
	            	mktLeadsExpertAssignDALService.updateByPrimaryKeySelective(mktLeadsExpertAssign);
	            }
	            
	            isExpertRequest.setIsActive(0);
	            isExpertRequest.setUpdatedAt(new Date());
	            isExpertRequest.setUpdatedBy(requestVO.getPractitionerId());
	            mktLeadsExpertRequestDALService.updateByPrimaryKeySelective(isExpertRequest);
            }
        }else{
            resp.setCommonResult(new CommonResult(false, "该商机不是有效的商机"));
            return resp;
        }
        return resp;
    }
    
    /**
     * 经纪人名片
     * @param PractitionerBusinessCardRequestVO
     * @return PractitionerBusinessCardResponseVO
     * @author Yan Wenyang
     */
    public PractitionerBusinessCardResponseVO businessCard(PractitionerBusinessCardRequestVO requestVO){
    	PractitionerBusinessCardResponseVO resp = new PractitionerBusinessCardResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        if (practitionerId == null) {
            resp.setCommonResult(new CommonResult(false, "经纪人ID不可为空"));
            return resp;
        }
        //等保调整
        List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
        if (null == findByObjSortable) {
        	resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
            return resp;
        }
        
        List<PractitionerBusinessCardResponseVO> rets = aclPractitionerDALService.businessCard(practitionerId);
        if(rets != null && rets.size() > 0){
        	resp = rets.get(0);
        	if(!Strings.isNullOrEmpty(resp.getCertList())){
                List<String> certIdStrList = Arrays.asList(resp.getCertList().split(","));
                List<Long> certIdList = new ArrayList<>();
                certIdStrList.forEach(i -> certIdList.add(Long.valueOf(i)));
                List<Certificate> certificateList = aclPractitionerDALService.findCertificate(certIdList);
            	resp.setCertificateList(certificateList);
        	}
        	if(!Strings.isNullOrEmpty(resp.getMobileNo())){
                DESTypeHandler jpaCryptoConverter = new DESTypeHandler();
                resp.setMobileNo(jpaCryptoConverter.decode(resp.getMobileNo()));
            }
            resp.setInsurerUrl("www.ydinsurance.cn");
            resp.setInsurerAbbre("银盾保险经纪");
            resp.setInsurerUser("全球保险集团BHL成员");
            resp.setBusinessCardType(requestVO.getBusinessCardType());
            if("1".equals(requestVO.getBusinessCardType()) || "2".equals(requestVO.getBusinessCardType()) || "3".equals(requestVO.getBusinessCardType())){
          		businessCardE(resp);
            }
            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
        }else{
            resp.setCommonResult(new CommonResult(false, "没有查到该经纪人"));
        }
        return resp;
    }
    
    /**
     * 经纪人电子名片
     * @param PractitionerBusinessCardResponseVO
     * @return void
     * @author Yan Wenyang
     */
    public void businessCardE(PractitionerBusinessCardResponseVO resp){
        Long practitionerId = resp.getPractitionerId();
        String templatePDF = PDFConfiguration.getProperty("businessCardE.pdf.template");
        //模板文件生成临时文件目录
        String tmpPathPDF = PDFConfiguration.getProperty("businessCardE.pdf.temp.path");
        //PDF模板输出结果文件
        String templateResultPDF = tmpPathPDF + practitionerId + "-businessCardE.pdf";
        //填充数据
        Map<String, String> initDatas = new HashMap<>();
        Map<String, String> initImages = new HashMap<>();
        //下载图片
        Map<String, Object> input = HttpUtil.getInput(resp.getWxQRImgUrl());
        if ((boolean) input.get("success")) {
            InputStream inputStream = (InputStream) input.get("is");
            String wxQRImgUrl = this.getImgStrFilePath(tmpPathPDF, "sign.png", inputStream);
            initImages.put("wxQRImgUrl", wxQRImgUrl);
        }
    	if(resp.getCertificateList() != null && resp.getCertificateList().size() > 0){
            for (int j = 0; j < resp.getCertificateList().size(); j++) {
            	Certificate certificate = resp.getCertificateList().get(j);
            	if(certificate != null){
            		int jj = j + 1;
            		initDatas.put("certName"+jj, certificate.getCertName() + "  " + certificate.getCertNameEn());
            	}
			}
    	}
        if(!Strings.isNullOrEmpty(resp.getPractitionerName())){
            initDatas.put("practitionerName", resp.getPractitionerName());
        }
        if(!Strings.isNullOrEmpty(resp.getPractitionerNameEn())){
            initDatas.put("practitionerNameEn", resp.getPractitionerNameEn());
        }
        if(!Strings.isNullOrEmpty(resp.getLevelName())){
            initDatas.put("levelName", resp.getLevelName());
        }
        if(!Strings.isNullOrEmpty(resp.getLevelNameEn())){
            initDatas.put("levelNameEn", resp.getLevelNameEn());
        }
        if(!Strings.isNullOrEmpty(resp.getInsurerName())){
            initDatas.put("insurerName", resp.getInsurerName());
        }
        if(!Strings.isNullOrEmpty(resp.getInsurerAbbre())){
            initDatas.put("insurerAbbre", resp.getInsurerAbbre());
        }
        if(!Strings.isNullOrEmpty(resp.getInsurerUrl())){
            initDatas.put("insurerUrl", resp.getInsurerUrl());
        }
        if(!Strings.isNullOrEmpty(resp.getInsurerAddress())){
            initDatas.put("insurerAddress", resp.getInsurerAddress());
        }
        if(!Strings.isNullOrEmpty(resp.getInsurerUser())){
            initDatas.put("insurerUser", resp.getInsurerUser());
        }
    	if(!Strings.isNullOrEmpty(resp.getMobileNo())){
            initDatas.put("mobileNo", "T: " + resp.getMobileNo());
        }
    	if(!Strings.isNullOrEmpty(resp.getEmail())){
            initDatas.put("email", "E: " + resp.getEmail());
        }
        //按模板填充数据生成结果PDF
        PDFTemplate.generatePDF(templatePDF, templateResultPDF, initDatas, initImages);
        try {
            if("1".equals(resp.getBusinessCardType()) || "3".equals(resp.getBusinessCardType())){
            	resp.setBusinessCardPdfUrl(putContractFileToOSS("businessCardEPDF", templateResultPDF, practitionerId));
            }
            if("2".equals(resp.getBusinessCardType()) || "3".equals(resp.getBusinessCardType())){
            	getBusinessCardImg(resp, practitionerId, templateResultPDF, tmpPathPDF);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 把PDF转换为图片
     * @param resp
     * @param practitionerId
     * @param templateResultPDF
     * @param tmpPathPDF
     * @throws Exception
     * @throws IOException
     */
	private void getBusinessCardImg(PractitionerBusinessCardResponseVO resp, Long practitionerId,
			String templateResultPDF,String tmpPathPDF) throws Exception, IOException {
        //JPG模板输出结果文件
        String templateResultPNG = tmpPathPDF + practitionerId + "-businessCardE.png";
		PDDocument doc = null;
		ByteArrayOutputStream os = null;
		InputStream stream = null;
		OutputStream out = null;
		try {
		    // pdf路径
		    stream = new FileInputStream(templateResultPDF);
		    // 加载解析PDF文件
		    doc = PDDocument.load(stream);
		    PDFRenderer pdfRenderer = new PDFRenderer(doc);
		    PDPageTree pages = doc.getPages();
		    int pageCount = pages.getCount();
		    for (int i = 0; i < pageCount; i++) {
		        BufferedImage bim = pdfRenderer.renderImageWithDPI(i, 70);
		        ImageIO.write(bim, "png", new File(templateResultPNG));
//                    os = new ByteArrayOutputStream();
//                    Image image = bim.getScaledInstance(70,45,Image.SCALE_SMOOTH); //设置图像的缩放大小
//                    AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(1,1),null); //设置图像的缩放比例
//                    image = op.filter(bim,null);
//                    ImageIO.write((BufferedImage)image, "png", os);
//                    byte[] dataList = os.toByteArray();
//                    // png文件转出路径
//                    File file = new File(templateResultPNG);
//                    if (!file.getParentFile().exists()) {
//                        // 不存在则创建父目录及子文件
//                        file.getParentFile().mkdirs();
//                        file.createNewFile();
//                    }
//                    out = new FileOutputStream(file);
//                    out.write(dataList);
		        if(i == 0){
		            resp.setBusinessCardProsImg(putContractFileToOSS("businessCardEPros", templateResultPNG, practitionerId));
		        }else if(i == 1){
		            resp.setBusinessCardConsImg(putContractFileToOSS("businessCardECons", templateResultPNG, practitionerId));
		        }
		    }
		} catch (Exception e) {
		    e.printStackTrace();
		    throw e;
		} finally {
		    if (doc != null) doc.close();
		    if (os != null) os.close();
		    if (stream != null) stream.close();
		    if (out != null) out.close();
		}
	}

    /**
     * 经纪人申请开通邮箱
     * @param PractitionerApplyEmailRequestVO
     * @return CommonResultResponseVO
     * @author Yan Wenyang
     */
    public CommonResultResponseVO applyEmail(PractitionerApplyEmailRequestVO requestVO){
    	CommonResultResponseVO resp = new CommonResultResponseVO();
        Long practitionerId = requestVO.getPractitionerId();
        if (practitionerId == null) {
            resp.setCommonResult(new CommonResult(false, "经纪人ID不可为空"));
            return resp;
        }
//        if (Strings.isNullOrEmpty(requestVO.getEmail())) {
//            resp.setCommonResult(new CommonResult(false, "经纪人申请的邮箱地址不可为空"));
//            return resp;
//        }
        //等保调整
        List<AclCustomer> findByObjSortable = aclPractitionerDALService.getAclCustomers(practitionerId, null);
        if (null == findByObjSortable) {
        	resp.setCommonResult(new CommonResult(false, ZHBErrorConfig.getErrorInfo("630028")));
            return resp;
        }
        
        AclPractitioner practitioner = aclPractitionerDALService.findPractitionerById(practitionerId);
        if(practitioner != null && practitioner.getIsActive() != null && practitioner.getIsActive().intValue() == 1){
            if(practitioner.getEmailIsActive() != null && practitioner.getEmailIsActive().intValue() == 1){
            	resp.setCommonResult(new CommonResult(false, "经纪人银盾保险专属办公邮箱已开通,无需在申请！"));
                return resp;
            }
//            if(!requestVO.getEmail().equals(practitioner.getEmail())){
//            	resp.setCommonResult(new CommonResult(false, "经纪人申请的邮箱与系统邮箱不一致,请联系管理员确认！"));
//                return resp;
//            }
            try {
				//发送邮件给客服，同步跟进
				String toAddress = systemConfigService.getSingleConfigValue("ApplyEmailToAddress");
				String ccAddress = systemConfigService.getSingleConfigValue("ApplyEmailCCAddresses");
				AclPractitioner aclPractitioner = aclPractitionerDALService.findById(practitionerId);
				if(aclPractitioner != null){
				    String subject = "经纪人【"+practitioner.getName()+"】申请开通银盾保险专属办公邮箱";
				    String messageText = "尊敬的银盾管理员，您好： </br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ";
				    boolean boole = false;
				  	if(aclPractitioner.getS3Id() != null){
						AclPractitionerSubordinateSystem subordinateInfo = aclPractitionerSubordinateSystemDALService.findById(aclPractitioner.getS3Id());
				        if (subordinateInfo != null) {
				        	messageText += subordinateInfo.getName() + "纵队-";
				        	boole = false;
				        }
					}
					if(aclPractitioner.getS2Id() != null){
						AclPractitionerSubordinateSystem subordinateInfo = aclPractitionerSubordinateSystemDALService.findById(aclPractitioner.getS2Id());
				        if (subordinateInfo != null) {
				        	messageText += subordinateInfo.getName() + "体系-";
				        	boole = false;
				        }
					}
					if(aclPractitioner.getS1Id() != null){
						AclPractitionerSubordinateSystem subordinateInfo = aclPractitionerSubordinateSystemDALService.findById(aclPractitioner.getS1Id());
				        if (subordinateInfo != null) {
				        	messageText += subordinateInfo.getName() + "分部";
				        	boole = true;
				        }
					}
					if(!boole){
						messageText = messageText.substring(0,messageText.length()-1);
					}
			        if (!Strings.isNullOrEmpty(practitioner.getEmail())) {
			        	if(!Strings.isNullOrEmpty(practitioner.getMobileNo())){
				        	messageText += "的经纪人【"+practitioner.getName()+"】申请开通银盾保险专属办公邮箱【"+practitioner.getEmail()+"】，"
				        			+ "手机号【"+practitioner.getMobileNo()+"】，请您在２个工作日内帮忙开通，谢谢！";
			            }else{
				        	messageText += "的经纪人【"+practitioner.getName()+"】申请开通银盾保险专属办公邮箱【"+practitioner.getEmail()+"】，请您在２个工作日内帮忙开通，谢谢！";
			            }
			        }else{
			        	if(!Strings.isNullOrEmpty(practitioner.getMobileNo())){
			                messageText += "的经纪人【"+practitioner.getName()+"】申请开通银盾保险专属办公邮箱，"
				        			+ "手机号【"+practitioner.getMobileNo()+"】，请您在２个工作日内帮忙开通，谢谢！";
			            }else{
			            	messageText += "的经纪人【"+practitioner.getName()+"】申请开通银盾保险专属办公邮箱，请您在２个工作日内帮忙开通，谢谢！";
			            }
			        }
				    mailService.sysNotify(toAddress, ccAddress.split(","), subject, messageText);
		            resp.setCommonResult(new CommonResult(true, ZHBErrorConfig.getErrorInfo("800000")));
				}
			} catch (Exception e) {
				e.printStackTrace();
	            resp.setCommonResult(new CommonResult(false, "邮箱申请失败,请联系管理人员,谢谢！"));
			}
        }else{
            resp.setCommonResult(new CommonResult(false, "没有查到该经纪人"));
        }
        return resp;
    }
    
}
