All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.founder.fsi.DataHandler Maven / Gradle / Ivy

package com.founder.fsi;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.founder.core.exception.BizException;
import com.founder.core.log.MyLog;
import com.founder.fsi.exception.FuncRetCode;
import com.founder.fsi.exception.ServerException;
import com.founder.fsi.utils.HttpUtils;
import com.founder.fsi.utils.RSAEncodeUtil;
import com.founder.fsi.utils.SHACoder;
import com.founder.fsi.utils.UniqueUtil;
import com.founder.sdk.model.catalogquery.QueryHilistResponse;
import com.founder.sdk.model.catalogquery.QueryHilistResponseOutput;
import com.founder.sdk.model.fileupload.DownloadRequest;
import com.founder.sdk.model.fileupload.DownloadResponseOutputData;
import com.founder.sdk.model.hsecfc.LocalQrCodeQueryRequestInput;
import com.founder.sdk.model.hsecfc.LocalQrCodeQueryResponse;
import com.founder.sdk.model.hsecfc.LocalQrCodeQueryResponseData;
import com.founder.sdk.model.hsecfc.LocalQrCodeQueryResponseOutput;
import com.founder.sdk.vopackage.VoFsiRequest;
import com.founder.sdk.vopackage.VoFsiResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import java.io.*;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class DataHandler {

    private static final MyLog _log = MyLog.getLog(DataHandler.class);

    private static Map serverMap = new HashMap();

    private String fsi_baseurl;

    private String fsi_passid;

    private String fsi_token;

    private String fsi_public_key;

    private String catalog_path = "\\opt\\";//医保目录下载文件路径

    private int connectTimeout = 10;

    private int readTimeout = 60;

    private String oss_type = "local";

    private DataHandler(String fsi_baseurl, String fsi_passid, String fsi_token, String fsi_public_key) {
        this.fsi_baseurl = fsi_baseurl;
        this.fsi_passid = fsi_passid;
        this.fsi_token = fsi_token;
        this.fsi_public_key = fsi_public_key;
    }

    private DataHandler(String fsi_baseurl, String fsi_passid, String fsi_token, String fsi_public_key, String catalog_path) {
        this.fsi_baseurl = fsi_baseurl;
        this.fsi_passid = fsi_passid;
        this.fsi_token = fsi_token;
        this.fsi_public_key = fsi_public_key;
        this.catalog_path = catalog_path;
    }

    private DataHandler(String fsi_baseurl, String fsi_passid, String fsi_token, String fsi_public_key, String catalog_path, int connectTimeout, int readTimeout) {
        this.fsi_baseurl = fsi_baseurl;
        this.fsi_passid = fsi_passid;
        this.fsi_token = fsi_token;
        this.fsi_public_key = fsi_public_key;
        this.catalog_path = catalog_path;
        this.connectTimeout = connectTimeout;
        this.readTimeout = readTimeout;
    }

    private DataHandler(String fsi_baseurl, String fsi_passid, String fsi_token, String fsi_public_key, String catalog_path, int connectTimeout, int readTimeout, String oss_type) {
        this.fsi_baseurl = fsi_baseurl;
        this.fsi_passid = fsi_passid;
        this.fsi_token = fsi_token;
        this.fsi_public_key = fsi_public_key;
        this.catalog_path = catalog_path;
        this.connectTimeout = connectTimeout;
        this.readTimeout = readTimeout;
        this.oss_type = oss_type;
    }

    @Deprecated
    public static DataHandler newInstance(String fsi_baseurl, String fsi_passid, String fsi_token, String fsi_public_key) {
        String secret = fsi_baseurl + "@" + fsi_passid + "@" + fsi_token;
        DataHandler INSTANCE = serverMap.get(secret);
        if (INSTANCE == null) {
            Class c = DataHandler.class;
            synchronized(c) {
                INSTANCE = serverMap.get(secret);
                if (INSTANCE == null) {
                    INSTANCE = new DataHandler(fsi_baseurl, fsi_passid, fsi_token, fsi_public_key);
                    serverMap.put(secret, INSTANCE);
                }
            }
        }
        return INSTANCE;
    }

    public static DataHandler newInstance(String fsi_baseurl, String fsi_passid, String fsi_token, String fsi_public_key, String catalog_path) {
        String secret = fsi_baseurl + "@" + fsi_passid + "@" + fsi_token + "@" + catalog_path;
        DataHandler INSTANCE = serverMap.get(secret);
        if (INSTANCE == null) {
            Class c = DataHandler.class;
            synchronized(c) {
                INSTANCE = serverMap.get(secret);
                if (INSTANCE == null) {
                    INSTANCE = new DataHandler(fsi_baseurl, fsi_passid, fsi_token, fsi_public_key, catalog_path);
                    serverMap.put(secret, INSTANCE);
                }
            }
        }
        return INSTANCE;
    }

    public static DataHandler newInstance(String fsi_baseurl, String fsi_passid, String fsi_token, String fsi_public_key, String catalog_path, int connectTimeout, int readTimeout) {
        String secret = fsi_baseurl + "@" + fsi_passid + "@" + fsi_token + "@" + catalog_path + "@" + connectTimeout + "@" + readTimeout;
        DataHandler INSTANCE = serverMap.get(secret);
        if (INSTANCE == null) {
            Class c = DataHandler.class;
            synchronized(c) {
                INSTANCE = serverMap.get(secret);
                if (INSTANCE == null) {
                    INSTANCE = new DataHandler(fsi_baseurl, fsi_passid, fsi_token, fsi_public_key, catalog_path, connectTimeout, readTimeout);
                    serverMap.put(secret, INSTANCE);
                }
            }
        }
        return INSTANCE;
    }

    public static DataHandler newInstance(String fsi_baseurl, String fsi_passid, String fsi_token, String fsi_public_key, String catalog_path, int connectTimeout, int readTimeout, String oss_type) {
        String secret = fsi_baseurl + "@" + fsi_passid + "@" + fsi_token + "@" + catalog_path + "@" + connectTimeout + "@" + readTimeout + "@" + oss_type;
        DataHandler INSTANCE = serverMap.get(secret);
        if (INSTANCE == null) {
            Class c = DataHandler.class;
            synchronized(c) {
                INSTANCE = serverMap.get(secret);
                if (INSTANCE == null) {
                    INSTANCE = new DataHandler(fsi_baseurl, fsi_passid, fsi_token, fsi_public_key, catalog_path, connectTimeout, readTimeout, oss_type);
                    serverMap.put(secret, INSTANCE);
                }
            }
        }
        return INSTANCE;
    }

    private String call(VoFsiRequest request) {
        String infno = request.getInfno();
        _log.info("打印报文交易编号>>>" + infno);
        int _connectTimeout = connectTimeout*1000;
        _log.info("打印连接超时配置(秒):" + connectTimeout);
        int _readTimeout = readTimeout*1000;
        _log.info("打印读取超时配置(秒):" + readTimeout);
        String jsonParam = JSONObject.toJSONString(request);
        _log.info("打印调用地址:" + fsi_baseurl + "\r\n最终post参数:\r\n" + jsonParam);
        if ("dzpz".equals(infno) || "localQrCodeQuery".equalsIgnoreCase(infno)) {
            LocalQrCodeQueryRequestInput input = JSON.parseObject(JSON.toJSONString(request.getInput()),LocalQrCodeQueryRequestInput.class);
            jsonParam = JSON.toJSONString(input.getData());
            _log.warn("电子凭证特殊处理参数:" + jsonParam);
        }
        long startTime = System.currentTimeMillis();
        _log.warn("使用HttpURLConnection方式发送请求数据包,连接超时配置"+connectTimeout+"秒,读取超时配置"+readTimeout+"秒.");
        byte[] buffer = HttpUtils.post(fsi_baseurl, jsonParam, _connectTimeout, _readTimeout, buildHeaders(), "9102".equals(infno));
        if (buffer == null) {
            _log.error("返回了null的buffer");
            throw new ServerException(FuncRetCode.ERROR_CODE_NET_ERROR);
        }
        String result = getDataOrFile(infno,jsonParam,buffer);
        JSONObject object = JSONObject.parseObject(result);
        if (object.containsKey("code") && StringUtils.isNotBlank(object.getString("code"))) {
            if (object.getInteger("code") != 0) {
                if (object.containsKey("data")) {
                    throw new RuntimeException(object.getString("data"));
                }
                if (object.containsKey("message")) {
                    throw new RuntimeException(object.getString("message"));
                }
                throw new RuntimeException(result);
            }
        }
        long endTime = System.currentTimeMillis();
        if ("9102".equals(infno)) {
            VoFsiResponse fsiResponse = JSON.parseObject(result, VoFsiResponse.class);
            Object o = fsiResponse.getOutput();
            DownloadResponseOutputData outputData = new DownloadResponseOutputData();
            if (o instanceof DownloadResponseOutputData) {
                outputData = (DownloadResponseOutputData) o;
            } else {
                _log.warn("将结果转换成文件下载对象");
                outputData = JSONObject.parseObject(JSON.toJSONString(o), DownloadResponseOutputData.class);
            }
            outputData.setFilecontent(null);
            fsiResponse.setOutput(outputData);
            String _result = JSONObject.toJSONString(fsiResponse, true);
            _log.info("打印调用输出参数(文件下载日志不打印出参):\r\n" + _result + "\r\n" + ">>>调用医保耗时" + (endTime - startTime) + "毫秒。");
        } else if ("1312".equals(infno)) {
            QueryHilistResponse fsiResponse = JSON.parseObject(result, QueryHilistResponse.class);
            QueryHilistResponseOutput outputData = fsiResponse.getOutput();
            if (outputData != null) {
                _log.warn("日志太大,直接清空数据再写日志");
                outputData.setData(null);
            }
            fsiResponse.setOutput(outputData);
            String _result = JSONObject.toJSONString(fsiResponse, true);
            _log.info("打印调用输出参数(目录下载日志不打印出参):\r\n" + _result + "\r\n" + ">>>调用医保耗时" + (endTime - startTime) + "毫秒。");
        } else if ("9204".equals(infno)) {
            JSONObject objectData = object.getJSONObject("data");
            VoFsiResponse fsiResponse = JSON.parseObject(objectData.toJSONString(), VoFsiResponse.class);
            result = JSONObject.toJSONString(fsiResponse, true);
            _log.info("转换为标准输出参数:\r\n" + result + "\r\n" + ">>>调用医保耗时" + (endTime - startTime) + "毫秒。");
        } else {
            _log.info("打印调用输出参数:\r\n" + result + "\r\n" + ">>>调用医保耗时" + (endTime - startTime) + "毫秒。");
        }
        return result;
    }

    /**
     * 非验密接口
     * @param request
     * @return
     */
    public VoFsiResponse invoke(VoFsiRequest request) {
        String result = call(request);
        VoFsiResponse response = JSONObject.parseObject(result,VoFsiResponse.class);
        return response;
    }

    /**
     * 验密接口
     * @param request
     * @param signtype
     * @param password
     * @return
     */
    public VoFsiResponse invoke(VoFsiRequest request, String signtype, String password) {
        String infno = request.getInfno();
        if ("2207".equals(infno) || "2207A".equals(infno) || "2304".equals(infno) || "2304A".equals(infno)) {
            _log.info("結算業務:" + infno + "开始結算嚴密。");
            String cainfo = sign(signtype, password);
            _log.info("密文:" + cainfo);
            request.setCainfo(cainfo);
            request.setSigntype(signtype);
            _log.info("验密配置完成");
        }
        return invoke(request);
    }

    /**
     * 构造请求头
     * @return
     */
    private HttpHeaders buildHeaders() {
        HttpHeaders headers = new HttpHeaders();
        String token = this.fsi_token;
        String paasid = this.fsi_passid;
        _log.info("打印paasid参数:" + paasid);
        String nonce = UniqueUtil.createUniqueId();//随机字符串
        _log.info("打印nonce参数:" + nonce);
        long timestamp = Instant.now().getEpochSecond();//当前时间戳
        _log.info("打印timestamp参数:" + timestamp);
        String signature = "";//价签结果
        try {
            signature = SHACoder.encodeSHA256(StringUtils.join(timestamp, token, nonce, timestamp).getBytes());
            _log.info("打印价签结果:" + signature);
        } catch (Exception e) {
            e.printStackTrace();
            _log.error("签名异常");
            throw new ServerException(FuncRetCode.ERROR_CODE_NET_ERROR);
        }
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("x-tif-paasid", paasid);
        headers.add("x-tif-signature", signature);
        headers.add("x-tif-timestamp", String.valueOf(timestamp));
        headers.add("x-tif-nonce", nonce);
        _log.info("获取报文消息头>>>" + JSON.toJSONString(headers));
        return headers;
    }

    /**
     * 从字节数组解析文件
     * @param jsonParam
     * @param fileBuffer
     * @return
     */
    private String getDataOrFile(String infno, String jsonParam, byte[] fileBuffer) {
        if ("9102".equals(infno)) {
            _log.info("文件数据特殊处理");
            VoFsiResponse fsiResponse = new VoFsiResponse();
            try {
                DownloadRequest requestVo = JSON.parseObject(jsonParam,DownloadRequest.class);
                if (StringUtils.isNotBlank(oss_type) && "local".equals(oss_type)) {
                    _log.warn("仅当oss_type=" + oss_type + "时保存本地文件!");
                    String f = requestVo.getInput().getFsDownloadIn().getFilename();
                    String fileName = catalog_path + f;
                    _log.info("文件本地保存路径:" + fileName);
                    File file = new File(fileName);
                    String path = file.getParentFile().getAbsolutePath();
                    File fileP = new File(path);
                    if (!fileP.exists()) {
                        _log.info("路径不存在,自动创建:" + path);
                        fileP.mkdirs();
                    }
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    InputStream inputStream = new ByteArrayInputStream(fileBuffer);
                    int temp;
                    while ((temp = inputStream.read()) != -1) {
                        fileOutputStream.write(temp);
                    }
                    fileOutputStream.close();
                }
                DownloadResponseOutputData outputData = new DownloadResponseOutputData();
                outputData.setFile_qury_no(requestVo.getInput().getFsDownloadIn().getFile_qury_no());
                outputData.setFilename(requestVo.getInput().getFsDownloadIn().getFilename());
                outputData.setFixmedins_code(requestVo.getInput().getFsDownloadIn().getFixmedins_code());
                outputData.setFilecontent(fileBuffer);
                fsiResponse.setCainfo(requestVo.getCainfo());
                fsiResponse.setSigntype(requestVo.getSigntype());
                fsiResponse.setErr_msg("ok");
                fsiResponse.setInfcode(0);
                fsiResponse.setInf_refmsgid(requestVo.getMsgid());
                fsiResponse.setRefmsg_time(requestVo.getInf_time());
                fsiResponse.setOutput(outputData);
                _log.info("文件流");
                return JSON.toJSONString(fsiResponse);
            } catch (IOException e) {
                e.printStackTrace();
                throw new BizException("处理文件流失败:" + e.getMessage());
            }
        }
        String result = IOUtils.toString(fileBuffer,"UTF-8");
        if ("localQrCodeQuery".equals(infno) || "dzpz".equals(infno)) {
            _log.warn("电子凭证封装特殊处理");
            VoFsiResponse voFsiResponse = new VoFsiResponse();
            LocalQrCodeQueryResponse response = JSON.parseObject(result,LocalQrCodeQueryResponse.class);
            voFsiResponse.setErr_msg(response.getMessage());
            if (response.getType() != null && "success".equals(response.getType())) {
                voFsiResponse.setInfcode(0);
                LocalQrCodeQueryResponseOutput output = new LocalQrCodeQueryResponseOutput();
                LocalQrCodeQueryResponseData outputData = JSON.parseObject(JSON.toJSONString(response.getData()),LocalQrCodeQueryResponseData.class);
                output.setData(outputData);
                voFsiResponse.setOutput(output);
            } else {
                voFsiResponse.setInfcode(-1);
            }
            voFsiResponse.setRespond_time(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS"));
            return JSON.toJSONString(voFsiResponse);
        } else {
            _log.info("字符串直接返回");
            return result;
        }
    }

    /**
     * 验密算法
     * @param signtype
     * @param password
     * @return
     */
    private String sign(String signtype, String password) {
        String cainfo = "";
        String text = password + this.fsi_token;
        _log.debug("待加密串串:" + text);
        try {
            _log.info("驗密方式:" + signtype);
            if ("RFID".equals(signtype)){
                _log.info("开始验证RFID电子凭证密码");
                cainfo = RSAEncodeUtil.encrypt(text, RSAEncodeUtil.getPublicKey(this.fsi_public_key));
            } else if ("PRCSSC".equals(signtype)){
                _log.info("开始验证PRCSSC医保卡密码");
                cainfo = RSAEncodeUtil.encrypt(text, RSAEncodeUtil.getPublicKey(this.fsi_public_key));
            } else if ("MOCK".equals(signtype)){
                _log.warn("MOCK不验密(只在测试环境生效)");
                cainfo = "MOCK";
            } else if ("FACE_SETL".equals(signtype)) {
                _log.warn("刷脸支付免密");
                cainfo = "uncheck";
            } else {
                _log.error("無效的驗密方式:" + signtype);
                cainfo = "無效的驗密方式:" + signtype;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return cainfo;
    }

    public String getFsi_baseurl() {
        return fsi_baseurl;
    }

    public void setFsi_baseurl(String fsi_baseurl) {
        this.fsi_baseurl = fsi_baseurl;
    }

    public String getFsi_passid() {
        return fsi_passid;
    }

    public void setFsi_passid(String fsi_passid) {
        this.fsi_passid = fsi_passid;
    }

    public String getFsi_token() {
        return fsi_token;
    }

    public void setFsi_token(String fsi_token) {
        this.fsi_token = fsi_token;
    }

    public String getFsi_public_key() {
        return fsi_public_key;
    }

    public void setFsi_public_key(String fsi_public_key) {
        this.fsi_public_key = fsi_public_key;
    }

    public String getCatalog_path() {
        return catalog_path;
    }

    public void setCatalog_path(String catalog_path) {
        this.catalog_path = catalog_path;
    }

    public int getConnectTimeout() {
        return connectTimeout;
    }

    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    public int getReadTimeout() {
        return readTimeout;
    }

    public void setReadTimeout(int readTimeout) {
        this.readTimeout = readTimeout;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy