Commit 74555209 authored by luojun's avatar luojun

Initial commit

parents
Pipeline #6407 canceled with stages
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="accountSettings">
<option name="activeRegion" value="us-east-1" />
<option name="recentlyUsedRegions">
<list>
<option value="us-east-1" />
</list>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="kedaxunfei" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="kedaxunfei" options="-parameters" />
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="justh5" />
<option name="name" value="Public Repositories" />
<option name="url" value="http://120.24.176.53:8081/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="http://120.24.176.53:8081/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>
\ No newline at end of file
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>deep-ask</artifactId>
<name>deepseek问答模块</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- spring boot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- sse长连接 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-sse</artifactId>
<version>4.12.0</version>
</dependency>
<!--用于构造http请求-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<!-- Spring boot websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.3.70</version>
</dependency>
<!--用于输出日志包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId >
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>voice-identify</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!--lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring boot websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--用于处理json数据(包括jsonPath功能)-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
<!--针对开发IO流功能的工具类库-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
</project>
package admin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync
@SpringBootApplication(scanBasePackages = {"admin"})
public class WeixinRun {
public static void main(String[] args) {
SpringApplication.run(WeixinRun.class, args);
}
}
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package admin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author ZhangHouYing
* @date 2019-08-24 15:44
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
package admin.listener;
import admin.model.deepseek.resp.stream.ChatStreamResponse;
import admin.model.maxdb.resp.MaxdbStreamResponse;
import admin.service.TextToSpeechService;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import javax.annotation.Resource;
import javax.websocket.Session;
import java.net.SocketException;
import java.util.Objects;
/**
* @author lj
* @date 2025/2/24 9:26
*/
@Slf4j
public class DeepSeekAiListener extends EventSourceListener {
StringBuffer stringBuffer = new StringBuffer();
private Session session;
private static TextToSpeechService textToSpeechService;
@Resource
public static void setTextToSpeechService(TextToSpeechService textToSpeechService){
DeepSeekAiListener.textToSpeechService = textToSpeechService;
}
public DeepSeekAiListener(Session session) {
this.session = session;
}
@Override
public void onOpen(EventSource eventSource, Response response) {
super.onOpen(eventSource, response);
log.info("DeepSeek建立sse连接...onOpen");
}
@Override
public void onEvent(EventSource eventSource, String id, String type, String data) {
super.onEvent(eventSource, id, type, data);
Gson gson= new Gson();
try {
MaxdbStreamResponse completionResponse = gson.fromJson(data, MaxdbStreamResponse.class);
if (completionResponse.getIsEnd()) {
log.info("DeepSeek返回数据结束了...onEvent");
textToSpeechService.convertTextToSpeech(this.stringBuffer.toString());
return;
}
if (completionResponse.getContent()!=null){
System.out.print(completionResponse.getContent());
this.stringBuffer.append(completionResponse.getContent());
this.session.getBasicRemote().sendText(completionResponse.getContent());
}
}catch (Exception e){
System.out.println(e.getMessage());
}
// ChatStreamResponse completionResponse = mapper.readValue(data, MaxdbStreamResponse.class);
// if (completionResponse.getChoices()!=null && !completionResponse.getChoices().isEmpty()){
// System.out.print(completionResponse.getChoices().get(0).getDelta().getContent());
// this.stringBuffer.append(completionResponse.getChoices().get(0).getDelta().getContent());
// }
}
@Override
public void onClosed(EventSource eventSource) {
super.onClosed(eventSource);
log.info("DeepSeek关闭sse连接...onClosed");
}
@Override
@SneakyThrows
public void onFailure(EventSource eventSource, Throwable t, Response response) {
super.onFailure(eventSource, t, response);
if (Objects.isNull(response)) {
return;
}
if(t instanceof SocketException){
log.info("用户停止输出...onFailure");
}else {
ResponseBody body = response.body();
if (Objects.nonNull(body)) {
log.error("DeepSeek sse连接异常data:{},异常:{}", body.string(), t);
} else {
log.error("DeepSeek sse连接异常data:{},异常:{}", response, t);
}
}
response.close();
eventSource.cancel();
log.info("eventSource cancel....onFailure");
}
}
package admin.model.deepseek.req;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 13:27
*/
@Data
public class ChatMessage {
/**
* 消息的内容
*/
@SerializedName("content")
private String content;
/**
* 该消息的发起角色,其值为 system user assistant tool
*/
@SerializedName("role")
private String role;
/**
* 可以选填的参与者的名称,为模型提供信息以区分相同角色的参与者
*/
@SerializedName("name")
private String name;
}
package admin.model.deepseek.req;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import java.util.List;
/**
* @author lj
* @date 2025/2/23 10:59
*/
@Data
public class ChatReqMsg {
/**
* 对话的消息列表
*/
@SerializedName("messages")
private List<ChatMessage> messages;
/**
* 使用的模型的 ID。您可以使用 deepseek-chat。
*/
@SerializedName("model")
private String model;
/**
* 介于 -2.0 和 2.0 之间的数字。如果该值为正,那么新 token 会根据其在已有文本中的出现频率受到相应的惩罚,降低模型重复相同内容的可能性。
*/
@SerializedName("frequency_penalty")
private Double frequencyPenalty;
/**
* 介于 1 到 8192 间的整数,限制一次请求中模型生成 completion 的最大 token 数。输入 token 和输出 token 的总长度受模型的上下文长度的限制。
* 如未指定 max_tokens参数,默认使用 4096。
*/
@SerializedName("max_tokens")
private Integer maxTokens;
/**
* 介于 -2.0 和 2.0 之间的数字。如果该值为正,那么新 token 会根据其是否已在已有文本中出现受到相应的惩罚,从而增加模型谈论新主题的可能性。
*/
@SerializedName("presence_penalty")
private Double presencePenalty;
/**
* 一个 object,指定模型必须输出的格式。
*
* 设置为 { "type": "json_object" } 以启用 JSON 模式,该模式保证模型生成的消息是有效的 JSON。
*
* 注意: 使用 JSON 模式时,你还必须通过系统或用户消息指示模型生成 JSON。否则,模型可能会生成不断的空白字符,直到生成达到令牌限制,从而导致请求长时间运行并显得“卡住”。此外,如果 finish_reason="length",这表示生成超过了 max_tokens 或对话超过了最大上下文长度,消息内容可能会被部分截断。
*
* type
* string
* Possible values: [text, json_object]
*
* Default value: text
*
* Must be one of text or json_object.
*/
@SerializedName("response_format")
private ChatRespType responseFormat;
/**
* 如果设置为 True,将会以 SSE(server-sent events)的形式以流式发送消息增量。消息流以 data: [DONE] 结尾。
*/
@SerializedName("stream")
private Boolean stream;
/**
* 流式输出相关选项。只有在 stream 参数为 true 时,才可设置此参数。
*
* include_usage
* boolean
* 如果设置为 true,在流式消息最后的 data: [DONE] 之前将会传输一个额外的块。此块上的 usage 字段显示整个请求的 token 使用统计信息,而 choices 字段将始终是一个空数组。所有其他块也将包含一个 usage 字段,但其值为 null。
*/
@SerializedName("stream_options")
private ChatStreamOption streamOptions;
/**
* 采样温度,介于 0 和 2 之间。更高的值,如 0.8,会使输出更随机,而更低的值,如 0.2,会使其更加集中和确定。 我们通常建议可以更改这个值或者更改 top_p,但不建议同时对两者进行修改。
*/
@SerializedName("temperature")
private Double temperature;
/**
* 作为调节采样温度的替代方案,模型会考虑前 top_p 概率的 token 的结果。所以 0.1 就意味着只有包括在最高 10% 概率中的 token 会被考虑。 我们通常建议修改这个值或者更改 temperature,但不建议同时对两者进行修改。
*/
@SerializedName("top_p")
private Double topP;
/**
* 是否返回所输出 token 的对数概率。如果为 true,则在 message 的 content 中返回每个输出 token 的对数概率。
*/
@SerializedName("logprobs")
private Boolean logprobs;
/**
* 一个介于 0 到 20 之间的整数 N,指定每个输出位置返回输出概率 top N 的 token,且返回这些 token 的对数概率。指定此参数时,logprobs 必须为 true。
*/
@SerializedName("top_logprobs")
private Integer topLogprobs;
}
package admin.model.deepseek.req;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 13:31
*/
@Data
public class ChatRespType {
/**
* 一个 object,指定模型必须输出的格式。
*
* 设置为 { "type": "json_object" } 以启用 JSON 模式,该模式保证模型生成的消息是有效的 JSON。
*
* 注意: 使用 JSON 模式时,你还必须通过系统或用户消息指示模型生成 JSON。否则,模型可能会生成不断的空白字符,直到生成达到令牌限制,从而导致请求长时间运行并显得“卡住”。此外,如果 finish_reason="length",这表示生成超过了 max_tokens 或对话超过了最大上下文长度,消息内容可能会被部分截断。
*
* type
* string
* Possible values: [text, json_object]
*
* Default value: text
*
* Must be one of text or json_object.
*/
@SerializedName("type")
private String type;
}
package admin.model.deepseek.req;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 13:33
*/
@Data
public class ChatStreamOption {
/**
* 流式输出相关选项。只有在 stream 参数为 true 时,才可设置此参数。
*
* include_usage
* boolean
* 如果设置为 true,在流式消息最后的 data: [DONE] 之前将会传输一个额外的块。此块上的 usage 字段显示整个请求的 token 使用统计信息,而 choices 字段将始终是一个空数组。所有其他块也将包含一个 usage 字段,但其值为 null。
*/
@SerializedName("include_usage")
private Boolean includeUsage;
@SerializedName("continuous_usage_stats")
private Boolean continuousUsageStats;
// @SerializedName("additional_prop1")
// private String additionalProp1="{}";
}
package admin.model.deepseek.resp.error;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 14:51
*/
@Data
public class ChatErrorResponse {
@SerializedName("error")
private Error error;
}
package admin.model.deepseek.resp.error;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 14:51
*/
@Data
public class Error {
@SerializedName("code")
private String code; // 错误码(如 "invalid_api_key")
@SerializedName("message")
private String message;
@SerializedName("type")
private String type; // 错误类型(如 "auth_error")
}
package admin.model.deepseek.resp.starnd;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import java.util.List;
/**
* @author lj
* @date 2025/2/23 14:36
*/
@Data
public class ChatTextResponse {
@SerializedName("id")
private String id;
@SerializedName("object")
private String object;
@SerializedName("created")
private long created;
@SerializedName("model")
private String model;
@SerializedName("choices")
private List<CompletionChoice> choices;
@SerializedName("usage")
private Usage usage;
}
package admin.model.deepseek.resp.starnd;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 14:47
*/
@Data
public class CompletionChoice {
@SerializedName("index")
private int index;
@SerializedName("message")
private Message message;
@SerializedName("finish_reason")
private String finishReason;
}
package admin.model.deepseek.resp.starnd;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 14:47
*/
@Data
public class Message {
@SerializedName("role")
private String role;
@SerializedName("content")
private String content;
}
package admin.model.deepseek.resp.starnd;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 14:47
*/
@Data
public class Usage {
@SerializedName("prompt_tokens")
private int promptTokens;
@SerializedName("completion_tokens")
private int completionTokens;
@SerializedName("total_tokens")
private int totalTokens;
}
package admin.model.deepseek.resp.stream;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import java.util.List;
/**
* @author lj
* @date 2025/2/23 14:50
*/
@Data
public class ChatStreamResponse {
@SerializedName("id")
private String id;
@SerializedName("object")
private String object; // 固定为 "chat.completion.chunk"
@SerializedName("created")
private long created;
@SerializedName("model")
private String model;
@SerializedName("choices")
private List<StreamChoice> choices;
}
package admin.model.deepseek.resp.stream;
import admin.model.deepseek.resp.starnd.Message;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/23 14:50
*/
@Data
public class StreamChoice {
@SerializedName("index")
private Integer index;
@SerializedName("delta")
private Message delta; // 流式返回的增量内容
@SerializedName("logprobs")
private String logprobs; // 流式返回的增量内容
@SerializedName("finish_reason")
private String finishReason; // 流式返回的增量内容
}
package admin.model.maxdb;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author lj
* @date 2025/2/26 12:41
*/
@Data
@Component
@ConfigurationProperties(prefix = "maxdb.screen")
public class MaxdbScreenConfig {
private String applicationId;
private String talkUrl;
private String chatUrl;
private String apiKey;
}
package admin.model.maxdb;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author lj
* @date 2025/2/25 22:24
*/
@Data
@Component
@ConfigurationProperties(prefix = "maxdb.zhongke")
public class MaxdbZkhjConfig {
private String applicationId;
private String talkUrl;
private String chatUrl;
private String apiKey;
}
package admin.model.maxdb.req;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/24 14:16
*/
@Data
public class MaxdbReq {
@SerializedName("message")
private String message;
@SerializedName("re_chat")
private boolean reChat=false;
@SerializedName("stream")
private boolean stream=true;
}
package admin.model.maxdb.resp;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/24 14:28
*/
@Data
public class ChatChildResponse {
@SerializedName("runtime_node_id")
private String runtimeNodeId;
@SerializedName("chat_record_id")
private String chatRecordId;
@SerializedName("child_node")
private ChatChildResponse childNode;
}
package admin.model.maxdb.resp;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import java.util.List;
/**
* @author lj
* @date 2025/2/24 14:26
*/
@Data
public class MaxdbStreamResponse {
@SerializedName("chat_id")
private String chatId;
@SerializedName("chat_record_id")
private String chatRecordId;
private Boolean operate;
private String content;
@SerializedName("node_id")
private String nodeId;
@SerializedName("up_node_id_list")
private List<String> upNodeIdList;
@SerializedName("is_end")
private Boolean isEnd;
@SerializedName("usage")
private Usage usage;
@SerializedName("node_type")
private String nodeType;
@SerializedName("runtime_node_id")
private String runtimeNodeId;
@SerializedName("view_type")
private Object viewType;
@SerializedName("child_node")
private ChatChildResponse childNode;
@SerializedName("node_is_end")
private Boolean nodeIsEnd;
@SerializedName("real_node_id")
private String realNodeId;
@SerializedName("reasoning_content")
private String reasoningContent;
}
package admin.model.maxdb.resp;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* @author lj
* @date 2025/2/24 14:27
*/
@Data
public class Usage {
@SerializedName("completion_tokens")
private Integer completionTokens;
@SerializedName("prompt_tokens")
private Integer promptTokens;
@SerializedName("total_tokens")
private Integer totalTokens;
}
/*
* Copyright (c) 2016, FPX and/or its affiliates. All rights reserved.
* Use, Copy is subject to authorized license.
*/
package admin.resp;
import lombok.Data;
@Data
public class ApiResponse<T> {
protected String code;
protected String message;
protected T data;
private String traceId;
public ApiResponse() {
}
public static <T> ApiResponse<T> buildSuccess() {
ApiResponse<T> response = new ApiResponse();
response.code = ApiResponseCode.SUCCESS.getCode();
response.message = ApiResponseCode.SUCCESS.getMessage();
return response;
}
public static <T> ApiResponse<T> buildSuccess(T data) {
ApiResponse<T> response = new ApiResponse();
response.data = data;
response.code = ApiResponseCode.SUCCESS.getCode();
response.message = ApiResponseCode.SUCCESS.getMessage();
return response;
}
public static <T> ApiResponse<T> buildFailure(ApiResponseCode responseCode) {
ApiResponse<T> response = new ApiResponse();
response.code = responseCode.getCode();
response.message = responseCode.getMessage();
return response;
}
public static <T> ApiResponse<T> buildFailure(String errorCode, String errorMsg) {
ApiResponse<T> response = new ApiResponse();
response.code = errorCode;
response.message = errorMsg;
return response;
}
public static boolean isSuccess(ApiResponse<Object> apiResponse){
return apiResponse.code.equals("0");
}
public void setTraceId(String traceId) {
this.traceId = traceId;
}
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return this.message;
}
public ApiResponse<T> setMessage(String message) {
this.message = message;
return this;
}
public T getData() {
return this.data;
}
public void setData(T data) {
this.data = data;
}
public String toString() {
return "data.ApiResponse{traceId='" + this.traceId + '\'' + ", code='" + this.code + '\'' + ", message='" + this.message + '\'' + ", data=" + this.data + '}';
}
}
package admin.resp;
public enum ApiResponseCode {
SUCCESS("0", "成功"),
FAILURE("9000", "处理失败"),
WAIT_CHECK("1001", "已认证,待处理"),
WAIT_PAY("1002", "待充值"),
DATA_EMPTY("9995", "数据为空"),
DB_ERROR("9996", "数据库错误"),
PARAM_NULL("9997", "参数为空"),
PARAM_ERROR("9998", "参数错误"),
SYSTEM_ERROR("9999", "系统异常"),
USER_NOT_LOGIN("9","已在其他设备登录!"),
USER_NO_BIND_Mobile("11","未绑定手机号码!"),
WAIT_RESULT("99","等待结果,请查询交易流水信息"),
MAS_SUCCESS("1", "成功"),
MAS_MOBILES_NULL("102", "mobiles为空"),
MAS_MOBILES_EMPTY("103", "mobiles为空数组"),
MAS_MOBILES_CHECK("104", "mobiles含有非法号码"),
MAS_AUTHENTICATION_CHECK("105", "未进行身份认证或认证失败"),
MAS_SIGN_NULL("106", "sign为空"),
MAS_OTHER_ERROR("107", "其它错误"),
MAS_MOBILES_REPEAT("109","mobiles含有重复号码"),
MAS_MOBILES_MAX("11","mobiles中号码数量超限(>5000),应≤5000"),
MAS_THREAD_POOL_BUSY("112","线程池忙");
private String code;
private String message;
private ApiResponseCode(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
public ApiResponseCode setMessage(String message) {
this.message = message;
return this;
}
public static String getMessage(String code) {
for (ApiResponseCode value : ApiResponseCode.values()) {
if (value.getCode().equals(code)) {
return value.getMessage();
}
}
return null;
}
}
package admin.rest;
import admin.resp.ApiResponse;
import admin.service.DeepSeekOpenApiService;
import admin.service.MaxkbOpenApiService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.websocket.Session;
/**
* @author lj
* @date 2025/2/23 13:35
*/
@RestController
@RequestMapping(value = "v1/openApi/")
@RequiredArgsConstructor
@Slf4j
public class OpenApiController {
private final DeepSeekOpenApiService deepSeekOpenApiService;
private final MaxkbOpenApiService maxkbOpenApiService;
@PostMapping(value = "completions")
public ApiResponse<Object> completions(@RequestParam String content){
deepSeekOpenApiService.chatCompletions(content);
return null;
}
@GetMapping("testOpen")
public ApiResponse<Object> open(@RequestParam String applicationId){
return maxkbOpenApiService.getMaxkbSessionId(applicationId);
}
@GetMapping("testcompletions")
public void testcompletions(@RequestParam String chatId,
@RequestParam String message){
maxkbOpenApiService.chatCompletions(message,chatId,null);
}
@GetMapping("aItalk")
public void testcompletions(@RequestParam String message){
maxkbOpenApiService.talk(message,null);
}
}
package admin.server;
import admin.config.SpeechToTextConfig;
import admin.service.MaxkbOpenApiService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.ResponseBody;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author lj
* @date 2025/2/20 19:46
*/
@ServerEndpoint("/webSocket/voice/{memberId}")
@Component
@Slf4j
public class VoiceWebSocketServer {
private static AtomicInteger onlineNum = new AtomicInteger();
private static SpeechToTextConfig voiceConfig;
private static MaxkbOpenApiService maxkbOpenApiService;
@Resource
public void setVoiceConfig(SpeechToTextConfig speechToTextConfig){
voiceConfig = speechToTextConfig;
}
@Resource
public void setMaxkbOpenApiService(MaxkbOpenApiService maxkbOpenApiService){
VoiceWebSocketServer.maxkbOpenApiService = maxkbOpenApiService;
}
private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
//建立连接成功调用
@OnOpen
public void onOpen(Session session, @PathParam(value = "memberId") String memberId) {
log.info("{}已连接", memberId);
sessionPools.put(memberId, session);
}
//关闭连接时调用
@OnClose
public void onClose(@PathParam(value = "memberId") String memberId) {
sessionPools.remove(memberId);
log.info("关闭连接");
System.out.println(sessionPools);
}
//收到客户端信息
@OnMessage
public void onTextMessage(Session session,String message) throws IOException {
session.setMaxBinaryMessageBufferSize(50 * 1024 * 1024);
log.info("message:{}",message);
maxkbOpenApiService.talk(message,session);
}
@OnMessage
public void onBinaryMessage(Session session, ByteBuffer data) {
session.setMaxBinaryMessageBufferSize(50 * 1024 * 1024);
// 处理二进制音频数据块
log.info("data:{}",data);
handleAudioChunk(session, data);
}
//错误时调用
@OnError
public void onError(Session session, Throwable throwable) {
System.out.println("发生错误");
for (Map.Entry<String, Session> map : sessionPools.entrySet()) {
Session value = map.getValue();
if (value.equals(session)) {
sessionPools.remove(map.getKey());
}
}
throwable.printStackTrace();
}
//发送消息
public void sendMessage(Session session, String message) {
if (session != null) {
synchronized (session) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
/**
* 处理音频数据
* @param session
* @param data
*/
private void handleAudioChunk(Session session, ByteBuffer data) {
//1.音频转文本
speechToText(data);
//2.向ai提问获取答案
//3.文本转语音
textToSpeech();
sendMessage(session, null);
}
private void textToSpeech() {
}
/**
* 语音转文本
* @param data 语音数据
*/
private void speechToText(ByteBuffer data) {
byte[] bytes = new byte[data.remaining()];
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
byteArrayOutputStream.write(bytes);
String authUrl = null;
authUrl = getAuthUrl(voiceConfig.getHostUrl(), voiceConfig.getApiKey(), voiceConfig.getApiSecret());
OkHttpClient client = new OkHttpClient.Builder().build();
String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");
Request request = new Request.Builder().url(url).build();
ResponseBody body = client.newCall(request).execute().body();
System.out.println(body.string());
// WebSocket webSocket = client.newWebSocket(request, new ResponseData());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
URL url = new URL(hostUrl);
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("GMT"));
String date = format.format(new Date());
StringBuilder builder = new StringBuilder("host: ").append(url.getHost()).append("\n").//
append("date: ").append(date).append("\n").//
append("GET ").append(url.getPath()).append(" HTTP/1.1");
//System.out.println(builder);
Charset charset = Charset.forName("UTF-8");
Mac mac = Mac.getInstance("hmacsha256");
SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(charset), "hmacsha256");
mac.init(spec);
byte[] hexDigits = mac.doFinal(builder.toString().getBytes(charset));
String sha = Base64.getEncoder().encodeToString(hexDigits);
//System.out.println(sha);
String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);
//System.out.println(authorization);
HttpUrl httpUrl = HttpUrl.parse("https://" + url.getHost() + url.getPath()).newBuilder().//
addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(charset))).//
addQueryParameter("date", date).//
addQueryParameter("host", url.getHost()).//
build();
return httpUrl.toString();
}
}
package admin.service;
/**
* @author lj
* @date 2025/2/23 13:41
*/
public interface DeepSeekOpenApiService {
void chatCompletions(String content);
}
package admin.service;
import admin.resp.ApiResponse;
import javax.websocket.Session;
/**
* @author lj
* @date 2025/2/24 11:11
*/
public interface MaxkbOpenApiService {
//获取应用id对应的会话id
ApiResponse<Object> getMaxkbSessionId(String apiKey);
/**
*
* @message message 问题
*/
void chatCompletions(String message,String chatId, Session session);
void talk(String message,Session seesion);
}
package admin.service.impl;
import admin.listener.DeepSeekAiListener;
import admin.model.deepseek.req.ChatMessage;
import admin.model.deepseek.req.ChatReqMsg;
import admin.model.deepseek.req.ChatStreamOption;
import admin.model.deepseek.resp.starnd.Message;
import admin.model.deepseek.resp.stream.ChatStreamResponse;
import admin.model.deepseek.resp.stream.StreamChoice;
import admin.service.DeepSeekOpenApiService;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import okhttp3.*;
import okhttp3.sse.EventSources;
import okio.BufferedSource;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
/**
* @author lj
* @date 2025/2/23 13:42
*/
@Service
@RequiredArgsConstructor
public class DeepSeekOpenApiServiceImpl implements DeepSeekOpenApiService {
@Override
public void chatCompletions(String content) {
OkHttpClient client = new OkHttpClient().newBuilder().readTimeout(1, TimeUnit.MINUTES)
.build();
MediaType mediaType = MediaType.parse("application/json");
ChatReqMsg req = createChatReqMsg(content);
Gson gson = new Gson();
RequestBody body = RequestBody.create(mediaType, gson.toJson(req));
Request request = new Request.Builder()
.url("http://192.168.0.122:6006/v1/chat/completions")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer zkhjdpQ8")
.build();
DeepSeekAiListener deepSeekAiListener = new DeepSeekAiListener(null);
// OkHttpClient okHttpClient = new OkHttpClient.Builder()
// .connectTimeout(1, TimeUnit.MINUTES)
// .readTimeout(1, TimeUnit.MINUTES)
// .build();
EventSources.createFactory(client).newEventSource(request,deepSeekAiListener);
// factory.newEventSource(request, eventSourceListener);
//
// client.newCall(request).enqueue(new Callback() {
// @Override
// public void onFailure(@NotNull Call call, @NotNull IOException e) {
//
// }
//
// @Override
// public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
// if (!response.isSuccessful()) {
// System.err.println("请求失败: " + response.code());
// return;
// }
//
// try (ResponseBody body = response.body()) {
// if (body != null) {
// processStream(body.source());
// }
// }
// }
// });
}
public static void processStream(BufferedSource source) throws IOException {
StringBuilder fullContent = new StringBuilder();
Gson gson = new Gson();
while (!source.exhausted()) {
String line = source.readUtf8Line();
if (line == null) break;
// 过滤心跳包和非数据行
if (line.startsWith("data: ")) {
String jsonData = line.substring(6).trim(); // 去掉 "data: "
if ("[DONE]".equals(jsonData)) {
System.out.println("\n[流式传输结束]");
break;
}
// 解析JSON块
ChatStreamResponse chunk = gson.fromJson(jsonData, ChatStreamResponse.class);
if (chunk != null && chunk.getChoices() != null) {
for (StreamChoice choice : chunk.getChoices()) {
Message deltaContent = choice.getDelta();
if (deltaContent != null && deltaContent.getContent()!=null) {
fullContent.append(deltaContent.getContent());
System.out.print(deltaContent.getContent()); // 实时输出
}
}
}
}
}
System.out.println("\n完整内容:\n" + fullContent);
}
private ChatReqMsg createChatReqMsg(String content) {
ChatReqMsg chatReqMsg = new ChatReqMsg();
ChatMessage chatMessage = new ChatMessage();
chatMessage.setContent(content);
chatMessage.setRole("user");
chatReqMsg.setMessages(new ArrayList<>(Collections.singleton(chatMessage)));
chatReqMsg.setModel("DeepSeek-R1-Distill-Qwen-32B-GGUF");
chatReqMsg.setStream(true);
ChatStreamOption chatStreamOption = new ChatStreamOption();
chatStreamOption.setIncludeUsage(true);
chatStreamOption.setContinuousUsageStats(false);
chatReqMsg.setStreamOptions(chatStreamOption);
// ChatRespType chatRespType = new ChatRespType();
// chatRespType.setType("text");
// chatReqMsg.setResponse_format(chatRespType);
return chatReqMsg;
}
}
package admin.service.impl;
import admin.model.maxdb.MaxdbScreenConfig;
import admin.model.maxdb.MaxdbZkhjConfig;
import admin.model.maxdb.req.MaxdbReq;
import admin.resp.ApiResponse;
import admin.service.MaxkbOpenApiService;
import admin.util.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.websocket.Session;
/**
* @author lj
* @date 2025/2/24 11:11
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MaxkbOpenApiServiceImpl implements MaxkbOpenApiService {
private final MaxdbZkhjConfig maxdbConfig;
private final MaxdbScreenConfig maxdbScreenConfig;
@Override
public ApiResponse<Object> getMaxkbSessionId(String applicationId) {
String data = HttpUtil.get(String.format(maxdbScreenConfig.getChatUrl(),applicationId),maxdbScreenConfig.getApiKey());
return JSONObject.parseObject(data, ApiResponse.class);
}
@Override
public void chatCompletions( String message, String chatId, Session session) {
MaxdbReq maxdbReq = new MaxdbReq();
maxdbReq.setMessage(message);
HttpUtil.postCallBackStream(String.format(maxdbScreenConfig.getTalkUrl(),chatId), maxdbReq, maxdbScreenConfig.getApiKey(),session);
}
@Override
public void talk(String message,Session seesion) {
// if (message.contains("中科")){
//
// }else if (message.contains("大屏")){
//
// }else if (message.contains("分析")){
//
// }else{
// }
ApiResponse<Object> maxkbSessionId = getMaxkbSessionId(maxdbScreenConfig.getApplicationId());
chatCompletions(message,String.valueOf(maxkbSessionId.getData()),seesion);
}
}
package admin.util;
import admin.listener.DeepSeekAiListener;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSources;
import javax.websocket.Session;
import java.io.IOException;
/**
* @author lj
* @date 2025/2/24 13:18
*/
public class HttpUtil {
public static String get(String url,String apiKey){
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder()
.url(url)
.method("GET",null)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("Authorization", apiKey)
.build();
try {
Response execute = okHttpClient.newCall(request).execute();
return execute.body().string();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void postCallBackStream(String url, Object data, String apiKey, Session session){
OkHttpClient okHttpClient = new OkHttpClient().newBuilder().build();
// RequestBody body = RequestBody.create(MediaType.parse("application/json"), data);
Request request = null;
try {
request = new Request.Builder()
.url(url)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.addHeader("Authorization", apiKey)
.post(RequestBody.create(MediaType.parse("application/json"),
new ObjectMapper().writeValueAsString(data)))
.build();
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
EventSource.Factory factory = EventSources.createFactory(okHttpClient);
factory.newEventSource(request,new DeepSeekAiListener(session));
}
}
maxdb:
zhongke:
api-key: application-5479ccf9b59c66432e5529febe94719a
application-id: 1a0e5e60-f1bd-11ef-a7de-0242ac110002
chat-url: http://192.168.0.122:8080/api/application/%s/chat/open
talk-url: http://192.168.0.122:8080/api/application/chat_message/%s
screen:
api-key: application-6e8250fa092a566c7c0aea0e08c9b1a3
application-id: adc51c8c-f3f4-11ef-a70b-0242ac110002
chat-url: http://192.168.0.122:8080/api/application/%s/chat/open
talk-url: http://192.168.0.122:8080/api/application/chat_message/%s
server:
port: 8888
tomcat:
max-swallow-size: 104857600
\ No newline at end of file
maxdb:
zhongke:
api-key: application-5479ccf9b59c66432e5529febe94719a
application-id: 1a0e5e60-f1bd-11ef-a7de-0242ac110002
chat-url: http://192.168.0.122:8080/api/application/%s/chat/open
talk-url: http://192.168.0.122:8080/api/application/chat_message/%s
screen:
api-key: application-6e8250fa092a566c7c0aea0e08c9b1a3
application-id: adc51c8c-f3f4-11ef-a70b-0242ac110002
chat-url: http://192.168.0.122:8080/api/application/%s/chat/open
talk-url: http://192.168.0.122:8080/api/application/chat_message/%s
server:
port: 8888
tomcat:
max-swallow-size: 104857600
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment