release
wangzhikun 2 years ago
commit 505212de0e
  1. 2
      dxhy-common/src/main/java/com/dxhy/common/enums/SNFplxEnum.java
  2. 55
      dxhy-erp/src/main/java/com/dxhy/erp/controller/SDNYMainProcessController.java
  3. 1
      dxhy-erp/src/main/java/com/dxhy/erp/dao/OrgUserInfoDao.java
  4. 18
      dxhy-erp/src/main/java/com/dxhy/erp/entity/kfpt/ApiCheckInvoiceSingleRequest.java
  5. 24
      dxhy-erp/src/main/java/com/dxhy/erp/entity/kfpt/ApiRequest.java
  6. 22
      dxhy-erp/src/main/java/com/dxhy/erp/entity/kfpt/ApiResponse.java
  7. 14
      dxhy-erp/src/main/java/com/dxhy/erp/entity/kfpt/ApiReturnStateInfo.java
  8. 14
      dxhy-erp/src/main/java/com/dxhy/erp/entity/kfpt/TokenRequest.java
  9. 18
      dxhy-erp/src/main/java/com/dxhy/erp/entity/kfpt/TokenResponse.java
  10. 41
      dxhy-erp/src/main/java/com/dxhy/erp/service/SNPushCheckRecordService.java
  11. 86
      dxhy-erp/src/main/java/com/dxhy/erp/utils/ApiUtils.java
  12. 271
      dxhy-erp/src/main/java/com/dxhy/erp/utils/Base64.java
  13. 228
      dxhy-erp/src/main/java/com/dxhy/erp/utils/HttpClientUtils.java
  14. 33
      dxhy-erp/src/main/java/com/dxhy/erp/utils/IcpUtils.java

