欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于SpringBoot+Vue實現(xiàn)DeepSeek對話效果的詳細步驟

 更新時間:2025年07月20日 08:30:19   作者:奇妙智能  
本文詳細介紹了使用SpringBoot和Vue構建對話系統(tǒng),包含API設計、聊天界面開發(fā)、前后端集成及WebSocket優(yōu)化,實現(xiàn)類似DeepSeek的交互效果,需要的朋友可以參考下

Spring Boot + Vue 實現(xiàn) DeepSeek 對話效果詳細步驟

一、整體架構設計

我們需要構建一個前后端分離的應用:

  • ??后端??:Spring Boot 提供 API 接口,處理與 AI 模型的交互
  • ??前端??:Vue 實現(xiàn)聊天界面,展示對話內容并發(fā)送用戶輸入

二、后端實現(xiàn) (Spring Boot)

1. 創(chuàng)建 Spring Boot 項目

<!-- pom.xml 主要依賴 -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- 如果需要持久化存儲 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>

2. 設計 API 接口

// 對話控制器
@RestController
@RequestMapping("/api/chat")
public class ChatController {
    
    @Autowired
    private ChatService chatService;
    
    @PostMapping("/message")
    public ResponseEntity<ChatResponse> sendMessage(@RequestBody ChatRequest request) {
        ChatResponse response = chatService.processMessage(request);
        return ResponseEntity.ok(response);
    }
    
    @GetMapping("/history/{sessionId}")
    public ResponseEntity<List<ChatMessage>> getHistory(@PathVariable String sessionId) {
        List<ChatMessage> history = chatService.getChatHistory(sessionId);
        return ResponseEntity.ok(history);
    }
}

3. 定義數(shù)據(jù)傳輸對象

public class ChatRequest {
    private String sessionId;
    private String message;
    // getter, setter
}

public class ChatResponse {
    private String message;
    private String sessionId;
    // getter, setter
}

public class ChatMessage {
    private String role; // "user" 或 "assistant"
    private String content;
    // getter, setter
}

4. 實現(xiàn)對話服務

@Service
public class ChatService {
    
    // 可以使用 Map 臨時存儲會話,生產(chǎn)環(huán)境建議使用數(shù)據(jù)庫
    private Map<String, List<ChatMessage>> chatSessions = new ConcurrentHashMap<>();
    
    // 處理用戶消息
    public ChatResponse processMessage(ChatRequest request) {
        String sessionId = request.getSessionId();
        if (sessionId == null || sessionId.isEmpty()) {
            sessionId = UUID.randomUUID().toString();
        }
        
        String userMessage = request.getMessage();
        
        // 保存用戶消息
        ChatMessage userMsg = new ChatMessage("user", userMessage);
        
        // 調用 AI 模型 API
        String aiResponse = callAIApi(userMessage, sessionId);
        
        // 保存 AI 回復
        ChatMessage aiMsg = new ChatMessage("assistant", aiResponse);
        
        // 更新會話歷史
        chatSessions.computeIfAbsent(sessionId, k -> new ArrayList<>()).add(userMsg);
        chatSessions.get(sessionId).add(aiMsg);
        
        return new ChatResponse(aiResponse, sessionId);
    }
    
    // 獲取聊天歷史
    public List<ChatMessage> getChatHistory(String sessionId) {
        return chatSessions.getOrDefault(sessionId, Collections.emptyList());
    }
    
    // 調用 AI 模型 API 的方法
    private String callAIApi(String message, String sessionId) {
        // 這里實現(xiàn)與 DeepSeek API 的實際交互
        // 可以使用 RestTemplate 或 WebClient
        // 示例代碼:
        try {
            // 實際開發(fā)中替換為真實 API 調用
            return "這是 AI 對 "" + message + "" 的回復";
        } catch (Exception e) {
            return "抱歉,我遇到了一些問題,請稍后再試。";
        }
    }
}

5. 配置 CORS

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://localhost:5173") // Vue 默認端口
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowCredentials(true);
    }
}

