meituan
This commit is contained in:
13
pom.xml
13
pom.xml
@ -190,6 +190,12 @@
|
||||
<version>2.11.1</version> <!-- 可根据需要选择版本 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Commons Codec -->
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.15</version>
|
||||
</dependency>
|
||||
<!-- swagger2 -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
@ -261,6 +267,13 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.meituan.sdk</groupId>
|
||||
<artifactId>sdk</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/lib/MtOpJavaSDK-1.0-SNAPSHOT.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
|
||||
@ -33,13 +33,10 @@ public class VerifyController {
|
||||
|
||||
@ApiOperation(value = "接收需据接口")
|
||||
@GetMapping("/Prepare")
|
||||
public Result prepare(@RequestParam("code") String code, @RequestParam("sign") String sign, @RequestParam("developerId") Long developerId, @RequestParam("businessId") int businessId,
|
||||
@RequestParam("state") String state) throws Exception {
|
||||
public Result prepare(@RequestParam("code") String code) throws Exception {
|
||||
|
||||
log.info("接收美团授权数据 - code: {}, sign: {}, developerId: {}, businessId: {}, state: {}",
|
||||
code, sign, developerId, businessId, state);
|
||||
|
||||
douyinService.prepare( null);
|
||||
douyinService.getAccessToken( code);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -8,4 +8,6 @@ public interface DouyinService {
|
||||
|
||||
|
||||
void prepare(List<String> orderIds) throws Exception;
|
||||
|
||||
void getAccessToken(String code);
|
||||
}
|
||||
|
||||
@ -1,23 +1,31 @@
|
||||
package com.sczx.order.service.impl;
|
||||
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.douyin.openapi.client.Client;
|
||||
import com.douyin.openapi.client.models.*;
|
||||
import com.douyin.openapi.credential.models.Config;
|
||||
|
||||
|
||||
import com.meituan.sdk.DefaultMeituanClient;
|
||||
import com.meituan.sdk.MeituanClient;
|
||||
import com.meituan.sdk.auth.MeituanTokenResponse;
|
||||
import com.meituan.sdk.internal.utils.SignerUtil;
|
||||
import com.sczx.order.common.Result;
|
||||
import com.sczx.order.config.DouyinTokenManager;
|
||||
import com.sczx.order.exception.InnerException;
|
||||
import com.sczx.order.service.DouyinService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -35,10 +43,16 @@ public class DouyinServiceImpl implements DouyinService {
|
||||
//@Value("${douyin.poiId}")
|
||||
private String POI_ID = "7442188302710065206";
|
||||
|
||||
private String meituanApiUrl = "https://api-open-cater.meituan.com/oauth/token";
|
||||
|
||||
private Long DeveloperId = 116997L;
|
||||
|
||||
private String Signkey = "n8xihtshk7t1luvi";
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public String resolveShortUrlToGetObjectId(String shortUrl) {
|
||||
try{
|
||||
try {
|
||||
URL url = new URL(shortUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setInstanceFollowRedirects(false); // 禁止自动重定向
|
||||
@ -60,7 +74,7 @@ public class DouyinServiceImpl implements DouyinService {
|
||||
}
|
||||
|
||||
return null;
|
||||
}catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
log.error("二维码不正确");
|
||||
throw new InnerException("扫码核销失败,二维码不正确");
|
||||
}
|
||||
@ -109,7 +123,7 @@ public class DouyinServiceImpl implements DouyinService {
|
||||
|
||||
response.getData().getCertificates().forEach(certificate -> {
|
||||
Long certificateId = certificate.getCertificateId();
|
||||
String skuId =certificate.getSku().getSkuId() ;
|
||||
String skuId = certificate.getSku().getSkuId();
|
||||
certificate.getReserveInfo().getOrderReserveUserInfoList().forEach(orderReserveUserInfo -> {
|
||||
|
||||
});
|
||||
@ -118,4 +132,22 @@ public class DouyinServiceImpl implements DouyinService {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAccessToken(String code) {
|
||||
try {
|
||||
// 使用美团SDK构建客户端
|
||||
MeituanClient client = DefaultMeituanClient.builder(DeveloperId, Signkey).build();
|
||||
|
||||
|
||||
// 使用美团SDK的getOAuthToken方法获取token
|
||||
MeituanTokenResponse response = client.getOAuthToken(58, code);
|
||||
|
||||
|
||||
log.info("获取access_token响应结果: {}", JSONObject.toJSONString(response));
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("获取access_token异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
107
src/main/java/com/sczx/order/utils/DouyinTokenManager.java
Normal file
107
src/main/java/com/sczx/order/utils/DouyinTokenManager.java
Normal file
@ -0,0 +1,107 @@
|
||||
package com.sczx.order.utils;
|
||||
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.douyin.openapi.client.Client;
|
||||
import com.douyin.openapi.client.models.OauthClientTokenRequest;
|
||||
import com.douyin.openapi.client.models.OauthClientTokenResponse;
|
||||
import com.douyin.openapi.credential.models.Config;
|
||||
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* 抖音 client_token 管理器
|
||||
* 负责定时获取和缓存 client_token
|
||||
*/
|
||||
public class DouyinTokenManager {
|
||||
|
||||
// 应用凭证信息
|
||||
private static final String CLIENT_KEY = "awomt6nnjlfc491m";
|
||||
private static final String CLIENT_SECRET = "c678c411c7a68c6f97969f2dbd8ef8fc";
|
||||
|
||||
// Token 缓存
|
||||
private static final AtomicReference<OauthClientTokenResponse> tokenCache =
|
||||
new AtomicReference<>();
|
||||
|
||||
// 定时任务执行器
|
||||
private static final ScheduledThreadPoolExecutor scheduler =
|
||||
new ScheduledThreadPoolExecutor(1, r -> {
|
||||
Thread t = new Thread(r, "DouyinTokenRefreshThread");
|
||||
t.setDaemon(false);
|
||||
return t;
|
||||
});
|
||||
|
||||
static {
|
||||
// 初始化时立即获取一次 token
|
||||
refreshClientToken();
|
||||
|
||||
// 每小时更新一次 token (3600秒)
|
||||
scheduler.scheduleAtFixedRate(
|
||||
DouyinTokenManager::refreshClientToken,
|
||||
3600,
|
||||
3600,
|
||||
TimeUnit.SECONDS
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前有效的 client_token
|
||||
*
|
||||
* @return 当前有效的 access_token
|
||||
*/
|
||||
public static String getCurrentToken() {
|
||||
OauthClientTokenResponse response = tokenCache.get();
|
||||
if (response != null && response.getData() != null) {
|
||||
return response.getData().getAccessToken();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新 client_token
|
||||
*/
|
||||
private static void refreshClientToken() {
|
||||
try {
|
||||
Config config = new Config()
|
||||
.setClientKey(CLIENT_KEY)
|
||||
.setClientSecret(CLIENT_SECRET);
|
||||
|
||||
Client client = new Client(config);
|
||||
|
||||
OauthClientTokenRequest sdkRequest = new OauthClientTokenRequest();
|
||||
sdkRequest.setClientKey(CLIENT_KEY);
|
||||
sdkRequest.setClientSecret(CLIENT_SECRET);
|
||||
sdkRequest.setGrantType("client_credential");
|
||||
|
||||
OauthClientTokenResponse sdkResponse = client.OauthClientToken(sdkRequest);
|
||||
|
||||
// 更新缓存
|
||||
tokenCache.set(sdkResponse);
|
||||
|
||||
if (sdkResponse.getData() != null) {
|
||||
System.out.println("抖音 client_token 更新成功,有效期至: " +
|
||||
(System.currentTimeMillis() + sdkResponse.getData().getExpiresIn() * 1000));
|
||||
}
|
||||
} catch (TeaException e) {
|
||||
System.err.println("获取抖音 client_token 失败 (TeaException): " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
System.err.println("获取抖音 client_token 失败 (Exception): " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭定时任务
|
||||
*/
|
||||
public static void shutdown() {
|
||||
scheduler.shutdown();
|
||||
|
||||
// 获取当前有效的 client_token
|
||||
String token = DouyinTokenManager.getCurrentToken();
|
||||
|
||||
// 使用 token 调用抖音 API
|
||||
if (token != null) {
|
||||
// 调用订单查询等接口
|
||||
}
|
||||
}
|
||||
}
|
||||
86
src/main/java/com/sczx/order/utils/MeiTuanSignUtils.java
Normal file
86
src/main/java/com/sczx/order/utils/MeiTuanSignUtils.java
Normal file
@ -0,0 +1,86 @@
|
||||
package com.sczx.order.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@Slf4j
|
||||
public class MeiTuanSignUtils {
|
||||
private MeiTuanSignUtils() {}
|
||||
|
||||
public static String getSign(String signKey, Map<String, String> params) {
|
||||
try {
|
||||
String sortedStr = getSortedParamStr(params);
|
||||
String paraStr = signKey + sortedStr;
|
||||
|
||||
return createSign(paraStr);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.warn("getSign UnsupportedEncodingException ", e);
|
||||
}
|
||||
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造自然排序请求参数
|
||||
*
|
||||
* @param params 请求
|
||||
* @return 字符串
|
||||
*/
|
||||
private static String getSortedParamStr(Map<String, String> params) throws UnsupportedEncodingException {
|
||||
Set<String> sortedParams = new TreeSet<>(params.keySet());
|
||||
|
||||
StringBuilder strB = new StringBuilder();
|
||||
// 排除sign和空值参数
|
||||
for (String key : sortedParams) {
|
||||
if ("sign".equalsIgnoreCase(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String value = params.get(key);
|
||||
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
strB.append(key).append(value);
|
||||
}
|
||||
}
|
||||
return strB.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成新sign
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return String
|
||||
*/
|
||||
private static String createSign(String str) {
|
||||
if (str == null || str.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
try {
|
||||
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
|
||||
mdTemp.update(str.getBytes("UTF-8"));
|
||||
|
||||
byte[] md = mdTemp.digest();
|
||||
int j = md.length;
|
||||
char[] buf = new char[j * 2];
|
||||
int k = 0;
|
||||
int i = 0;
|
||||
while (i < j) {
|
||||
byte byte0 = md[i];
|
||||
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
|
||||
buf[k++] = hexDigits[byte0 & 0xf];
|
||||
i++;
|
||||
}
|
||||
return new String(buf);
|
||||
} catch (Exception e) {
|
||||
log.warn("create sign was failed", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/lib/MtOpJavaSDK-1.0-SNAPSHOT.jar
Normal file
BIN
src/main/resources/lib/MtOpJavaSDK-1.0-SNAPSHOT.jar
Normal file
Binary file not shown.
Reference in New Issue
Block a user