@ -140,7 +140,7 @@ public enum SNFplxEnum {
return null;
}
public String getFplxDm(String snFplxDm) {
public static String getFplxDm(String snFplxDm) {
for (SNFplxEnum fplx : SNFplxEnum.values()) {
if (fplx.getSnFplxDm() == snFplxDm) {
return fplx.fplxDm;

@ -1,13 +1,16 @@
package com.dxhy.erp.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.common.aspect.SysLog;
import com.dxhy.common.constant.CommonConstants;
import com.dxhy.common.controller.AbstractController;
import com.dxhy.common.enums.FplxEnum;
import com.dxhy.common.enums.SNFplxEnum;
import com.dxhy.common.jwt.IJWTInfo;
import com.dxhy.common.util.InvoiceUtil;
import com.dxhy.common.util.UserInfoUtil;
import com.dxhy.common.utils.BaseContextHandler;
import com.dxhy.common.utils.R;
import com.dxhy.erp.entity.sdny.*;
import com.dxhy.erp.service.InvoiceQueryService;
@ -21,6 +24,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.security.auth.message.config.AuthConfig;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
@ -50,21 +54,22 @@ public class SDNYMainProcessController extends AbstractController {
@ResponseBody
@SysLog("发票查验")
public ResponseEntity<?> singleInvoiceCheck(@RequestBody Map<String, String> pramsMap) {
// 入参统一在入口处理
String userid = getLoginName();
pramsMap.put("userid", userid);
String dbName = getUserInfo().getDbName();
pramsMap.put("dbName", dbName);
pramsMap.put("saveHistory","Y");
pramsMap.put("company", getUserInfo().getCompany());
List<String> gfshAll = UserInfoUtil.getGfshAll(getUserInfo().getOrg());
if (gfshAll.size() > 0) {
pramsMap.put("taxNo", gfshAll.get(0));
}
pramsMap.put("purchaserTaxNo", pramsMap.get("purchaserTaxNo"));
// // 入参统一在入口处理
// String userid = getLoginName();
// pramsMap.put("userid", userid);
// String dbName = getUserInfo().getDbName();
// pramsMap.put("dbName", dbName);
// pramsMap.put("saveHistory","Y");
//
// pramsMap.put("company", getUserInfo().getCompany());
//
// List<String> gfshAll = UserInfoUtil.getGfshAll(getUserInfo().getOrg());
// if (gfshAll.size() > 0) {
// pramsMap.put("taxNo", gfshAll.get(0));
//
// }
// pramsMap.put("purchaserTaxNo", pramsMap.get("purchaserTaxNo"));
InvoiceUtil iu = new InvoiceUtil(pramsMap.get("invoiceCode"));
@ -74,7 +79,7 @@ public class SDNYMainProcessController extends AbstractController {
return ResponseEntity.ok(R.error("发票代码不能为空!"));
}
pramsMap.put("invoiceType", iu.getFplxdm());
// pramsMap.put("invoiceType", iu.getFplxdm());
if (pramsMap.get("invoiceNumber").isEmpty()) {
@ -84,7 +89,7 @@ public class SDNYMainProcessController extends AbstractController {
if (!pramsMap.get("billingDate").isEmpty()) {
iu.setKprq(pramsMap.get("billingDate"));
pramsMap.put("invoiceDate", pramsMap.get("invoiceNumber"));
pramsMap.put("invoiceDate", pramsMap.get("billingDate"));
if (!iu.kprqValid(null)) {
pramsMap.put("invoiceDate", "开票日期格式错误!");
}
@ -92,12 +97,12 @@ public class SDNYMainProcessController extends AbstractController {
return ResponseEntity.ok(R.error("开票日期不能为空!"));
}
if (FplxEnum.ZP.getFplxDm().equals(pramsMap.get("invoiceType"))
|| FplxEnum.JDC.getFplxDm().equals(pramsMap.get("invoiceType"))
|| FplxEnum.DZZP.getFplxDm().equals(pramsMap.get("invoiceType"))
|| FplxEnum.ESC.getFplxDm().equals(pramsMap.get("invoiceType"))
|| FplxEnum.QDZZP.getFplxDm().equals(pramsMap.get("invoiceType"))
|| FplxEnum.QDPP.getFplxDm().equals(pramsMap.get("invoiceType"))) {
if (SNFplxEnum.ZP.getSnFplxDm().equals(pramsMap.get("invoiceType"))
|| SNFplxEnum.JDC.getSnFplxDm().equals(pramsMap.get("invoiceType"))
|| SNFplxEnum.DZZP.getSnFplxDm().equals(pramsMap.get("invoiceType"))
|| SNFplxEnum.ESC.getSnFplxDm().equals(pramsMap.get("invoiceType"))
|| SNFplxEnum.QDZP.getSnFplxDm().equals(pramsMap.get("invoiceType"))
|| SNFplxEnum.QDPP.getSnFplxDm().equals(pramsMap.get("invoiceType"))) {
if (pramsMap.get("totalAmount").isEmpty()) {
return ResponseEntity.ok(R.error("金额不能为空!"));
}
@ -108,7 +113,7 @@ public class SDNYMainProcessController extends AbstractController {
}
String uuid = (StringUtils.isBlank(pramsMap.get("invoiceCode"))?"":pramsMap.get("invoiceCode"))+ pramsMap.get("invoiceNo");
String notes = invoiceQueryService.checkingInvoiceInfo(dbName, uuid, getUserInfo());
String notes = invoiceQueryService.checkingInvoiceInfo("business", uuid, getUserInfo());
if (notes != null) {
return ResponseEntity.ok(R.error(notes));
}
@ -124,11 +129,13 @@ public class SDNYMainProcessController extends AbstractController {
|| SNFplxEnum.QDZP.getSnFplxDm().equals(pramsMap.get("invoiceType"))
|| SNFplxEnum.QDPP.getSnFplxDm().equals(pramsMap.get("invoiceType"))
) {
pramsMap.put("invoiceType",fplxdm);
//查验发票数据
checkInvoiceResult = snPushCheckRecordService.checkInvoice(pramsMap, getUserInfo());
}else{
//价税分离
// snPushCheckRecordService.valoremTaxCount();
}
return ResponseEntity.ok(R.ok().put("data", checkInvoiceResult));
}

@ -4,6 +4,7 @@ import com.dxhy.erp.entity.sdny.BxwxEnterpriseUserEntity;
import com.dxhy.erp.entity.sdny.OrgUserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;

@ -0,0 +1,18 @@
package com.dxhy.erp.entity.kfpt;
import lombok.Data;
/**
* Created by rei on 2021/8/26.
*/
@Data
public class ApiCheckInvoiceSingleRequest {
private String fpdm;
private String fphm;
private String fpje;
private String jym;
private String kprq;
private String fpzl;
}

@ -0,0 +1,24 @@
package com.dxhy.erp.entity.kfpt;
import lombok.Data;
import java.util.UUID;
/**
* Created by rei on 2021/8/26.
*/
@Data
public class ApiRequest {
private String zipCode;
private String encryptCode;
private String dataExchangeId;
private String entCode;
private String content;
public ApiRequest() {
zipCode = "0";
encryptCode = "0";
dataExchangeId = UUID.randomUUID().toString().replace("-", "");
}
}

@ -0,0 +1,22 @@
package com.dxhy.erp.entity.kfpt;
import lombok.Data;
/**
* Created by rei on 2021/8/26.
*/
@Data
public class ApiResponse {
private String zipCode;
private String encryptCode;
private String dataExchangeId;
private String entCode;
private String content;
private ApiReturnStateInfo returnStateInfo;
private String status;
private String error;
private String message;
private String timestamp;
}

@ -0,0 +1,14 @@
package com.dxhy.erp.entity.kfpt;
import lombok.Data;
/**
* Created by rei on 2021/8/26.
*/
@Data
public class ApiReturnStateInfo {
private String returnCode;
private String returnMessage;
}

@ -0,0 +1,14 @@
package com.dxhy.erp.entity.kfpt;
import lombok.Data;
/**
* Created by rei on 2021/8/26.
*/
@Data
public class TokenRequest {
private String appKey;
private String appSecret;
}

@ -0,0 +1,18 @@
package com.dxhy.erp.entity.kfpt;
import lombok.Data;
/**
* Created by rei on 2021/8/26.
*/
@Data
public class TokenResponse {
private String access_token;
private String token_type;
private String expires_in;
private String scope;
private String error;
private String error_description;
}

@ -6,6 +6,7 @@ import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.enums.SNFplxEnum;
import com.dxhy.common.util.UserInfoUtil;
import com.dxhy.common.vo.UserInfo;
import com.dxhy.erp.dao.AreaDao;
@ -41,12 +42,13 @@ public class SNPushCheckRecordService extends AbstractServiceAdapter {
@Value("${sdny.snYxUrl}")
private String snYxUrl;
@Resource
private InvoiceQueryUtil invoiceQueryUtil;
@Resource
@Autowired
private AreaDao areaDao;
@Resource
@Autowired
private OrgUserInfoDao orgUserInfoDao;
public String pushCheckResultToSAP(JSONObject result) throws Exception {
@ -67,33 +69,38 @@ public class SNPushCheckRecordService extends AbstractServiceAdapter {
// uuid = 发票代码+发票号码
String uuid = (org.apache.commons.lang.StringUtils.isBlank(pramsMap.get("invoiceCode"))?"":pramsMap.get("invoiceCode")) + pramsMap.get("invoiceNo");
DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_READ);
DynamicContextHolder.push("business" + DbConstant.BUSINESS_READ);
List<String> gfshAll = UserInfoUtil.getGfshAll(userInfo.getOrg());
// List<String> gfshAll = UserInfoUtil.getGfshAll(userInfo.getOrg());
String gfsh = "";
if (gfshAll.size() > 0) {
gfsh = gfshAll.get(0);
}
// if (gfshAll.size() > 0) {
// gfsh = gfshAll.get(0);
// }
gfsh = "91370000166120002R";
JSONObject queryInvoiceResult = invoiceQueryUtil.queryInvoice(pramsMap.get("invoiceCode"),
pramsMap.get("invoiceNo"), pramsMap.get("invoiceDate"), pramsMap.get("invoiceAmount"), pramsMap.get("checkCode"),
gfsh,"31");
pramsMap.get("invoiceNumber"), pramsMap.get("billingDate"), pramsMap.get("totalAmount"), pramsMap.get("checkCode"),
gfsh,pramsMap.get("invoiceType"));
String resultCode = queryInvoiceResult.getString("resultCode");
DynamicContextHolder.push(userInfo.getDbName() + DbConstant.BUSINESS_WRITE);
DynamicContextHolder.push("business" + DbConstant.BUSINESS_WRITE);
// 调用查验接口失败,将签收状态更新到扫描表中或者insert数据到扫描表,然后return;
if (queryInvoiceResult.containsKey("returnCode")) {
log.error("发票号码:" + pramsMap.get("invoiceNo") + "签收失败,失败原因:" + queryInvoiceResult.getString("returnMessage"));
return queryInvoiceResult;
}
if (!"0001".equals(resultCode)) {
// 接口通过但,调用返回失败
log.error("发票号码:" + pramsMap.get("invoiceNo") + "签收失败,失败原因:" + queryInvoiceResult.getString("resultTip"));
if (queryInvoiceResult.containsKey("returnCode") && !"0001".equals(resultCode)) {
log.error("发票号码:" + pramsMap.get("invoiceNo") + "查验失败,失败原因:" + queryInvoiceResult.getString("returnMessage"));
return queryInvoiceResult;
}
return queryInvoiceResult;
}
/**
* 客票价税计算
*

@ -0,0 +1,86 @@
package com.dxhy.erp.utils;
import com.alibaba.fastjson.JSONObject;
import com.dxhy.erp.entity.kfpt.ApiRequest;
import com.dxhy.erp.entity.kfpt.ApiResponse;
import com.dxhy.erp.entity.kfpt.TokenRequest;
import com.dxhy.erp.entity.kfpt.TokenResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 接口工具类
*
* @author REI
*/
@Component
@Slf4j
public class ApiUtils {
@Value("${params.api.tokenUrl}")
private String tokenUrl;
@Value("${params.api.loginUrl}")
private String loginUrl;
@Value("${params.api.connTimeout}")
private int connTimeout;
@Value("${params.api.readTimeout}")
private int readTimeout;
private String contentType = "application/json";
private String charset = "UTF-8";
private TokenResponse callToken(String url, TokenRequest tokenRequest) {
final DateTime start = DateTime.now();
String body = JSONObject.toJSONString(tokenRequest);
String result = null;
try {
result = HttpClientUtils.post(url, body, contentType, charset, connTimeout, readTimeout);
} catch (Exception e) {
log.error("<线程" + Thread.currentThread().getId() + ">调用开放平台获取token异常:", e);
} finally {
log.info("<线程{}>interface={}|param={}|result={}|responseTime={}",
Thread.currentThread().getId(), url, body, result, new Duration(start, DateTime.now()).getMillis());
}
return JSONObject.parseObject(result, TokenResponse.class);
}
public ApiResponse callApi(String url, String entCode, Object content, String accessToken, String requestId) {
final DateTime start = DateTime.now();
ApiRequest apiRequest = new ApiRequest();
apiRequest.setContent(Base64.encode(JSONObject.toJSONBytes(content)));
apiRequest.setEntCode(entCode);
apiRequest.setDataExchangeId(requestId);
String body = JSONObject.toJSONString(apiRequest);
url = url + "?access_token=" + accessToken;
String result = null;
try {
result = HttpClientUtils.post(url, body, contentType, charset, connTimeout, readTimeout);
} catch (Exception e) {
log.error("<线程" + Thread.currentThread().getId() + ">调用开放平台业务接口异常:", e);
} finally {
log.info("<线程{}>interface={}|param={}|result={}|responseTime={}",
Thread.currentThread().getId(), url, body, result, new Duration(start, DateTime.now()).getMillis());
}
ApiResponse apiResponse = JSONObject.parseObject(result, ApiResponse.class);
return apiResponse;
}
public TokenResponse getToken(String appKey, String appSecret) {
TokenRequest tokenRequest = new TokenRequest();
tokenRequest.setAppKey(appKey);
tokenRequest.setAppSecret(appSecret);
TokenResponse tokenResponse = callToken(tokenUrl, tokenRequest);
if (tokenResponse != null && StringUtils.isEmpty(tokenResponse.getError())) {
return tokenResponse;
} else {
return null;
}
}
}

@ -0,0 +1,271 @@
package com.dxhy.erp.utils;
public final class Base64 {
static private final int BASELENGTH = 128;
static private final int LOOKUPLENGTH = 64;
static private final int TWENTYFOURBITGROUP = 24;
static private final int EIGHTBIT = 8;
static private final int SIXTEENBIT = 16;
static private final int SIXBIT = 6;
static private final int FOURBYTE = 4;
static private final int SIGN = -128;
static private final char PAD = '=';
static private final boolean fDebug = false;
static final private byte [] base64Alphabet = new byte[BASELENGTH];
static final private char [] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
static {
for (int i = 0; i < BASELENGTH; ++i) {
base64Alphabet[i] = -1;
}
for (int i = 'Z'; i >= 'A'; i--) {
base64Alphabet[i] = (byte) (i-'A');
}
for (int i = 'z'; i>= 'a'; i--) {
base64Alphabet[i] = (byte) ( i-'a' + 26);
}
for (int i = '9'; i >= '0'; i--) {
base64Alphabet[i] = (byte) (i-'0' + 52);
}
base64Alphabet['+'] = 62;
base64Alphabet['/'] = 63;
for (int i = 0; i<=25; i++)
lookUpBase64Alphabet[i] = (char)('A'+i);
for (int i = 26, j = 0; i<=51; i++, j++)
lookUpBase64Alphabet[i] = (char)('a'+ j);
for (int i = 52, j = 0; i<=61; i++, j++)
lookUpBase64Alphabet[i] = (char)('0' + j);
lookUpBase64Alphabet[62] = (char)'+';
lookUpBase64Alphabet[63] = (char)'/';
}
protected static boolean isWhiteSpace(char octect) {
return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
}
protected static boolean isPad(char octect) {
return (octect == PAD);
}
protected static boolean isData(char octect) {
return (octect < BASELENGTH && base64Alphabet[octect] != -1);
}
protected static boolean isBase64(char octect) {
return (isWhiteSpace(octect) || isPad(octect) || isData(octect));
}
/**
* Encodes hex octects into Base64
*
* @param binaryData Array containing binaryData
* @return Encoded Base64 array
*/
public static String encode(byte[] binaryData) {
if (binaryData == null)
return null;
int lengthDataBits = binaryData.length*EIGHTBIT;
if (lengthDataBits == 0) {
return "";
}
int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP;
int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP;
int numberQuartet = fewerThan24bits != 0 ? numberTriplets+1 : numberTriplets;
char encodedData[] = null;
encodedData = new char[numberQuartet*4];
byte k=0, l=0, b1=0,b2=0,b3=0;
int encodedIndex = 0;
int dataIndex = 0;
if (fDebug) {
System.out.println("number of triplets = " + numberTriplets );
}
for (int i=0; i<numberTriplets; i++) {
b1 = binaryData[dataIndex++];
b2 = binaryData[dataIndex++];
b3 = binaryData[dataIndex++];
if (fDebug) {
System.out.println( "b1= " + b1 +", b2= " + b2 + ", b3= " + b3 );
}
l = (byte)(b2 & 0x0f);
k = (byte)(b1 & 0x03);
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc);
if (fDebug) {
System.out.println( "val2 = " + val2 );
System.out.println( "k4 = " + (k<<4));
System.out.println( "vak = " + (val2 | (k<<4)));
}
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
encodedData[encodedIndex++] = lookUpBase64Alphabet[ (l <<2 ) | val3 ];
encodedData[encodedIndex++] = lookUpBase64Alphabet[ b3 & 0x3f ];
}
// form integral number of 6-bit groups
if (fewerThan24bits == EIGHTBIT) {
b1 = binaryData[dataIndex];
k = (byte) ( b1 &0x03 );
if (fDebug) {
System.out.println("b1=" + b1);
System.out.println("b1<<2 = " + (b1>>2) );
}
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
encodedData[encodedIndex++] = lookUpBase64Alphabet[ k<<4 ];
encodedData[encodedIndex++] = PAD;
encodedData[encodedIndex++] = PAD;
} else if (fewerThan24bits == SIXTEENBIT) {
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex +1 ];
l = ( byte ) ( b2 &0x0f );
k = ( byte ) ( b1 &0x03 );
byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0);
byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0);
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ];
encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )];
encodedData[encodedIndex++] = lookUpBase64Alphabet[ l<<2 ];
encodedData[encodedIndex++] = PAD;
}
return new String(encodedData);
}
/**
* Decodes Base64 data into octects
*
* @param encoded string containing Base64 data
* @return Array containind decoded data.
*/
public static byte[] decode(String encoded) {
if (encoded == null)
return null;
char[] base64Data = encoded.toCharArray();
// remove white spaces
int len = removeWhiteSpace(base64Data);
if (len%FOURBYTE != 0) {
return null;//should be divisible by four
}
int numberQuadruple = (len/FOURBYTE );
if (numberQuadruple == 0)
return new byte[0];
byte decodedData[] = null;
byte b1=0,b2=0,b3=0,b4=0;
char d1=0,d2=0,d3=0,d4=0;
int i = 0;
int encodedIndex = 0;
int dataIndex = 0;
decodedData = new byte[ (numberQuadruple)*3];
for (; i<numberQuadruple-1; i++) {
if (!isData( (d1 = base64Data[dataIndex++]) )||
!isData( (d2 = base64Data[dataIndex++]) )||
!isData( (d3 = base64Data[dataIndex++]) )||
!isData( (d4 = base64Data[dataIndex++]) ))
return null;//if found "no data" just return null
b1 = base64Alphabet[d1];
b2 = base64Alphabet[d2];
b3 = base64Alphabet[d3];
b4 = base64Alphabet[d4];
decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ;
decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
}
if (!isData( (d1 = base64Data[dataIndex++]) ) ||
!isData( (d2 = base64Data[dataIndex++]) )) {
return null;//if found "no data" just return null
}
b1 = base64Alphabet[d1];
b2 = base64Alphabet[d2];
d3 = base64Data[dataIndex++];
d4 = base64Data[dataIndex++];
if (!isData( (d3 ) ) ||
!isData( (d4 ) )) {//Check if they are PAD characters
if (isPad( d3 ) && isPad( d4)) { //Two PAD e.g. 3c[Pad][Pad]
if ((b2 & 0xf) != 0)//last 4 bits should be zero
return null;
byte[] tmp = new byte[ i*3 + 1 ];
System.arraycopy( decodedData, 0, tmp, 0, i*3 );
tmp[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
return tmp;
} else if (!isPad( d3) && isPad(d4)) { //One PAD e.g. 3cQ[Pad]
b3 = base64Alphabet[ d3 ];
if ((b3 & 0x3 ) != 0)//last 2 bits should be zero
return null;
byte[] tmp = new byte[ i*3 + 2 ];
System.arraycopy( decodedData, 0, tmp, 0, i*3 );
tmp[encodedIndex++] = (byte)( b1 <<2 | b2>>4 );
tmp[encodedIndex] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
return tmp;
} else {
return null;//an error like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
}
} else { //No PAD e.g 3cQl
b3 = base64Alphabet[ d3 ];
b4 = base64Alphabet[ d4 ];
decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ;
decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) );
decodedData[encodedIndex++] = (byte)( b3<<6 | b4 );
}
return decodedData;
}
/**
* remove WhiteSpace from MIME containing encoded Base64 data.
*
* @param data the byte array of base64 data (with WS)
* @return the new length
*/
protected static int removeWhiteSpace(char[] data) {
if (data == null)
return 0;
// count characters that's not whitespace
int newSize = 0;
int len = data.length;
for (int i = 0; i < len; i++) {
if (!isWhiteSpace(data[i]))
data[newSize++] = data[i];
}
return newSize;
}
}

@ -0,0 +1,228 @@
package com.dxhy.erp.utils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class HttpClientUtils {
public static final int connTimeout = 10000;
public static final int readTimeout = 10000;
public static final String charset = "UTF-8";
private static HttpClient client = null;
static {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(1000);
cm.setDefaultMaxPerRoute(500);
client = HttpClients.custom().setConnectionManager(cm).build();
}
public static String postParameters(String url, String parameterStr) throws ConnectTimeoutException, SocketTimeoutException, Exception {
return post(url, parameterStr, "application/json", charset, connTimeout, readTimeout);
}
public static String get(String url) throws Exception {
return get(url, charset, null, null);
}
public static String get(String url, String charset) throws Exception {
return get(url, charset, connTimeout, readTimeout);
}
/**
* 发送一个 Post 请求, 使用指定的字符集编码.
*
* @param url
* @param body RequestBody
* @param mimeType 例如 application/xml "application/x-www-form-urlencoded" a=1&b=2&c=3
* @param charset 编码
* @param connTimeout 建立链接超时时间,毫秒.
* @param readTimeout 响应超时时间,毫秒.
* @return ResponseBody, 使用指定的字符集编码.
* @throws ConnectTimeoutException 建立链接超时异常
* @throws SocketTimeoutException 响应超时
* @throws Exception
*/
public static String post(String url, String body, String mimeType, String charset, Integer connTimeout, Integer readTimeout)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
HttpClient client = null;
HttpPost post = new HttpPost(url);
String result = "";
try {
if (StringUtils.isNotBlank(body)) {
HttpEntity entity = new StringEntity(body, ContentType.create(mimeType, charset));
post.setEntity(entity);
}
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
post.setConfig(customReqConf.build());
HttpResponse res;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(post);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(post);
}
result = IOUtils.toString(res.getEntity().getContent(), charset);
} finally {
post.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* 发送一个 GET 请求
*
* @param url
* @param charset
* @param connTimeout 建立链接超时时间,毫秒.
* @param readTimeout 响应超时时间,毫秒.
* @return
* @throws ConnectTimeoutException 建立链接超时
* @throws SocketTimeoutException 响应超时
* @throws Exception
*/
public static String get(String url, String charset, Integer connTimeout, Integer readTimeout)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
HttpClient client = null;
HttpGet get = new HttpGet(url);
get.setHeader("Authorization", "pq8fTpZWeWv8");
String result = "";
try {
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
get.setConfig(customReqConf.build());
HttpResponse res = null;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(get);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(get);
}
result = IOUtils.toString(res.getEntity().getContent(), charset);
} finally {
get.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* response 里获取 charset
*
* @param ressponse
* @return
*/
@SuppressWarnings("unused")
private static String getCharsetFromResponse(HttpResponse ressponse) {
// Content-Type:text/html; charset=GBK
if (ressponse.getEntity() != null && ressponse.getEntity().getContentType() != null && ressponse.getEntity().getContentType().getValue() != null) {
String contentType = ressponse.getEntity().getContentType().getValue();
if (contentType.contains("charset=")) {
return contentType.substring(contentType.indexOf("charset=") + 8);
}
}
return null;
}
/**
* 创建 SSL连接
*
* @return
* @throws GeneralSecurityException
*/
private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl)
throws IOException {
}
@Override
public void verify(String host, X509Certificate cert)
throws SSLException {
}
@Override
public void verify(String host, String[] cns,
String[] subjectAlts) throws SSLException {
}
});
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (GeneralSecurityException e) {
throw e;
}
}
}

@ -0,0 +1,33 @@
package com.dxhy.erp.utils;
import com.dxhy.erp.entity.kfpt.ApiCheckInvoiceSingleRequest;
import com.dxhy.erp.entity.kfpt.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class IcpUtils {
@Value("${params.api.invoiceCheckSingleUrl}")
private String invoiceCheckSingleUrl;
@Autowired
private ApiUtils apiUtils;
/**
* 调用开放平台单张发票查验
*
* @param requestId
* @param singleInvoiceRequest
* @param taxpayerId
* @return InvoiceCheckResponse
*/
public ApiResponse callSingleCheck(String requestId, ApiCheckInvoiceSingleRequest singleInvoiceRequest, String taxpayerId, String access_token) {
ApiResponse apiResponse = apiUtils.callApi(invoiceCheckSingleUrl, taxpayerId, singleInvoiceRequest, access_token, requestId);
return apiResponse;
}
}
Loading…
Cancel
Save