三、前端實現(xiàn) (Vue)

1. 創(chuàng)建 Vue 項目

# 使用 npm
npm create vue@latest my-chat-app
cd my-chat-app
npm install

# 安裝必要的依賴
npm install axios

2. 創(chuàng)建聊天組件

<!-- ChatWindow.vue -->
<template>
  <div class="chat-container">
    <div class="chat-header">
      <h2>AI 助手對話</h2>
    </div>
    
    <div class="chat-messages" ref="messageContainer">
      <div v-for="(msg, index) in messages" :key="index" 
           :class="['message', msg.role === 'user' ? 'user-message' : 'assistant-message']">
        <div class="message-content">
          {{ msg.content }}
        </div>
      </div>
      <div v-if="loading" class="message assistant-message">
        <div class="message-content">
          <span class="loading-dots">思考中<span>.</span><span>.</span><span>.</span></span>
        </div>
      </div>
    </div>
    
    <div class="chat-input">
      <textarea 
        v-model="userInput" 
        placeholder="請輸入您的問題..." 
        @keyup.enter.ctrl="sendMessage"
      ></textarea>
      <button @click="sendMessage" :disabled="loading || !userInput.trim()">
        發(fā)送
      </button>
    </div>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  name: 'ChatWindow',
  data() {
    return {
      messages: [],
      userInput: '',
      loading: false,
      sessionId: this.generateSessionId(),
      apiBaseUrl: 'http://localhost:8080/api/chat'
    };
  },
  methods: {
    generateSessionId() {
      return Math.random().toString(36).substring(2, 15);
    },
    async sendMessage() {
      if (!this.userInput.trim() || this.loading) return;
      
      const userMessage = this.userInput.trim();
      this.messages.push({ role: 'user', content: userMessage });
      this.userInput = '';
      this.loading = true;
      
      // 滾動到底部
      this.$nextTick(() => {
        this.scrollToBottom();
      });
      
      try {
        const response = await axios.post(`${this.apiBaseUrl}/message`, {
          sessionId: this.sessionId,
          message: userMessage
        });
        
        this.messages.push({ role: 'assistant', content: response.data.message });
        this.sessionId = response.data.sessionId;
      } catch (error) {
        console.error('Error sending message:', error);
        this.messages.push({ 
          role: 'assistant', 
          content: '抱歉,發(fā)生了錯誤,請稍后再試。' 
        });
      } finally {
        this.loading = false;
        this.$nextTick(() => {
          this.scrollToBottom();
        });
      }
    },
    scrollToBottom() {
      if (this.$refs.messageContainer) {
        this.$refs.messageContainer.scrollTop = this.$refs.messageContainer.scrollHeight;
      }
    },
    loadHistory() {
      axios.get(`${this.apiBaseUrl}/history/${this.sessionId}`)
        .then(response => {
          this.messages = response.data;
          this.$nextTick(() => {
            this.scrollToBottom();
          });
        })
        .catch(error => {
          console.error('Error loading history:', error);
        });
    }
  },
  mounted() {
    // 在實際應用中,可以從 URL 參數(shù)或本地存儲獲取 sessionId
    // this.loadHistory();
  }
}
</script>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  max-width: 800px;
  margin: 0 auto;
  padding: 1rem;
}

.chat-header {
  text-align: center;
  padding: 1rem 0;
  border-bottom: 1px solid #eee;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.message {
  max-width: 75%;
  padding: 0.75rem;
  border-radius: 0.5rem;
  margin-bottom: 0.5rem;
}

.user-message {
  align-self: flex-end;
  background-color: #e1f5fe;
}

.assistant-message {
  align-self: flex-start;
  background-color: #f5f5f5;
}

.chat-input {
  display: flex;
  padding: 1rem 0;
  gap: 0.5rem;
}

.chat-input textarea {
  flex: 1;
  padding: 0.75rem;
  border: 1px solid #ddd;
  border-radius: 0.5rem;
  resize: none;
  min-height: 60px;
}

