diff --git a/pom.xml b/pom.xml
index ec88727..ccb1e73 100644
--- a/pom.xml
+++ b/pom.xml
@@ -190,6 +190,12 @@
2.11.1
+
+
+ commons-codec
+ commons-codec
+ 1.15
+
io.springfox
@@ -261,6 +267,13 @@
+
+ com.meituan.sdk
+ sdk
+ 1.0
+ system
+ ${project.basedir}/src/main/resources/lib/MtOpJavaSDK-1.0-SNAPSHOT.jar
+
com.google.code.gson
gson
diff --git a/src/main/java/com/sczx/order/controller/VerifyController.java b/src/main/java/com/sczx/order/controller/VerifyController.java
index 1863f30..2d29f74 100644
--- a/src/main/java/com/sczx/order/controller/VerifyController.java
+++ b/src/main/java/com/sczx/order/controller/VerifyController.java
@@ -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;
}
diff --git a/src/main/java/com/sczx/order/service/DouyinService.java b/src/main/java/com/sczx/order/service/DouyinService.java
index d35ef2b..a9f5083 100644
--- a/src/main/java/com/sczx/order/service/DouyinService.java
+++ b/src/main/java/com/sczx/order/service/DouyinService.java
@@ -8,4 +8,6 @@ public interface DouyinService {
void prepare(List orderIds) throws Exception;
+
+ void getAccessToken(String code);
}
diff --git a/src/main/java/com/sczx/order/service/impl/DouyinServiceImpl.java b/src/main/java/com/sczx/order/service/impl/DouyinServiceImpl.java
index dd4f90e..edd6b73 100644
--- a/src/main/java/com/sczx/order/service/impl/DouyinServiceImpl.java
+++ b/src/main/java/com/sczx/order/service/impl/DouyinServiceImpl.java
@@ -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);
+ }
+ }
}
diff --git a/src/main/java/com/sczx/order/utils/DouyinTokenManager.java b/src/main/java/com/sczx/order/utils/DouyinTokenManager.java
new file mode 100644
index 0000000..b691366
--- /dev/null
+++ b/src/main/java/com/sczx/order/utils/DouyinTokenManager.java
@@ -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 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) {
+ // 调用订单查询等接口
+ }
+ }
+}
diff --git a/src/main/java/com/sczx/order/utils/MeiTuanSignUtils.java b/src/main/java/com/sczx/order/utils/MeiTuanSignUtils.java
new file mode 100644
index 0000000..d07b85a
--- /dev/null
+++ b/src/main/java/com/sczx/order/utils/MeiTuanSignUtils.java
@@ -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 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 params) throws UnsupportedEncodingException {
+ Set 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;
+ }
+ }
+}
diff --git a/src/main/resources/lib/MtOpJavaSDK-1.0-SNAPSHOT.jar b/src/main/resources/lib/MtOpJavaSDK-1.0-SNAPSHOT.jar
new file mode 100644
index 0000000..613edac
Binary files /dev/null and b/src/main/resources/lib/MtOpJavaSDK-1.0-SNAPSHOT.jar differ