浏览代码

1、添加亚马逊令牌自动刷新功能
2、代码进行优化调整

jiabin 10 月之前
父节点
当前提交
c0cf68c1d7
共有 21 个文件被更改,包括 620 次插入489 次删除
  1. 8 0
      raycos_common/pom.xml
  2. 30 2
      raycos_common/src/main/java/com/raycos/raycoscommon/Internal/datacenterapi/TbAmzToken.java
  3. 15 6
      raycos_common/src/main/java/com/raycos/raycoscommon/Internal/datacenterapi/TbStoreInfo.java
  4. 36 0
      raycos_common/src/main/java/com/raycos/raycoscommon/Internal/datacenterapi/vo/GetAmzTokenByLwaCodeVo.java
  5. 30 0
      raycos_common/src/main/java/com/raycos/raycoscommon/amzjson/TokenAmz.java
  6. 27 0
      raycos_common/src/main/java/com/raycos/raycoscommon/amzjson/TokenRetAmzJson.java
  7. 0 212
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/Amazon.java
  8. 0 90
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/AmazonController.java
  9. 0 19
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/AmzAuthorizeService.java
  10. 66 13
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/AmzTokenController.java
  11. 11 0
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/AmzTokenService.java
  12. 50 20
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/StoreInfoController.java
  13. 1 1
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/StoreInfoService.java
  14. 0 107
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/impl/AmzAuthorizeServiceImpl.java
  15. 185 2
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/impl/AmzTokenServiceImpl.java
  16. 2 1
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/impl/StoreInfoServiceImpl.java
  17. 7 1
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/config/RestTemplateConfig.java
  18. 0 14
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/mapper/TbAmzAuthorizeMapper.java
  19. 8 0
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/mapper/TbAmzTokenMapper.java
  20. 42 1
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/scheduledtasks/RefreshAmazonToken.java
  21. 102 0
      raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/scheduledtasks/RefreshTask.java

+ 8 - 0
raycos_common/pom.xml

@@ -17,6 +17,14 @@
     <properties>
     </properties>
     <dependencies>
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 30 - 2
raycos_common/src/main/java/com/raycos/raycoscommon/Internal/datacenterapi/TbAmzToken.java

@@ -1,6 +1,8 @@
 package com.raycos.raycoscommon.Internal.datacenterapi;
 
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -10,13 +12,39 @@ import lombok.NoArgsConstructor;
 @NoArgsConstructor
 public class TbAmzToken {
 
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
     private Long id;
+    /**
+     * 企业编号
+     */
+    private Long companyId;
+    /**
+     * 店铺ID
+     */
+    private Long storeId;
+    /**
+     * 短令牌 接口访问令牌
+     */
     private String accessToken;
+    /**
+     * token 类型
+     */
     private String tokenType;
+    /**
+     * 过期时间戳
+     */
     private Long expiresIn;
+    /**
+     * 长令牌 可以用于刷新访问令牌
+     */
     private String refreshToken;
-    private String sellingPartnerId;
-
+    /**
+     * 亚马逊区域ID
+     */
+    private String marketId;
 
 
 }

+ 15 - 6
raycos_common/src/main/java/com/raycos/raycoscommon/Internal/datacenterapi/TbStoreInfo.java

