对接邮政订单系统
parent
3b0eb0bb97
commit
8e0d8d39c1
|
|
@ -0,0 +1,196 @@
|
||||||
|
package com.cpxt.web.controller.biz.orderutil;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.http.HttpRequest;
|
||||||
|
import cn.hutool.http.HttpResponse;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.cpxt.common.annotation.Anonymous;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author Ly
|
||||||
|
* @Create 2024/12/4 18:57
|
||||||
|
* @Desc
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/test")
|
||||||
|
@Slf4j
|
||||||
|
public class cityDelivery {
|
||||||
|
private static final char[] specialChars = {'\n', '\r', '\t', '\f','\b',' '};
|
||||||
|
|
||||||
|
// test
|
||||||
|
String clientKey ="7480617400984563";//accessKey
|
||||||
|
String clientSecret = "91wCEvn82CeyMg3k";
|
||||||
|
String sm4Key = "MJy05dcI4mPbGB61";
|
||||||
|
String appType = "wxmp";
|
||||||
|
String client_type = "other";
|
||||||
|
String version = "1.0.0";
|
||||||
|
|
||||||
|
/*static{
|
||||||
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同城急送平台工具,post接口
|
||||||
|
*/
|
||||||
|
@Anonymous
|
||||||
|
public void cityDelivery_signBody2(){
|
||||||
|
Long timeStamp = System.currentTimeMillis();
|
||||||
|
String nonce = UUID.randomUUID().toString().replace("-","");
|
||||||
|
System.out.println("nonce:"+nonce );
|
||||||
|
System.out.println("timeStamp:"+timeStamp );
|
||||||
|
//签名
|
||||||
|
Map<String,Object> sortedMap = new TreeMap<>();
|
||||||
|
//下单接口
|
||||||
|
String body = "{\n" +
|
||||||
|
" \"customerCode\": \"GZHX\",\n" +
|
||||||
|
" \"payTypeFirst\": \"03\",\n" +
|
||||||
|
" \"convertFlag\": false,\n" +
|
||||||
|
" \"weight\": \"501\",\n" +
|
||||||
|
" \"expectedTime\": \"2024-11-11 12:12:00\",\n" +
|
||||||
|
" \"platformOrderNo\": \"\",\n" +
|
||||||
|
" \"channelOrderNo\": \"\",\n" +
|
||||||
|
" \"orderSource\": \"meituan\",\n" +
|
||||||
|
" \"orderSourcePlatform\": \"01\",\n" +
|
||||||
|
" \"costFee\": \"100\",\n" +
|
||||||
|
" \"packageDesc\": \"药品\",\n" +
|
||||||
|
" \"remark\": \"手机尾号1234\",\n" +
|
||||||
|
" \"expressNbr\": \"\",\n" +
|
||||||
|
" \"insuredFee\": \"1\",\n" +
|
||||||
|
" \"otherFee1\": \"2\",\n" +
|
||||||
|
" \"otherFee2\": \"3\",\n" +
|
||||||
|
" \"addressFirst\": {\n" +
|
||||||
|
" \"senderProviceCode\": \"440000\",\n" +
|
||||||
|
" \"senderProviceName\": \"广东省\",\n" +
|
||||||
|
" \"senderCityCode\": \"440100\",\n" +
|
||||||
|
" \"senderCityName\": \"广州市\",\n" +
|
||||||
|
" \"senderCountyCode\": \"440106\",\n" +
|
||||||
|
" \"senderCountyName\": \"天河区\",\n" +
|
||||||
|
" \"senderContactName\": \"中山三院\",\n" +
|
||||||
|
" \"senderContactPhone\": \"17523029470\",\n" +
|
||||||
|
" \"senderLongitude\": \"113.264000\",\n" +
|
||||||
|
" \"senderLatitude\": \"23.129101\",\n" +
|
||||||
|
" \"senderStreetCode\": \"001\",\n" +
|
||||||
|
" \"senderStreetName\": \"林和街道1\",\n" +
|
||||||
|
" \"senderAddr\": \"天河北路188号\",\n" +
|
||||||
|
" \"receiverProviceCode\": \"440000\",\n" +
|
||||||
|
" \"receiverProviceName\": \"广东省\",\n" +
|
||||||
|
" \"receiverCityCode\": \"440100\",\n" +
|
||||||
|
" \"receiverCityName\": \"广州市\",\n" +
|
||||||
|
" \"receiverCountyCode\": \"440106\",\n" +
|
||||||
|
" \"receiverCountyName\": \"天河区\",\n" +
|
||||||
|
" \"receiverContactName\": \"陈先生\",\n" +
|
||||||
|
" \"receiverContactPhone\": \"13711511111\",\n" +
|
||||||
|
" \"receiverAddr\": \"信源大厦20楼2007\",\n" +
|
||||||
|
" \"receiverLongitude\": \"113.265000\",\n" +
|
||||||
|
" \"receiverLatitude\": \"23.129101\",\n" +
|
||||||
|
" \"receiverStreetCode\": \"002\",\n" +
|
||||||
|
" \"receiverStreetName\": \"林和街道2\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"businessJson\": {\n" +
|
||||||
|
" \"a\": \"asd\",\n" +
|
||||||
|
" \"b\": \"asd\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}";
|
||||||
|
//查询物流轨迹
|
||||||
|
// String body = "{\n" +
|
||||||
|
// " \"expressNbr\": \"1158114584567\",\n" +
|
||||||
|
// " \"channelOrderNo\": \"\"\n" +
|
||||||
|
// "}";
|
||||||
|
//get请求,组装成 k v类型
|
||||||
|
// sortedMap.put(paramName,request.getParameter(paramName));
|
||||||
|
/**
|
||||||
|
* post请求,需要放data
|
||||||
|
*/
|
||||||
|
sortedMap.put("data", JSON.toJSONString(StrUtil.removeAll(body, specialChars)));
|
||||||
|
sortedMap.put("access_id",clientKey);
|
||||||
|
sortedMap.put("nonce", nonce);
|
||||||
|
sortedMap.put("timestamp",timeStamp);
|
||||||
|
//排序
|
||||||
|
Map<String,Object> sortedParams = new TreeMap<>(sortedMap);
|
||||||
|
Set<Map.Entry<String,Object>> entrySet = sortedParams.entrySet();
|
||||||
|
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
|
||||||
|
StringBuilder stringToSign = new StringBuilder();
|
||||||
|
for (Map.Entry<String,Object> param : entrySet) {
|
||||||
|
stringToSign.append(param.getKey()).append("=").append(param.getValue()).append(",");
|
||||||
|
}
|
||||||
|
stringToSign.append("accessSecret").append("=").append(clientSecret);
|
||||||
|
String genSign = cityDelivery_SM4Util.encryptCBC(stringToSign.toString(),clientSecret,sm4Key);
|
||||||
|
System.out.println("sign:" + genSign);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取token
|
||||||
|
@Anonymous
|
||||||
|
@PostMapping("/getToken")
|
||||||
|
public void getToken(){
|
||||||
|
System.out.println("获取token");
|
||||||
|
String url = "https://wyjcs.gdwyj.cn/szelec/city-delivery-api/api/mini/app/login/token";
|
||||||
|
String nonce = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
Long timestamp = System.currentTimeMillis();
|
||||||
|
//body
|
||||||
|
Map map = new HashMap();
|
||||||
|
map.put("clientKey",clientKey);
|
||||||
|
map.put("clientSecret",clientSecret);
|
||||||
|
map.put("appType",appType);
|
||||||
|
map.put("clientType",client_type);
|
||||||
|
map.put("version",version);
|
||||||
|
|
||||||
|
Map<String, Object> sortedParams1 = new TreeMap<>(map);
|
||||||
|
Set<Map.Entry<String, Object>> entrySet1 = sortedParams1.entrySet();
|
||||||
|
StringBuilder stringToSign = new StringBuilder();
|
||||||
|
for (Map.Entry<String, Object> param : entrySet1) {
|
||||||
|
stringToSign.append(param.getKey()).append("=").append(param.getValue()).append(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
String encryptBase64 = cityDelivery_SM4Util.encryptCBC(stringToSign.toString(),clientSecret,sm4Key);
|
||||||
|
System.out.println("body:" + encryptBase64);
|
||||||
|
//签名
|
||||||
|
Map<String,Object> sortedMap2 = new TreeMap<>();
|
||||||
|
|
||||||
|
//get请求,组装成 k v类型
|
||||||
|
// sortedMap2.put(paramName,request.getParameter(paramName));
|
||||||
|
/**
|
||||||
|
* post请求,需要放data
|
||||||
|
*/
|
||||||
|
Map bodyMap = new HashMap();
|
||||||
|
bodyMap.put("body",encryptBase64);
|
||||||
|
String bodyJson = JSON.toJSONString(bodyMap);
|
||||||
|
sortedMap2.put("data", JSON.toJSONString(bodyJson));
|
||||||
|
sortedMap2.put("access_id",clientKey);
|
||||||
|
sortedMap2.put("nonce", nonce);
|
||||||
|
sortedMap2.put("timestamp",timestamp);
|
||||||
|
//排序
|
||||||
|
Map<String,Object> sortedParams2 = new TreeMap<>(sortedMap2);
|
||||||
|
Set<Map.Entry<String,Object>> entrySet2 = sortedParams2.entrySet();
|
||||||
|
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
|
||||||
|
StringBuilder stringToSign2 = new StringBuilder();
|
||||||
|
for (Map.Entry<String,Object> param : entrySet2) {
|
||||||
|
stringToSign2.append(param.getKey()).append("=").append(param.getValue()).append(",");
|
||||||
|
}
|
||||||
|
stringToSign2.append("accessSecret").append("=").append(clientSecret);
|
||||||
|
// String genSign = DigestUtils.md5Hex(stringToSign2.toString());
|
||||||
|
String genSign = cityDelivery_SM4Util.encryptCBC(stringToSign2.toString(),clientSecret,sm4Key);
|
||||||
|
System.out.println("------------");
|
||||||
|
System.out.println("sign:" + genSign);
|
||||||
|
|
||||||
|
|
||||||
|
HttpResponse response = HttpRequest.post(url)
|
||||||
|
.body(JSON.toJSONString(bodyMap))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("client_type", client_type)
|
||||||
|
.header("app_type", appType)
|
||||||
|
.header("access_id", clientKey)
|
||||||
|
.header("nonce", nonce)
|
||||||
|
.header("timestamp", timestamp.toString())
|
||||||
|
.header("sign", genSign)
|
||||||
|
.execute();
|
||||||
|
System.out.println(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
||||||
|
package com.cpxt.web.controller.biz.orderutil;
|
||||||
|
|
||||||
|
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||||
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.crypto.Mode;
|
||||||
|
import cn.hutool.crypto.Padding;
|
||||||
|
import cn.hutool.crypto.symmetric.SM4;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @Author Mitch
|
||||||
|
* @Date 2024-12-12 16:30
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class cityDelivery_SM4Util {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static String encryptCBC(String str, String secretKey, String iv) {
|
||||||
|
return encryptCBC(str, secretKey, iv, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encryptCBC(String str, String secretKey, String iv, boolean checkBase64) {
|
||||||
|
String encryptBase64 = null;
|
||||||
|
if (StrUtil.isEmpty(str)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (checkBase64 && isBase64(str)) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
SM4 sm4 = new SM4(Mode.CBC, Padding.PKCS5Padding,
|
||||||
|
secretKey.getBytes(CharsetUtil.CHARSET_UTF_8),
|
||||||
|
iv.getBytes(CharsetUtil.CHARSET_UTF_8));
|
||||||
|
encryptBase64 = sm4.encryptBase64(str);
|
||||||
|
return encryptBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decryptCBC(String str, String secretKey, String iv) {
|
||||||
|
return decryptCBC(str, secretKey, iv, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decryptCBC(String str, String secretKey, String iv, boolean checkBase64) {
|
||||||
|
String decryptStr = null;
|
||||||
|
try {
|
||||||
|
if (checkBase64 && !isBase64(str)) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
SM4 sm4 = new SM4(Mode.CBC, Padding.PKCS5Padding,
|
||||||
|
secretKey.getBytes(CharsetUtil.CHARSET_UTF_8),
|
||||||
|
iv.getBytes(CharsetUtil.CHARSET_UTF_8));
|
||||||
|
decryptStr = sm4.decryptStr(str);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解密参数:{}", str, "国密解密算法工具类异常--->{}", ExceptionUtil.getMessage(e));
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return decryptStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBase64(String input) {
|
||||||
|
char specificChar = '=';
|
||||||
|
if (input == null || input.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (input.length() == 20 && input.matches("[0-9]+")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (input.length() % 4 != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (input.length() < 16) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (input.length() == 16 && input.matches("[0-9]+")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
byte[] decodedBytes = Base64.getDecoder().decode(input);
|
||||||
|
// 判断是否以=号结尾的
|
||||||
|
if (input.endsWith(String.valueOf(specificChar))) {
|
||||||
|
int numEquals = 0;
|
||||||
|
for (int i = input.length() - 1; i >= 0; i--) {
|
||||||
|
if (input.charAt(i) == '=') {
|
||||||
|
numEquals++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numEquals >= 0 && numEquals <= 2;
|
||||||
|
}
|
||||||
|
for (char c : input.toCharArray()) {
|
||||||
|
if (!(isBase64Character(c))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isBase64Character(char c) {
|
||||||
|
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
|
||||||
|
|| (c >= '0' && c <= '9') || c == '+' || c == '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getKey(){
|
||||||
|
return RandomUtil.randomString(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// String content = "我是字符串";
|
||||||
|
//16位字符串
|
||||||
|
String key = "nCWGwBstWF3MOu8T";
|
||||||
|
String iv = "ABtjL78T7vBjhqyb";
|
||||||
|
// String s = encryptCBC(content, key, iv);
|
||||||
|
// System.out.println(s);
|
||||||
|
String m = "1lcPgvBeFGaXJKrDfpOiAw==";
|
||||||
|
String string = decryptCBC(m, key, iv);
|
||||||
|
System.out.println(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -137,6 +137,20 @@
|
||||||
<version>5.5.7</version>
|
<version>5.5.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>1.2.83</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
|
<version>1.70</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
Loading…
Reference in New Issue