123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- package thyyxxk.webserver.service.medicalinsurance;
- import cn.hutool.core.util.StrUtil;
- import com.alibaba.fastjson.JSONObject;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.codec.binary.Base64;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.http.HttpEntity;
- import org.springframework.http.HttpHeaders;
- import org.springframework.stereotype.Service;
- import org.springframework.web.client.RestTemplate;
- import thyyxxk.webserver.config.envionment.MedinsurConfig;
- import thyyxxk.webserver.config.exception.BizException;
- import thyyxxk.webserver.constants.sidicts.SiFunction;
- import thyyxxk.webserver.dao.his.medicalinsurance.SiZyDao;
- import thyyxxk.webserver.utils.DateUtil;
- import thyyxxk.webserver.utils.StringUtil;
- import thyyxxk.webserver.utils.TokenUtil;
- import javax.crypto.Mac;
- import javax.crypto.spec.SecretKeySpec;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * @description: 医保交易执行
- * @author: DingJie
- * @create: 2021-05-28 15:57:26
- **/
- @Slf4j
- @Service
- public class ExecService {
- private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
- private static final String RESULT_CODE = "infcode";
- private static final String OUTPUT = "output";
- private static int serial = 1000;
- private static final int MIN_VAL = 1000;
- private static final int MAX_VAL = 9999;
- private volatile String signNo;
- private final SiZyDao dao;
- private final RestTemplate template;
- private final MedinsurConfig cfg;
- @Autowired
- public ExecService(SiZyDao dao, RestTemplate template, MedinsurConfig cfg) {
- this.dao = dao;
- this.template = template;
- this.cfg = cfg;
- }
- public synchronized String makeMsgId() {
- serial += 1;
- if (serial > MAX_VAL) {
- serial = MIN_VAL;
- }
- return cfg.getHospId() + sdf.format(new Date()) + serial;
- }
- private synchronized String getSignNo() {
- if (StringUtil.isBlank(signNo)) {
- signIn();
- }
- return signNo;
- }
- public synchronized void signIn() {
- String dbSignNo = dao.getSignInNo();
- if (StrUtil.isNotBlank(dbSignNo)) {
- signNo = dbSignNo;
- log.info("获取历史签到号成功:{}", dbSignNo);
- return;
- }
- JSONObject input = makeSignHeader(SiFunction.SIGN_IN);
- JSONObject signIn = new JSONObject();
- signIn.put("opter_no", "99999");
- signIn.put("mac", cfg.getMacAddress());
- signIn.put("ip", cfg.getIpAddress());
- input.getJSONObject("input").put("signIn", signIn);
- JSONObject result = executeTrade(input, SiFunction.SIGN_IN);
- if (null != result && result.getInteger(RESULT_CODE) == 0) {
- try {
- JSONObject output = result.getJSONObject(OUTPUT);
- signNo = output.getJSONObject("signinoutb").getString("sign_no");
- dao.updateSignNo(signNo);
- log.info("签到成功,签到号:{}", signNo);
- } catch (Exception e) {
- throw new BizException();
- }
- }
- }
- public void signOut() {
- if (StringUtil.notBlank(signNo)) {
- JSONObject input = makeSignHeader(SiFunction.SIGN_OUT);
- JSONObject signOut = new JSONObject();
- signOut.put("sign_no", signNo);
- signOut.put("opter_no", "99999");
- input.getJSONObject("input").put("signOut", signOut);
- JSONObject result = executeTrade(input, SiFunction.SIGN_OUT);
- if (null != result && result.getIntValue(RESULT_CODE) == 0) {
- log.info("医保签退成功。");
- signNo = null;
- dao.updateSignNo(signNo);
- }
- }
- }
- public String getInstitutionArea(String insureArea) {
- String hospArea = cfg.getHospArea();
- String prefix = hospArea.substring(0, 4);
- return insureArea.startsWith(prefix) ? hospArea : prefix.substring(0, 2) + "9900";
- }
- private JSONObject makeSignHeader(SiFunction function) {
- JSONObject header = makePublicHeader("");
- header.put("infno", function.getCode());
- header.put("opter", "99999");
- header.put("opter_name", "全院");
- return header;
- }
- public JSONObject makeTradeHeader(SiFunction function) {
- String staffId = TokenUtil.getInstance().getTokenUserId();
- String staffName = dao.selectStaffName(staffId);
- JSONObject header = makePublicHeader(cfg.getHospArea());
- header.put("infno", function.getCode());
- header.put("opter", staffId);
- header.put("opter_name", staffName);
- header.replace("sign_no", getSignNo());
- return header;
- }
- public JSONObject makeTradeHeaderWithInsureArea(SiFunction function, String insureArea) {
- String staffId = TokenUtil.getInstance().getTokenUserId();
- String staffName = dao.selectStaffName(staffId);
- JSONObject header = makePublicHeader(insureArea);
- header.put("infno", function.getCode());
- header.put("opter", staffId);
- header.put("opter_name", staffName);
- header.replace("sign_no", getSignNo());
- return header;
- }
- private JSONObject makePublicHeader(String insureArea) {
- if (null == insureArea) {
- insureArea = "";
- }
- JSONObject header = new JSONObject();
- JSONObject input = new JSONObject();
- header.put("msgid", makeMsgId());
- header.put("mdtrtarea_admvs", getInstitutionArea(insureArea));
- header.put("insuplc_admdvs", insureArea);
- header.put("recer_sys_code", "医院");
- header.put("dev_no", "");
- header.put("dev_safe_info", "");
- header.put("cainfo", "");
- header.put("signtype", "");
- header.put("infver", cfg.getApiVersion());
- header.put("opter_type", "1");
- header.put("inf_time", DateUtil.now());
- header.put("fixmedins_code", cfg.getHospId());
- header.put("fixmedins_name", cfg.getHospName());
- header.put("sign_no", "");
- if (StrUtil.isNotBlank(cfg.getSoftDeveloper())) {
- header.put("fixmedins_soft_fcty", cfg.getSoftDeveloper());
- }
- header.put("input", input);
- return header;
- }
- public Map<String, String> getSiHeaderMap(SiFunction function) {
- Map<String, String> headers = new HashMap<>();
- String timestamp = String.valueOf(System.currentTimeMillis());
- String signature = getSignature(timestamp, function.getCode());
- // 医保原始地址添加header
- // headers.put("_api_access_key", apiAccessKey);
- // headers.put("_api_secreKey", apiSecretKey);
- // headers.put("_api_name", function.getCode());
- // headers.put("_api_version", API_VERSION);
- // headers.put("_api_timestamp", timestamp);
- // headers.put("_api_signature", signature);
- // webhis.thyy.cn代理地址添加header
- headers.put("apiAccessKey", cfg.getAccessKey());
- headers.put("apiSecreKey", cfg.getSecretKey());
- headers.put("apiName", StrUtil.isBlank(cfg.getApiName()) ? function.getCode() : cfg.getApiName());
- headers.put("apiVersion", cfg.getApiVersion());
- headers.put("apiTimestamp", timestamp);
- headers.put("apiSignature", signature);
- return headers;
- }
- public HttpHeaders getHttpHeaders(SiFunction function) {
- String timestamp = String.valueOf(System.currentTimeMillis());
- String signature = getSignature(timestamp, function.getCode());
- HttpHeaders headers = new HttpHeaders();
- headers.add("apiAccessKey", cfg.getAccessKey());
- headers.add("apiSecreKey", cfg.getSecretKey());
- headers.add("apiName", StrUtil.isBlank(cfg.getApiName()) ? function.getCode() : cfg.getApiName());
- headers.add("apiVersion", cfg.getApiVersion());
- headers.add("apiTimestamp", timestamp);
- headers.add("apiSignature", signature);
- return headers;
- }
- public String getSignature(String timestamp, String function) {
- String source =
- "_api_access_key=" + cfg.getAccessKey() +
- "&_api_name=" + function +
- "&_api_timestamp=" + timestamp +
- "&_api_version=" + cfg.getApiVersion();
- return hmacSha1(source);
- }
- private String hmacSha1(String src) {
- byte[] result = null;
- try {
- SecretKeySpec signInKey = new SecretKeySpec(cfg.getSecretKey().getBytes(), "HmacSHA1");
- Mac mac = Mac.getInstance("HmacSHA1");
- mac.init(signInKey);
- byte[] rawHmac = mac.doFinal(src.getBytes());
- result = Base64.encodeBase64(rawHmac);
- } catch (Exception e) {
- log.error("HmacSHA1加密出错", e);
- }
- return null == result ? null : new String(result);
- }
- public JSONObject executeTrade(JSONObject input, SiFunction function) {
- try {
- log.info("医保接口调用:【接口号:" + function.getCode() +
- ",接口名:" + function.getName() +
- ",操作员:" + input.getString("opter_name"));
- String result = template.postForObject(cfg.getApiUrl(),
- new HttpEntity<>(input, getHttpHeaders(function)), String.class);
- log.info("医保接口调用:返回:" + result);
- return JSONObject.parseObject(result);
- } catch (Exception e) {
- log.error("医保网络出错", e);
- JSONObject object = new JSONObject();
- object.put("infcode", -1);
- if (e.getMessage().contains("Connection timed out")) {
- object.put("err_msg", "医保中心网络故障,连接超时。");
- } else {
- object.put("err_msg", e.getMessage());
- }
- return object;
- }
- }
- /**
- * 工伤接口URL
- */
- // 模拟接口地址(当前使用)
- private static final String WORK_INJURY_API_URL = "http://130.150.161.72:9206/thyy/api/public/injury/workinjury";
- // 真实接口地址(注释掉,需要时手动切换)
- // private static final String WORK_INJURY_API_URL = "http://localhost:8321/api/entry/workinjury";
- /**
- * 执行工伤接口调用(工伤接口使用不同的请求头格式)
- */
- public JSONObject executeWorkInjuryTrade(JSONObject input) {
- HttpHeaders headers = new HttpHeaders();
- headers.add("Content-Type", "application/json");
- // 工伤接口可能不需要医保接口的认证头,直接使用简单的JSON头
- return template.postForObject(WORK_INJURY_API_URL,
- new HttpEntity<>(input, headers), JSONObject.class);
- }
- }
|