@@ -1,6 +1,8 @@
 package com.raycos.raycoscommon.Internal.datacenterapi;
 
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -13,7 +15,13 @@ public class TbStoreInfo {
     /**
      * 主键ID
      */
+    @TableId(type = IdType.AUTO)
     private Long id;
+
+    /**
+     * 企业编号
+     */
+    private Long companyId;
     /**
      * 店铺名称
      */
@@ -21,24 +29,25 @@ public class TbStoreInfo {
     /**
      * 店铺类型 跨境:1 本土:2
      */
-    private Integer storeType;
+    private Short storeType;
     /**
      * 店铺类型 FBA:1 FBM:2
      */
-    private Integer storeModel;
+    private Short storeModel;
     /**
      * 平台账号
      */
     private String platformAccount;
     /**
-     * 区域
+     * 站点
      */
-    private String  region;
+    private String stationsIdStr;
 
     /**
-     * 站点
+     *  授权时应用程序生成的 state (UUID) 值。
      */
-    private String  site;
+    private String   state;
+
 
 
 }

+ 36 - 0
raycos_common/src/main/java/com/raycos/raycoscommon/Internal/datacenterapi/vo/GetAmzTokenByLwaCodeVo.java

@@ -0,0 +1,36 @@
+package com.raycos.raycoscommon.Internal.datacenterapi.vo;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * url:   /erp/amztoken/getamztokenbylwacode
+ *  使用LWA code 获取亚马逊令牌
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class GetAmzTokenByLwaCodeVo {
+
+
+    /**
+     *  企业 ID
+     */
+    private Long companyId;
+    /**
+     *  亚马逊店铺信息ID
+     */
+    private Long storeId;
+    /**
+     * 用于生成 LWA 刷新令牌的 Login with Amazon (LWA) 授权码
+     */
+    private String lwaCode;
+    /**
+     * 参考文档:https://developer-docs.amazon.com/sp-api/docs/website-authorization-workflow
+     * 其中:第 4 步: 亚马逊发送授权信息 selling_partner_id  授权您的应用程序的销售合作伙伴的标识符。
+     */
+    private String sellingPartnerId;
+
+}

+ 30 - 0
raycos_common/src/main/java/com/raycos/raycoscommon/amzjson/TokenAmz.java

@@ -0,0 +1,30 @@
+package com.raycos.raycoscommon.amzjson;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+/**
+ *   https://api.amazon.com/auth/o2/token   接口入参实体类
+ *
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TokenAmz {
+    @JSONField(name = "grant_type")
+    private String grantType;
+    @JSONField(name = "code")
+    private String code;
+    @JSONField(name = "redirect_uri")
+    private String redirectUri;
+    @JSONField(name = "client_id")
+    private String clientId;
+    @JSONField(name = "client_secret")
+    private String clientSecret;
+
+
+
+}

+ 27 - 0
raycos_common/src/main/java/com/raycos/raycoscommon/amzjson/TokenRetAmzJson.java

@@ -0,0 +1,27 @@
+package com.raycos.raycoscommon.amzjson;
+
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * https://api.amazon.com/auth/o2/token   接口返回实体类 接口返回正确的情况下 (不包括 异常情况返回)
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TokenRetAmzJson {
+    @JSONField(name = "access_token")
+    private String accessToken;
+    @JSONField(name = "token_type")
+    private String tokenType;
+    @JSONField(name = "expires_in")
+    private Long expiresIn;
+    @JSONField(name = "refresh_token")
+    private String refreshToken;
+
+
+}

+ 0 - 212
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/Amazon.java

@@ -1,212 +0,0 @@
-package com.raycos.raycosdatacenterapi.authorize;
-
-
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @Author: xiaojiabin
- * @Date: 2024/9/2 10:55
- *
- *  亚马逊授权
- */
-@Slf4j
-public class Amazon {
-
-
-
-
-    // 用户通过页面调用Amazon授权 接口
-    // 授权成功后 亚马逊回调  我的接口 入参:
-    /**
-     * state	步骤 2 中的 state 值。
-     * selling_partner_id	授权您的应用程序的销售合作伙伴的标识符。
-     * mws_auth_token	(仅限卖家应用程序)您在为 Amazon Marketplace Web Service 调用创建查询字符串时指定的值。
-     * spapi_oauth_code	用于生成 LWA 刷新令牌的 Login with Amazon (LWA) 授权码(请参阅第 5 步)。
-     */
-    //  我拿到 spapi_oauth_code 去调用刷新令牌接口
-    //  发送:
-    /**
-     * grant_type	请求的访问授权的类型。必须是 。authorization_code
-     * code	您在步骤 4 中收到的 LWA 授权码。Amazon 会向您发送授权信息。
-     * redirect_uri	应用程序的重定向 URI。
-     * client_id	LWA 凭证的一部分。要获取此值,请参阅 查看您的开发者信息。
-     * client_secret	LWA 凭证的一部分。要获取此值,请参阅 查看您的开发者信息。
-     */
-    //  接收:
-    /**
-     * access_token	一个令牌,用于授权您的应用程序代表销售合作伙伴执行某些操作。有关详细信息,请参阅连接到 SP-API。
-     * token_type	返回的 token 类型。应该是 bearer。
-     * expires_in	访问令牌失效前的秒数。
-     * refresh_token	可用于生成新访问令牌的长寿命令牌。有关详细信息,请参阅连接到 SP-API。
-     */
-
-
-
-
-// LWA客户端编码
-    private  static  String  client_id = "amzn1.application-oa2-client.2d001c4aeaaf438f98ee0b07070c1cf8";
-    // LWA客户端秘钥
-    private  static  String  client_secret = "amzn1.oa2-cs.v1.52b13f4ce04e83046b3426b620b6bfb94fd3ce61c815c6f68858af69d0ccbe54";
-
-
-
-    public static String getAccessToken(String code) {
-        try {
-
-            String url = "https://api.amazon.com/auth/o2/token";
-            Map<String, String> map = new HashMap<>();
-            map.put("grant_type", "authorization_code");
-            map.put("code", code);
-            map.put("client_id", client_id);
-            map.put("redirect_uri", "https://api.mabangerp.com/fba/api/v1/authCode");
-            map.put("client_secret", client_secret);
-            Map<String, String> headerMap = new HashMap<>();
-//            log.info();
-            headerMap.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
-//            String response = HttpClientUtil.httpPostForm(url, map, headerMap, null, 5000);
-
-//            logger.info(", get accessToken response : " + response);
-            return null;
-        } catch (Exception e) {
-            e.printStackTrace();
-//            logger.error(e.getMessage(), e);
-        }
-        return "报错";
-    }
-//
-//    public static String refreshAccessToken(String refresh_token) {
-//        try {
-//            String url = "https://api.amazon.com/auth/o2/token";
-//            Map<String, String> map = new HashMap<>();
-//            map.put("grant_type", "refresh_token");
-//            map.put("refresh_token", refresh_token);
-//            map.put("client_id", client_id);
-//            map.put("client_secret", client_secret);
-//            Map<String, String> headerMap = new HashMap<>();
-//            logger.info(JSONObject.toJSONString(map));
-//            headerMap.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
-//            String response = HttpClientUtil.httpPostForm(url, map, headerMap, null, 5000);
-//            logger.info("refresh access_token response : " + response);
-//            return response;
-//        } catch (Exception e) {
-//            e.printStackTrace();
-//            logger.error(e.getMessage(), e);
-//        }
-//        return "报错";
-//    }
-//
-//
-//    public static String httpPostForm(String requestUrl, Map<String, String> paramMap,
-//                                      Map<String, String> headerMap, String encode, int timeOut) {
-//        String response = "";
-//        if (encode == null) {
-//            encode = "utf-8";
-//        }
-//
-//        // HttpClients.createDefault() 等价于 HttpClientBuilder.create().build();
-//        CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
-//        HttpPost httpPost = new HttpPost(requestUrl);
-//
-//        // 设置超时时间
-//        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(timeOut)
-//                .setConnectTimeout(timeOut).setSocketTimeout(timeOut).build();
-//        httpPost.setConfig(requestConfig);
-//
-//        // 设置header
-//        if (headerMap != null && headerMap.size() > 0) {
-//            for (String key : headerMap.keySet()) {
-//                httpPost.setHeader(key, headerMap.get(key));
-//            }
-//        }
-//
-//        // 设置Param
-//        if (paramMap != null && paramMap.size() > 0) {
-//
-//            List<NameValuePair> paramList = new ArrayList<NameValuePair>();
-//            for (String key : paramMap.keySet()) {
-//                paramList.add(new BasicNameValuePair(key, paramMap.get(key)));
-//            }
-//
-//            try {
-//                httpPost.setEntity(new UrlEncodedFormEntity(paramList, encode));
-//            } catch (UnsupportedEncodingException e) {
-//                e.printStackTrace();
-//            }
-//
-//        }
-//
-//        CloseableHttpResponse httpResponse = null;
-//        try {
-//            httpResponse = closeableHttpClient.execute(httpPost);
-//            HttpEntity entity = httpResponse.getEntity();
-//            byte[] bytes = (entity == null ? null : EntityUtils.toByteArray(entity));
-//            String content = (bytes == null ? null : new String(bytes, encode));
-//            response = content;
-//        } catch (Exception e) {
-//            e.printStackTrace();
-//        } finally {
-//            try {
-//                if (httpResponse != null) {
-//                    httpResponse.close();
-//                }
-//            } catch (IOException e) {
-//                e.printStackTrace();
-//            }
-//        }
-//
-//        try {
-//            // 关闭连接、释放资源
-//            if (closeableHttpClient != null) {
-//                closeableHttpClient.close();
-//            }
-//        } catch (IOException e) {
-//            e.printStackTrace();
-//        }
-//
-//        return response;
-//    }
-//
-//    /**
-//
-//     https://sellingpartnerapi-na.amazon.com/apps/authorize/consent
-//     https://sellingpartnerapi-eu.amazon.com/apps/authorize/consent
-//     https://sellingpartnerapi-fe.amazon.com/apps/authorize/consent
-//
-//     https://www.amazon.com/ap/oa?client_id=AKIAJQM2XW6X65DC5OWA
-//     &scope=profile
-//     &response_type=code
-//     &state=208257577ll0975l93l2l59l895857093449424
-//     &redirect_uri=https://client.example.com/auth_popup/token
-//     &code_challenge=Fw7s3XHRVb2m1nT7s646UrYiYLMJ54as0ZIU_injyqw
-//     &code_challenge_method=S256
-//
-//     if ($this->site == 'eu') {
-//     return 'https://sellercentral-europe.amazon.com/apps/authorize/consent';
-//     } elseif ($this->site == 'fe') {
-//     if ($this->countryCode == 'au') {
-//     return 'https://sellercentral.amazon.com.au/apps/authorize/consent';
-//     } elseif ($this->countryCode == 'jp') {
-//     return 'https://sellercentral-japan.amazon.com/apps/authorize/consent';
-//     } else {
-//     //新加坡
-//     return 'https://sellercentral.amazon.sg/apps/authorize/consent';
-//     }
-//     } else {
-//     return 'https://sellercentral.amazon.com/apps/authorize/consent';
-//     }
-//
-//     //     https://raycos.com.cn/authorize
-//
-//
-//
-//     */
-
-
-
-
-
-
-}

+ 0 - 90
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/AmazonController.java

@@ -1,90 +0,0 @@
-package com.raycos.raycosdatacenterapi.authorize;
-
-import com.alibaba.fastjson2.JSONObject;
-import com.raycos.raycoscommon.Internal.Result;
-import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzAuthorize;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.List;
-
-/**
- * @Author: xiaojiabin
- * @Date: 2024/9/2 13:25
- */
-
-@RestController
-@Slf4j
-@RequestMapping("/erp/amz")
-public class AmazonController {
-
-
-    @Autowired
-    private AmzAuthorizeService authorizeService;
-//    @Resource
-//    private  LwaClientInfoNacos lwaClientInfoNacos;
-
-    @GetMapping("/authcode")
-    public Result<String> getSpapiOauthCode(
-            @RequestParam(value = "state") String state,
-            @RequestParam(value = "selling_partner_id") String sellingPartnerId,
-            @RequestParam("mws_auth_token") String mwsAuthToken,
-            @RequestParam("spapi_oauth_code") String spapiOauthCode
-    ) {
-        Result<String> rt = new Result<>();
-        log.info("来了老弟 !! ");
-
-        try {
-            TbAmzAuthorize taa = new TbAmzAuthorize();
-            taa.setSpapiOauthCode(spapiOauthCode);
-            taa.setMwsAuthToken(mwsAuthToken);
-            taa.setSellingPartnerId(sellingPartnerId);
-
-            log.info("亚马逊授权成功 重定向接口 接收参数 = " + JSONObject.toJSONString(taa));
-
-            authorizeService.addAmzAuthorize(taa);
-
-            rt.success();
-        } catch (Exception e) {
-            e.printStackTrace();
-            log.error(" 查询异常  ", e);
-            rt.fail();
-        }
-        return rt;
-    }
-
-
-
-
-    @GetMapping("/sel")
-    public Result<List<TbAmzAuthorize>> selectAll() {
-
-        List<TbAmzAuthorize> list = null;
-        try {
-
-            list = authorizeService.selectAll();
-
-        } catch (Exception e) {
-            e.printStackTrace();
-            log.error(" 查询异常  ", e);
-        }
-        return new Result<List<TbAmzAuthorize>>().success(list);
-    }
-//    @GetMapping("/sellwa")
-//    public  Result<LwaClientInfoNacos>  findLwa () {
-//        Result<LwaClientInfoNacos> ss = new Result<>();
-//
-////        String jsonString = JSONObject.toJSONString(lwaClientInfoNacos);
-////        log.info("lwaClientInfoNacos  " + jsonString);
-////        ss.success(lwaClientInfoNacos);
-//
-//        return ss;
-//
-//    }
-
-
-}

+ 0 - 19
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/AmzAuthorizeService.java

@@ -1,19 +0,0 @@
-package com.raycos.raycosdatacenterapi.authorize;
-
-import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzAuthorize;
-
-import java.util.List;
-
-/**
- * @Author: xiaojiabin
- * @Date: 2024/9/2 14:40
- */
-
-public interface AmzAuthorizeService {
-
-    List<TbAmzAuthorize> selectAll()throws   Exception;
-
-    void  addAmzAuthorize ( TbAmzAuthorize tbAmzAuthorize) throws Exception;
-
-    void getAccessToken(TbAmzAuthorize tbAmzAuthorize ) throws Exception;
-}

+ 66 - 13
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/AmzTokenController.java

@@ -3,46 +3,99 @@ package com.raycos.raycosdatacenterapi.authorize;
 import com.alibaba.fastjson2.JSONObject;
 import com.raycos.raycoscommon.Internal.Result;
 import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzToken;
+import com.raycos.raycoscommon.Internal.datacenterapi.vo.GetAmzTokenByLwaCodeVo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.Assert;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
+/**
+ * 亚马逊令牌 服务接口
+ */
 @RestController
 @Slf4j
-@RequestMapping("/erp/token")
+@RequestMapping("/erp/amztoken")
 public class AmzTokenController {
 
     @Autowired
     private AmzTokenService amzTokenService;
 
     @GetMapping
-    public Result<List<TbAmzToken>> selToken (){
+    public Result<List<TbAmzToken>> selToken() {
         Result<List<TbAmzToken>> tr = new Result<>();
-        try{
+        try {
             List<TbAmzToken> list = amzTokenService.selAmzToken(null);
             tr.success(list);
-        }catch (Exception e){
-
+        } catch (Exception e) {
             tr.fail();
         }
-        return  tr;
+        return tr;
     }
 
+    /**
+     * 新增 amz令牌
+     *
+     * @param tbAmzToken
+     * @return
+     */
     @PostMapping
-    public  Result<String > addToken (@RequestBody TbAmzToken tbAmzToken ){
+    public Result<String> addToken(@RequestBody TbAmzToken tbAmzToken) {
         Result<String> rt = new Result<>();
-        try{
-            log.info( "  新增 token   来了老弟  " + JSONObject.toJSONString(tbAmzToken));
-            amzTokenService.addAmzToken( tbAmzToken );
+        try {
+            log.info("  新增 token   来了老弟  " + JSONObject.toJSONString(tbAmzToken));
+            amzTokenService.addAmzToken(tbAmzToken);
             rt.success();
-        }catch (Exception e){
-            log.error(" 新增token 异常 ",e);
+        } catch (Exception e) {
+            log.error(" 新增token 异常 ", e);
             rt.fail();
         }
-        return  rt;
+        return rt;
+
+    }
+
+    /**
+     * LWA code 获取亚马逊令牌
+     *
+     * @return
+     */
+    @PostMapping("/getamztokenbylwacode")
+    public Result<String> getAmzTokenByLwaCode(@RequestBody GetAmzTokenByLwaCodeVo params) {
+        Result<String> rt = new Result<>();
+        try {
+            Assert.hasLength(params.getLwaCode() , " getLwaCode is Empty 请检查提交参数 !");
+            Assert.notNull(params.getStoreId() , " getStoreId is Empty 请检查提交参数 !");
+            Assert.notNull(params.getCompanyId() , " getCompanyId is Empty 请检查提交参数 !");
+            Assert.hasLength(params.getSellingPartnerId() , " getSellingPartnerId is Empty 请检查提交参数 !");
+
+            rt = amzTokenService.getAmzTokenByLwaCode( params);
 
+        } catch (Exception e) {
+            rt.fail();
+            rt.setMsg( e.getMessage());
+            log.error(" /getamztokenbylwacode 异常 ", e);
+        }
+        return rt;
     }
 
+    /**
+     * 刷新 LWA  令牌
+     *
+     * @return
+     */
+    @GetMapping("/lrt")
+    public Result<String> lwaRefreshToken(@RequestBody TbAmzToken tbAmzToken) {
+        Result<String> rt = new Result<>();
+        try {
+            amzTokenService.lwaRefreshToken(tbAmzToken);
+            rt.success();
+        } catch (Exception e) {
+            rt.fail();
+            log.error(" 新增token 异常 ", e);
+        }
+        return rt;
+    }
+
+
 }

+ 11 - 0
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/AmzTokenService.java

@@ -1,6 +1,8 @@
 package com.raycos.raycosdatacenterapi.authorize;
 
+import com.raycos.raycoscommon.Internal.Result;
 import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzToken;
+import com.raycos.raycoscommon.Internal.datacenterapi.vo.GetAmzTokenByLwaCodeVo;
 
 import java.util.List;
 
@@ -14,5 +16,14 @@ public interface AmzTokenService {
 
     List<TbAmzToken> selAmzToken (TbAmzToken tbAmzToken)throws Exception;
 
+    Result<String>  lwaRefreshToken(TbAmzToken tbAmzToken  ) throws Exception;
+
+    /**
+     * 使用LWA code 获取亚马逊令牌
+     *
+     * @return
+     */
+    Result<String> getAmzTokenByLwaCode (GetAmzTokenByLwaCodeVo  gatblcVo )throws Exception;
+
 
 }

+ 50 - 20
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/StoreInfoController.java

@@ -8,47 +8,77 @@ import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
+/**
+ *   亚马逊店铺 服务接口
+ *
+ */
 @RestController
 @Slf4j
-@RequestMapping("/erp/store")
+@RequestMapping("/erp/amzstore")
 public class StoreInfoController {
 
 
     @Autowired
-    private  StoreInfoService storeInfoService;
+    private StoreInfoService storeInfoService;
 
 
+    /**
+     * 新增店铺信息
+     *
+     * @param tbStoreInfo
+     * @return
+     */
     @PostMapping("/add")
-    public Result<String> addStoreInfo (@RequestBody TbStoreInfo tbStoreInfo){
-        Result<String> rt = new  Result<>();
-        try{
-            tbStoreInfo.setStoreName("美国,加拿大,墨西哥,巴西");
-            tbStoreInfo.setStoreType(1);
-            tbStoreInfo.setStoreModel(2);
-            storeInfoService.addStoreInfo(tbStoreInfo);
-            rt.success();
+    public Result<Long> addStoreInfo(@RequestBody TbStoreInfo tbStoreInfo) {
+        Result<Long> rt = new Result<>();
+        try {
+            TbStoreInfo tsi = storeInfoService.addStoreInfo(tbStoreInfo);
+            log.info(" 新增店铺信息 成功 返回 ID =>  " + tsi.getId());
+            rt.success(tsi.getId());
             rt.setMsg("保存成功!");
-        }catch (Exception e ){
-            log.error(  e.getMessage() , e);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
             rt.fail();
         }
-        return  rt;
+        return rt;
     }
 
 
+    /**
+     * 获取访问令牌
+     *
+     * @return
+     */
+    public Result<String> getAccessToken() {
+        Result<String> rt = new Result<>();
+
+        try {
+
+            rt.success();
+        } catch (Exception e) {
+            rt.fail();
+            log.error("   异常 ", e);
+        }
+        return rt;
+    }
 
+    /**
+     * 查询全部店铺信息
+     *
+     * @return
+     */
     @GetMapping("/sel")
-    public Result<List<TbStoreInfo> > selStoreInfo (  ){
-        Result<List<TbStoreInfo> > rt = new  Result<>();
-        try{
+    public Result<List<TbStoreInfo>> selStoreInfo() {
+        Result<List<TbStoreInfo>> rt = new Result<>();
+        try {
             List<TbStoreInfo> tbStoreInfos = storeInfoService.selStoreInfo(null);
-            rt.success( tbStoreInfos );
+            rt.success(tbStoreInfos);
             rt.setMsg("查询成功!");
-        }catch (Exception e ){
-            log.error(  e.getMessage() , e);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
             rt.fail();
         }
-        return  rt;
+        return rt;
     }
 
 

+ 1 - 1
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/StoreInfoService.java

@@ -5,7 +5,7 @@ import com.raycos.raycoscommon.Internal.datacenterapi.TbStoreInfo;
 import java.util.List;
 
 public interface StoreInfoService {
-    void  addStoreInfo (TbStoreInfo tbStoreInfo)throws Exception;
+    TbStoreInfo  addStoreInfo (TbStoreInfo tbStoreInfo)throws Exception;
 
     void  delStoreInfo (TbStoreInfo tbStoreInfo)throws Exception;
 

+ 0 - 107
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/impl/AmzAuthorizeServiceImpl.java

@@ -1,107 +0,0 @@
-package com.raycos.raycosdatacenterapi.authorize.impl;
-
-
-import com.alibaba.fastjson2.JSONObject;
-import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzAuthorize;
-import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzToken;
-import com.raycos.raycosdatacenterapi.authorize.AmzAuthorizeService;
-import com.raycos.raycosdatacenterapi.authorize.AmzTokenService;
-import com.raycos.raycosdatacenterapi.mapper.TbAmzAuthorizeMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.stereotype.Service;
-import org.springframework.util.Assert;
-import org.springframework.web.client.RestTemplate;
-
-import java.util.List;
-
-/**
- * @Author: xiaojiabin
- * @Date: 2024/9/2 14:41
- */
-
-@Service
-@Slf4j
-public class AmzAuthorizeServiceImpl implements AmzAuthorizeService {
-
-
-    @Autowired
-    private TbAmzAuthorizeMapper tbAmzAuthorizeMapper;
-
-    @Autowired
-    private AmzTokenService amzTokenService;
-
-    @Autowired
-    private RestTemplate restTemplate;
-
-    @Override
-    public List<TbAmzAuthorize> selectAll() throws Exception {
-        List<TbAmzAuthorize> list = tbAmzAuthorizeMapper.selectList(null);
-
-        return list;
-    }
-
-    @Override
-    public void addAmzAuthorize(TbAmzAuthorize tbAmzAuthorize) throws Exception {
-        // 亚马逊 回调接口  返回 LWA code
-        tbAmzAuthorizeMapper.insert(tbAmzAuthorize);
-        try {
-            // 使用LWA code 获取长短令牌
-            getAccessToken(tbAmzAuthorize);
-        } catch (Exception e) {
-            log.error(" 亚马逊授权 LWACODE 刷新令牌失败   "+e.getMessage(), e);
-        }
-    }
-
-    /**
-     * 调亚马逊接口 获取 AccessToken( 长令牌、短令牌)
-     *
-     * @param tbAmzAuthorize
-     * @throws Exception
-     */
-    @Override
-    public void getAccessToken(TbAmzAuthorize tbAmzAuthorize) throws Exception {
-
-
-        RestTemplate restTemplate = new RestTemplate();
-        String url = "https://api.amazon.com/auth/o2/token";
-
-        // 设置请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_JSON);
-
-        JSONObject params = new JSONObject();
-        params.put("grant_type", "authorization_code");
-        params.put("code", tbAmzAuthorize.getSpapiOauthCode());
-        params.put("redirect_uri", "https://apisaas.raycos.net/erp/amz/authcode");
-        params.put("client_id", "amzn1.application-oa2-client.2d001c4aeaaf438f98ee0b07070c1cf8");
-        params.put("client_secret", "amzn1.oa2-cs.v1.52b13f4ce04e83046b3426b620b6bfb94fd3ce61c815c6f68858af69d0ccbe54");
-
-        // 设置请求体
-        String requestBody = params.toString();
-        // 创建请求实体
-        HttpEntity<String> request = new HttpEntity<>(requestBody, headers);
-        // 发送 POST 请求
-        String response = restTemplate.postForObject(url, request, String.class);
-
-        log.info("Response: " + response);
-
-        try {
-            JSONObject json = JSONObject.parseObject(response);
-            Assert.notNull(json.get("access_token"), " 获取令牌接口返回异常 请查看返回分析 "+json);
-            TbAmzToken tbAmzToken = JSONObject.parseObject(response, TbAmzToken.class);
-            amzTokenService.addAmzToken(tbAmzToken);
-
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            throw e;
-        }
-
-
-    }
-
-
-}

+ 185 - 2
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/impl/AmzTokenServiceImpl.java

@@ -1,14 +1,24 @@
 package com.raycos.raycosdatacenterapi.authorize.impl;
 
+import com.alibaba.fastjson2.JSONObject;
+import com.raycos.raycoscommon.Internal.Result;
 import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzToken;
+import com.raycos.raycoscommon.Internal.datacenterapi.vo.GetAmzTokenByLwaCodeVo;
+import com.raycos.raycoscommon.amzjson.TokenAmz;
+import com.raycos.raycoscommon.amzjson.TokenRetAmzJson;
 import com.raycos.raycosdatacenterapi.authorize.AmzTokenService;
 import com.raycos.raycosdatacenterapi.mapper.TbAmzTokenMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 import org.springframework.web.client.RestTemplate;
 
+import javax.annotation.Resource;
+import java.time.Instant;
 import java.util.List;
 
 
@@ -16,11 +26,57 @@ import java.util.List;
 @Slf4j
 public class AmzTokenServiceImpl implements AmzTokenService {
 
+    /**
+     * 参考文档:https://developer-docs.amazon.com/sp-api/docs/website-authorization-workflow
+     * 文档: 步骤 5:应用程序使用 LWA 授权码生成 LWA 刷新令牌
+     * 5.1  -> grant_type	请求的访问授权的类型。必须是 。authorization_code
+     */
+    private final String AUTHORIZATION_CODE = "authorization_code";
+    /**
+     *  参考文档: https://developer-docs.amazon.com/sp-api/docs/connecting-to-the-selling-partner-api
+     *  文档: 步骤 1.申请 Login with Amazon 访问令牌
+     *  refresh_token.将此函数用于需要销售合作伙伴授权的调用操作。所有非无授权操作都需要销售伙伴的授权。指定此值时,请包括rrefresh_token参数。
+     */
+    private final String  REFRESH_TOKEN = "refresh_token";
+    /**
+     * 参考文档:https://developer-docs.amazon.com/sp-api/docs/website-authorization-workflow
+     * 文档: 步骤 5:应用程序使用 LWA 授权码生成 LWA 刷新令牌
+     * 5.2  -> token_type	返回的 token 类型。应该是 bearer。
+     */
+    private final String BEARER = "bearer";
+    /**
+     * 参考文档:https://developer-docs.amazon.com/sp-api/docs/website-authorization-workflow
+     * 文档: 步骤 5:应用程序使用 LWA 授权码生成 LWA 刷新令牌
+     * LWA CODE 调用接口 返回令牌信息
+     */
+    private final String URL = "https://api.amazon.com/auth/o2/token";
+    /**
+     * 亚马逊授权成功 重定向浏览器页面 并且通过URL 携带
+     * LWA code 用于生成亚马逊令牌
+     */
+    private final String REDIRECTURI = "https://www.raycos.net/erp/authorize";
     @Autowired
     private TbAmzTokenMapper tbAmzTokenMapper;
 
-    @Autowired
+    @Resource(name = "externalRequestsRestTemplate")
     private RestTemplate restTemplate;
+
+    /**
+     * 亚马逊刷新令牌接口
+     */
+    private String url = "https://api.amazon.com/auth/o2/token";
+
+
+    private String getRequestBody(GetAmzTokenByLwaCodeVo gatblcVo) {
+        TokenAmz amz = new TokenAmz();
+        amz.setGrantType(AUTHORIZATION_CODE);
+        amz.setCode(gatblcVo.getLwaCode());
+        amz.setRedirectUri(REDIRECTURI);
+        amz.setClientId("amzn1.application-oa2-client.2d001c4aeaaf438f98ee0b07070c1cf8");
+        amz.setClientSecret("amzn1.oa2-cs.v1.52b13f4ce04e83046b3426b620b6bfb94fd3ce61c815c6f68858af69d0ccbe54");
+        return JSONObject.toJSONString(amz);
+    }
+
     @Override
     public void addAmzToken(TbAmzToken tbAmzToken) throws Exception {
         tbAmzTokenMapper.insert(tbAmzToken);
@@ -28,7 +84,7 @@ public class AmzTokenServiceImpl implements AmzTokenService {
 
     @Override
     public void delAmzToken(TbAmzToken tbAmzToken) throws Exception {
-        Assert.notNull( tbAmzToken.getId() , "请检查提交参数!");
+        Assert.notNull(tbAmzToken.getId(), "请检查提交参数!");
         tbAmzTokenMapper.delAmzToken(tbAmzToken.getId());
     }
 
@@ -41,4 +97,131 @@ public class AmzTokenServiceImpl implements AmzTokenService {
     public List<TbAmzToken> selAmzToken(TbAmzToken tbAmzToken) throws Exception {
         return tbAmzTokenMapper.selectList(null);
     }
+
+
+    /**
+     *  刷新亚马逊 访问令牌过期时间
+     *
+     * @throws Exception
+     */
+    @Override
+    public Result<String>  lwaRefreshToken(TbAmzToken tat) throws Exception {
+        Assert.hasLength(tat.getRefreshToken(), "请检查提交参数!  getRefreshToken  is empty  ");
+        Result<String> rt = new Result<>();
+        // 设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+
+        JSONObject params = new JSONObject();
+        params.put("grant_type", REFRESH_TOKEN);
+        params.put("refresh_token", tat.getRefreshToken());
+        params.put("client_id", "amzn1.application-oa2-client.2d001c4aeaaf438f98ee0b07070c1cf8");
+        params.put("client_secret", "amzn1.oa2-cs.v1.52b13f4ce04e83046b3426b620b6bfb94fd3ce61c815c6f68858af69d0ccbe54");
+
+        // 设置请求体
+        String requestBody = params.toString();
+        // 创建请求实体
+        HttpEntity<String> request = new HttpEntity<>(requestBody, headers);
+        // 发送 POST 请求
+        String response = restTemplate.postForObject(URL, request, String.class);
+        log.info("企业编码=>"+tat.getCompanyId()+" 调用亚马逊" + URL + " 接口刷新令牌信息: 入参数据=> " + params);
+        log.info("企业编码=>"+tat.getCompanyId()+" 调用亚马逊" + URL + " 接口刷新令牌信息: 接口返回=> " + response);
+        try {
+            // 数据校验
+            TokenRetAmzJson tokenJson = JSONObject.parseObject(response, TokenRetAmzJson.class);
+            Assert.notNull(tokenJson, " TokenRetAmzJson is null : 接口返回数据为空  ");
+            Assert.hasLength(tokenJson.getTokenType(), "getTokenType is empty :LWA 授权码 刷新令牌失败   接口返回=>" + response);
+            Assert.isTrue(BEARER.equals(tokenJson.getTokenType()), "getTokenType 类型 不等于 bearer :LWA 授权码 刷新令牌失败   接口返回=>" + response);
+            // 获取当前时间戳
+            long second = Instant.now().getEpochSecond();
+            // 计算过期时间  *0.8 让令牌过期时间提前  留给让刷令牌操作时间
+            second = (long) (second+tokenJson.getExpiresIn() * 0.8);
+
+            // 组织更新 数据
+            TbAmzToken tbAmzToken = new TbAmzToken();
+            tbAmzToken.setId(tat.getId());
+            tbAmzToken.setCompanyId(tat.getCompanyId());
+
+            tbAmzToken.setAccessToken(tokenJson.getAccessToken());
+            tbAmzToken.setTokenType(tokenJson.getTokenType());
+            tbAmzToken.setExpiresIn(second);
+            tbAmzToken.setRefreshToken(tokenJson.getRefreshToken());
+
+            //执行更新
+            tbAmzTokenMapper.updateAccessToken( tbAmzToken );
+
+            rt.success();
+            rt.setMsg("刷新令牌成功!");
+        } catch (Exception e) {
+            log.error("刷新令牌失败! 企业编号=>" + tat.getCompanyId() + "  接口入参=>" + JSONObject.toJSONString(tat));
+            log.error("刷新令牌失败! 企业编号=>" + tat.getCompanyId() + "  接口返回=>" + JSONObject.toJSONString(response));
+            log.error("刷新令牌失败! 企业编号=>" + tat.getCompanyId() + "  异常信息=>" + e.getMessage(), e);
+            rt.fail();
+            rt.setMsg("刷新令牌失败!");
+        }
+        return rt;
+    }
+
+    /**
+     * 使用LWA code 获取亚马逊令牌
+     *
+     * @return
+     */
+    @Override
+    public Result<String> getAmzTokenByLwaCode(GetAmzTokenByLwaCodeVo gatblcVo) throws Exception {
+        Result<String> rt = new Result<>();
+        // 设置请求头
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        //设置请求体
+        String params = this.getRequestBody(gatblcVo);
+        // 创建请求实体
+        HttpEntity<String> request = new HttpEntity<>(params, headers);
+        // 发送 POST 请求
+        String response = restTemplate.postForObject(URL, request, String.class);
+
+        log.info("企业编码=>"+gatblcVo.getCompanyId()+" 调用亚马逊" + URL + " 接口获取令牌信息: 入参数据=> " + params);
+        log.info("企业编码=>"+gatblcVo.getCompanyId()+" 调用亚马逊" + URL + " 接口获取令牌信息: 接口返回=> " + response);
+
+        try {
+            // 数据校验
+            TokenRetAmzJson tokenJson = JSONObject.parseObject(response, TokenRetAmzJson.class);
+            Assert.notNull(tokenJson, " TokenRetAmzJson is null : 接口返回数据为空  ");
+            Assert.hasLength(tokenJson.getTokenType(), "getTokenType is empty :LWA 授权码 刷新令牌失败   接口返回=>" + response);
+            Assert.isTrue(BEARER.equals(tokenJson.getTokenType()), "getTokenType 类型 不等于 bearer :LWA 授权码 刷新令牌失败   接口返回=>" + response);
+
+            // 获取当前时间戳
+            long second = Instant.now().getEpochSecond();
+            // 计算过期时间  *0.8 让令牌过期时间提前  留给让刷令牌操作时间
+            second = (long) (second+tokenJson.getExpiresIn() * 0.8);
+
+
+            // 组织保存数据
+            TbAmzToken tbAmzToken = new TbAmzToken();
+            tbAmzToken.setCompanyId(gatblcVo.getCompanyId());
+            tbAmzToken.setStoreId(gatblcVo.getStoreId());
+            tbAmzToken.setMarketId(gatblcVo.getSellingPartnerId());
+
+            tbAmzToken.setAccessToken(tokenJson.getAccessToken());
+            tbAmzToken.setTokenType(tokenJson.getTokenType());
+            tbAmzToken.setExpiresIn(second);
+            tbAmzToken.setRefreshToken(tokenJson.getRefreshToken());
+
+            //保存令牌 信息
+            this.addAmzToken(tbAmzToken);
+            rt.success();
+            rt.setMsg("LWA CODE 获取令牌成功!");
+        } catch (Exception e) {
+            log.error(" LWA CODE 获取令牌失败! 企业编号=>" + gatblcVo.getCompanyId() + "  接口入参=>" + JSONObject.toJSONString(gatblcVo));
+            log.error(" LWA CODE 获取令牌失败! 企业编号=>" + gatblcVo.getCompanyId() + "  接口返回=>" + JSONObject.toJSONString(response));
+            log.error(" LWA CODE 获取令牌失败! 企业编号=>" + gatblcVo.getCompanyId() + "  异常信息=>" + e.getMessage(), e);
+            rt.fail();
+            rt.setMsg("LWA CODE 获取令牌失败!");
+        }
+        return rt;
+    }
+
+
+
+
 }

+ 2 - 1
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/authorize/impl/StoreInfoServiceImpl.java

@@ -17,8 +17,9 @@ public class StoreInfoServiceImpl implements StoreInfoService {
     private TbStoreInfoMapper tbStoreInfoMapper;
 
     @Override
-    public void addStoreInfo(TbStoreInfo tbStoreInfo) throws Exception {
+    public TbStoreInfo addStoreInfo(TbStoreInfo tbStoreInfo) throws Exception {
         tbStoreInfoMapper.insert( tbStoreInfo);
+        return tbStoreInfo;
     }
 
     @Override

+ 7 - 1
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/config/RestTemplateConfig.java

@@ -16,7 +16,13 @@ public class RestTemplateConfig {
     @Bean
     @LoadBalanced
     public RestTemplate restTemplate() {
-        System.out.println("来了吗老弟 ");
+        System.out.println("restTemplate nacos 服务间的调用 ");
+        return new RestTemplate();
+    }
+
+    @Bean("externalRequestsRestTemplate")
+    public RestTemplate externalRequestsRestTemplate() {
+        System.out.println("externalRequestsRestTemplate  对外发送请求 ");
         return new RestTemplate();
     }
 }

+ 0 - 14
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/mapper/TbAmzAuthorizeMapper.java

@@ -1,14 +0,0 @@
-package com.raycos.raycosdatacenterapi.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzAuthorize;
-
-/**
- * @Author: xiaojiabin
- * @Date: 2024/9/2 14:26
- */
-
-public interface TbAmzAuthorizeMapper extends BaseMapper<TbAmzAuthorize> {
-
-
-}

+ 8 - 0
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/mapper/TbAmzTokenMapper.java

@@ -4,9 +4,17 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzToken;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
 
 public interface TbAmzTokenMapper extends BaseMapper<TbAmzToken> {
     @Delete("DELETE FROM  tb_amz_token  WHERE id = #{id}")
     int delAmzToken(@Param("id") Long id );
 
+    @Update("UPDATE tb_amz_token " +
+            "SET access_token = #{accessToken}, " +
+            "token_type = #{tokenType} ," +
+            "expires_in =#{expiresIn } , " +
+            "refresh_token =#{refreshToken} " +
+            "WHERE id = #{id}")
+    int  updateAccessToken( TbAmzToken  tbAmzToken);
 }

+ 42 - 1
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/scheduledtasks/RefreshAmazonToken.java

@@ -1,11 +1,17 @@
 package com.raycos.raycosdatacenterapi.scheduledtasks;
 
+import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzToken;
+import com.raycos.raycosdatacenterapi.authorize.AmzTokenService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
 
+import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.List;
 
 /**
  * @Author: xiaojiabin
@@ -16,15 +22,50 @@ import java.time.format.DateTimeFormatter;
 @Slf4j
 public class RefreshAmazonToken {
 
-
+    /**
+     * {
+     * "access_token": "Atza|IwEBIBfvDi8BGuMZaWHUiClkd6mr9gucUJlIyf4yFjxpao9cfC4jDZXoud2G3ktVcMz6bYw2aweBLUu1E3otBYSaFbY7mJjqKGanMIW0EQX2a-RHPjpx_zkdkv719DmvZquQDgRCXywCogNG81usXd-ZwFYBQ96XjcYPaTC8w4WNNdJ4JHAo02BHRzLCV7I5E-S2u6PPoeM8lv-k7QXDvQhw7S1X2ldI2CVN0QYzMTDUqQ8M7Sn-UcaUJX_CD1AgN1HbsnJZlYLcC1FVmN5rj0tNzqA0s7Usc3be7RPVtFzBa58h75H7QnETHuhn_VordCETb7g",
+     * "refresh_token": "Atzr|IwEBIITKfZoBv6fJBrBBG1tJHhgCxqePUah2uQpaUaCRgMpzYowNrpO1fQZqJuH-YxtXue5E6-0fWlQWKr9BfxuyfnCejJtaX3jxKo0TdN6l6woAv8awQrhLJuwO-KN3kDrdiB3VKyEDy-R6V0pKz7b9w0gzTN-PEL-e7uA-5CaRLOwV_299HF4ZTsz5nrfZIQMZ1S0Rgbs3TNHhw48OAlLOIXlwt95mPL7gMLvy6CJf-u5_vwh38sCQLu472ViwGGr936lGN38QSBaXaUf6mKt9LT_12C5x68nBGNsi1ZhzdMGDLJZcVHiq5CSXzL-HSa1G2VDv-0ej1YupcjBefCFBGnIS",
+     * "token_type": "bearer",
+     * "expires_in": 3600
+     * }
+     */
     private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
 
+    @Autowired
+    private AmzTokenService amzTokenService;
     @Scheduled(fixedRate = 5000)
     public void reportCurrentTime() {
 
         log.info("现在时间是:" + dateTimeFormatter.format(LocalDateTime.now()));
+
+        try{
+            // 查询 令牌
+            List<TbAmzToken> list = amzTokenService.selAmzToken(null);
+            if(CollectionUtils.isEmpty(list)){
+                log.info(" 没有查询到 需要 刷新的 amz token 稍后再试!     ");
+                return;
+            }
+            // 获取当前时间戳
+            long second = Instant.now().getEpochSecond();
+
+            // 检查是否临近过期时间
+            for (TbAmzToken tbAmzToken : list) {
+
+                Long expiresIn = tbAmzToken.getExpiresIn();
+                if(  second >=  expiresIn ){
+                    RefreshTask.queue.put( tbAmzToken );
+                }
+
+            }
+        }catch (Exception e){
+            log.error( e.getMessage() , e );
+        }
+
+
     }
 
 
 
+
 }

+ 102 - 0
raycos_datacenter_api/src/main/java/com/raycos/raycosdatacenterapi/scheduledtasks/RefreshTask.java

@@ -0,0 +1,102 @@
+package com.raycos.raycosdatacenterapi.scheduledtasks;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzToken;
+import com.raycos.raycosdatacenterapi.authorize.AmzTokenService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedTransferQueue;
+import java.util.concurrent.locks.ReentrantLock;
+
+@Component
+@Slf4j
+public class RefreshTask {
+
+    public static LinkedTransferQueue<TbAmzToken> queue = new LinkedTransferQueue<>();
+    private final ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
+
+    @Autowired
+    private AmzTokenService amzTokenService;
+
+
+
+    public static final ReentrantLock lock = new ReentrantLock();
+
+
+    @Scheduled(fixedRate = 5000)
+    public void runTask() {
+        try {
+
+            log.info(" 调用用亚马逊 刷新令牌接口    ");
+            if (queue.isEmpty()) {
+                log.info(" 暂时没有需要刷新的LWA 令牌    ");
+                return;
+            }
+            if (lock.isLocked()) {
+                log.info(" 执行中...    ");
+                return;
+            }
+            lock.lock();
+            Runnable runnable;
+            while (!queue.isEmpty()) {
+
+                // 实现线程
+                runnable = new Runnable() {
+                    @Override
+                    public void run() {
+                        TbAmzToken poll = queue.poll();
+                        try {
+                            amzTokenService.lwaRefreshToken(  poll );
+                        } catch (Exception e) {
+                            log.error(" 亚马逊刷新令牌程序出错   异常参数=>" + JSONObject.toJSONString(poll) , e);
+                        }
+
+                    }
+                };
+                singleThreadPool.execute(runnable);
+                // 每个发出一个刷新请求 睡眠300毫秒 避免发送太快 超出亚马逊 每秒最大5个请求的限制
+                Thread.sleep(300);
+
+            }
+
+
+
+
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            try{
+                lock.unlock();
+            }catch (Exception ee){
+
+            }
+        }
+
+    }
+
+
+
+
+
+
+    /*
+    {
+    "grant_type": "refresh_token",
+    "refresh_token": "Atzr|IwEBIITKfZoBv6fJBrBBG1tJHhgCxqePUah2uQpaUaCRgMpzYowNrpO1fQZqJuH-YxtXue5E6-0fWlQWKr9BfxuyfnCejJtaX3jxKo0TdN6l6woAv8awQrhLJuwO-KN3kDrdiB3VKyEDy-R6V0pKz7b9w0gzTN-PEL-e7uA-5CaRLOwV_299HF4ZTsz5nrfZIQMZ1S0Rgbs3TNHhw48OAlLOIXlwt95mPL7gMLvy6CJf-u5_vwh38sCQLu472ViwGGr936lGN38QSBaXaUf6mKt9LT_12C5x68nBGNsi1ZhzdMGDLJZcVHiq5CSXzL-HSa1G2VDv-0ej1YupcjBefCFBGnIS",
+    "client_id": "amzn1.application-oa2-client.2d001c4aeaaf438f98ee0b07070c1cf8",
+    "client_secret": "amzn1.oa2-cs.v1.52b13f4ce04e83046b3426b620b6bfb94fd3ce61c815c6f68858af69d0ccbe54"
+}
+     */
+    /*
+    {
+    "access_token": "Atza|IwEBIBNp7J72AS5WkMjUq5LrhVMKk-dc9cbqoYnetxxTClYxYQb75c9x8R__m156V3fZj3UifdVq0VHsMINDGAnfXPKloDtx05sIl2EQ0Znetz8283UsCuObApHz-JY6wD2g_sZNcENHNZS_FLAB1nbWxI-c8teMv5W4ryBOlb4pMsQymSbqDfTtaPeq4RZ98vt3hzq6Zep6b7E2dyNXdcNLqbO8TI1q7SXy2-NPzGisq9CwxreVqeP9DZb91uSZs060Ofu5NneABx3SyUMa-yPWPJZ7Wqys-V472un5v9s_b--Bibz8mqWqm6OI4SV7aprOPaI_vtM92L55bxoLnzsfCNxp",
+    "refresh_token": "Atzr|IwEBIITKfZoBv6fJBrBBG1tJHhgCxqePUah2uQpaUaCRgMpzYowNrpO1fQZqJuH-YxtXue5E6-0fWlQWKr9BfxuyfnCejJtaX3jxKo0TdN6l6woAv8awQrhLJuwO-KN3kDrdiB3VKyEDy-R6V0pKz7b9w0gzTN-PEL-e7uA-5CaRLOwV_299HF4ZTsz5nrfZIQMZ1S0Rgbs3TNHhw48OAlLOIXlwt95mPL7gMLvy6CJf-u5_vwh38sCQLu472ViwGGr936lGN38QSBaXaUf6mKt9LT_12C5x68nBGNsi1ZhzdMGDLJZcVHiq5CSXzL-HSa1G2VDv-0ej1YupcjBefCFBGnIS",
+    "token_type": "bearer",
+    "expires_in": 3600
+     */
+}