当前位置: 首页 > news >正文

SpringBoot集成 DeepSeek 对话补全功能

概述

在 Ruoyi-Vue 这一流行的前后端分离权限管理系统基础上,集成 DeepSeek 提供的强大 AI 对话补全功能,可以为系统添加智能对话和内容生成能力。本文将详细介绍如何在 Ruoyi-Vue 中实现这一集成。

技术栈

  • 后端:Ruoyi Spring Boot

  • 前端:Ruoyi Vue + Element UI

  • AI服务:DeepSeek API

1. 准备工作

首先需要获取 DeepSeek API 访问权限:

  1. 访问 DeepSeek 官网 注册账号

  2. 获取 API Key

  3. 了解 API 调用方式和参数

1.1在application.yml中添加配置

# application.yml
# DeepSeek配置
deepseek:api:apiKey: your_deepseek_api_key_here  # 替换为您的实际API密钥apiUrl: https://api.deepseek.com/chat/completionsdefault-model: deepseek-chatdefault-temperature: 0.7default-max-tokens: 2000connect-timeout: 10000  # 连接超时时间(毫秒)read-timeout: 30000     # 读取超时时间(毫秒)# 日志配置
logging:level:com.ruoyi.project.system.service.DeepSeekService: DEBUGcom.ruoyi.project.system.controller.DeepSeekController: DEBUG

1.2DeepSeek配置属性类

package com.dafu.common.ai;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;/*** DeepSeek配置属性类* 用于从application.yml中读取DeepSeek相关配置*/
@Component
@ConfigurationProperties(prefix = "deepseek.api")
@Data
public class DeepSeekProperties {/*** API密钥*/private String apiKey;/*** API端点URL*/private String apiUrl = "https://api.deepseek.com/chat/completions";/*** 默认模型名称*/private String defaultModel = "deepseek-chat";/*** 默认温度参数*/private double defaultTemperature = 0.7;/*** 默认最大token数量*/private int defaultMaxTokens = 2000;/*** 连接超时时间(毫秒)*/private int connectTimeout = 10000;/*** 读取超时时间(毫秒)*/private int readTimeout = 30000;
}

2. 添加DeepSeek请求/响应DTO

2.1. DeepSeek API请求参数实体类用于构建发送到DeepSeek API的请求数据
package com.dafu.chat.domain;import lombok.Data;import java.util.List;/*** @author:DaFu* @date: 2025/8/27 16:09* DeepSeek API请求参数实体类* 用于构建发送到DeepSeek API的请求数据*/
@Data
public class DeepSeekRequest {/*** 模型名称,例如:deepseek-chat*/private String model;/*** 消息列表,包含对话历史*/private List<Message> messages;/*** 生成文本的随机性控制(0-1之间)* 值越高,生成结果越随机;值越低,结果越确定*/private double temperature = 0.7;/*** 生成的最大token数量*/private int max_tokens = 2000;/*** 是否流式输出*/private boolean stream = false;/*** 消息实体内部类*/@Datapublic static class Message {/*** 角色:system、user、assistant*/private String role;/*** 消息内容*/private String content;/*** 构造函数* @param role 角色* @param content 内容*/public Message(String role, String content) {this.role = role;this.content = content;}}
}

2.2 DeepSeek API响应实体类用于解析DeepSeek API返回的响应数据

package com.dafu.chat.domain;import lombok.Data;import java.util.List;/*** @author:DaFu* @date: 2025/8/27 16:08* DeepSeek API响应实体类* 用于解析DeepSeek API返回的响应数据*/
@Data
public class DeepSeekResponse {/*** 请求ID*/private String id;/*** 对象类型*/private String object;/*** 创建时间戳*/private long created;/*** 使用的模型名称*/private String model;/*** 生成的选择列表*/private List<Choice> choices;/*** token使用情况统计*/private Usage usage;/*** 错误信息(如果有)*/private Error error;/*** 选择实体内部类*/@Datapublic static class Choice {/*** 选择索引*/private int index;/*** 生成的消息*/private Message message;/*** 结束原因*/private String finish_reason;}/*** 消息实体内部类*/@Datapublic static class Message {/*** 角色*/private String role;/*** 内容*/private String content;}/*** token使用统计内部类*/@Datapublic static class Usage {/*** 提示token数量*/private int prompt_tokens;/*** 补全token数量*/private int completion_tokens;/*** 总token数量*/private int total_tokens;}/*** 错误信息内部类*/@Datapublic static class Error {/*** 错误消息*/private String message;/*** 错误类型*/private String type;/*** 参数信息*/private String param;/*** 错误代码*/private String code;}
}

2.3前端聊天请求参数实体 类用于接收前端发送的聊天请求

package com.dafu.chat.domain;import lombok.Data;import javax.validation.constraints.NotBlank;/*** @author:DaFu* @date: 2025/8/27 16:09* 前端聊天请求参数实体类* 用于接收前端发送的聊天请求*/
@Data
public class ChatRequest {/*** 用户消息内容*/@NotBlank(message = "消息内容不能为空")private String message;/*** 对话ID,用于多轮对话上下文管理*/private String conversationId;/*** 模型名称,可选参数,默认使用配置的模型*/private String model;
}

3.RestTemplate配置类

package com.dafu.framework.config;
import com.dafu.common.ai.DeepSeekProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;/*** RestTemplate配置类* 配置HTTP请求的超时时间等参数*/
@Configuration
public class RestTemplateConfig {private final DeepSeekProperties deepSeekProperties;/*** 构造函数* @param deepSeekProperties DeepSeek配置属性*/public RestTemplateConfig(DeepSeekProperties deepSeekProperties) {this.deepSeekProperties = deepSeekProperties;}/*** 创建RestTemplate Bean* @return 配置好的RestTemplate实例*/@Beanpublic RestTemplate restTemplate() {SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();// 设置连接超时时间factory.setConnectTimeout(deepSeekProperties.getConnectTimeout());// 设置读取超时时间factory.setReadTimeout(deepSeekProperties.getReadTimeout());return new RestTemplate(factory);}
}

4.DeepSeek服务类

4.1负责与DeepSeek API进行交互

package com.dafu.chat.service;
import com.dafu.chat.domain.DeepSeekRequest;
import com.dafu.chat.domain.DeepSeekResponse;
import com.dafu.common.ai.DeepSeekProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
import java.util.List;/*** @author:DaFu* @date: 2025/8/27* DeepSeek服务类* 负责与DeepSeek API进行交互*/
@Slf4j
@Service
public class DeepSeekService {private final DeepSeekProperties properties;private final RestTemplate restTemplate;/*** 构造函数* @param properties DeepSeek配置属性* @param restTemplate RestTemplate实例*/public DeepSeekService(DeepSeekProperties properties, RestTemplate restTemplate) {this.properties = properties;this.restTemplate = restTemplate;}/*** 发送聊天补全请求到DeepSeek API* @param messages 消息列表* @return DeepSeek响应对象*/public DeepSeekResponse chatCompletion(List<DeepSeekRequest.Message> messages) {return chatCompletion(messages, properties.getDefaultModel(),properties.getDefaultTemperature(), properties.getDefaultMaxTokens());}/*** 发送聊天补全请求到DeepSeek API(带参数)* @param messages 消息列表* @param model 模型名称* @param temperature 温度参数* @param maxTokens 最大token数量* @return DeepSeek响应对象*/public DeepSeekResponse chatCompletion(List<DeepSeekRequest.Message> messages, String model,double temperature, int maxTokens) {// 记录请求日志log.info("发送请求到DeepSeek API,模型: {}, 消息数量: {}", model, messages.size());// 设置请求头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);headers.set("Authorization", "Bearer " + properties.getApiKey());headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));// 构建请求体DeepSeekRequest request = new DeepSeekRequest();request.setModel(model);request.setMessages(messages);request.setTemperature(temperature);request.setMax_tokens(maxTokens);HttpEntity<DeepSeekRequest> entity = new HttpEntity<>(request, headers);try {// 发送请求ResponseEntity<DeepSeekResponse> response = restTemplate.exchange(properties.getApiUrl(),HttpMethod.POST,entity,DeepSeekResponse.class);// 检查响应状态if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {DeepSeekResponse responseBody = response.getBody();// 检查API返回的错误if (responseBody.getError() != null) {log.error("DeepSeek API返回错误: {}", responseBody.getError().getMessage());throw new RuntimeException("DeepSeek API错误: " + responseBody.getError().getMessage());}// 记录使用情况if (responseBody.getUsage() != null) {log.info("API使用情况 - 提示token: {}, 补全token: {}, 总计token: {}",responseBody.getUsage().getPrompt_tokens(),responseBody.getUsage().getCompletion_tokens(),responseBody.getUsage().getTotal_tokens());}return responseBody;} else {log.error("DeepSeek API请求失败,状态码: {}", response.getStatusCode());throw new RuntimeException("DeepSeek API请求失败,状态码: " + response.getStatusCode());}} catch (Exception e) {log.error("调用DeepSeek API失败: {}", e.getMessage(), e);throw new RuntimeException("调用DeepSeek API失败: " + e.getMessage(), e);}}
}

5.DeepSeek聊天控制器

5.1提供与前端交互的API接口

package com.dafu.chat.controller;
import com.dafu.chat.domain.ChatRequest;
import com.dafu.chat.domain.DeepSeekRequest;
import com.dafu.chat.domain.DeepSeekResponse;
import com.dafu.chat.service.DeepSeekService;
import com.dafu.common.constant.HttpStatus;
import com.dafu.common.core.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;/*** @author:DaFu* @date: 2025/8/27* DeepSeek聊天控制器* 提供与前端交互的API接口*/
@RestController
@RequestMapping("/api/chat")
@Validated
@Slf4j
public class DeepSeekController {private final DeepSeekService deepSeekService;/*** 构造函数* @param deepSeekService DeepSeek服务*/public DeepSeekController(DeepSeekService deepSeekService) {this.deepSeekService = deepSeekService;}/*** 处理聊天补全请求* @param chatRequest 聊天请求参数* @return 包含AI回复的响应结果*/@PostMapping("/completion")public AjaxResult chatCompletion(@Valid @RequestBody ChatRequest chatRequest) {try {log.info("收到聊天请求,对话ID: {}, 消息长度: {}",chatRequest.getConversationId(), chatRequest.getMessage().length());// 构建消息列表List<DeepSeekRequest.Message> messages = new ArrayList<>();// 可以根据conversationId获取对话历史(此处为简化版,实际应查询数据库)// 这里只添加当前消息messages.add(new DeepSeekRequest.Message("user", chatRequest.getMessage()));// 调用DeepSeek服务DeepSeekResponse response = deepSeekService.chatCompletion(messages);// 检查响应有效性if (response != null &&response.getChoices() != null &&!response.getChoices().isEmpty() &&response.getChoices().get(0).getMessage() != null) {String reply = response.getChoices().get(0).getMessage().getContent();// 记录成功日志log.info("成功获取AI回复,回复长度: {}", reply.length());// 返回成功响应return AjaxResult.success("操作成功", reply);}// 处理无效响应log.warn("未获取到有效回复");return AjaxResult.error(HttpStatus.ERROR, "未获取到有效回复");} catch (Exception e) {// 记录错误日志log.error("处理聊天请求时发生错误: {}", e.getMessage(), e);// 返回错误响应return AjaxResult.error(HttpStatus.ERROR, "请求失败: " + e.getMessage());}}/*** 健康检查接口* @return 健康状态*/@GetMapping("/health")public AjaxResult healthCheck() {return AjaxResult.success("DeepSeek服务正常运行");}
}

6.前端实现 (Vue)

6.1. 创建API调用方法
// src/api/chat/deepseek.js
import request from '@/utils/request'export function chatCompletion(data) {return request({url: '/api/chat/completion',method: 'post',data: data})
}
6.2. 创建聊天组件
<!-- src/views/chat/DeepSeekChat.vue -->
<template><div class="app-container"><el-card class="box-card"><div slot="header" class="clearfix"><span>DeepSeek 智能对话</span></div><div class="chat-container"><!-- 消息显示区域 --><div class="messages" ref="messagesContainer"><div v-for="(message, index) in messages" :key="index" :class="['message', message.role]"><div class="avatar"><i :class="message.role === 'user' ? 'el-icon-user' : 'el-icon-robot'"></i></div><div class="content"><div class="text">{{ message.content }}</div><div class="time">{{ message.time }}</div></div></div></div><!-- 输入区域 --><div class="input-area"><el-inputtype="textarea":rows="3"placeholder="请输入您的问题..."v-model="inputMessage"@keydown.enter.native="handleSend":disabled="loading"></el-input><div class="actions"><el-button type="primary" @click="handleSend" :loading="loading":disabled="!inputMessage.trim()">发送</el-button><el-button @click="clearChat">清空对话</el-button></div></div></div></el-card></div>
</template><script>
import { chatCompletion } from "@/api/chat/deepseek";export default {name: "DeepSeekChat",data() {return {messages: [],inputMessage: "",loading: false,conversationId: null};},methods: {handleSend() {if (!this.inputMessage.trim() || this.loading) return;const userMessage = {role: "user",content: this.inputMessage,time: new Date().toLocaleTimeString()};this.messages.push(userMessage);this.scrollToBottom();const messageToSend = this.inputMessage;this.inputMessage = "";this.loading = true;// 调用APIchatCompletion({ message: messageToSend, conversationId: this.conversationId }).then(response => {const assistantMessage = {role: "assistant",content: response.data,time: new Date().toLocaleTimeString()};this.messages.push(assistantMessage);this.scrollToBottom();}).catch(error => {this.$message.error("请求失败: " + (error.message || "未知错误"));}).finally(() => {this.loading = false;});},scrollToBottom() {this.$nextTick(() => {const container = this.$refs.messagesContainer;if (container) {container.scrollTop = container.scrollHeight;}});},clearChat() {this.messages = [];this.conversationId = null;}}
};
</script><style scoped>
.chat-container {display: flex;flex-direction: column;height: 600px;
}.messages {flex: 1;overflow-y: auto;padding: 10px;border: 1px solid #ebeef5;border-radius: 4px;margin-bottom: 15px;background-color: #fafafa;
}.message {display: flex;margin-bottom: 15px;
}.message.user {flex-direction: row-reverse;
}.message .avatar {width: 40px;height: 40px;border-radius: 50%;background-color: #409EFF;color: white;display: flex;align-items: center;justify-content: center;margin: 0 10px;
}.message.user .avatar {background-color: #67C23A;
}.message .content {max-width: 70%;
}.message.user .content {text-align: right;
}.message .text {padding: 10px 15px;border-radius: 4px;background-color: white;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}.message.user .text {background-color: #ecf5ff;
}.message .time {font-size: 12px;color: #909399;margin-top: 5px;
}.input-area {border-top: 1px solid #ebeef5;padding-top: 15px;
}.actions {margin-top: 10px;text-align: right;
}
</style>

7.响应显示

http://www.dtcms.com/a/353266.html

相关文章:

  • 安全建设之SLA指标(服务等级协议)
  • Linux基础优化(Ubuntu、Kylin)
  • k8s—部署discuz论坛和tomca商城
  • 轮转数组或者旋转数组-力扣189
  • 【开题答辩全过程】以基于Android的校园跳蚤市场交易系统的设计与实现为例,包含答辩的问题和答案
  • java基础(十六)操作系统(上)
  • RCLAMP3552T.TQT电子元器件Semtech 多通道、低电容、高速ESD保护器件/TVS二极管阵列
  • Git零基础入门实践(带图解)
  • JMeter —— 压力测试
  • ES01-环境安装
  • Ansible 核心模块与实操练习
  • 使用Python自动化VS 2022的C++项目构建流程
  • 数据结构青铜到王者第六话---栈(Stack)
  • 使用 ROS2 构建客户端-服务器通信:一个简单的计算器示例
  • 2024年12月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • Vue3音频组件开发与使用指南
  • PythonDay38
  • 虚拟机逃逸攻防演练
  • 【项目】分布式Json-RPC框架 - 抽象层与具象层实现
  • 借助 LAMBDA 公式,实现单元格区域高效转换
  • 云计算资源分配问题
  • 【CVE-2025-49113】(内附EXP) 通过 PHP 对象反序列化在 Roundcube 中执行身份验证后远程代码
  • MongoDB Shell
  • 解决.env.production 写死 IP 的问题:Vue + config.json 运行时加载方案
  • vsCode如何自定义编辑器背景色
  • 元宇宙与医疗健康:重构诊疗体验与健康管理模式
  • 硬件开发_基于物联网的儿童座椅系统
  • Milvus + Reranker 混合搜索技术方案详细文档
  • 低空无人机系统关键技术与应用前景:SmartMediaKit视频链路的基石价值
  • SyncBackPro 备份及同步软件中的脚本功能简介