From 10b15315adbf81a2d88f22b33da11030c07f1918 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期五, 09 十月 2026 10:46:03 +0800
Subject: [PATCH] 修改bug

---
 UserFBTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GDFalconUtil.java |  232 ++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 162 insertions(+), 70 deletions(-)

diff --git a/UserFBTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GDFalconUtil.java b/UserFBTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GDFalconUtil.java
index 75ff775..7452ed3 100644
--- a/UserFBTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GDFalconUtil.java
+++ b/UserFBTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GDFalconUtil.java
@@ -17,16 +17,23 @@
 
 /**
  * 高德猎鹰服务
+ * key次数用完时自动切换可用key(切换后自动重建serverId)
  */
 @Component
 public class GDFalconUtil implements ApplicationRunner {
 
-    private String key = "ca723c3c8a78962a7751129ae035dc9d";
-
     @Autowired
     private RestTemplate restTemplate;
 
+    @Autowired
+    private GDKeyManager gdKeyManager;
+
     private static String serverId = null;
+
+    /**
+     * 当前serverId对应的key(key切换后需重建serverId)
+     */
+    private static volatile String currentKey = null;
 
 
     public String getServerId() {
@@ -44,20 +51,137 @@
     }
 
 
-
     /**
      * 初始化创建服务
      */
     public void init(){
         if(serverId == null){
-            JSONArray jsonArray = this.selectServer();
-            if(null == jsonArray){
-                serverId = this.createServer("server");
-            }else{
-                serverId = jsonArray.getJSONObject(0).getString("sid");
+            if (gdKeyManager == null || restTemplate == null) {
+                // 非容器实例(如 GunsApplication.main 中 new 出来的对象),由容器内bean完成初始化
+                return;
             }
+            ensureServerId();
         }
+    }
 
+    /**
+     * 参数构造器:key与sid切换后需按最新值重新构造
+     */
+    private interface ParamsBuilder {
+        MultiValueMap<String, Object> build(String key, String sid);
+    }
+
+    /**
+     * 确保serverId与当前使用的key对应:
+     * key切换后自动查询/重建serverId;key用完自动切换可用key重试
+     */
+    private synchronized String ensureServerId(){
+        int maxAttempts = 5;
+        String lastKey = gdKeyManager.getKey();
+        for (int i = 0; i < maxAttempts; i++) {
+            String gdKey = gdKeyManager.getKey();
+            lastKey = gdKey;
+            if (serverId != null && gdKey.equals(currentKey)) {
+                return gdKey;
+            }
+            // 1. 查询该key下的服务列表
+            JSONArray jsonArray = null;
+            try {
+                String url = "https://tsapi.amap.com/v1/track/service/list?key=" + gdKey;
+                String forObject = restTemplate.getForObject(url, String.class);
+                JSONObject jsonObject = JSON.parseObject(forObject);
+                if (GDKeyManager.isFalconExhausted(jsonObject)) {
+                    gdKeyManager.reportExhausted(gdKey);
+                    serverId = null;
+                    continue;
+                }
+                if (jsonObject.getIntValue("errcode") == 10000) {
+                    JSONObject data = jsonObject.getJSONObject("data");
+                    if (null != data) {
+                        jsonArray = data.getJSONArray("results");
+                    }
+                }
+            } catch (Exception e) {
+                loggerWarn("查询猎鹰服务列表异常", e);
+            }
+            if (jsonArray != null && jsonArray.size() > 0) {
+                serverId = jsonArray.getJSONObject(0).getString("sid");
+                currentKey = gdKey;
+                return gdKey;
+            }
+            // 2. 无服务:创建新服务
+            String sid = createServerInternal("server", gdKey);
+            if (sid != null) {
+                serverId = sid;
+                currentKey = gdKey;
+                return gdKey;
+            }
+            // 3. 创建失败(可能key用完):切换key重试
+            gdKeyManager.reportExhausted(gdKey);
+            serverId = null;
+        }
+        return lastKey;
+    }
+
+    private void loggerWarn(String msg, Exception e) {
+        System.err.println("[GDFalconUtil] " + msg + ":" + e.getMessage());
+    }
+
+    /**
+     * 执行猎鹰POST表单请求:key次数用完时自动切换key并重建serverId重试
+     */
+    private String doFalconPost(String url, ParamsBuilder builder) {
+        String lastResp = null;
+        int maxAttempts = 5;
+        for (int i = 0; i < maxAttempts; i++) {
+            String gdKey = ensureServerId();
+            String sid = serverId;
+            MultiValueMap<String, Object> params = builder.build(gdKey, sid);
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
+            String resp = restTemplate.postForObject(url, requestEntity, String.class);
+            lastResp = resp;
+            JSONObject jsonObject;
+            try {
+                jsonObject = JSON.parseObject(resp);
+            } catch (Exception e) {
+                return resp;
+            }
+            if (GDKeyManager.isFalconExhausted(jsonObject)) {
+                gdKeyManager.reportExhausted(gdKey);
+                serverId = null;
+                continue;
+            }
+            return resp;
+        }
+        return lastResp;
+    }
+
+    /**
+     * 执行猎鹰GET请求:key次数用完时自动切换可用key重试
+     */
+    private String doFalconGet(String baseUrl) {
+        String lastResp = null;
+        int maxAttempts = 5;
+        for (int i = 0; i < maxAttempts; i++) {
+            String gdKey = gdKeyManager.getKey();
+            String url = baseUrl + (baseUrl.contains("?") ? "&" : "?") + "key=" + gdKey;
+            String resp = restTemplate.getForObject(url, String.class);
+            lastResp = resp;
+            JSONObject jsonObject;
+            try {
+                jsonObject = JSON.parseObject(resp);
+            } catch (Exception e) {
+                return resp;
+            }
+            if (GDKeyManager.isFalconExhausted(jsonObject)) {
+                gdKeyManager.reportExhausted(gdKey);
+                continue;
+            }
+            return resp;
+        }
+        return lastResp;
     }
 
 
@@ -66,6 +190,13 @@
      * @return
      */
     public String createServer(String name){
+        return createServerInternal(name, gdKeyManager.getKey());
+    }
+
+    /**
+     * 创建新的服务(内部直连,供ensureServerId使用)
+     */
+    private String createServerInternal(String name, String key){
         String url = "https://tsapi.amap.com/v1/track/service/add";
         //调用推送
         HttpHeaders headers = new HttpHeaders();
@@ -89,24 +220,6 @@
 
 
     /**
-     * 查询服务
-     * @return
-     */
-    private JSONArray selectServer(){
-        String url = "https://tsapi.amap.com/v1/track/service/list?key=" + key;
-        String forObject = restTemplate.getForObject(url, String.class);
-        JSONObject jsonObject = JSON.parseObject(forObject);
-        if(jsonObject.getIntValue("errcode") == 10000){
-            JSONObject data = jsonObject.getJSONObject("data");
-            if(null != data){
-                return data.getJSONArray("results");
-            }
-        }
-        return null;
-    }
-
-
-    /**
      * 创建终端数据
      * @param name
      * @return
@@ -116,18 +229,13 @@
         if(tid != null){
             return tid;
         }
-        String url = "https://tsapi.amap.com/v1/track/terminal/add";
-        //调用推送
-        HttpHeaders headers = new HttpHeaders();
-        // 以表单的方式提交
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        //将请求头部和参数合成一个请求
-        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
-        params.add("key", key);
-        params.add("sid", serverId);
-        params.add("name", name);
-        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
-        String s = restTemplate.postForObject(url, requestEntity , String.class);
+        String s = doFalconPost("https://tsapi.amap.com/v1/track/terminal/add", (key, sid) -> {
+            MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+            params.add("key", key);
+            params.add("sid", sid);
+            params.add("name", name);
+            return params;
+        });
         JSONObject jsonObject = JSON.parseObject(s);
         if(jsonObject.getIntValue("errcode") == 10000){
             JSONObject data = jsonObject.getJSONObject("data");
@@ -144,8 +252,7 @@
      * @return
      */
     public String selectTerminal(String name){
-        String url = "https://tsapi.amap.com/v1/track/terminal/list?key=" + key + "&name=" + name;
-        String forObject = restTemplate.getForObject(url, String.class);
+        String forObject = doFalconGet("https://tsapi.amap.com/v1/track/terminal/list?name=" + name);
         JSONObject jsonObject = JSON.parseObject(forObject);
         if(jsonObject.getIntValue("errcode") == 10000){
             JSONObject data = jsonObject.getJSONObject("data");
@@ -170,18 +277,13 @@
      * @return
      */
     public String createTrack(String tid){
-        String url = "https://tsapi.amap.com/v1/track/trace/add";
-        //调用推送
-        HttpHeaders headers = new HttpHeaders();
-        // 以表单的方式提交
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        //将请求头部和参数合成一个请求
-        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
-        params.add("key", key);
-        params.add("sid", serverId);
-        params.add("tid", tid);
-        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
-        String s = restTemplate.postForObject(url, requestEntity , String.class);
+        String s = doFalconPost("https://tsapi.amap.com/v1/track/trace/add", (key, sid) -> {
+            MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+            params.add("key", key);
+            params.add("sid", sid);
+            params.add("tid", tid);
+            return params;
+        });
         JSONObject jsonObject = JSON.parseObject(s);
         if(jsonObject.getIntValue("errcode") == 10000){
             return jsonObject.getString("data");
@@ -197,28 +299,18 @@
      * @param trid      轨迹id
      */
     public void deleteTrack(String tid, String trid){
-        String url = "https://tsapi.amap.com/v1/track/trace/delete";
-        //调用推送
-        HttpHeaders headers = new HttpHeaders();
-        // 以表单的方式提交
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        //将请求头部和参数合成一个请求
-        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
-        params.add("key", key);
-        params.add("sid", serverId);
-        params.add("tid", tid);
-        params.add("trid", trid);
-        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
-        String s = restTemplate.postForObject(url, requestEntity , String.class);
+        String s = doFalconPost("https://tsapi.amap.com/v1/track/trace/delete", (key, sid) -> {
+            MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+            params.add("key", key);
+            params.add("sid", sid);
+            params.add("tid", tid);
+            params.add("trid", trid);
+            return params;
+        });
         JSONObject jsonObject = JSON.parseObject(s);
         if(jsonObject.getIntValue("errcode") != 10000){
             System.err.println(jsonObject.getString("errmsg"));
         }
     }
 
-
-//
-//    public Map<String, Object> queryTrsearch(){
-//
-//    }
 }

--
Gitblit v1.7.1