.chat-input button {
  padding: 0.75rem 1.5rem;
  background-color: #2196f3;
  color: white;
  border: none;
  border-radius: 0.5rem;
  cursor: pointer;
}

.chat-input button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.loading-dots span {
  animation: loading 1.4s infinite;
  display: inline-block;
}

.loading-dots span:nth-child(2) {
  animation-delay: 0.2s;
}

.loading-dots span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes loading {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 1; }
}
</style>

3. 在主應用中使用聊天組件

<!-- App.vue -->
<template>
  <div class="app">
    <ChatWindow />
  </div>
</template>

<script>
import ChatWindow from './components/ChatWindow.vue'

export default {
  name: 'App',
  components: {
    ChatWindow
  }
}
</script>

<style>
body {
  margin: 0;
  padding: 0;
  font-family: Arial, sans-serif;
}

.app {
  width: 100%;
  height: 100vh;
}
</style>

四、前后端集成與部署

1. 開發(fā)環(huán)境配置

??啟動后端服務??

./mvnw spring-boot:run

??啟動前端開發(fā)服務器??

npm run dev

2. 生產(chǎn)環(huán)境部署

??構建前端應用??

npm run build

??配置后端服務提供靜態(tài)文件??

// Spring Boot 配置類
@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Value("${frontend.resources.path:${user.home}/my-chat-app/dist}")
    private Resource frontendResources;
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("file:" + frontendResources.getFile().getAbsolutePath() + "/")
                .resourceChain(true)
                .addResolver(new PathResourceResolver() {
                    @Override
                    protected Resource getResource(String resourcePath, Resource location) throws IOException {
                        Resource requestedResource = location.createRelative(resourcePath);
                        return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                                : new ClassPathResource("/static/index.html");
                    }
                });
    }
}

??將前端構建文件復制到后端資源目錄??

五、進階優(yōu)化

1. WebSocket 實現(xiàn)實時通信

// 后端 WebSocket 配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
               .setAllowedOriginPatterns("*")
               .withSockJS();
    }
}

// WebSocket 控制器
@Controller
public class WebSocketController {
    
    @Autowired
    private ChatService chatService;
    
    @MessageMapping("/chat.sendMessage")
    @SendToUser("/queue/reply")
    public ChatMessage sendMessage(@Payload ChatMessage chatMessage, Principal principal) {
        return chatService.processWebSocketMessage(chatMessage);
    }
}

2. 使用 Redis 緩存會話歷史

@Configuration
@EnableRedisHttpSession
public class SessionConfig {
    
    @Bean
    public LettuceConnectionFactory connectionFactory() {
        return new LettuceConnectionFactory();
    }
}

3. 前端連接 WebSocket

// 在 ChatWindow.vue 中添加 WebSocket 連接
export default {
  // ... 其他代碼 ...
  data() {
    return {
      // ... 其他數(shù)據(jù) ...
      stompClient: null
    };
  },
  methods: {
    // ... 其他方法 ...
    
    connectWebSocket() {
      const socket = new SockJS(this.apiBaseUrl.replace('/api', ''));
      this.stompClient = Stomp.over(socket);
      
      this.stompClient.connect({}, frame => {
        console.log('Connected: ' + frame);
        this.stompClient.subscribe(`/user/queue/reply`, response => {
          const receivedMessage = JSON.parse(response.body);
          this.messages.push(receivedMessage);
          this.$nextTick(() => {
            this.scrollToBottom();
          });
        });
      }, error => {
        console.error('WebSocket Error: ' + error);
        // 重連邏輯
        setTimeout(() => {
          this.connectWebSocket();
        }, 5000);
      });
    },
    
    disconnectWebSocket() {
      if (this.stompClient !== null) {
        this.stompClient.disconnect();
      }
    },
    
    sendWebSocketMessage() {
      if (!this.userInput.trim() || this.loading) return;
      
      const userMessage = this.userInput.trim();
      
      this.stompClient.send("/app/chat.sendMessage", {}, JSON.stringify({
        sessionId: this.sessionId,
        message: userMessage
      }));
      
      this.messages.push({ role: 'user', content: userMessage });
      this.userInput = '';
    }
  },
  mounted() {
    // ... 其他代碼 ...
    this.connectWebSocket();
  },
  beforeUnmount() {
    this.disconnectWebSocket();
  }
}

