diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 7883a6b..162e62e 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -11,6 +11,7 @@ + diff --git a/.idea/encodings.xml b/.idea/encodings.xml index bb396d2..910cea3 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -13,6 +13,8 @@ + + diff --git a/vetti-admin/src/main/java/com/vetti/web/controller/ai/AiCommonController.java b/vetti-admin/src/main/java/com/vetti/web/controller/ai/AiCommonController.java index d84dcc4..ebc1fa0 100644 --- a/vetti-admin/src/main/java/com/vetti/web/controller/ai/AiCommonController.java +++ b/vetti-admin/src/main/java/com/vetti/web/controller/ai/AiCommonController.java @@ -5,6 +5,9 @@ import com.vetti.common.ai.gpt.ChatGPTClient; import com.vetti.common.ai.whisper.WhisperClient; import com.vetti.common.core.controller.BaseController; import com.vetti.common.core.domain.AjaxResult; +import com.vetti.common.core.domain.R; +import com.vetti.common.core.domain.dto.RealtimeClientSecretDto; +import com.vetti.web.service.ICommonService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -32,6 +35,9 @@ public class AiCommonController extends BaseController @Autowired private WhisperClient whisperClient; + @Autowired + private ICommonService commonService; + /** * 进行文本转语音处理 */ @@ -70,4 +76,16 @@ public class AiCommonController extends BaseController return success(); } + + /** + * 获取客户端临时Key + */ + @ApiOperation("获取客户端临时Key") + @GetMapping("/getRealtimeClientSecret") + public R handleRealtimeClientSecret() + { + RealtimeClientSecretDto dto = commonService.getRealtimeClientSecret(); + return R.ok(dto); + } + } diff --git a/vetti-admin/src/main/java/com/vetti/web/service/ICommonService.java b/vetti-admin/src/main/java/com/vetti/web/service/ICommonService.java new file mode 100644 index 0000000..ef14f3b --- /dev/null +++ b/vetti-admin/src/main/java/com/vetti/web/service/ICommonService.java @@ -0,0 +1,19 @@ +package com.vetti.web.service; + +import com.vetti.common.core.domain.dto.RealtimeClientSecretDto; + +/** + * 共同 信息 服务类 + * + * @author WangXiangShun + * @since 2025-08-27 + */ +public interface ICommonService { + + + /** + * 获取openAi客户端临时Key + * @return + */ + public RealtimeClientSecretDto getRealtimeClientSecret(); +} diff --git a/vetti-admin/src/main/java/com/vetti/web/service/impl/CommonServiceImpl.java b/vetti-admin/src/main/java/com/vetti/web/service/impl/CommonServiceImpl.java new file mode 100644 index 0000000..6c7e33b --- /dev/null +++ b/vetti-admin/src/main/java/com/vetti/web/service/impl/CommonServiceImpl.java @@ -0,0 +1,76 @@ +package com.vetti.web.service.impl; + +import cn.hutool.json.JSONUtil; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.vetti.common.core.domain.dto.RealtimeClientSecretDto; +import com.vetti.web.service.ICommonService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.Map; +/** + * 共同 信息 服务实现类 + * + * @author WangXiangShun + * @since 2025-08-27 + */ +@Slf4j +@Service +public class CommonServiceImpl implements ICommonService { + + // OpenAI API密钥,需要替换为你自己的密钥 + @Value("${chatGpt.apiKey}") + private String apiKey; + // API端点URL + @Value("${chatGpt.apiClientTokenUrl}") + private String apiClientTokenUrl; + + /** + * 获取openAi客户端临时Key + * @return + */ + @Override + public RealtimeClientSecretDto getRealtimeClientSecret() { + RealtimeClientSecretDto dto = new RealtimeClientSecretDto(); + try { + // 1. 创建 HTTP 客户端 + HttpClient client = HttpClient.newBuilder() + .version(HttpClient.Version.HTTP_2) + .connectTimeout(Duration.ofSeconds(10)) + .build(); + + // 2. 构建请求体(空 JSON 对象) + ObjectMapper objectMapper = new ObjectMapper(); + String requestBody = ""; + // 3. 构建 HTTP 请求 + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(apiClientTokenUrl)) + .header("Content-Type", "application/json") + .header("Authorization", "Bearer " + apiKey) // 核心认证头 + .POST(HttpRequest.BodyPublishers.ofString(requestBody)) + .build(); + // 4. 发送请求并获取响应 + HttpResponse response = client.send( + request, + HttpResponse.BodyHandlers.ofString() + ); + // 5. 处理响应 + if (response.statusCode() == 200) { + // 解析响应为实体类 + System.out.println(JSONUtil.toJsonStr(response.body())); + Map entity = JSONUtil.toBean(response.body(), Map.class); + dto.setClientSecret(entity.get("value").toString()); + dto.setExpiresAt(Long.valueOf(entity.get("expires_at").toString())); + } + } catch (Exception e) { + e.printStackTrace(); + } + return dto; + } +} diff --git a/vetti-admin/src/main/resources/application-dev.yml b/vetti-admin/src/main/resources/application-dev.yml index 2711ee9..477e3ed 100644 --- a/vetti-admin/src/main/resources/application-dev.yml +++ b/vetti-admin/src/main/resources/application-dev.yml @@ -162,6 +162,7 @@ chatGpt: apiUrl: https://api.openai.com/v1/chat/completions model: gpt-3.5-turbo role: user + apiClientTokenUrl: https://api.openai.com/v1/realtime/client_secrets http: diff --git a/vetti-admin/src/main/resources/application-druid.yml b/vetti-admin/src/main/resources/application-druid.yml index aa11628..311e212 100644 --- a/vetti-admin/src/main/resources/application-druid.yml +++ b/vetti-admin/src/main/resources/application-druid.yml @@ -169,6 +169,7 @@ chatGpt: apiUrl: https://api.openai.com/v1/chat/completions model: ft:gpt-3.5-turbo-0125:vetti:construction-labourer-test:CWKBNvE2 role: system + apiClientTokenUrl: https://api.openai.com/v1/realtime/client_secrets http: diff --git a/vetti-admin/target/classes/application-druid.yml b/vetti-admin/target/classes/application-druid.yml index 3df6826..311e212 100644 --- a/vetti-admin/target/classes/application-druid.yml +++ b/vetti-admin/target/classes/application-druid.yml @@ -167,8 +167,9 @@ whisper: chatGpt: apiKey: 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 apiUrl: https://api.openai.com/v1/chat/completions - model: ft:gpt-3.5-turbo-0125:vetti:construction-labourer-test:CTIvLD5n + model: ft:gpt-3.5-turbo-0125:vetti:construction-labourer-test:CWKBNvE2 role: system + apiClientTokenUrl: https://api.openai.com/v1/realtime/client_secrets http: diff --git a/vetti-common/src/main/java/com/vetti/common/core/domain/dto/RealtimeClientSecretDto.java b/vetti-common/src/main/java/com/vetti/common/core/domain/dto/RealtimeClientSecretDto.java new file mode 100644 index 0000000..eb75f7f --- /dev/null +++ b/vetti-common/src/main/java/com/vetti/common/core/domain/dto/RealtimeClientSecretDto.java @@ -0,0 +1,23 @@ +package com.vetti.common.core.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * openAi 客户端密钥返回结构 + * + * @author wangxiangshun + * @date 2025-10-29 + */ +@Data +@Accessors(chain = true) +public class RealtimeClientSecretDto { + + @ApiModelProperty("生成的客户端密钥") + private String clientSecret; + + @ApiModelProperty("过期时间(Unix 时间戳,秒") + private long expiresAt; + +} diff --git a/vetti-system/target/classes/mapper/system/SysUserMapper.xml b/vetti-system/target/classes/mapper/system/SysUserMapper.xml index d6fb590..4f86fc6 100644 --- a/vetti-system/target/classes/mapper/system/SysUserMapper.xml +++ b/vetti-system/target/classes/mapper/system/SysUserMapper.xml @@ -35,6 +35,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +