feat(ai-chat): 新增豆包API + AI模型配置项支持动态切换

- 后端新增豆包(火山引擎Ark)API集成:DoubaoController、ToolDoubaoServiceImpl,
  使用OkHttp3 SSE流式对话,兼容OpenAI Chat Completions格式
- 新增DoubaoConfig配置类,读取doubao.api.*配置
- 在eb_system_config表新增ai_chat_model配置项,支持doubao/coze/gemini三种模型切换
- 新增GET /api/front/doubao/ai-model-config接口供前端读取当前模型配置
- 前端ai-nutritionist.vue的sendToAI按系统配置分发到_sendViaDoubao/_sendViaCoze/_sendViaGemini
- 前端models-api.js新增doubaoChatStream/doubaoChat/getAiModelConfig函数
- 附带豆包API测试脚本和数据库初始化SQL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
msh-agent
2026-04-11 18:03:21 +08:00
parent 58ea76498f
commit b164d8ba11
14 changed files with 1369 additions and 119 deletions

View File

@@ -0,0 +1,43 @@
package com.zbkj.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 豆包(火山引擎 ArkAPI 配置类
* 使用 OpenAI 兼容的 Chat Completions 接口
* +----------------------------------------------------------------------
* | Author:ScottPan
* +----------------------------------------------------------------------
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "doubao.api")
public class DoubaoConfig {
/**
* API 基础 URL
*/
private String baseUrl = "https://ark.cn-beijing.volces.com/api/v3";
/**
* API Key火山引擎控制台获取
*/
private String apiKey;
/**
* 默认模型名称
*/
private String model = "doubao-seed-2-0-pro-260215";
/**
* 连接超时时间(毫秒)
*/
private Integer connectTimeout = 30000;
/**
* 读取超时时间(毫秒)
*/
private Integer readTimeout = 120000;
}

View File

@@ -202,4 +202,7 @@ public class SysConfigConstants {
/** 京东云存储端点 */
public static final String CONFIG_JD_CLOUD_ENDPOINT = "jdEndpoint";
// ====== AI 模型配置 ======
/** AI 营养师对话模型选择: doubao / coze / gemini */
public static final String CONFIG_KEY_AI_CHAT_MODEL = "ai_chat_model";
}

View File

@@ -0,0 +1,58 @@
package com.zbkj.common.request.doubao;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* 豆包(火山引擎 ArkChat Completions 请求 DTO
* 兼容 OpenAI Chat Completions 格式
* +----------------------------------------------------------------------
* | Author:ScottPan
* +----------------------------------------------------------------------
*/
@Data
@NoArgsConstructor
@ApiModel(value = "DoubaoChatRequest", description = "豆包 Chat Completions 请求")
public class DoubaoChatRequest implements Serializable {
private static final long serialVersionUID = 1L;
@Valid
@NotEmpty(message = "messages不能为空")
@ApiModelProperty(value = "消息列表", required = true)
private List<Message> messages;
@ApiModelProperty(value = "是否流式返回", example = "false")
private Boolean stream;
@ApiModelProperty(value = "模型名称(可选,不传则使用服务端默认配置)")
private String model;
@ApiModelProperty(value = "温度参数 (0-2)", example = "0.7")
private Double temperature;
@ApiModelProperty(value = "最大输出 token 数")
private Integer maxTokens;
@Data
@NoArgsConstructor
@ApiModel(value = "Message", description = "单条消息")
public static class Message implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "角色: system, user, assistant")
private String role;
@NotNull(message = "content不能为空")
@ApiModelProperty(value = "内容:字符串或多模态数组", required = true)
private Object content;
}
}