فهرست منبع

接入火山引擎deepseek

wangyunpeng 1 ماه پیش
والد
کامیت
c04c01cfc4

+ 22 - 0
api-module/src/main/java/com/tzld/piaoquan/api/common/enums/ApiChannelEnum.java

@@ -0,0 +1,22 @@
+package com.tzld.piaoquan.api.common.enums;
+
+public enum ApiChannelEnum {
+    OFFICIAL("official", "DeepSeek 官方 API"),
+    VOLCENGINE("volcengine", "火山引擎方舟 API");
+
+    private final String code;
+    private final String desc;
+
+    ApiChannelEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}

+ 67 - 6
api-module/src/main/java/com/tzld/piaoquan/api/component/DeepSeekApiService.java

@@ -2,6 +2,7 @@ package com.tzld.piaoquan.api.component;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.tzld.piaoquan.api.common.enums.ApiChannelEnum;
 import com.tzld.piaoquan.api.model.dto.AIOfficialApiResponse;
 import com.tzld.piaoquan.api.model.dto.AIResult;
 import com.tzld.piaoquan.growth.common.utils.MapBuilder;
@@ -26,6 +27,21 @@ public class DeepSeekApiService {
     @Value("${deepseek.default.model:deepseek-v4-flash}")
     private String defaultModel;
 
+    @Value("${deepseek.official.url:https://api.deepseek.com/chat/completions}")
+    private String officialUrl;
+
+    @Value("${deepseek.official.apiKey:sk-62d7b2c37f824735aa4985852c919c1f}")
+    private String officialApiKey;
+
+    @Value("${deepseek.volcengine.url:https://ark.cn-beijing.volces.com/api/v3/chat/completions}")
+    private String volcengineUrl;
+
+    @Value("${deepseek.volcengine.apiKey:ark-b5d6fcbb-14f9-4f70-a92d-605ec6a72c8d-40883}")
+    private String volcengineApiKey;
+
+    @Value("${deepseek.volcengine.model:ep-20250717193758-8gvmz}")
+    private String volcengineModel;
+
     @PostConstruct
     public void init() {
         client = new OkHttpClient().newBuilder()
@@ -35,7 +51,17 @@ public class DeepSeekApiService {
                 .build();
     }
 
-    public AIResult requestOfficialApi(String prompt, String model, Double temperature, Boolean isJSON) {
+    /**
+     * 默认调用火山引擎 API
+     */
+    public AIResult request(String prompt, String model, Double temperature, Boolean isJSON) {
+        return request(prompt, model, temperature, isJSON, ApiChannelEnum.VOLCENGINE);
+    }
+
+    /**
+     * 支持指定渠道的 API 调用
+     */
+    public AIResult request(String prompt, String model, Double temperature, Boolean isJSON, ApiChannelEnum channel) {
         AIResult result = new AIResult();
         result.setSuccess(false);
         if (TextUtils.isBlank(prompt) || TextUtils.isBlank(prompt.trim())) {
@@ -43,6 +69,28 @@ public class DeepSeekApiService {
             return result;
         }
 
+        String url;
+        String apiKey;
+        String defaultChannelModel;
+        String channelName;
+
+        if (channel == ApiChannelEnum.OFFICIAL) {
+            url = officialUrl;
+            apiKey = officialApiKey;
+            defaultChannelModel = defaultModel;
+            channelName = "official";
+        } else {
+            url = volcengineUrl;
+            apiKey = volcengineApiKey;
+            defaultChannelModel = volcengineModel;
+            channelName = "volcengine";
+        }
+
+        if (TextUtils.isBlank(apiKey)) {
+            result.setFailReason(channelName + " apiKey is not configured");
+            return result;
+        }
+
         try {
             JSONArray jsonArray = new JSONArray();
             JSONObject message = new JSONObject();
@@ -50,9 +98,15 @@ public class DeepSeekApiService {
             message.put("content", prompt);
             jsonArray.add(message);
 
+            String useModel = Optional.ofNullable(model).orElse(defaultChannelModel);
+            if (TextUtils.isBlank(useModel)) {
+                result.setFailReason("model is empty");
+                return result;
+            }
+
             Map<Object, Object> bodyParam = MapBuilder
                     .builder()
-                    .put("model", Optional.ofNullable(model).orElse(defaultModel))
+                    .put("model", useModel)
                     .put("temperature", Optional.ofNullable(temperature).orElse(0.3))
                     .put("messages", jsonArray)
                     .build();
@@ -65,17 +119,17 @@ public class DeepSeekApiService {
             MediaType mediaType = MediaType.parse("application/json");
             RequestBody body = RequestBody.create(mediaType, JSONObject.toJSONString(bodyParam));
             Request request = new Request.Builder()
-                    .url("https://api.deepseek.com/chat/completions")
+                    .url(url)
                     .method("POST", body)
                     .addHeader("Content-Type", "application/json")
                     .addHeader("Accept", "application/json")
-                    .addHeader("Authorization", "Bearer sk-62d7b2c37f824735aa4985852c919c1f")
+                    .addHeader("Authorization", "Bearer " + apiKey)
                     .build();
             Response response = client.newCall(request).execute();
 
             String responseContent = response.body().string();
             result.setResponseStr(responseContent);
-            log.info("deepseek api responseContent = {}", responseContent);
+            log.info("deepseek {} api responseContent = {}", channelName, responseContent);
             if (response.isSuccessful()) {
                 AIOfficialApiResponse obj = JSONObject.parseObject(responseContent, AIOfficialApiResponse.class);
                 if (CollectionUtils.isNotEmpty(obj.getChoices())) {
@@ -89,9 +143,16 @@ public class DeepSeekApiService {
                 result.setFailReason("request error code:" + response.code() + " message:" + json.getString("error"));
             }
         } catch (Exception e) {
-            log.error("deepseek official api fail: " + e.getMessage());
+            log.error("deepseek {} api fail: {}", channelName, e.getMessage());
             result.setFailReason(e.getMessage());
         }
         return result;
     }
+
+    /**
+     * 调用 DeepSeek 官方 API(向后兼容)
+     */
+    public AIResult requestOfficialApi(String prompt, String model, Double temperature, Boolean isJSON) {
+        return request(prompt, model, temperature, isJSON, ApiChannelEnum.OFFICIAL);
+    }
 }

+ 1 - 1
api-module/src/main/java/com/tzld/piaoquan/api/job/GzhReplyVideoRefreshJob.java

@@ -148,7 +148,7 @@ public class GzhReplyVideoRefreshJob {
         for (JSONObject obj : sortedList) {
             String text = obj.getString("title");
             String keywordPrompt = getKeyWordPrompt(text);
-            AIResult aiResult = deepSeekApiService.requestOfficialApi(keywordPrompt, null, null, false);
+            AIResult aiResult = deepSeekApiService.request(keywordPrompt, null, null, false);
             if (aiResult.isSuccess()) {
                 List<String> keywords = JSONObject.parseArray(aiResult.getResponse().getChoices().get(0).getMessage().getContent(), String.class);
                 log.info("GzhReplyVideoRefreshJob accountName:{} text:{} keywords:{}", accountName, text, keywords);

+ 1 - 1
api-module/src/test/java/com/tzld/piaoquan/api/WeComThirdPartTest.java

@@ -193,7 +193,7 @@ public class WeComThirdPartTest {
                             "请基于上述规则,输出最终的JSON:";
             keywordPrompt = keywordPrompt.replace("text", title);
             // 调用API
-            AIResult result = deepSeekApiService.requestOfficialApi(keywordPrompt, null, null, true);
+            AIResult result = deepSeekApiService.request(keywordPrompt, null, null, true);
             List<String> keywords = JSONObject.parseArray(result.getResponse().getChoices().get(0).getMessage().getContent(), String.class);
 
             System.out.println(String.format("title: %s, keywords: %s", title, keywords));