總結

通過上述步驟,你可以實現(xiàn)一個基于 Spring Boot 和 Vue 的對話系統(tǒng),類似 DeepSeek 的交互效果。這個實現(xiàn)包含了:

  1. 后端 API 設計與實現(xiàn)
  2. 前端聊天界面設計
  3. 會話管理與歷史記錄
  4. WebSocket 實現(xiàn)實時通信(可選)
  5. 部署配置

根據(jù)實際需求,你可以進一步擴展功能,如支持 Markdown 渲染、代碼高亮、對話導出等高級特性。

以上就是基于SpringBoot+Vue實現(xiàn)DeepSeek對話效果的詳細步驟的詳細內容,更多關于SpringBoot Vue DeepSeek對話的資料請關注腳本之家其它相關文章!

相關文章

  • Java8并發(fā)新特性CompletableFuture

    Java8并發(fā)新特性CompletableFuture

    這篇文章主要介紹了Java8并發(fā)新特性CompletableFuture,CompletableFuture針對Future接口做了改進,相比Callable/Runnable接口它支持多任務進行鏈式調用、組合、多任務并發(fā)處理,下面文章更多相關內容得介紹,需要的小伙伴可以參考一下
    2022-06-06
  • Presto自定義函數(shù)@SqlNullable引發(fā)問題詳解

    Presto自定義函數(shù)@SqlNullable引發(fā)問題詳解

    這篇文章主要為大家介紹了Presto自定義函數(shù)@SqlNullable引發(fā)問題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • mybatis foreach批量插入數(shù)據(jù):Oracle與MySQL區(qū)別介紹

    mybatis foreach批量插入數(shù)據(jù):Oracle與MySQL區(qū)別介紹

    這篇文章主要介紹了,需要的朋友可以參考下
    2018-01-01
  • dom4j操作xml的demo(分享)

    dom4j操作xml的demo(分享)

    下面小編就為大家?guī)硪黄猟om4j操作xml的demo(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • IDEA中將SpringBoot項目提交到git倉庫的方法步驟

    IDEA中將SpringBoot項目提交到git倉庫的方法步驟

    本文主要介紹了IDEA中將SpringBoot項目提交到git倉庫的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Idea中Jdk和Language level的指定方式

    Idea中Jdk和Language level的指定方式

    這篇文章主要介紹了Idea中Jdk和Language level的指定方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 舉例講解Java中final關鍵字的用法

    舉例講解Java中final關鍵字的用法

    Java中的final關鍵字可以被用來修飾變量、方法和類等,意味著終結、不可改變,下面我們就來舉例講解Java中final關鍵字的用法:
    2016-06-06
  • SpringBoot后端服務重定向的實現(xiàn)示例

    SpringBoot后端服務重定向的實現(xiàn)示例

    本文主要介紹了SpringBoot后端服務重定向的實現(xiàn)示例,通過重定向、路徑匹配、反向代理和直接調用Controller層接口等方法來實現(xiàn),感興趣的可以了解一下
    2025-01-01
  • 通過代碼實例了解SpringBoot啟動原理

    通過代碼實例了解SpringBoot啟動原理

    這篇文章主要介紹了通過代碼實例了解SpringBoot啟動原理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • 使用Fastjson進行JSON生成與解析的新手指南

    使用Fastjson進行JSON生成與解析的新手指南

    Fastjson是阿里巴巴開源的高性能 JSON 庫,適用于 Java 對象的序列化和反序列化,本文將詳細介紹一下如何使用Fastjson進行json的生成與解析吧
    2025-04-04

最新評論