启航电商ERP系统正在重构AI原生ERP系统
This commit is contained in:
parent
37c0f3feef
commit
f309e90812
|
|
@ -6,8 +6,11 @@
|
||||||
|
|
||||||
> **启航电商ERP系统3.0版本在原版本基础上新增自动任务拉取订单、订单自动导入订单库等重大升级,进一步提升了开箱即用的特性。**
|
> **启航电商ERP系统3.0版本在原版本基础上新增自动任务拉取订单、订单自动导入订单库等重大升级,进一步提升了开箱即用的特性。**
|
||||||
|
|
||||||
|
> **启航电商ERP系统正在重构AI原生ERP系统。**
|
||||||
## 一、系统介绍
|
## 一、系统介绍
|
||||||
|
|
||||||
|
**启航电商ERP系统正在重构AI原生ERP系统。**
|
||||||
|
|
||||||
#### 项目定位
|
#### 项目定位
|
||||||
|
|
||||||
启航电商ERP系统是一个驱动电商企业数字化转型的电商业务中台系统底座。
|
启航电商ERP系统是一个驱动电商企业数字化转型的电商业务中台系统底座。
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,18 @@
|
||||||
<!-- <scope>provided</scope>-->
|
<!-- <scope>provided</scope>-->
|
||||||
<!-- </dependency>-->
|
<!-- </dependency>-->
|
||||||
|
|
||||||
|
<!-- LangChain4J 依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.langchain4j</groupId>
|
||||||
|
<artifactId>langchain4j</artifactId>
|
||||||
|
<version>1.11.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Ollama 集成 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.langchain4j</groupId>
|
||||||
|
<artifactId>langchain4j-ollama</artifactId>
|
||||||
|
<version>1.11.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
@ -153,4 +164,4 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -64,13 +64,13 @@ public class SseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/send")
|
@GetMapping("/send")
|
||||||
public String sendMessage(@RequestParam String clientId, @RequestParam String message) {
|
public String sendMessage(@RequestParam String clientId, @RequestParam String message, @RequestParam(required = false, defaultValue = "llama3") String model) {
|
||||||
log.info("=============来新消息了!");
|
log.info("=============来新消息了!");
|
||||||
SseEmitter emitter = emitters.get(clientId);
|
SseEmitter emitter = emitters.get(clientId);
|
||||||
if (emitter != null) {
|
if (emitter != null) {
|
||||||
try {
|
try {
|
||||||
// 使用AiService处理消息
|
// 使用AiService处理消息,传递模型参数
|
||||||
String response = aiService.processMessage(message);
|
String response = aiService.processMessage(message, model);
|
||||||
|
|
||||||
emitter.send(SseEmitter.event()
|
emitter.send(SseEmitter.event()
|
||||||
.name("message")
|
.name("message")
|
||||||
|
|
|
||||||
|
|
@ -1,67 +1,45 @@
|
||||||
package cn.qihangerp.erp.serviceImpl;
|
package cn.qihangerp.erp.serviceImpl;
|
||||||
|
|
||||||
import cn.qihangerp.common.ResultVo;
|
import dev.langchain4j.model.ollama.OllamaChatModel;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.StringUtils;
|
import java.time.Duration;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI服务类,直接调用Ollama API处理聊天内容
|
* AI服务类,使用LangChain4J调用Ollama模型处理聊天内容
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class AiService {
|
public class AiService {
|
||||||
|
|
||||||
private final HttpClient httpClient;
|
/**
|
||||||
private final String ollamaUrl;
|
* 处理聊天消息
|
||||||
|
* @param message 用户消息
|
||||||
public AiService() {
|
* @param model 模型名称
|
||||||
this.httpClient = HttpClient.newHttpClient();
|
* @return AI回复
|
||||||
this.ollamaUrl = "http://localhost:11434/api/generate";
|
*/
|
||||||
|
public String processMessage(String message, String model) {
|
||||||
|
try {
|
||||||
|
// 根据模型名称创建对应的ChatModel
|
||||||
|
OllamaChatModel modelInstance = OllamaChatModel.builder()
|
||||||
|
.baseUrl("http://localhost:11434") // Ollama默认端口
|
||||||
|
.modelName(model) // 使用指定的模型
|
||||||
|
.temperature(0.7)
|
||||||
|
.timeout(Duration.ofSeconds(300)) // 超时时间设置为300秒(5分钟)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 调用Ollama模型获取回复
|
||||||
|
return modelInstance.chat(message);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "错误: " + e.getMessage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理聊天消息
|
* 处理聊天消息(使用默认模型)
|
||||||
* @param message 用户消息
|
* @param message 用户消息
|
||||||
* @return AI回复
|
* @return AI回复
|
||||||
*/
|
*/
|
||||||
public String processMessage(String message) {
|
public String processMessage(String message) {
|
||||||
try {
|
return processMessage(message, "llama3");
|
||||||
// 构建请求体
|
|
||||||
JSONObject requestBody = new JSONObject();
|
|
||||||
requestBody.put("model", "llama3");
|
|
||||||
requestBody.put("prompt", message);
|
|
||||||
requestBody.put("stream", false);
|
|
||||||
requestBody.put("temperature", 0.7);
|
|
||||||
|
|
||||||
// 创建HTTP请求
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create(ollamaUrl))
|
|
||||||
.header("Content-Type", "application/json")
|
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(requestBody.toJSONString()))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// 发送请求并获取响应
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
// 解析响应
|
|
||||||
JSONObject responseBody = JSONObject.parseObject(response.body());
|
|
||||||
|
|
||||||
// 检查是否有错误
|
|
||||||
if (responseBody.containsKey("error")) {
|
|
||||||
String errorMessage = responseBody.getString("error");
|
|
||||||
return "错误: " + errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseBody.getString("response");
|
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return "抱歉,我暂时无法处理您的请求,请稍后重试。";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
docs/preview.png
BIN
docs/preview.png
Binary file not shown.
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 354 KiB |
|
|
@ -8,6 +8,13 @@
|
||||||
<span class="title">工作助手</span>
|
<span class="title">工作助手</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
|
<el-select v-model="selectedModel" size="mini" style="width: 120px; margin-right: 10px;">
|
||||||
|
<el-option label="qwen3.5:2b" value="qwen3.5:2b"></el-option>
|
||||||
|
<el-option label="Llama 3" value="llama3"></el-option>
|
||||||
|
<el-option label="Gemini" value="gemini"></el-option>
|
||||||
|
<el-option label="Claude" value="claude"></el-option>
|
||||||
|
<el-option label="Gemma" value="gemma"></el-option>
|
||||||
|
</el-select>
|
||||||
<el-tag type="success" size="mini">在线</el-tag>
|
<el-tag type="success" size="mini">在线</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -166,7 +173,8 @@ export default {
|
||||||
sse: null,
|
sse: null,
|
||||||
clientId: '',
|
clientId: '',
|
||||||
isSseConnected: false,
|
isSseConnected: false,
|
||||||
isLoading: false
|
isLoading: false,
|
||||||
|
selectedModel: 'qwen3.5:2b'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -259,13 +267,21 @@ export default {
|
||||||
|
|
||||||
// 通过SSE发送消息到后端
|
// 通过SSE发送消息到后端
|
||||||
if (this.isSseConnected) {
|
if (this.isSseConnected) {
|
||||||
|
// 使用AbortController实现超时
|
||||||
|
const controller = new AbortController();
|
||||||
|
const timeoutId = setTimeout(() => controller.abort(), 300000); // 300秒超时
|
||||||
|
|
||||||
// 使用fetch发送消息
|
// 使用fetch发送消息
|
||||||
fetch(`${process.env.VUE_APP_BASE_API}/api/ai-agent/sse/send?clientId=${this.clientId}&message=${encodeURIComponent(this.inputMessage)}&token=${token}`)
|
fetch(`${process.env.VUE_APP_BASE_API}/api/ai-agent/sse/send?clientId=${this.clientId}&message=${encodeURIComponent(this.inputMessage)}&model=${this.selectedModel}&token=${token}`, {
|
||||||
|
signal: controller.signal
|
||||||
|
})
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
console.log('消息发送结果:', data);
|
console.log('消息发送结果:', data);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
console.error('消息发送失败:', error);
|
console.error('消息发送失败:', error);
|
||||||
// 发送失败时使用模拟回复
|
// 发送失败时使用模拟回复
|
||||||
this.generateReply(this.inputMessage);
|
this.generateReply(this.inputMessage);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue