package info.aspirecn.iov.sjjh.supplier10000027.service;

import cn.com.jit.new_vstk.exception.NewCSSException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import info.aspirecn.iov.sjjh.commons.lang.ChannelTypeHandleResponseObject;
import info.aspirecn.iov.sjjh.commons.lang.Constant;
import info.aspirecn.iov.sjjh.commons.lang.PatternTools;
import info.aspirecn.iov.sjjh.supplier10000027.constant.SjjhConstant;
import info.aspirecn.iov.sjjh.supplier10000027.util.DESedeUtil;
import info.aspirecn.iov.sjjh.supplier10000027.util.DataSignature;
import info.aspirecn.iov.sjjh.supplier10000027.util.EncryptedReservedData;
import info.aspirecn.iov.sjjh.supplier10000027.vo.*;
import info.aspirecn.rdc.aspirecloud.node.except.utils.ErrorUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.URLDecoder;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: xusonglin
 * @create: 2019/9/3 10:22
 * @version: V1.0
 **/
@Service
@Slf4j
public class ChannelServiceImpl implements ChannelService {
    @Value("${custom.applyUrl}")
    private String applyUrl;
    @Value("${custom.requestUrl}")
    private String requestUrl;
    @Value("${custom.customerNumber}")
    private String customerNumber;
    @Value("${custom.appName}")
    private String appName;
    @Value("${custom.cardReaderVersion}")
    private String cardReaderVersion;
    @Value("${custom.liveDetectionControlVersion}")
    private String liveDetectionControlVersion;
    @Value("${custom.authCodeControlVersion}")
    private String authCodeControlVersion;
    @Value("${custom.authMode-0x10}")
    private String authMode10;
    @Value("${custom.authMode-0x40}")
    private String authMode40;
    @Value("${custom.authMode-0x42}")
    private String authMode42;
    @Value("${custom.bjcaRoot}")
    private String bjcaRootTest;
    @Value("${custom.decryptKey}")
    private String decryptKey;

    private OkHttpClient okHttpClient = new OkHttpClient.Builder().build();

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public ApplyResponseObject dataSignature(String authMode, int outTime) {
        ApplyRequestObject.BizPackageBean bizPackageBean = new ApplyRequestObject.BizPackageBean();
        bizPackageBean.setCustomerNumber(customerNumber);
        bizPackageBean.setAppName(appName);
        bizPackageBean.setTimeStamp(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
        bizPackageBean.setCardReaderVersion(cardReaderVersion);
        bizPackageBean.setLiveDetectionControlVersion(liveDetectionControlVersion);
        bizPackageBean.setAuthCodeControlVersion(authCodeControlVersion);
        bizPackageBean.setAuthMode(authMode);
        try {
            log.info("dataSignature.bizPackageBean--bizPackageBean={}", bizPackageBean);
            //身份认证申请签名
            DataSignature ds = new DataSignature();
            String signature = ds.signDataByP7DetachForJit(JSON.toJSONString(bizPackageBean));

            ApplyRequestObject applyRequestObject = new ApplyRequestObject();
            applyRequestObject.setBizPackage(bizPackageBean);
            applyRequestObject.setSign(signature);

            String responseContext = callService(applyUrl, JSONObject.toJSONString(applyRequestObject), outTime);
            ApplyResponseObject responseObject = objectMapper.readValue(responseContext, ApplyResponseObject.class);
            log.info("签名：" + responseObject.getSign());
            return responseObject;
        } catch (Exception e) {
            ErrorUtils.captureException(e);
            log.info("supplier10000027.dataSignature接口Exception={}", e);
            return null;
        }
    }

    @Override
    public ChannelTypeHandleResponseObject validateCompositeIdentityInfo(HttpServletRequest request, String customBody, int outTime) {
        ChannelTypeHandleResponseObject ret = new ChannelTypeHandleResponseObject();
        ret.setIsCharge(Constant.INTERFACE_QUERY_NO_FEE);
        String upstreamCode = Constant.LOG_UPSTREAM_DEFAULT_RESPONSE_CODE;
        String returnType = request.getHeader(Constant.CUSTOMER_RETURN_TYPE_PARA);

        if (StringUtils.isBlank(returnType)) {
            returnType = Constant.CUSTOMER_RETURN_ZW;
        }
        if (outTime <= 0) {
            outTime = Constant.HTTPCLIENT_CONNECTTIMEOUT;
        }

        log.info("validateCompositeIdentityInfo---customBody={},outTime={}", customBody, outTime);

        try {
            CompositeIdentityInfoJsonResolveObject jsonResolveObject = objectMapper.readValue(customBody,
                    CompositeIdentityInfoJsonResolveObject.class);

            // 参数校验
            if (!validateCompositeIdentityParams(ret, returnType, jsonResolveObject)) {
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                return ret;
            }

            // 申请
            ApplyResponseObject apply = dataSignature(authMode10, outTime);
            if (apply == null || !apply.getBizPackage().getSuccess().equals("true")) {
                // 申请失败，返回查询错误
                if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                    ret.setResultCode(Constant.OTHER_ERROR_CODE);
                } else {
                    ret.setResultCode(Constant.JK_RETURN_CODE_OTHER_ERROR);
                }
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                log.info("validateCompositeIdentityInfo---apply失败");
                return ret;
            }
            // 设置请求参数
            DataRequestObject requestObject = getRequestObject(jsonResolveObject, authMode10, apply.getBizPackage().getBusinessSerialNumber(), "");

            // 发起业务请求
            String responseContext = callService(requestUrl, JSONObject.toJSONString(requestObject), outTime);
            log.info("supplier10000027.validateCompositeIdentityInfo接口responseContext={}", responseContext);
            DataResponseObject responseObject = objectMapper.readValue(responseContext, DataResponseObject.class);
            log.info("supplier10000027.validateCompositeIdentityInfo接口responseObject={}", responseObject);

            if (responseObject != null && responseObject.getBizPackage().getSuccess().equals("true")) {
                ret.setCode(Constant.SUCCESS);
                setIdentityInfoResponse(ret, returnType, responseObject.getBizPackage().getAuthResult());
                upstreamCode = responseObject.getBizPackage().getAuthResult();
            } else {
                ret.setCode(Constant.FAIL);
            }
        } catch (SocketTimeoutException ste) {
            ErrorUtils.captureException(ste);
            log.info("supplier10000027.validateCompositeIdentityInfo接口SocketTimeoutException={}", ste);
            ret.setCode(Constant.REQUEST_TIMEOUT);
        } catch (Exception ioe) {
            ErrorUtils.captureException(ioe);
            log.info("supplier10000027.validateCompositeIdentityInfo接口Exception={}", ioe);
            ret.setCode(Constant.FAIL);
        }
        //上游返回码
        request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
        return ret;
    }

    @Override
    public ChannelTypeHandleResponseObject validateIdentityInfo(HttpServletRequest request, String customBody, int outTime) {
        ChannelTypeHandleResponseObject ret = new ChannelTypeHandleResponseObject();
        ret.setIsCharge(Constant.INTERFACE_QUERY_NO_FEE);
        String upstreamCode = Constant.LOG_UPSTREAM_DEFAULT_RESPONSE_CODE;
        String returnType = request.getHeader(Constant.CUSTOMER_RETURN_TYPE_PARA);

        if (StringUtils.isBlank(returnType)) {
            returnType = Constant.CUSTOMER_RETURN_ZW;
        }
        if (outTime <= 0) {
            outTime = Constant.HTTPCLIENT_CONNECTTIMEOUT;
        }

        log.info("validateIdentityInfo---customBody={},outTime={}", customBody, outTime);

        try {
           /* BASE64Decoder decoder = new BASE64Decoder();
            customBody = new String(decoder.decodeBuffer(customBody));
            log.info("BASE64解码后customBody === " + customBody);*/
            IdentityInfoJsonResolveObject jsonResolveObject = objectMapper.readValue(customBody,
                    IdentityInfoJsonResolveObject.class);
            // 参数校验
            if (!validateIdentityInfoParams(ret, returnType, jsonResolveObject)) {
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                return ret;
            }

            // 申请
            ApplyResponseObject apply = dataSignature(authMode40, outTime);
            if (apply == null || !apply.getBizPackage().getSuccess().equals("true")) {
                // 申请失败，返回查询错误
                if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                    ret.setResultCode(Constant.OTHER_ERROR_CODE);
                } else {
                    ret.setResultCode(Constant.JK_RETURN_CODE_OTHER_ERROR);
                }
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                log.info("validateIdentityInfo---apply失败");
                return ret;
            }

            // 设置请求参数
            DataRequestObject requestObject = getRequestObject(jsonResolveObject, authMode40, apply.getBizPackage().getBusinessSerialNumber(), "");
            log.info("supplier10000027.validateIdentityInfo接口requestObject={}", requestObject);
            // 发起业务请求
            String responseContext = callService(requestUrl, JSONObject.toJSONString(requestObject), outTime);
            log.info("请求上游");
            log.info("supplier10000027.validateIdentityInfo接口responseContext={}", responseContext);
            DataResponseObject responseObject = objectMapper.readValue(responseContext, DataResponseObject.class);
            log.info("supplier10000027.validateIdentityInfo接口responseObject={}", responseObject);

            if (responseObject != null && responseObject.getBizPackage().getSuccess().equals("true")) {
                ret.setCode(Constant.SUCCESS);
                setIdentityInfoResponse(ret, returnType, responseObject.getBizPackage().getAuthResult());
                upstreamCode = responseObject.getBizPackage().getAuthResult();
            } else {
                ret.setCode(Constant.FAIL);
            }
        } catch (SocketTimeoutException ste) {
            ErrorUtils.captureException(ste);
            log.info("supplier10000027.validateIdentityInfo接口SocketTimeoutException={}", ste);
            ret.setCode(Constant.REQUEST_TIMEOUT);
        } catch (Exception ioe) {
            ErrorUtils.captureException(ioe);
            log.info("supplier10000027.validateIdentityInfo接口Exception={}", ioe);
            ret.setCode(Constant.FAIL);
        }
        //上游返回码
        request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
        return ret;
    }

    @Override
    public ChannelTypeHandleResponseObject validatePhotoIdentityInfo(HttpServletRequest request, String customBody, int outTime) {
        ChannelTypeHandleResponseObject ret = new ChannelTypeHandleResponseObject();
        ret.setIsCharge(Constant.INTERFACE_QUERY_NO_FEE);
        String upstreamCode = Constant.LOG_UPSTREAM_DEFAULT_RESPONSE_CODE;
        String returnType = request.getHeader(Constant.CUSTOMER_RETURN_TYPE_PARA);

        if (StringUtils.isBlank(returnType)) {
            returnType = Constant.CUSTOMER_RETURN_ZW;
        }
        if (outTime <= 0) {
            outTime = Constant.HTTPCLIENT_CONNECTTIMEOUT;
        }

        try {
            JSONObject paramObject = JSON.parseObject(customBody);
            paramObject.put("photo", "base64");
            log.info("validatePhotoIdentityInfo---customBody={},outTime={}", paramObject.toJSONString(), outTime);

            PhotoIdentityInfoJsonResolveObject jsonResolveObject = objectMapper.readValue(customBody,
                    PhotoIdentityInfoJsonResolveObject.class);
            // 参数校验
            if (!validatePhotoIdentityInfoParams(ret, returnType, jsonResolveObject)) {
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                return ret;
            }

            // 申请
            ApplyResponseObject apply = dataSignature(authMode42, outTime);
            if (apply == null || !apply.getBizPackage().getSuccess().equals("true")) {
                // 申请失败，返回查询错误
                if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                    ret.setResultCode(Constant.OTHER_ERROR_CODE);
                } else {
                    ret.setResultCode(Constant.JK_RETURN_CODE_OTHER_ERROR);
                }
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                log.info("validatePhotoIdentityInfo---apply失败");
                return ret;
            }

            // 设置请求参数
            DataRequestObject requestObject = getRequestObject(jsonResolveObject, authMode42, apply.getBizPackage().getBusinessSerialNumber(), jsonResolveObject.getPhoto());
            // 发起业务请求
            String responseContext = callService(requestUrl, JSONObject.toJSONString(requestObject), outTime);
            log.info("supplier10000027.validatePhotoIdentityInfo接口responseContext={}", responseContext);
            DataResponseObject responseObject = objectMapper.readValue(responseContext, DataResponseObject.class);
            log.info("supplier10000027.validatePhotoIdentityInfo接口responseObject={}", responseObject);

            if (responseObject != null && responseObject.getBizPackage().getSuccess().equals("true")) {
                ret.setCode(Constant.SUCCESS);
                setPhotoIdentityInfoResponse(ret, returnType, responseObject.getBizPackage().getAuthResult());
                upstreamCode = responseObject.getBizPackage().getAuthResult();
            } else {
                ret.setCode(Constant.FAIL);
            }
        } catch (SocketTimeoutException ste) {
            ErrorUtils.captureException(ste);
            log.info("supplier10000027.validatePhotoIdentityInfo接口SocketTimeoutException={}", ste);
            ret.setCode(Constant.REQUEST_TIMEOUT);
        } catch (Exception ioe) {
            ErrorUtils.captureException(ioe);
            log.info("supplier10000027.validatePhotoIdentityInfo接口Exception={}", ioe);
            ret.setCode(Constant.FAIL);
        }
        //上游返回码
        request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
        return ret;
    }

    private boolean validateCompositeIdentityParams(ChannelTypeHandleResponseObject ret, String returnType,
                                                    CompositeIdentityInfoJsonResolveObject jsonResolveObject) {
        if (!validateParamNullValue(jsonResolveObject)) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
                ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
                ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
            } else {
                ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
                ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
                ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
            }
            return false;
        } else if (StringUtils.isBlank(jsonResolveObject.getName()) ||
                !PatternTools.checkResult(Constant.PATTERN_CN_NAME_REGEX, jsonResolveObject.getName())) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.NAME_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.NAME_FORMAT_ERROR);
                ret.setResultBody(Constant.NAME_FORMAT_ERROR);
            } else {
                ret.setResultCode(Constant.JK_NAME_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.JK_NAME_FORMAT_ERROR);
                ret.setResultBody(Constant.JK_NAME_FORMAT_ERROR);
            }
            return false;
        } else if (StringUtils.isBlank(jsonResolveObject.getIdCode())
                || !PatternTools.checkResult(Constant.PATTERN_SPECIAL_ID_NUMBER_REGEX, jsonResolveObject.getIdCode())) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.IDCODE_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.IDCODE_FORMAT_ERROR);
                ret.setResultBody(Constant.IDCODE_FORMAT_ERROR);
            } else {
                ret.setResultCode(Constant.JK_IDCODE_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.JK_IDCODE_FORMAT_ERROR);
                ret.setResultBody(Constant.JK_IDCODE_FORMAT_ERROR);
            }
            return false;
        } else if (StringUtils.isBlank(jsonResolveObject.getStartTime())
                || StringUtils.isBlank(jsonResolveObject.getEndTime())
                || !isValidDate(jsonResolveObject.getStartTime())
                || (!isValidDate(jsonResolveObject.getEndTime()) && !jsonResolveObject.getEndTime().equals("00000000"))) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
                ret.setResultBody(Constant.INVALID_PARAMETER);
                ret.setResultDesc(Constant.INVALID_PARAMETER);
            } else {
                ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
                ret.setResultBody(Constant.INVALID_PARAMETER);
                ret.setResultDesc(Constant.INVALID_PARAMETER);
            }
            return false;
        }
        return true;
    }

    private boolean validateIdentityInfoParams(ChannelTypeHandleResponseObject ret, String returnType,
                                                    IdentityInfoJsonResolveObject jsonResolveObject) {
        if (!validateParamNullValue(jsonResolveObject)) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
                ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
                ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
            } else {
                ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
                ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
                ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
            }
            return false;
        } else if (StringUtils.isBlank(jsonResolveObject.getName()) ||
                !PatternTools.checkResult(Constant.PATTERN_CN_NAME_REGEX, jsonResolveObject.getName())) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.NAME_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.NAME_FORMAT_ERROR);
                ret.setResultBody(Constant.NAME_FORMAT_ERROR);
            } else {
                ret.setResultCode(Constant.JK_NAME_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.JK_NAME_FORMAT_ERROR);
                ret.setResultBody(Constant.JK_NAME_FORMAT_ERROR);
            }
            return false;
        } else if (StringUtils.isBlank(jsonResolveObject.getIdCode())
                || !PatternTools.checkResult(Constant.PATTERN_SPECIAL_ID_NUMBER_REGEX, jsonResolveObject.getIdCode())) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.IDCODE_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.IDCODE_FORMAT_ERROR);
                ret.setResultBody(Constant.IDCODE_FORMAT_ERROR);
            } else {
                ret.setResultCode(Constant.JK_IDCODE_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.JK_IDCODE_FORMAT_ERROR);
                ret.setResultBody(Constant.JK_IDCODE_FORMAT_ERROR);
            }
            return false;
        }
        return true;
    }

    private boolean validatePhotoIdentityInfoParams(ChannelTypeHandleResponseObject ret, String returnType,
                                               PhotoIdentityInfoJsonResolveObject jsonResolveObject) {
        if (!validateParamNullValue(jsonResolveObject)) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
                ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
                ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
            } else {
                ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
                ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
                ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
            }
            return false;
        } else if (StringUtils.isBlank(jsonResolveObject.getName()) ||
                !PatternTools.checkResult(Constant.PATTERN_CN_NAME_REGEX, jsonResolveObject.getName())) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.NAME_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.NAME_FORMAT_ERROR);
                ret.setResultBody(Constant.NAME_FORMAT_ERROR);
            } else {
                ret.setResultCode(Constant.JK_NAME_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.JK_NAME_FORMAT_ERROR);
                ret.setResultBody(Constant.JK_NAME_FORMAT_ERROR);
            }
            return false;
        } else if (StringUtils.isBlank(jsonResolveObject.getIdCode())
                || !PatternTools.checkResult(Constant.PATTERN_SPECIAL_ID_NUMBER_REGEX, jsonResolveObject.getIdCode())) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.IDCODE_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.IDCODE_FORMAT_ERROR);
                ret.setResultBody(Constant.IDCODE_FORMAT_ERROR);
            } else {
                ret.setResultCode(Constant.JK_IDCODE_FORMAT_ERROR_CODE);
                ret.setResultDesc(Constant.JK_IDCODE_FORMAT_ERROR);
                ret.setResultBody(Constant.JK_IDCODE_FORMAT_ERROR);
            }
            return false;
        } else if (StringUtils.isBlank(jsonResolveObject.getPhoto())
                || !validatePhoto(jsonResolveObject.getPhoto())) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
                ret.setResultBody(Constant.INVALID_PARAMETER);
                ret.setResultDesc(Constant.INVALID_PARAMETER);
            } else {
                ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
                ret.setResultBody(Constant.INVALID_PARAMETER);
                ret.setResultDesc(Constant.INVALID_PARAMETER);
            }
            return false;
        }
        return true;
    }

    private String callService(String url, String requestParam, int outTime) throws IOException {
        MediaType mediaType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE);
        RequestBody requestBody = RequestBody.create(mediaType, requestParam);

        Request okRequest = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        OkHttpClient client = okHttpClient.newBuilder()
                .connectTimeout(outTime, TimeUnit.MILLISECONDS)
                .readTimeout(outTime, TimeUnit.MILLISECONDS)
                .writeTimeout(outTime, TimeUnit.MILLISECONDS)
                .build();
        Response response = client.newCall(okRequest).execute();
        String responseContext = "";
        if (response.body() != null) {
            responseContext = response.body().string();
            response.close();
        }
        return responseContext;
    }

    private DataRequestObject getRequestObject(Object params, String authMode, String businessSerialNumber, String photoData) throws NewCSSException, IOException {
        JSONObject jsonParam = JSON.parseObject(JSON.toJSONString(params));
        // 网站信息
        JSONObject wZXX = new JSONObject();

        if (jsonParam.get("businessType") != null) {
            wZXX.put("businessType", jsonParam.get("businessType"));
        } else {
            wZXX.put("businessType","");
        }

        if (jsonParam.get("dealDate") != null) {
            wZXX.put("dealDate", jsonParam.get("dealDate"));
        } else {
            wZXX.put("dealDate","");
        }

        if (jsonParam.get("venderName") != null) {
            BASE64Encoder encoder = new BASE64Encoder();
            wZXX.put("venderName", jsonParam.get("venderName"));
        } else {
            wZXX.put("venderName", "");
        }

        if (jsonParam.get("vendorIp") != null) {
            wZXX.put("vendorIp",jsonParam.get("vendorIp"));
        } else {
            wZXX.put("vendorIp","");
        }

        // 照片
        JSONObject zP = new JSONObject();
        zP.put("wLTZP", "");

        log.info("getRequestObject name = {}", jsonParam.get("xM"));
        JSONObject requestParamObject = new JSONObject();
        requestParamObject.put("sFXX", jsonParam);
        requestParamObject.put("wZXX", wZXX);
        requestParamObject.put("zP", zP);


        DataSignature ds = new DataSignature();
        DataRequestObject.BizPackageBean bizPackageBean = new DataRequestObject.BizPackageBean();
        bizPackageBean.setCustomNumber(customerNumber);
        bizPackageBean.setAppName(appName);
        bizPackageBean.setTimeStamp(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
        bizPackageBean.setBusinessSerialNumber(businessSerialNumber);
        bizPackageBean.setAuthMode(authMode);
        bizPackageBean.setAuthApplyRetainData(EncryptedReservedData.encodeEnvelopedDataForJit(JSON.toJSONString(requestParamObject)));
        if (authMode.equals(authMode42)) {
            String fileName = photoData.substring(11, 15);
            if (fileName.equals("jpeg")) {
                bizPackageBean.setPhotoData(photoData.split("data:image/jpeg;base64,")[1]);
            } else {
                bizPackageBean.setPhotoData(photoData.split("data:image/jpg;base64,")[1]);
            }
        }

        DataRequestObject requestObject = new DataRequestObject();
        requestObject.setBizPackage(bizPackageBean);
        requestObject.setSign(ds.signDataByP7DetachForJit(JSON.toJSONString(bizPackageBean)));

        return requestObject;
    }

    private boolean validateParamNullValue(Object jsonResolveObject) {
        ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
        Validator validator = vf.getValidator();
        Set<ConstraintViolation<Object>> set = validator.validate(jsonResolveObject);
        for (ConstraintViolation<Object> con : set) {
            if (StringUtils.isNotBlank(con.getMessage())) {
                return false;
            }
        }
        return true;
    }

    private static boolean isValidDate(String str) {
        // 指定日期格式，注意yyyy/MM/dd区分大小写；
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        try {
            // 设置lenient为false.
            // 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            // e.printStackTrace();
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            return false;
        }
        return true;
    }

    private void setIdentityInfoResponse(ChannelTypeHandleResponseObject ret, String returnType, String responseCode) {
        boolean isCharge = responseCode != null
                && ArrayUtils.contains(SjjhConstant.IDENTITY_CHARGE_CODE, responseCode);
        if (isCharge) {
            ret.setIsCharge(Constant.INTERFACE_QUERY_FEE);
        }
        if (Constant.CUSTOMER_RETURN_JK.equals(returnType)) {
            if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_0XXX)) {
                // 身份信息有效
                ret.setResultCode(Constant.JK_RETURN_CODE_1174);
                ret.setResultBody(Constant.RETURN_MESSAGE_114);
                ret.setResultDesc(Constant.RETURN_MESSAGE_114);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_5XXX)) {
                // 身份信息无效
                ret.setResultCode(Constant.JK_RETURN_CODE_1175);
                ret.setResultBody(Constant.RETURN_MESSAGE_115);
                ret.setResultDesc(Constant.RETURN_MESSAGE_115);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_6XXX)) {
                // 身份信息有误
                ret.setResultCode(Constant.JK_RETURN_CODE_1176);
                ret.setResultBody(Constant.RETURN_MESSAGE_116);
                ret.setResultDesc(Constant.RETURN_MESSAGE_116);
            } else {
                // 查询错误
                ret.setResultCode(Constant.JK_RETURN_CODE_OTHER_ERROR);
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
            }
        } else {
            if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_0XXX)) {
                // 身份信息有效
                ret.setResultCode(Constant.ZW_RETURN_CODE_114);
                ret.setResultBody(Constant.RETURN_MESSAGE_114);
                ret.setResultDesc(Constant.RETURN_MESSAGE_114);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_5XXX)) {
                // 身份信息无效
                ret.setResultCode(Constant.ZW_RETURN_CODE_115);
                ret.setResultBody(Constant.RETURN_MESSAGE_115);
                ret.setResultDesc(Constant.RETURN_MESSAGE_115);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_6XXX)) {
                // 身份信息有误
                ret.setResultCode(Constant.ZW_RETURN_CODE_116);
                ret.setResultBody(Constant.RETURN_MESSAGE_116);
                ret.setResultDesc(Constant.RETURN_MESSAGE_116);
            } else {
                // 查询错误
                ret.setResultCode(Constant.OTHER_ERROR_CODE);
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
            }
        }
    }

    private void setPhotoIdentityInfoResponse(ChannelTypeHandleResponseObject ret, String returnType, String responseCode) {
        boolean isCharge = responseCode != null
                && ArrayUtils.contains(SjjhConstant.PHOTO_IDENTITY_CHARGE_CODE, responseCode);
        if (isCharge) {
            ret.setIsCharge(Constant.INTERFACE_QUERY_FEE);
        }
        if (Constant.CUSTOMER_RETURN_JK.equals(returnType)) {
            if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_00XX)) {
                // 同一人
                ret.setResultCode(Constant.JK_RETURN_CODE_1143);
                ret.setResultBody(Constant.RETURN_MESSAGE_68);
                ret.setResultDesc(Constant.RETURN_MESSAGE_68);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_01XX)) {
                // 非同一人
                ret.setResultCode(Constant.JK_RETURN_CODE_1145);
                ret.setResultBody(Constant.RETURN_MESSAGE_70);
                ret.setResultDesc(Constant.RETURN_MESSAGE_70);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_02XX)) {
                // 疑似
                ret.setResultCode(Constant.JK_RETURN_CODE_1144);
                ret.setResultBody(Constant.RETURN_MESSAGE_69);
                ret.setResultDesc(Constant.RETURN_MESSAGE_69);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_5XXX)) {
                // 身份信息无效
                ret.setResultCode(Constant.JK_RETURN_CODE_1175);
                ret.setResultBody(Constant.RETURN_MESSAGE_115);
                ret.setResultDesc(Constant.RETURN_MESSAGE_115);
            } else if (responseCode != null && (responseCode.equals(SjjhConstant.RESPONSE_CODE_6XXX) || responseCode.equals(SjjhConstant.RESPONSE_CODE_0CXX))) {
                // 身份信息有误
                ret.setResultCode(Constant.JK_RETURN_CODE_1176);
                ret.setResultBody(Constant.RETURN_MESSAGE_116);
                ret.setResultDesc(Constant.RETURN_MESSAGE_116);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_0DXX)) {
                // 无人像信息
                ret.setResultCode(Constant.JK_RETURN_CODE_NO_INFO);
                ret.setResultBody(SjjhConstant.RESPONSE_MESSAGE_1);
                ret.setResultDesc(SjjhConstant.RESPONSE_MESSAGE_1);
            } else if (responseCode != null && ArrayUtils.contains(SjjhConstant.PHOTO_BELOW_STANDARD, responseCode)) {
                // 照片质量不合格
                ret.setResultCode(Constant.JK_RETURN_CODE_1177);
                ret.setResultBody(Constant.RETURN_MESSAGE_117);
                ret.setResultDesc(Constant.RETURN_MESSAGE_117);
            } else if (responseCode != null && (responseCode.equals(SjjhConstant.RESPONSE_CODE_0IXX) || responseCode.equals(SjjhConstant.RESPONSE_CODE_0HXX))) {
                // 活体检测失败
                ret.setResultCode(Constant.JK_RETURN_CODE_1178);
                ret.setResultBody(Constant.RETURN_MESSAGE_118);
                ret.setResultDesc(Constant.RETURN_MESSAGE_118);
            } else {
                // 查询错误
                ret.setResultCode(Constant.JK_RETURN_CODE_OTHER_ERROR);
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
            }
        } else {
            if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_00XX)) {
                // 同一人
                ret.setResultCode(Constant.ZW_RETURN_CODE_68);
                ret.setResultBody(Constant.RETURN_MESSAGE_68);
                ret.setResultDesc(Constant.RETURN_MESSAGE_68);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_01XX)) {
                // 非同一人
                ret.setResultCode(Constant.ZW_RETURN_CODE_70);
                ret.setResultBody(Constant.RETURN_MESSAGE_70);
                ret.setResultDesc(Constant.RETURN_MESSAGE_70);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_02XX)) {
                // 疑似
                ret.setResultCode(Constant.ZW_RETURN_CODE_69);
                ret.setResultBody(Constant.RETURN_MESSAGE_69);
                ret.setResultDesc(Constant.RETURN_MESSAGE_69);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_5XXX)) {
                // 身份信息无效
                ret.setResultCode(Constant.ZW_RETURN_CODE_115);
                ret.setResultBody(Constant.RETURN_MESSAGE_115);
                ret.setResultDesc(Constant.RETURN_MESSAGE_115);
            } else if (responseCode != null && (responseCode.equals(SjjhConstant.RESPONSE_CODE_6XXX) || responseCode.equals(SjjhConstant.RESPONSE_CODE_0CXX))) {
                // 身份信息有误
                ret.setResultCode(Constant.ZW_RETURN_CODE_116);
                ret.setResultBody(Constant.RETURN_MESSAGE_116);
                ret.setResultDesc(Constant.RETURN_MESSAGE_116);
            } else if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_0DXX)) {
                // 无人像信息
                ret.setResultCode(Constant.UN_FIND_NUM_CODE);
                ret.setResultBody(SjjhConstant.RESPONSE_MESSAGE_1);
                ret.setResultDesc(SjjhConstant.RESPONSE_MESSAGE_1);
            } else if (responseCode != null && ArrayUtils.contains(SjjhConstant.PHOTO_BELOW_STANDARD, responseCode)) {
                // 照片质量不合格
                ret.setResultCode(Constant.ZW_RETURN_CODE_117);
                ret.setResultBody(Constant.RETURN_MESSAGE_117);
                ret.setResultDesc(Constant.RETURN_MESSAGE_117);
            } else if (responseCode != null && (responseCode.equals(SjjhConstant.RESPONSE_CODE_0IXX) || responseCode.equals(SjjhConstant.RESPONSE_CODE_0HXX))) {
                // 活体检测失败
                ret.setResultCode(Constant.ZW_RETURN_CODE_118);
                ret.setResultBody(Constant.RETURN_MESSAGE_118);
                ret.setResultDesc(Constant.RETURN_MESSAGE_118);
            } else {
                // 查询错误
                ret.setResultCode(Constant.OTHER_ERROR_CODE);
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
            }
        }
    }

    private boolean validatePhoto(String photo) {
        // 判断图片格式
        String fileName = photo.substring(11, 15);
        if (!fileName.equals("jpeg") && !fileName.equals("jpg;")) {
            return false;
        }
        // 判断图片大小
        String str = photo.substring(22); // 1.需要计算文件流大小，首先把头部的data:image/png;base64,（注意有逗号）去掉。
        Integer equalIndex = str.indexOf("=");//2.找到等号，把等号也去掉
        if (str.indexOf("=") > 0) {
            str = str.substring(0, equalIndex);
        }
        Integer strLength = str.length();//3.原来的字符流大小，单位为字节
        Integer size = strLength - (strLength / 8) * 2;//4.计算后得到的文件流大小，单位为字节
        Double fileSize = size/1024.0;

        if (fileSize < 5 || fileSize > 40) {
            return false;
        }
        return true;
    }

    @Override
    public ChannelTypeHandleResponseObject validateIdentityInfoCommon(HttpServletRequest request, String customBody, int outTime, String decodeType) {
        ChannelTypeHandleResponseObject ret = new ChannelTypeHandleResponseObject();
        ret.setIsCharge(Constant.INTERFACE_QUERY_NO_FEE);
        String upstreamCode = Constant.LOG_UPSTREAM_DEFAULT_RESPONSE_CODE;
        String returnType = request.getHeader(Constant.CUSTOMER_RETURN_TYPE_PARA);

        if (StringUtils.isBlank(returnType)) {
            returnType = Constant.CUSTOMER_RETURN_ZW;
        }
        if (outTime <= 0) {
            outTime = Constant.HTTPCLIENT_CONNECTTIMEOUT;
        }

        log.info("validateIdentityInfoCommon---customBody={},outTime={}", customBody, outTime);
        if (!decodeType.equals(SjjhConstant.DECODE_TYPE_COMMON)) {
            customBody = decodeParams(ret, returnType, customBody, decodeType);
            if (StringUtils.isBlank(customBody)) {
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                return ret;
            }
        }
        try {
            IdentityInfoJsonResolveObject jsonResolveObject = objectMapper.readValue(customBody,
                    IdentityInfoJsonResolveObject.class);
            // 参数校验
            if (!validateIdentityInfoParams(ret, returnType, jsonResolveObject)) {
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                return ret;
            }

            // 申请
            ApplyResponseObject apply = dataSignature(authMode40, outTime);
            if (apply == null || !apply.getBizPackage().getSuccess().equals("true")) {
                // 申请失败，返回查询错误
                if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                    ret.setResultCode(Constant.OTHER_ERROR_CODE);
                } else {
                    ret.setResultCode(Constant.JK_RETURN_CODE_OTHER_ERROR);
                }
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
                ret.setCode(Constant.SUCCESS);
                request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
                log.info("validateIdentityInfoCommon---apply失败");
                return ret;
            }

            // 设置请求参数
            DataRequestObject requestObject = getRequestObject(jsonResolveObject, authMode40, apply.getBizPackage().getBusinessSerialNumber(), "");
            log.info("supplier10000027.validateIdentityInfoCommon接口requestObject={}", requestObject);
            // 发起业务请求
            String responseContext = callService(requestUrl, JSONObject.toJSONString(requestObject), outTime);
            log.info("请求上游");
            log.info("supplier10000027.validateIdentityInfoCommon接口responseContext={}", responseContext);
            DataResponseObject responseObject = objectMapper.readValue(responseContext, DataResponseObject.class);
            log.info("supplier10000027.validateIdentityInfoCommon接口responseObject={}", responseObject);

            if (responseObject != null && responseObject.getBizPackage().getSuccess().equals("true")) {
                ret.setCode(Constant.SUCCESS);
                setIdentityInfoResponseCommonVersion(ret, returnType, responseObject.getBizPackage().getAuthResult());
                upstreamCode = responseObject.getBizPackage().getAuthResult();
            } else {
                ret.setCode(Constant.FAIL);
            }
        } catch (SocketTimeoutException ste) {
            ErrorUtils.captureException(ste);
            log.info("supplier10000027.validateIdentityInfoCommon接口SocketTimeoutException={}", ste);
            ret.setCode(Constant.REQUEST_TIMEOUT);
        } catch (Exception ioe) {
            ErrorUtils.captureException(ioe);
            log.info("supplier10000027.validateIdentityInfoCommon接口Exception={}", ioe);
            ret.setCode(Constant.FAIL);
        }
        //上游返回码
        request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
        return ret;
    }

    private void setIdentityInfoResponseCommonVersion(ChannelTypeHandleResponseObject ret, String returnType, String responseCode) {
        boolean isCharge = responseCode != null
                && ArrayUtils.contains(SjjhConstant.IDENTITY_COMMON_CHARGE_CODE, responseCode);
        if (isCharge) {
            ret.setIsCharge(Constant.INTERFACE_QUERY_FEE);
        }
        if (Constant.CUSTOMER_RETURN_JK.equals(returnType)) {
            if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_0XXX)) {
                // 身份信息有效
                ret.setResultCode(Constant.JK_RETURN_CODE_MATCH);
                ret.setResultBody(Constant.MATCH);
                ret.setResultDesc(Constant.MATCH);
            } else if (responseCode != null
                    && (responseCode.equals(SjjhConstant.RESPONSE_CODE_5XXX)
                    || responseCode.equals(SjjhConstant.RESPONSE_CODE_6XXX))) {
                // 身份信息无效
                ret.setResultCode(Constant.JK_RETURN_CODE_NO_MATCH);
                ret.setResultBody(Constant.UN_MATCH);
                ret.setResultDesc(Constant.UN_MATCH);
            } else {
                // 查询错误
                ret.setResultCode(Constant.JK_RETURN_CODE_OTHER_ERROR);
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
            }
        } else {
            if (responseCode != null && responseCode.equals(SjjhConstant.RESPONSE_CODE_0XXX)) {
                // 身份信息有效
                ret.setResultCode(Constant.MATCH_CODE);
                ret.setResultBody(Constant.MATCH);
                ret.setResultDesc(Constant.MATCH);
            } else if (responseCode != null
                    && (responseCode.equals(SjjhConstant.RESPONSE_CODE_5XXX)
                    || responseCode.equals(SjjhConstant.RESPONSE_CODE_6XXX))) {
                // 身份信息无效
                ret.setResultCode(Constant.UN_MATCH_CODE);
                ret.setResultBody(Constant.UN_MATCH);
                ret.setResultDesc(Constant.UN_MATCH);
            } else {
                // 查询错误
                ret.setResultCode(Constant.OTHER_ERROR_CODE);
                ret.setResultBody(Constant.OTHER_ERROR);
                ret.setResultDesc(Constant.OTHER_ERROR);
            }
        }
    }

    private String decodeParams(ChannelTypeHandleResponseObject ret, String returnType, String customBody, String decodeType) {
        JSONObject requestParamObject = JSONObject.parseObject(customBody);
        if (requestParamObject.get("params") == null) {
            if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
                ret.setResultBody(Constant.INVALID_PARAMETER);
                ret.setResultDesc(Constant.INVALID_PARAMETER);
            } else {
                ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
                ret.setResultBody(Constant.INVALID_PARAMETER);
                ret.setResultDesc(Constant.INVALID_PARAMETER);
            }
            return "";
        }
        if (decodeType.equals(SjjhConstant.DECODE_TYPE_WEIZHONG)) {
            customBody = DESedeUtil.decryptMode(requestParamObject.getString("params"), decryptKey);
            if (StringUtils.isBlank(customBody)) {
                if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
                    ret.setResultCode(Constant.ZW_RETURN_CODE_133);
                    ret.setResultBody(Constant.RETURN_MESSAGE_133);
                    ret.setResultDesc(Constant.RETURN_MESSAGE_133);
                } else {
                    ret.setResultCode(Constant.JK_RETURN_CODE_9931);
                    ret.setResultBody(Constant.RETURN_MESSAGE_133);
                    ret.setResultDesc(Constant.RETURN_MESSAGE_133);
                }
            }
        }
        return customBody;
    }
}
