Kaynağa Gözat

Merge branch 'refs/heads/master' into pre

zoujiajian 1 ay önce
ebeveyn
işleme
655880e20c

+ 21 - 7
netflix-service/src/main/java/com/cyksj/server/recharge/impl/GptProxyRechargeServiceImpl.java

@@ -251,6 +251,26 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
         }
     }
 
+    private String getAccessTokenFromRechargePayload(String saveTokenJson) {
+        try {
+            JSONObject jsonObject = JSONUtil.parseObj(saveTokenJson);
+            String accessToken = jsonObject.getStr("accessToken");
+            if (StrUtil.isNotBlank(accessToken)) {
+                return accessToken;
+            }
+            String payload = jsonObject.getStr("payload");
+            if (StrUtil.isNotBlank(payload)) {
+                GptCardTokenDto gptCardTokenDto = Jsons.parseObject(payload, GptCardTokenDto.class);
+                if (gptCardTokenDto != null && StrUtil.isNotBlank(gptCardTokenDto.getAccessToken())) {
+                    return gptCardTokenDto.getAccessToken();
+                }
+            }
+        } catch (Exception e) {
+            return saveTokenJson;
+        }
+        return saveTokenJson;
+    }
+
 	@Override
 	@Transactional(rollbackFor = Throwable.class)
 	public String confirmRecharge(GroupsRelationRechargeReq req) {
@@ -330,13 +350,7 @@ public class GptProxyRechargeServiceImpl implements GptProxyRechargeService {
 			}
 			//入库token json
 			String saveTokenJson = req.getAccessToken();
-			String accessToken;
-			try {
-				GptCardTokenDto gptCardTokenDto = Jsons.parseObject(saveTokenJson, GptCardTokenDto.class);
-				accessToken = gptCardTokenDto.getAccessToken();
-			} catch (Exception e) {
-				accessToken = saveTokenJson;
-			}
+			String accessToken = getAccessTokenFromRechargePayload(saveTokenJson);
 			//验证用户token是否正确
 			TokenParseResult tokenParseResult = parseToken(accessToken);
 			if (!tokenParseResult.getSuccess()) {

+ 21 - 7
netflix-service/src/main/java/com/cyksj/service/mange/gpt/impl/GptRechargeServiceImpl.java

@@ -201,13 +201,7 @@ public class GptRechargeServiceImpl implements GptRechargeService {
 			}
 			//入库token json
 			String saveTokenJson = req.getAccessToken();
-			String accessToken;
-			try {
-				GptCardTokenDto gptCardTokenDto = Jsons.parseObject(saveTokenJson, GptCardTokenDto.class);
-				accessToken = gptCardTokenDto.getAccessToken();
-			} catch (Exception e) {
-				accessToken = saveTokenJson;
-			}
+			String accessToken = getAccessTokenFromRechargePayload(saveTokenJson);
 			//验证用户token是否正确
 			TokenParseResult tokenParseResult = parseToken(accessToken);
 			if (!tokenParseResult.getSuccess()) {
@@ -409,6 +403,26 @@ public class GptRechargeServiceImpl implements GptRechargeService {
 		}
 	}
 
+    private String getAccessTokenFromRechargePayload(String saveTokenJson) {
+        try {
+            JSONObject jsonObject = JSONUtil.parseObj(saveTokenJson);
+            String accessToken = jsonObject.getStr("accessToken");
+            if (StrUtil.isNotBlank(accessToken)) {
+                return accessToken;
+            }
+            String payload = jsonObject.getStr("payload");
+            if (StrUtil.isNotBlank(payload)) {
+                GptCardTokenDto gptCardTokenDto = Jsons.parseObject(payload, GptCardTokenDto.class);
+                if (gptCardTokenDto != null && StrUtil.isNotBlank(gptCardTokenDto.getAccessToken())) {
+                    return gptCardTokenDto.getAccessToken();
+                }
+            }
+        } catch (Exception e) {
+            return saveTokenJson;
+        }
+        return saveTokenJson;
+    }
+
 	@Override
 	public void gptIndependentExportRecharge(GptIndependentExportRechargeReq rechargeReq) {
 		String orderNo = rechargeReq.getOrderNo();

+ 110 - 77
netflix-service/src/main/java/com/cyksj/service/recharge/impl/RedeemCloudRechargeServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
+import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.cyksj.common.exception.BusinessRuntimeException;
@@ -13,7 +14,6 @@ import com.cyksj.common.util.Jsons;
 import com.cyksj.mapper.*;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.response.recharge.RedeemCloudCdkQueryResponse;
-import com.cyksj.model.response.recharge.RedeemCloudExchangeResponse;
 import com.cyksj.model.response.recharge.RedeemCloudTaskResultResponse;
 import com.cyksj.redis.RedisService;
 import com.cyksj.server.recharge.dto.TaskResult;
@@ -24,6 +24,9 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.Date;
 
 @Service
@@ -51,45 +54,29 @@ public class RedeemCloudRechargeServiceImpl implements RedeemCloudRechargeServic
 
     private static final int SUCCESS_CODE = 200;
 
-    private static final int UNUSED_STATUS = 0;
+    private static final int LEGACY_SUCCESS_CODE = 10000;
 
     @Override
     public RedeemCloudCdkQueryResponse validateCardKey(String cardKey) throws Exception {
         String baseUrl = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
-        String url = baseUrl + "/sys-cdk/query?cdkCode=" + cardKey;
+        String url = baseUrl + "/sys-cdk/query?cdkCode=" + encode(cardKey);
 
         HttpResponse response = HttpRequest.get(url)
                 .setConnectionTimeout(10000)
                 .execute();
         String body = response.body();
-        log.info("redeemcloud验证卡密结果: {}", body);
+        log.info("redeemcloud validate card key response: {}", body);
         return Jsons.parseObject(body, RedeemCloudCdkQueryResponse.class);
     }
 
     @Override
     public String confirmRecharge(GroupsRelation relation, String gptCardKey, CmsUser cmsUser) {
         Long relationId = relation.getId();
-        RedeemCloudCdkQueryResponse validateResponse;
-        try {
-            validateResponse = validateCardKey(gptCardKey);
-        } catch (Exception e) {
-            if (cmsUser == null) {
-                throw BusinessRuntimeException.getInstance("系统繁忙,请重试");
-            }
-            throw BusinessRuntimeException.getInstance("卡密:{0}错误", gptCardKey);
-        }
-        if (!isCardKeyAvailable(validateResponse)) {
-            if (cmsUser == null) {
-                throw BusinessRuntimeException.getInstance("系统繁忙,请重试");
-            }
-            throw BusinessRuntimeException.getInstance(getValidateErrorMessage(validateResponse, gptCardKey));
-        }
-
-        String accessToken = relation.getGptToken();
+        String rechargePayload = relation.getGptToken();
         String rechargeAccount = relation.getAccount();
         String taskId;
         try {
-            taskId = submitTask(gptCardKey, accessToken);
+            taskId = submitTask(gptCardKey, rechargePayload);
         } catch (Exception e) {
             setRechargeRelationStatusAutoError(relation);
             if (cmsUser == null) {
@@ -106,7 +93,7 @@ public class RedeemCloudRechargeServiceImpl implements RedeemCloudRechargeServic
                 .set(StrUtil.isNotBlank(password), GroupsRelation::getPassword, password)
                 .set(GroupsRelation::getRechargeStatus, GroupsRelation.RechargeStatus.recharging)
                 .set(GroupsRelation::getCardKey, gptCardKey)
-                .set(GroupsRelation::getGptToken, accessToken)
+                .set(GroupsRelation::getGptToken, rechargePayload)
                 .set(GroupsRelation::getGptTaskId, taskId)
                 .eq(GroupsRelation::getId, relationId));
         relation.setRechargeStatus(GroupsRelation.RechargeStatus.recharging);
@@ -115,70 +102,98 @@ public class RedeemCloudRechargeServiceImpl implements RedeemCloudRechargeServic
         return taskId;
     }
 
-    private boolean isCardKeyAvailable(RedeemCloudCdkQueryResponse validateResponse) {
-        return validateResponse != null
-                && validateResponse.getCode() != null
-                && validateResponse.getCode() == SUCCESS_CODE
-                && validateResponse.getData() != null
-                && validateResponse.getData().getUseStatus() != null
-                && validateResponse.getData().getUseStatus() == UNUSED_STATUS
-                && Boolean.TRUE.equals(validateResponse.getData().getChannelEnabled());
-    }
-
-    private String getValidateErrorMessage(RedeemCloudCdkQueryResponse validateResponse, String cardKey) {
-        if (validateResponse == null) {
-            return "卡密错误:" + cardKey;
-        }
-        if (StrUtil.isNotBlank(validateResponse.getMessage())) {
-            return validateResponse.getMessage();
-        }
-        return "卡密错误:" + cardKey;
-    }
-
     private String submitTask(String cardKey, String rechargePayload) {
-        log.info("开始提交redeemcloud任务 - 卡密: {}", cardKey);
+        log.info("start submit redeemcloud task - cardKey: {}", cardKey);
         try {
             String baseUrl = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
-            String url = baseUrl + "/sys-cdk/exchange?cdkCode=" + cardKey;
-            String requestBody = normalizeRechargePayload(rechargePayload);
+            String requestBody = buildExchangeBody(baseUrl, cardKey, rechargePayload);
+            String url = baseUrl + "/sys-cdk/exchange?cdkCode=" + encode(cardKey);
 
-            HttpResponse response = HttpRequest.post(url)
+            HttpResponse response = addBrowserHeaders(HttpRequest.post(url)
                     .setConnectionTimeout(60000)
-                    .header("accept", "*/*")
-                    .header("accept-language", "zh-CN")
-                    .header("content-type", "application/json")
-                    .header("origin", "https://redeemcloud.com")
-                    .header("referer", "https://redeemcloud.com/zh")
-                    .header("sec-ch-ua", "\"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"150\", \"Microsoft Edge\";v=\"150\"")
-                    .header("sec-ch-ua-mobile", "?0")
-                    .header("sec-ch-ua-platform", "\"Windows\"")
-                    .header("sec-fetch-dest", "empty")
-                    .header("sec-fetch-mode", "cors")
-                    .header("sec-fetch-site", "same-origin")
-                    .header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0")
-                    .header("x-product-code", "GPT")
+                    .header("content-type", "application/json"))
                     .body(requestBody)
                     .execute();
             String body = response.body();
-            log.info("redeemcloud任务提交响应: {}", body);
+            log.info("redeemcloud submit response: {}", body);
 
-            RedeemCloudExchangeResponse exchangeResponse = Jsons.parseObject(body, RedeemCloudExchangeResponse.class);
-            if (exchangeResponse != null && exchangeResponse.getCode() != null && exchangeResponse.getCode() == SUCCESS_CODE && StrUtil.isNotBlank(exchangeResponse.getData())) {
-                return exchangeResponse.getData();
+            JSONObject jsonResponse = JSONUtil.parseObj(body);
+            Object data = jsonResponse.get("data");
+            if (isSuccessResponse(jsonResponse) && data instanceof CharSequence && StrUtil.isNotBlank(data.toString())) {
+                return data.toString();
+            }
+            if (data instanceof JSONObject) {
+                JSONObject dataObj = (JSONObject) data;
+                String status = dataObj.getStr("status");
+                if ("FAILED".equalsIgnoreCase(status)) {
+                    throw BusinessRuntimeException.getInstance(getErrorMessage(dataObj, jsonResponse));
+                }
             }
-            String errorMessage = exchangeResponse != null && StrUtil.isNotBlank(exchangeResponse.getMessage()) ? exchangeResponse.getMessage() : "提交任务失败";
-            throw BusinessRuntimeException.getInstance(errorMessage);
+            throw BusinessRuntimeException.getInstance(getErrorMessage(null, jsonResponse));
         } catch (Exception e) {
-            log.error("提交redeemcloud任务失败: {}", e.getMessage(), e);
+            log.error("submit redeemcloud task failed: {}", e.getMessage(), e);
             throw new RuntimeException("提交任务失败: " + e.getMessage(), e);
         }
     }
 
-    private String normalizeRechargePayload(String rechargePayload) {
+    private String buildExchangeBody(String baseUrl, String cardKey, String rechargePayload) throws Exception {
         if (StrUtil.isBlank(rechargePayload) || !StrUtil.startWith(rechargePayload.trim(), "{")) {
-            throw BusinessRuntimeException.getInstance("redeemcloud提交任务需要完整充值参数JSON");
+            throw BusinessRuntimeException.getInstance("redeemcloud提交任务需要完整session JSON");
+        }
+        JSONObject payload = JSONUtil.parseObj(rechargePayload);
+        if (isExchangeBody(payload)) {
+            return payload.toString();
+        }
+        return verifyAccount(baseUrl, cardKey, rechargePayload).toString();
+    }
+
+    private boolean isExchangeBody(JSONObject payload) {
+        return payload.containsKey("cdkPackageName") && payload.containsKey("payload") && payload.containsKey("idp");
+    }
+
+    private JSONObject verifyAccount(String baseUrl, String cardKey, String content) {
+        String url = baseUrl + "/account/verify?cdkCode=" + encode(cardKey) + "&content=" + encode(content);
+        HttpResponse response = addBrowserHeaders(HttpRequest.post(url)
+                .setConnectionTimeout(60000))
+                .execute();
+        String body = response.body();
+        log.info("redeemcloud account verify response: {}", body);
+
+        JSONObject jsonResponse = JSONUtil.parseObj(body);
+        Object data = jsonResponse.get("data");
+        if (isSuccessResponse(jsonResponse) && data instanceof JSONObject) {
+            return (JSONObject) data;
+        }
+        throw BusinessRuntimeException.getInstance(getErrorMessage(data instanceof JSONObject ? (JSONObject) data : null, jsonResponse));
+    }
+
+    private HttpRequest addBrowserHeaders(HttpRequest request) {
+        return request
+                .header("accept", "*/*")
+                .header("accept-language", "zh-CN")
+                .header("origin", "https://redeemcloud.com")
+                .header("referer", "https://redeemcloud.com/zh")
+                .header("sec-ch-ua", "\"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"150\", \"Microsoft Edge\";v=\"150\"")
+                .header("sec-ch-ua-mobile", "?0")
+                .header("sec-ch-ua-platform", "\"Windows\"")
+                .header("sec-fetch-dest", "empty")
+                .header("sec-fetch-mode", "cors")
+                .header("sec-fetch-site", "same-origin")
+                .header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0")
+                .header("x-product-code", "GPT");
+    }
+
+    private boolean isSuccessResponse(JSONObject jsonResponse) {
+        Integer code = jsonResponse.getInt("code");
+        return code != null && (code == SUCCESS_CODE || code == LEGACY_SUCCESS_CODE) && !Boolean.FALSE.equals(jsonResponse.getBool("flag"));
+    }
+
+    private String encode(String value) {
+        try {
+            return URLEncoder.encode(value, StandardCharsets.UTF_8.name());
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
         }
-        return JSONUtil.parseObj(rechargePayload).toString();
     }
 
     @Override
@@ -191,20 +206,20 @@ public class RedeemCloudRechargeServiceImpl implements RedeemCloudRechargeServic
             resetGroupsRelationRechargeStatus(relation, taskResult.getStatus(), taskResult.getError());
             return taskResult;
         } catch (Exception e) {
-            log.error("查询redeemcloud任务结果失败: {}", e.getMessage(), e);
+            log.error("query redeemcloud task result failed: {}", e.getMessage(), e);
             throw new RuntimeException("获取任务结果失败: " + e.getMessage(), e);
         }
     }
 
     private RedeemCloudTaskResultResponse queryTaskResult(String cardKey, String taskId) throws Exception {
         String baseUrl = gptRechargeCardKeyChannelService.getCardKeyDomain(cardKey);
-        String url = baseUrl + "/sys-cdk/exchange/result?taskId=" + taskId;
+        String url = baseUrl + "/sys-cdk/exchange/result?taskId=" + encode(taskId);
 
         HttpResponse response = HttpRequest.get(url)
                 .setConnectionTimeout(10000)
                 .execute();
         String body = response.body();
-        log.info("redeemcloud任务查询响应: {}", body);
+        log.info("redeemcloud task result response: {}", body);
         return Jsons.parseObject(body, RedeemCloudTaskResultResponse.class);
     }
 
@@ -225,10 +240,6 @@ public class RedeemCloudRechargeServiceImpl implements RedeemCloudRechargeServic
             result.setStatus("completed");
         } else if ("FAILED".equalsIgnoreCase(status) || "ERROR".equalsIgnoreCase(status)) {
             result.setStatus("failed");
-        } else if (taskResultResponse.getData().getUseStatus() != null && taskResultResponse.getData().getUseStatus() != UNUSED_STATUS) {
-            result.setStatus("completed");
-        } else if (StrUtil.isNotBlank(taskResultResponse.getData().getEmail()) || StrUtil.isNotBlank(taskResultResponse.getData().getAccountId())) {
-            result.setStatus("completed");
         } else {
             result.setStatus("recharging");
         }
@@ -237,6 +248,28 @@ public class RedeemCloudRechargeServiceImpl implements RedeemCloudRechargeServic
         return result;
     }
 
+    private String getErrorMessage(JSONObject data, JSONObject response) {
+        if (data != null) {
+            String error = data.getStr("error");
+            if (StrUtil.isNotBlank(error)) {
+                return error;
+            }
+            String errorMessage = data.getStr("errorMessage");
+            if (StrUtil.isNotBlank(errorMessage)) {
+                return errorMessage;
+            }
+            String result = data.getStr("result");
+            if (StrUtil.isNotBlank(result)) {
+                return result;
+            }
+        }
+        String message = response.getStr("message");
+        if (StrUtil.isBlank(message)) {
+            message = response.getStr("msg");
+        }
+        return StrUtil.isNotBlank(message) ? message : "提交任务失败";
+    }
+
     public void setRechargeRelationStatusAutoError(GroupsRelation relation) {
         TASK_EXECUTOR.execute(() -> relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
                 .set(GroupsRelation::getAccount, relation.getAccount())