...
|
...
|
@@ -8,19 +8,51 @@ import com.yoho.product.dal.ProductChainMapper; |
|
|
import com.yoho.product.dal.ProductInfoMapper;
|
|
|
import com.yoho.product.model.ProductChain;
|
|
|
import com.yoho.product.model.ProductInfo;
|
|
|
import com.yoho.ufo.util.DateUtil;
|
|
|
import com.yohobuy.ufo.model.request.nfc.ProductInfoReq;
|
|
|
import org.apache.commons.beanutils.BeanUtils;
|
|
|
import org.apache.commons.codec.binary.*;
|
|
|
import org.apache.commons.lang3.*;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.http.HttpEntity;
|
|
|
import org.springframework.http.HttpHeaders;
|
|
|
import org.springframework.http.MediaType;
|
|
|
import org.springframework.http.ResponseEntity;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
import sun.misc.BASE64Encoder;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import javax.crypto.Cipher;
|
|
|
import javax.crypto.NoSuchPaddingException;
|
|
|
import java.io.BufferedReader;
|
|
|
import java.io.File;
|
|
|
import java.io.FileInputStream;
|
|
|
import java.io.FileReader;
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.security.*;
|
|
|
import java.security.spec.PKCS8EncodedKeySpec;
|
|
|
import java.util.*;
|
|
|
import java.util.Base64;
|
|
|
|
|
|
/**
|
|
|
* Created by li.ma on 2020/3/31.
|
|
|
*/
|
|
|
@Service
|
|
|
public class ProductChainService {
|
|
|
private static final Logger logger = LoggerFactory.getLogger(ProductChainService.class);
|
|
|
|
|
|
|
|
|
private static final byte[] priKeyText;
|
|
|
|
|
|
static {
|
|
|
priKeyText = getFileContent("rsa_private_key.pem");
|
|
|
}
|
|
|
|
|
|
@Autowired
|
|
|
private ProductInfoMapper productInfoMapper;
|
|
|
|
...
|
...
|
@@ -30,44 +62,61 @@ public class ProductChainService { |
|
|
@Autowired
|
|
|
private ServiceCaller serviceCaller;
|
|
|
|
|
|
@Resource(name="restTemplate")
|
|
|
private RestTemplate restTemplate;
|
|
|
|
|
|
@Value("${urltrainblock.url}")
|
|
|
private String urltrainblockUrl;
|
|
|
|
|
|
// curl http://40.73.0.117:8078/yoho/post/query POST -H "Content-Type:application/json" -d '"id":"156663177401529"' -v
|
|
|
public void postQuery(String chainId) {
|
|
|
public void postQuery(Long chainId) {
|
|
|
// (String serviceName, String url, Object request, Class<T> responseType, T fallback, int timeout)
|
|
|
Map<String, Object> request = new HashMap<>(); request.put("id", chainId);
|
|
|
AsyncFuture<String> post = serviceCaller.post("ufo-platform.chain", urltrainblockUrl + "/post/query", request, String.class, null, 1);
|
|
|
String response = post.get(1);
|
|
|
|
|
|
JSONObject jsonObject = JSONObject.parseObject(response);
|
|
|
String errorCode = jsonObject.getString("errorCode");
|
|
|
String errorMsg = jsonObject.getString("errorMsg");
|
|
|
HttpHeaders headers = getHttpHeaders("");
|
|
|
HttpEntity<String> formEntity = getStringHttpEntity(request, headers);
|
|
|
ResponseEntity<String> response = restTemplate.postForEntity(urltrainblockUrl + "/post/query", formEntity, String.class);
|
|
|
|
|
|
JSONObject jsonObject = JSONObject.parseObject(response.getBody());
|
|
|
String errorCode = jsonObject.getString("errorCode");
|
|
|
JSONObject result = jsonObject.getJSONObject("result");
|
|
|
JSONArray yohoInfos = result.getJSONArray("yohoInfos");
|
|
|
|
|
|
logger.info("postQuery success. chainId is {}, errorCode is {}, result is {}", chainId, errorCode, result);
|
|
|
|
|
|
if (org.apache.commons.lang3.StringUtils.isEmpty(errorCode) && null != result) {
|
|
|
JSONArray yohoInfos = result.getJSONArray("yohoInfos");
|
|
|
int size = yohoInfos.size();
|
|
|
JSONObject item = (JSONObject)yohoInfos.get(0);
|
|
|
String transactionId = item.getString("transactionId");
|
|
|
|
|
|
updateProductChain(ProductChain.builder().chainId(chainId).transactionId(transactionId).build());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public void postChainInfo(ProductInfo productInfo) {
|
|
|
|
|
|
|
|
|
public void postChainInfo(ProductInfoReq bo, Long id, String sign) {
|
|
|
// (String serviceName, String url, Object request, Class<T> responseType, T fallback, int timeout)
|
|
|
Map<String, Object> request = null;
|
|
|
try {
|
|
|
request = BeanUtils.describe(productInfo);
|
|
|
request = BeanUtils.describe(bo);
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
AsyncFuture<String> post = serviceCaller.post("ufo-platform.chainInfo", urltrainblockUrl + "/post/info", request, String.class, null, 1);
|
|
|
String response = post.get(1);
|
|
|
|
|
|
JSONObject jsonObject = JSONObject.parseObject(response);
|
|
|
String errorCode = jsonObject.getString("errorCode");
|
|
|
HttpHeaders headers = getHttpHeaders(sign);
|
|
|
HttpEntity<String> formEntity = getStringHttpEntity(request, headers);
|
|
|
ResponseEntity<String> response = restTemplate.postForEntity(urltrainblockUrl + "/post/query", formEntity, String.class);
|
|
|
JSONObject jsonObject = JSONObject.parseObject(response.getBody());
|
|
|
String errorMsg = jsonObject.getString("errorMsg");
|
|
|
String result = jsonObject.getString("result");
|
|
|
|
|
|
JSONObject result = jsonObject.getJSONObject("result");
|
|
|
JSONArray yohoInfos = result.getJSONArray("yohoInfos");
|
|
|
logger.info("postChainInfo success. bo is {}, id is {}, errorMsg is {}, result is {}", bo, id, errorMsg, result);
|
|
|
|
|
|
if ("Y".equals(result) || "ID字段重复".equals(errorMsg)) {
|
|
|
updateIsupload(id, 1); // 如果更新成功,则更新数据库字段
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// SELECT * FROM ${TABLE_PRODUCT_CHAIN} WHERE transaction_id IS NULL
|
...
|
...
|
@@ -75,29 +124,255 @@ public class ProductChainService { |
|
|
return productChainMapper.selectProductChain();
|
|
|
}
|
|
|
|
|
|
public int updateProductChain(ProductChain chain) {
|
|
|
return productChainMapper.updateProductChain(chain);
|
|
|
}
|
|
|
|
|
|
// select * from ${TABLE_PRODUCT_INFO} where isupload = :isupload
|
|
|
public List<ProductInfo> queryIsuploadIsZero() {
|
|
|
return productInfoMapper.selectIsuploadIsZero();
|
|
|
}
|
|
|
|
|
|
public int updateIsupload(ProductInfo productInfo) {
|
|
|
return productInfoMapper.updateIsupload(productInfo);
|
|
|
public int updateIsupload(Long id, int isupload) {
|
|
|
ProductInfo build = ProductInfo.builder().isupload(isupload).id(id).build();
|
|
|
return productInfoMapper.updateIsupload(build);
|
|
|
}
|
|
|
|
|
|
public int insertProductInfo(ProductInfo productInfo) {
|
|
|
/*let id = +data.id
|
|
|
let product_url = data.product_url
|
|
|
let color = data.color
|
|
|
let size = data.size
|
|
|
let goods_no = data.goods_no
|
|
|
let source = data.source
|
|
|
let owner = data.owner
|
|
|
let transaction_time = data.transaction_time
|
|
|
let tagid = data.tagid
|
|
|
let sign = data.sign
|
|
|
let isupload = data.isupload || 0
|
|
|
let auth_time = data.auth_time
|
|
|
let last_transaction_id = data.last_transaction_id || ''
|
|
|
let from_platform = data.from_platform || 0 //0为默认UFO, 1为有货
|
|
|
let nfcid = data.nfcid || ''*/
|
|
|
return productInfoMapper.insertProductInfo(productInfo);
|
|
|
}
|
|
|
|
|
|
public int updateIsupload(String tagId, String transaction_id) {
|
|
|
public int updateTransactionId(String tagId, String transaction_id) {
|
|
|
return productChainMapper.updateTransactionId(tagId, transaction_id);
|
|
|
}
|
|
|
|
|
|
// 同步上链的数据
|
|
|
public void addItem(ProductInfo bo) {
|
|
|
public void addItem(ProductInfoReq bo) {
|
|
|
Long generateid = generateid();
|
|
|
logger.info("generateid is : " , generateid);
|
|
|
|
|
|
updatechainSql(bo.getTagid(), generateid, null, Integer.valueOf(bo.getTransaction_time()));
|
|
|
|
|
|
try {
|
|
|
String sign = generateSign(BeanUtils.describe(bo));
|
|
|
logger.info("sign is : " , sign);
|
|
|
|
|
|
insertProductInfo(convertVo(bo, generateid, sign));
|
|
|
|
|
|
postChainInfo(bo, generateid, sign);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private ProductInfo convertVo(ProductInfoReq bo, Long generateid, String sign) {
|
|
|
return ProductInfo.builder().id(generateid).productUrl(bo.getProduct_url()).color(bo.getColor())
|
|
|
.size(bo.getSize()).goodsNo(bo.getGoods_no()).source(bo.getSource()).owner(bo.getOwner())
|
|
|
.transactionTime(bo.getTransaction_time()).tagid(bo.getTagid()).sign(sign).isupload(0)
|
|
|
.authTime(bo.getAuth_time()).lastTransactionId(null == bo.getLast_transaction_id() ? "" : bo.getLast_transaction_id())
|
|
|
.fromPlatform(null == bo.getFrom_platform() ? 0 : bo.getFrom_platform())
|
|
|
.nfcid(null == bo.getNfcid() ? "" : bo.getNfcid()).build();
|
|
|
}
|
|
|
|
|
|
|
|
|
private void updatechainSql(String tagId, Long chainId, String transactionId, Integer transactionTime) {
|
|
|
ProductChain chain = new ProductChain();
|
|
|
chain.setChainId(chainId);
|
|
|
chain.setTagId(tagId);
|
|
|
chain.setTransactionId(transactionId);
|
|
|
chain.setTransactionTime(transactionTime);
|
|
|
updateProductChain(chain);
|
|
|
}
|
|
|
|
|
|
|
|
|
private String generateid() {
|
|
|
return Math.floor(new Date().getTime()/1000) + "01" + new Random(3).nextInt();
|
|
|
private static Long generateid() {
|
|
|
return Long.valueOf(DateUtil.getCurrentTimeSeconds() + "01" + getRandom(3));
|
|
|
}
|
|
|
// const generateid = () => {
|
|
|
//return Math.floor(new Date().getTime()/1000) + '01' + getRandom(3)
|
|
|
//return Math.floor(new Date().getTime()/1000) + '01' + getRandom(3) 155289842201546
|
|
|
|
|
|
private static int getRandom(int num) {
|
|
|
return (int)Math.floor((Math.random()+Math.floor(Math.random()*9+1))*Math.pow(10,num-1));
|
|
|
}
|
|
|
|
|
|
private static String generateSign(Map<String, Object> params) {
|
|
|
List<String> strings = new ArrayList<>(params.keySet());
|
|
|
Collections.sort(strings);
|
|
|
String str = "";
|
|
|
for(String item : strings) {
|
|
|
str += item + "=" + params.get(item) + "&";
|
|
|
}
|
|
|
|
|
|
String substring = str.substring(0, str.length() - 1);
|
|
|
String hashvalue = md5Hex(str);
|
|
|
|
|
|
// const encodeData = crypto.privateEncrypt(privatekey, Buffer.from(hashvalue)).toString('base64');
|
|
|
String base64Sign = null; //RSA解密
|
|
|
try {
|
|
|
/*Signature sign = Signature.getInstance("SHA1withRSA");
|
|
|
sign.initSign(getPrivateKey());
|
|
|
byte[] bysData = hashvalue.getBytes("UTF-8");
|
|
|
sign.update(bysData);
|
|
|
byte[] signByte = sign.sign();
|
|
|
BASE64Encoder encoder = new BASE64Encoder();
|
|
|
base64Sign = encoder.encode(signByte);*/
|
|
|
|
|
|
base64Sign = sign(hashvalue);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
|
|
|
return base64Sign;
|
|
|
}
|
|
|
|
|
|
|
|
|
public static String sign(String plainText) {
|
|
|
try {
|
|
|
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(priKeyText));
|
|
|
KeyFactory keyf = KeyFactory.getInstance("RSA");
|
|
|
PrivateKey prikey = keyf.generatePrivate(priPKCS8);
|
|
|
|
|
|
// 用私钥对信息生成数字签名
|
|
|
Signature signet = Signature.getInstance("MD5withRSA");
|
|
|
signet.initSign(prikey);
|
|
|
signet.update(plainText.getBytes());
|
|
|
byte[] signed = Base64.getEncoder().encode(signet.sign());
|
|
|
return new String(signed);
|
|
|
} catch (java.lang.Exception e) {
|
|
|
System.out.println("签名失败");
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 将字符串进行MD5加密并十六进制编码
|
|
|
*
|
|
|
* @param src 字符串
|
|
|
* @return D5加密并十六进制编码字符串
|
|
|
*/
|
|
|
public static String md5Hex(String src) {
|
|
|
try {
|
|
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
|
|
md5.update(src.getBytes(StandardCharsets.UTF_8));
|
|
|
byte[] md = md5.digest();
|
|
|
return new String(md, StandardCharsets.UTF_8);
|
|
|
} catch (Exception e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
public static byte[] getFileContent(String fileName) {
|
|
|
byte[] data = (byte[])null;
|
|
|
FileInputStream fis = null;
|
|
|
try {
|
|
|
File f = new File(fileName);
|
|
|
data = new byte[(int)f.length()];
|
|
|
fis = new FileInputStream(f);
|
|
|
fis.read(data);
|
|
|
fis.close();
|
|
|
} catch (Exception e) {
|
|
|
return null;
|
|
|
}
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
|
|
|
/*public static PrivateKey getPrivateKey() {
|
|
|
PrivateKey priKey = null;
|
|
|
try {
|
|
|
FileInputStream fis = new FileInputStream("rsa_private_key.pem");
|
|
|
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
|
|
char[] pscs = pfxPassword.toCharArray();
|
|
|
keyStore.load(fis, pscs);
|
|
|
priKey = (PrivateKey) (keyStore.getKey(aliasName, pscs));
|
|
|
} catch (Exception e) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
return priKey;
|
|
|
}*/
|
|
|
|
|
|
/**
|
|
|
* 字符串Base64解码
|
|
|
*
|
|
|
* @param src 字符串
|
|
|
* @return 经过Base64解码的字符串
|
|
|
*/
|
|
|
public static String base64Decode(String src) {
|
|
|
|
|
|
if (src == null || src.equals("")) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
// decodeBase64
|
|
|
|
|
|
org.apache.commons.codec.binary.Base64 decoder = new org.apache.commons.codec.binary.Base64();
|
|
|
byte[] deByte = decoder.decode(src.getBytes(StandardCharsets.UTF_8));
|
|
|
return new String(deByte, StandardCharsets.UTF_8).trim();
|
|
|
}
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
System.out.println();
|
|
|
}
|
|
|
|
|
|
public void postChainInfoEx(ProductInfo item) {
|
|
|
ProductInfoReq build = ProductInfoReq.builder()
|
|
|
.auth_time(item.getAuthTime())
|
|
|
.color(item.getColor())
|
|
|
.from_platform(item.getFromPlatform())
|
|
|
.goods_no(item.getGoodsNo())
|
|
|
.last_transaction_id(item.getLastTransactionId())
|
|
|
.nfcid(item.getNfcid())
|
|
|
.owner(item.getOwner())
|
|
|
.product_url(item.getProductUrl())
|
|
|
.size(item.getSize())
|
|
|
.transaction_time(item.getTransactionTime())
|
|
|
.tagid(item.getTagid())
|
|
|
.source(item.getSource())
|
|
|
.build();
|
|
|
|
|
|
|
|
|
postChainInfo(build, item.getId(), item.getSign());
|
|
|
}
|
|
|
|
|
|
|
|
|
private HttpEntity<String> getStringHttpEntity(Map<String, Object> params, HttpHeaders headers) {
|
|
|
JSONObject jsonObj = new JSONObject();
|
|
|
for(Map.Entry<String, Object> item : params.entrySet()) {
|
|
|
jsonObj.put(item.getKey(), item.getValue());
|
|
|
}
|
|
|
return new HttpEntity<>(jsonObj.toString(), headers);
|
|
|
}
|
|
|
|
|
|
private HttpHeaders getHttpHeaders(String signature) {
|
|
|
HttpHeaders headers = new HttpHeaders();
|
|
|
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
|
|
|
headers.setContentType(type);
|
|
|
headers.add("signature", signature);
|
|
|
return headers;
|
|
|
}
|
|
|
} |
...
|
...
|
|