Selaa lähdekoodia

调用claudecode接口重试

zoujiajian 1 vuosi sitten
vanhempi
sitoutus
282310722e

+ 0 - 14
netflix-service/src/main/java/com/cyksj/service/claude/ClaudeCodeService.java

@@ -3,13 +3,11 @@ package com.cyksj.service.claude;
 import com.cyksj.model.entity.ClaudeCodeUser;
 import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.request.ClaudeCodeApiKeysReq;
-import com.cyksj.model.request.ClaudeCodeApiKeysStatusReq;
 import com.cyksj.model.request.ClaudeCodeDelReq;
 import com.cyksj.model.response.ClaudeCodePointsHistoryResp;
 import com.cyksj.model.response.claudecode.ClaudeCodeResp;
 import com.cyksj.model.views.ClaudeCodeUserApiKeysView;
 import com.cyksj.model.views.ClaudeCodeUserInfoView;
-import com.cyksj.model.views.ClaudeCodeUserPackageView;
 
 import java.util.List;
 
@@ -31,11 +29,6 @@ public interface ClaudeCodeService {
 	 */
 	ClaudeCodeResp createApiKeys(ClaudeCodeApiKeysReq req) throws Exception;
 
-	/**
-	 * 用户更新api key状态
-	 */
-	void updateApiKeysStatus(ClaudeCodeApiKeysStatusReq req) throws Exception;
-
 	/**
 	 * 删除api key
 	 */
@@ -46,15 +39,8 @@ public interface ClaudeCodeService {
 	 */
 	List<ClaudeCodeUserApiKeysView> getUserApiKeys(long userId) throws Exception;
 
-	/**
-	 * 用户套餐信息
-	 */
-	ClaudeCodeUserPackageView getUserPackage(long userId) throws Exception;
-
 	ClaudeCodePointsHistoryResp getUserPointsDetail(Long userId, String type, Integer page, Integer limit) throws Exception;
 
-	ClaudeCodeResp getUserPointsStatisticsData(Long userId, Integer days) throws Exception;
-
 	ClaudeCodeResp getUserDashboard(Long userId) throws Exception;
 
 	ClaudeCodeResp getUserBalance(Long userId) throws Exception;

+ 80 - 105
netflix-service/src/main/java/com/cyksj/service/claude/impl/ClaudeCodeServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.http.HttpException;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.http.Method;
@@ -16,18 +17,17 @@ import com.cyksj.mapper.*;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.GroupsRelationView;
 import com.cyksj.model.request.ClaudeCodeApiKeysReq;
-import com.cyksj.model.request.ClaudeCodeApiKeysStatusReq;
 import com.cyksj.model.request.ClaudeCodeDelReq;
 import com.cyksj.model.response.ClaudeCodePointsHistoryResp;
 import com.cyksj.model.response.claudecode.ClaudeCodeResp;
 import com.cyksj.model.views.ClaudeCodeUserApiKeysView;
 import com.cyksj.model.views.ClaudeCodeUserInfoView;
-import com.cyksj.model.views.ClaudeCodeUserPackageView;
 import com.cyksj.service.claude.ClaudeCodeService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.ejlchina.searcher.BeanSearcher;
 import com.ejlchina.searcher.param.Operator;
 import com.ejlchina.searcher.util.MapUtils;
+import com.github.rholder.retry.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.dao.DuplicateKeyException;
@@ -37,6 +37,8 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 项目名: yhlxj11111111
@@ -66,6 +68,9 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 
 	public static final String CLAUDE_CODE_API_ADMIN_KEY = "claudecodeyhlxjclaude";
 
+	//连接超时时间 毫秒
+	public static final int CONNECT_MILLISECONDS = 10000;
+
 	@Override
 	public void generateOrUpdateClaudeCodeUserInfo(Long orderId, Long relationId, Long userId, GoodsDonSku sku, Integer orderType) {
 		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
@@ -84,31 +89,31 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		Integer codePoints = sku.getCodePoints();
 		Integer codeCreditRecovery = sku.getCodeCreditRecovery();
 		Long skuId = sku.getId();
-		try {
-			Boolean isUpgrade = false;
-			Date renewExpiryTime = null;
-			//若是续费升级 记录此时续费升级的过期时间
-			if (thisRelationCodePoints != null && thisRelationCodePoints <= codePoints && !ObjectUtil.equal(thisCodeOriSkuId, skuId)) {
-				saveClaudeCodeRenewExpiryRecord(orderId, relationUserId, relationId, expiryTime, skuId);
-				if (sku.getDays() != null) {
-					renewExpiryTime = DateUtil.offsetDay(DateTime.now(), sku.getDays());
-				} else {
-					renewExpiryTime = DateUtil.offsetMonth(DateTime.now(), sku.getMonths());
-				}
-				isUpgrade = true;
+		Boolean isUpgrade = false;
+		Date renewExpiryTime = null;
+		//若是续费升级 记录此时续费升级的过期时间
+		if (thisRelationCodePoints != null && thisRelationCodePoints <= codePoints && !ObjectUtil.equal(thisCodeOriSkuId, skuId)) {
+			saveClaudeCodeRenewExpiryRecord(orderId, relationUserId, relationId, expiryTime, skuId);
+			if (sku.getDays() != null) {
+				renewExpiryTime = DateUtil.offsetDay(DateTime.now(), sku.getDays());
+			} else {
+				renewExpiryTime = DateUtil.offsetMonth(DateTime.now(), sku.getMonths());
 			}
-			relationMapper.updateById(relation);
-			//清缓存
-			if (orderType == 2) {
-				invalidateUserCache(relationUserId);
-			}
-			generateOrUpdateClaudeCodeUser(relationUserId, relationId, codePoints, codeCreditRecovery, expiryTime, isUpgrade, orderId, skuId, renewExpiryTime, sku.getSpecVal());
+			isUpgrade = true;
+		}
+		generateOrUpdateClaudeCodeUser(relationUserId, relationId, codePoints, codeCreditRecovery, expiryTime, isUpgrade, orderId, skuId, renewExpiryTime, sku.getSpecVal());
+		try {
 			//生成claude code或更新用户套餐
 			ClaudeCodeResp codeUserPackage = createOrUpdateClaudeCodeUserPackage(relation.getUserId(), sku.getSpecVal(), codePoints, codeCreditRecovery, expiryTime);
 			if (!Constant.SUCCESS.equals(codeUserPackage.getMessage())) {
 				log.info("更新 claude code 用户:{}套餐数据失败", userId);
 				//重试更新code userInfo数据
 				setClaudeCodeUserRetryUpdateInfo(relationId);
+				return;
+			}
+			//清缓存
+			if (orderType == 2) {
+				invalidateUserCache(relationUserId);
 			}
 		} catch (Exception e) {
 			log.error("生成或更新claude code用户:{}套餐skuId:{} 失败,error_info:{}", userId, skuId, StringUtil.getErrorText(e));
@@ -165,27 +170,6 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		throw new BusinessRuntimeException("您还没有claudecode账号");
 	}
 
-	@Override
-	public void updateApiKeysStatus(ClaudeCodeApiKeysStatusReq req) throws Exception {
-		Long userId = req.getUserId();
-		Integer keyId = req.getId();
-		String status = req.getStatus();
-		String keyValue = req.getKeyValue();
-		if (checkClaudeCodeUser(userId)) {
-			Long claudeCodeUserId = getClaudeCodeUserId(userId);
-			Assert.notNull(claudeCodeUserId, "您的claude code账号已过期");
-			String apiKeyUrl = String.format(CLAUDE_CODE_API_PREFIX + "api/keys/%s/%s", claudeCodeUserId, keyId);
-			Map<String, Object> parmas = new HashMap<>();
-			parmas.put("status", status);
-			String responseBody = executeClaudeCodePostApi(apiKeyUrl, parmas.toString());
-			ClaudeCodeResp claudeCodeResp = Jsons.parseObject(responseBody, ClaudeCodeResp.class);
-			if (!Constant.SUCCESS.equals(claudeCodeResp.getMessage())) {
-				//更新用户apikey缓存
-				updateUserApiKeysCache(keyValue);
-			}
-		}
-	}
-
 	@Override
 	public void deleteApiKeysById(ClaudeCodeDelReq delReq) throws Exception {
 		Long userId = delReq.getUserId();
@@ -193,7 +177,7 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		if (checkClaudeCodeUser(userId)) {
 			Long claudeCodeUserId = getClaudeCodeUserId(userId);
 			String url = String.format(CLAUDE_CODE_API_PREFIX + "api/keys/%s/%s", claudeCodeUserId, keyId);
-			HttpResponse execute = HttpUtil.createRequest(Method.DELETE, url).execute();
+			HttpResponse execute = HttpUtil.createRequest(Method.DELETE, url).setConnectionTimeout(CONNECT_MILLISECONDS).execute();
 			String responseBody = execute.body();
 			ClaudeCodeResp claudeCodeResp = Jsons.parseObject(responseBody, ClaudeCodeResp.class);
 			if (!Constant.SUCCESS.equals(claudeCodeResp.getMessage())) {
@@ -202,17 +186,6 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		}
 	}
 
-	/**
-	 * 更新api key缓存
-	 * @param keyValue
-	 */
-	private void updateUserApiKeysCache(String keyValue) {
-		String url = CLAUDE_CODE_API_PREFIX + "api/cache/invalidate/apikey";
-		Map<String, Object> parmas = new HashMap<>();
-		parmas.put("api_key", keyValue);
-		executeClaudeCodePostApi(url,parmas.toString());
-	}
-
 	@Override
 	public List<ClaudeCodeUserApiKeysView> getUserApiKeys(long userId) throws Exception {
 		Long claudeCodeUserId = getClaudeCodeUserId(userId);
@@ -225,20 +198,6 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		return null;
 	}
 
-	@Override
-	public ClaudeCodeUserPackageView getUserPackage(long userId) throws Exception {
-		Long claudeCodeUserId = getClaudeCodeUserId(userId);
-		if (claudeCodeUserId != null) {
-			String url = String.format(CLAUDE_CODE_API_PREFIX + "api/users/%s/plan", claudeCodeUserId);
-			String responseBody = executeClaudeCodeGetApi(url);
-			ClaudeCodeResp claudeCodeResp = Jsons.parseObject(responseBody, ClaudeCodeResp.class);
-			if (!Constant.SUCCESS.equals(claudeCodeResp.getMessage())) {
-				return Jsons.parseObject(responseBody, ClaudeCodeUserPackageView.class);
-			}
-		}
-		return null;
-	}
-
 	@Override
 	public ClaudeCodePointsHistoryResp getUserPointsDetail(Long userId, String type, Integer page, Integer limit) throws Exception {
 		Long claudeCodeUserId = getClaudeCodeUserId(userId);
@@ -252,18 +211,6 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		return null;
 	}
 
-	@Override
-	public ClaudeCodeResp getUserPointsStatisticsData(Long userId, Integer days) throws Exception {
-		Long claudeCodeUserId = getClaudeCodeUserId(userId);
-		if (claudeCodeUserId != null) {
-			String url = String.format(CLAUDE_CODE_API_PREFIX + "api/users/%s/usage/stats?days=%s", claudeCodeUserId, days);
-			String responseBody = executeClaudeCodeGetApi(url);
-			ClaudeCodeResp claudeCodeResp = Jsons.parseObject(responseBody, ClaudeCodeResp.class);
-			return claudeCodeResp;
-		}
-		return null;
-	}
-
 	@Override
 	public ClaudeCodeResp getUserDashboard(Long userId) throws Exception {
 		Long claudeCodeUserId = getClaudeCodeUserId(userId);
@@ -312,7 +259,11 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 	@Override
 	public void invalidateUserCache(Long userId) {
 		String url = String.format(CLAUDE_CODE_API_PREFIX + "api/cache/invalidate/user/%s", userId);
-		executeClaudeCodeGetApi(url);
+		try {
+			executeClaudeCodePostApi(url, null);
+		} catch (Exception e) {
+
+		}
 	}
 
 	@Override
@@ -417,24 +368,23 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 	 * claude code GET请求
 	 */
 	public String executeClaudeCodeGetApi(String url) {
-		HttpResponse execute = HttpUtil.createGet(url)
-				.header("X-Admin-Key", CLAUDE_CODE_API_ADMIN_KEY)
-				.setConnectionTimeout(3000)
-				.setReadTimeout(3000)
-				.execute();
-		return execute.body();
-	}
-
-	/**
-	 * claude code GET请求
-	 */
-	public String executeClaudeCodeDeleteApi(String url) {
-		HttpResponse execute = HttpUtil.createPost(url)
-				.header("X-Admin-Key", CLAUDE_CODE_API_ADMIN_KEY)
-				.setConnectionTimeout(3000)
-				.setReadTimeout(3000)
-				.execute();
-		return execute.body();
+		Retryer<String> build = getApiRetryer(1, 3);
+		try {
+			return build.call(() -> {
+				try {
+					HttpResponse execute = HttpUtil.createGet(url)
+							.header("X-Admin-Key", CLAUDE_CODE_API_ADMIN_KEY)
+							.setConnectionTimeout(CONNECT_MILLISECONDS)
+							.execute();
+					return execute.body();
+				} catch (HttpException e) {
+					return null;
+				}
+			});
+		} catch (ExecutionException | RetryException e) {
+			log.info("重试调用claude code GET请求url->{}失败,msg->{}", url, StringUtil.getErrorText(e));
+			throw BusinessRuntimeException.getInstance("接口请求失败");
+		}
 	}
 
 
@@ -442,13 +392,24 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 	 * claude code Post请求
 	 */
 	public String executeClaudeCodePostApi(String url, String body) {
-		HttpResponse execute = HttpUtil.createPost(url)
-				.header("X-Admin-Key", CLAUDE_CODE_API_ADMIN_KEY)
-				.setConnectionTimeout(3000)
-				.setReadTimeout(3000)
-				.body(body)
-				.execute();
-		return execute.body();
+		Retryer<String> build = getApiRetryer(1, 3);
+		try {
+			return build.call(() -> {
+				try {
+					HttpResponse execute = HttpUtil.createPost(url)
+							.header("X-Admin-Key", CLAUDE_CODE_API_ADMIN_KEY)
+							.setConnectionTimeout(CONNECT_MILLISECONDS)
+							.body(body)
+							.execute();
+					return execute.body();
+				} catch (Exception e) {
+					return null;
+				}
+			});
+		} catch (ExecutionException | RetryException e) {
+			log.info("重试调用claude code POST请求 url->{}失败,msg->{}", url, StringUtil.getErrorText(e));
+			throw BusinessRuntimeException.getInstance("接口请求失败");
+		}
 	}
 
 	/**
@@ -475,4 +436,18 @@ public class ClaudeCodeServiceImpl implements ClaudeCodeService {
 		}
 	}
 
+	public Retryer getApiRetryer(Integer sleepSecond, Integer attemptNum) {
+		Retryer<String> build = RetryerBuilder.<String>newBuilder()
+				.retryIfException()
+				//运行时异常重试
+				.retryIfRuntimeException()
+				//false重试
+				.retryIfResult(res -> res == null)
+				//1s 间隔
+				.withWaitStrategy(WaitStrategies.fixedWait(sleepSecond, TimeUnit.SECONDS))
+				//停止策略 : 尝试请求3次
+				.withStopStrategy(StopStrategies.stopAfterAttempt(attemptNum)).build();
+		return build;
+	}
+
 }