| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- package com.cyksj.service.api.impl;
- import cn.hutool.core.date.DateUtil;
- import cn.hutool.http.HttpException;
- import cn.hutool.http.HttpResponse;
- import cn.hutool.http.HttpUtil;
- import cn.hutool.http.Method;
- import com.cyksj.common.constant.Constant;
- import com.cyksj.common.exception.BusinessRuntimeException;
- import com.cyksj.common.util.Jsons;
- import com.cyksj.common.util.StringUtil;
- import com.cyksj.model.request.ClaudeCodeApiKeysReq;
- import com.cyksj.model.response.claudecode.ClaudeCodeResp;
- import com.cyksj.model.views.ClaudeCodeUserApiKeysView;
- import com.cyksj.service.api.ClaudeCodexApiService;
- import com.github.rholder.retry.*;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- 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
- * 文件名: ClaudeCodexApiServiceImpl
- * 创建者: JavaZou
- * 创建时间:2025/9/25 16:35
- */
- @Service
- @RequiredArgsConstructor
- @Slf4j
- public class ClaudeCodexApiServiceImpl implements ClaudeCodexApiService {
- @Override
- public ClaudeCodeResp createApiKeys(ClaudeCodeApiKeysReq req) throws Exception {
- String apiKeyUrl = String.format(Constant.CLAUDE_CODE_API_PREFIX + "api/users/%s/keys", req.getUserId());
- Map<String, Object> parmas = new HashMap<>();
- parmas.put("name", req.getName());
- Integer expiresDays = req.getExpiresDays();
- if (expiresDays != null) {
- parmas.put("expires_days", expiresDays);
- }
- ClaudeCodeResp claudeCodeResp = executePostApi(apiKeyUrl, Jsons.toJson(parmas));
- if (!Constant.SUCCESS.equals(claudeCodeResp.getMessage())) {
- throw BusinessRuntimeException.getInstance("创建失败");
- }
- return claudeCodeResp;
- }
- @Override
- public void deleteApiKeysById(Long userId, Long keyId) throws Exception {
- String url = String.format(Constant.CLAUDE_CODE_API_PREFIX + "api/keys/%s/%s", userId, keyId);
- HttpResponse execute = HttpUtil.createRequest(Method.DELETE, url).header(Constant.CLAUDE_CODE_HEARD_KEY, Constant.CLAUDE_CODE_API_ADMIN_KEY).setConnectionTimeout(Constant.CONNECT_MILLISECONDS).execute();
- String responseBody = execute.body();
- ClaudeCodeResp claudeCodeResp = Jsons.parseObject(responseBody, ClaudeCodeResp.class);
- if (!Constant.SUCCESS.equals(claudeCodeResp.getMessage())) {
- log.error("删除key失败:{}", claudeCodeResp.getMessage());
- throw BusinessRuntimeException.getInstance("删除失败");
- }
- }
- @Override
- public List<ClaudeCodeUserApiKeysView> getUserApiKeys(Long codexUserId) {
- String url = String.format(Constant.CLAUDE_CODE_API_PREFIX + "api/users/%s/keys", codexUserId);
- ClaudeCodeResp claudeCodeResp = executeGetApi(url);
- return Jsons.parseList(claudeCodeResp.getData(), ClaudeCodeUserApiKeysView.class);
- }
- @Override
- public ClaudeCodeResp createOrUpdateCodexUserPackageApi(Long userId, String planName, Integer openaiDailyLimit, Integer openaiQuota, Date expiryTime) throws Exception {
- Map<String, Object> params = new HashMap<>();
- params.put("plan_name", planName.replaceAll(";", ""));
- params.put("openai_daily_limit", openaiDailyLimit);
- params.put("openai_quota", openaiQuota);
- params.put("expire_time", DateUtil.format(expiryTime, "yyyy-MM-dd HH:mm:ss"));
- //claude 类型
- params.put("service_type", "openai");
- String planUrl = String.format(Constant.CLAUDE_CODE_API_PREFIX + "api/users/%s/plan", userId);
- ClaudeCodeResp codexResp = executePostApi(planUrl, Jsons.toJson(params));
- if (!"success".equals(codexResp.getMessage())) {
- log.info("用户codex用户:{}套餐:{}创建或更新失败,info:{}", userId, planName, codexResp.getMessage());
- throw BusinessRuntimeException.getInstance("调用codex 套餐接口失败");
- }
- return codexResp;
- }
- @Override
- public boolean delCodexUserPackages(Long userId) {
- String url = String.format(Constant.CLAUDE_CODE_API_PREFIX + "api/users/%s/plan?service_type=openai", userId);
- try {
- ClaudeCodeResp claudeCodeResp = executeDeletedApi(url);
- if (!Constant.SUCCESS.equals(claudeCodeResp.getMessage())) {
- log.error("删除用户:{} codex套餐失败:{}", userId, claudeCodeResp.getMessage());
- return Boolean.FALSE;
- }
- return Boolean.TRUE;
- } catch (Exception e) {
- log.error("删除用户:{} codex套餐报错:{}", userId, StringUtil.getErrorText(e));
- }
- return Boolean.FALSE;
- }
- @Override
- public ClaudeCodeResp getCodexUserOpenAIUsage(Long userId, String period) {
- // 调用Codex API获取实时使用统计
- String usageUrl = String.format(Constant.CLAUDE_CODE_API_PREFIX + "api/openai/users/%s/usage?period=%s", userId, period);
- ClaudeCodeResp codexResp = executeGetApi(usageUrl);
- return codexResp;
- }
- @Override
- public ClaudeCodeResp getCodexUserDashboard(Long userId) {
- // 调用Codex API获取用户控制台数据
- String dashboardUrl = String.format(Constant.CLAUDE_CODE_API_PREFIX + "api/openai/users/%s/dashboard", userId);
- ClaudeCodeResp codexResp = executeGetApi(dashboardUrl);
- return codexResp;
- }
- @Override
- public ClaudeCodeResp getCodexUserAnalytics(Long userId, String start, String end, Integer page, Integer limit, String order) {
- // 调用Codex API获取用户分析数据
- String analyticsUrl = String.format(Constant.CLAUDE_CODE_API_PREFIX + "api/openai/users/%s/analytics?start=%s&end=%s&page=%s&limit=%s&order=%s", userId, start, end, page, limit, order);
- ClaudeCodeResp codexResp = executeGetApi(analyticsUrl);
- return codexResp;
- }
- /**
- * GET请求
- */
- public ClaudeCodeResp executeGetApi(String url) {
- Retryer<ClaudeCodeResp> build = getApiRetryer(1, 3);
- try {
- return build.call(() -> {
- try {
- HttpResponse execute = HttpUtil.createGet(url)
- .header(Constant.CLAUDE_CODE_HEARD_KEY, Constant.CLAUDE_CODE_API_ADMIN_KEY)
- .setConnectionTimeout(Constant.CONNECT_MILLISECONDS)
- .execute();
- ClaudeCodeResp resp = Jsons.parseObject(execute.body(), ClaudeCodeResp.class);
- if (!Constant.SUCCESS.equals(resp.getMessage())) {
- log.error("GET URL:{}接口返回msg:{}", url, resp.getMessage());
- }
- return resp;
- } catch (HttpException e) {
- return null;
- }
- });
- } catch (ExecutionException | RetryException e) {
- log.error("重试调用GET请求url->{}失败,msg->{}", url, StringUtil.getErrorText(e));
- throw BusinessRuntimeException.getInstance("接口请求失败");
- }
- }
- /**
- * Post请求
- */
- public ClaudeCodeResp executePostApi(String url, String body) {
- Retryer<ClaudeCodeResp> build = getApiRetryer(1, 3);
- try {
- return build.call(() -> {
- try {
- HttpResponse execute = HttpUtil.createPost(url)
- .header(Constant.CLAUDE_CODE_HEARD_KEY, Constant.CLAUDE_CODE_API_ADMIN_KEY)
- .setConnectionTimeout(Constant.CONNECT_MILLISECONDS)
- .body(body)
- .execute();
- ClaudeCodeResp resp = Jsons.parseObject(execute.body(), ClaudeCodeResp.class);
- if (!Constant.SUCCESS.equals(resp.getMessage())) {
- log.error("POST URL:{}接口返回msg:{}", url, resp.getMessage());
- }
- return resp;
- } catch (Exception e) {
- return null;
- }
- });
- } catch (ExecutionException | RetryException e) {
- log.info("重试调用 POST请求 url->{}失败,msg->{}", url, StringUtil.getErrorText(e));
- throw BusinessRuntimeException.getInstance("接口请求失败");
- }
- }
- /**
- * claude code DELETE请求
- */
- public ClaudeCodeResp executeDeletedApi(String url) {
- Retryer<ClaudeCodeResp> build = getApiRetryer(1, 3);
- try {
- return build.call(() -> {
- try {
- HttpResponse execute = HttpUtil.createRequest(Method.DELETE, url).header(Constant.CLAUDE_CODE_HEARD_KEY, Constant.CLAUDE_CODE_API_ADMIN_KEY).setConnectionTimeout(Constant.CONNECT_MILLISECONDS).execute();
- ClaudeCodeResp resp = Jsons.parseObject(execute.body(), ClaudeCodeResp.class);
- if (!Constant.SUCCESS.equals(resp.getMessage())) {
- log.error("DELETE URL:{}接口返回msg:{}", url, resp.getMessage());
- }
- return resp;
- } catch (HttpException e) {
- return null;
- }
- });
- } catch (ExecutionException | RetryException e) {
- log.error("重试调用DELETE请求url->{}失败,msg->{}", url, StringUtil.getErrorText(e));
- throw BusinessRuntimeException.getInstance("接口请求失败");
- }
- }
- public Retryer getApiRetryer(Integer sleepSecond, Integer attemptNum) {
- Retryer build = RetryerBuilder.newBuilder()
- .retryIfException()
- //运行时异常重试
- .retryIfRuntimeException()
- //false重试
- .retryIfResult(res -> res == null)
- //1s 间隔
- .withWaitStrategy(WaitStrategies.fixedWait(sleepSecond, TimeUnit.SECONDS))
- //停止策略 : 尝试请求3次
- .withStopStrategy(StopStrategies.stopAfterAttempt(attemptNum)).build();
- return build;
- }
- }
|