qidao123.com ToB IT社区-企服评测·应用市场

标题: 基于spring boot 集成 deepseek 流式输出 的vue3使用指南 [打印本页]

作者: 民工心事    时间: 2025-9-27 16:02
标题: 基于spring boot 集成 deepseek 流式输出 的vue3使用指南
本文使用deepseek API接口流式输出的文章。
环境要求 jdk17 spring boot 3.4
代码如下:
  1. package com.example.controller;
  2. import jakarta.annotation.PostConstruct;
  3. import org.springframework.ai.chat.messages.AssistantMessage;
  4. import org.springframework.ai.chat.messages.Message;
  5. import org.springframework.ai.chat.messages.SystemMessage;
  6. import org.springframework.ai.chat.messages.UserMessage;
  7. import org.springframework.ai.chat.model.ChatResponse;
  8. import org.springframework.ai.chat.model.Generation;
  9. import org.springframework.ai.chat.prompt.Prompt;
  10. import org.springframework.ai.openai.OpenAiChatModel;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.web.bind.annotation.GetMapping;
  13. import org.springframework.web.bind.annotation.RequestParam;
  14. import org.springframework.web.bind.annotation.RestController;
  15. import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
  16. import reactor.core.Disposable;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import java.util.Optional;
  20. @RestController
  21. public class ChatController {
  22.     // 注入OpenAI聊天模型实例,已通过配置文件完成API密钥等参数配置
  23.     @Autowired
  24.     private OpenAiChatModel chatModel;
  25.     // 使用List维护对话上下文,包含系统消息和用户消息
  26.     private List<Message> chatHistory = new ArrayList<>();
  27.     @PostConstruct
  28.     public void init() {
  29.         // 添加系统消息定义AI行为准则
  30.         chatHistory.add(new SystemMessage("You are a helpful assistant."));
  31.     }
  32.     /**
  33.      * 流式聊天内容生成接口(Server-Sent Events 实现)
  34.      *
  35.      * @param message 用户输入的聊天消息
  36.      * @return SseEmitter 用于服务端推送事件的发射器对象
  37.      */
  38.     @GetMapping("/generateStream")
  39.     public SseEmitter streamChat(@RequestParam String message) {
  40.         // 创建 SSE 发射器并设置 180 秒超时(可根据业务需求调整)
  41.         SseEmitter emitter = new SseEmitter(180_000L);
  42.         // 记录请求开始(实际项目建议使用 SLF4J 等日志框架)
  43.         System.out.println("SSE connection established for message: " + message);
  44.         // 构建对话请求参数
  45.         Prompt prompt = new Prompt(new UserMessage(message));
  46.         // 获取流式处理订阅对象(用于后续资源清理)
  47.         Disposable subscription = chatModel.stream(prompt)
  48.                 .subscribe(
  49.                         // 处理每个响应块
  50.                         response -> {
  51.                             try {
  52.                                 // 安全获取响应文本
  53.                                 String text = Optional.ofNullable(response)
  54.                                         .map(ChatResponse::getResult)
  55.                                         .map(Generation::getOutput)
  56.                                         .map(AssistantMessage::getText)
  57.                                         .orElse("");  // 空值处理
  58.                                 // 发送 SSE 事件(建议实际项目添加 JSON 包装)
  59.                                 emitter.send(SseEmitter.event()
  60.                                         .id(String.valueOf(System.currentTimeMillis()))  // 事件ID用于客户端排序
  61.                                         .data(text)      // 事件数据内容
  62.                                         .name("message")// 定义事件类型
  63.                                         .build());
  64.                                 // 打印到控制台用于调试
  65.                                 System.out.print(text);
  66.                             } catch (Exception e) {
  67.                                 // 发送异常时关闭连接并记录错误
  68.                                 emitter.completeWithError(e);
  69.                                 System.err.println("Error sending SSE event: " + e.getMessage());
  70.                             }
  71.                         },
  72.                         // 处理流式响应异常
  73.                         error -> {
  74.                             emitter.completeWithError(error);
  75.                             System.err.println("Stream error: " + error.getMessage());
  76.                         },
  77.                         // 处理流式响应完成
  78.                         () -> {
  79.                             emitter.complete();
  80.                             System.out.println("\nStream completed");
  81.                         }
  82.                 );
  83.         // 注册连接完成回调(客户端断开/正常结束)
  84.         emitter.onCompletion(() -> {
  85.             // 取消订阅释放资源
  86.             if (!subscription.isDisposed()) {
  87.                 subscription.dispose();
  88.             }
  89.             System.out.println("SSE connection completed");
  90.         });
  91.         // 注册超时回调
  92.         emitter.onTimeout(() -> {
  93.             // 主动完成连接并释放资源
  94.             emitter.complete();
  95.             subscription.dispose();
  96.             System.out.println("SSE connection timed out");
  97.         });
  98.         return emitter;
  99.     }
  100. }
复制代码
设置key
  1. spring.ai.openai.api-key=你申请的key
  2. spring.ai.openai.base-url=https://api.deepseek.com
  3. spring.ai.openai.chat.options.model=deepseek-chat
  4. spring.ai.openai.chat.options.temperature=0.7
  5. # The DeepSeek API doesn't support embeddings, so we need to disable it.
  6. spring.ai.openai.embedding.enabled=false
复制代码
Vue 3 使用指南

1. Vue 3 简介

Vue 3 是 Vue.js 框架的最新重要版本,于 2020 年 9 月正式发布。它带来了许多改进和新特性:

2. 创建 Vue 3 项目

使用 Vite 创建项目

  1. npm create vite@latest my-vue-app --template vue
复制代码
使用 Vue CLI 创建项目

  1. npm install -g @vue/cli
  2. vue create my-vue-app
  3. # 选择 Vue 3 预设
复制代码
3. Composition API

Vue 3 引入了 Composition API 作为 Options API 的增补,提供了更好的代码构造和复用。
根本示例

  1. <script setup>
  2. import { ref, computed, onMounted } from 'vue'
  3. // 响应式状态
  4. const count = ref(0)
  5. // 计算属性
  6. const doubleCount = computed(() => count.value * 2)
  7. // 方法
  8. function increment() {
  9.   count.value++
  10. }
  11. // 生命周期钩子
  12. onMounted(() => {
  13.   console.log('组件已挂载')
  14. })
  15. </script>
  16. <template>
  17.   <button @click="increment">
  18.     计数: {{ count }}, 双倍: {{ doubleCount }}
  19.   </button>
  20. </template>
复制代码
相应式底子


  1. import { ref, reactive, toRefs } from 'vue'
  2. const counter = ref(0)
  3. const state = reactive({
  4.   name: 'Vue 3',
  5.   version: '3.x'
  6. })
  7. // 在模板中使用时不需要 .value
  8. const { name, version } = toRefs(state)
复制代码
4. 组件体系

组件界说

  1. <script setup>
  2. // 使用 <script setup> 语法糖
  3. import { ref } from 'vue'
  4. import ChildComponent from './ChildComponent.vue'
  5. const message = ref('Hello from parent')
  6. </script>
  7. <template>
  8.   <ChildComponent :message="message" />
  9. </template>
复制代码
Props 和 Emits

  1. <script setup>
  2. // ChildComponent.vue
  3. const props = defineProps({
  4.   message: {
  5.     type: String,
  6.     required: true
  7.   }
  8. })
  9. const emit = defineEmits(['response'])
  10. function sendResponse() {
  11.   emit('response', 'Hello from child')
  12. }
  13. </script>
  14. <template>
  15.   <div>
  16.     {{ message }}
  17.     <button @click="sendResponse">Reply</button>
  18.   </div>
  19. </template>
复制代码
5. 生命周期钩子

Vue 3 生命周期钩子(Composition API 版本):
Options APIComposition APIbeforeCreate不必要 (setup 更换)created不必要 (setup 更换)beforeMountonBeforeMountmountedonMountedbeforeUpdateonBeforeUpdateupdatedonUpdatedbeforeUnmountonBeforeUnmountunmountedonUnmountederrorCapturedonErrorCapturedrenderTrackedonRenderTrackedrenderTriggeredonRenderTriggered6. 新特性

Teleport

将子节点渲染到 DOM 中的其他位置:
  1. <template>
  2.   <button @click="open = true">打开模态框</button>
  3.   
  4.   <Teleport to="body">
  5.     <div v-if="open" class="modal">
  6.       <p>模态框内容</p>
  7.       <button @click="open = false">关闭</button>
  8.     </div>
  9.   </Teleport>
  10. </template>
复制代码
Suspense

处理处罚异步组件加载状态:
  1. <template>
  2.   <Suspense>
  3.     <template #default>
  4.       <AsyncComponent />
  5.     </template>
  6.     <template #fallback>
  7.       <div>加载中...</div>
  8.     </template>
  9.   </Suspense>
  10. </template>
  11. <script setup>
  12. const AsyncComponent = defineAsyncComponent(() =>
  13.   import('./AsyncComponent.vue')
  14. )
  15. </script>
复制代码
7. 状态管理 (Pinia)

Vue 3 保举使用 Pinia 作为状态管理库:
安装 Pinia

  1. npm install pinia
复制代码
根本使用

  1. // stores/counter.js
  2. import { defineStore } from 'pinia'
  3. export const useCounterStore = defineStore('counter', {
  4.   state: () => ({
  5.     count: 0
  6.   }),
  7.   actions: {
  8.     increment() {
  9.       this.count++
  10.     }
  11.   },
  12.   getters: {
  13.     doubleCount: (state) => state.count * 2
  14.   }
  15. })
复制代码
  1. <script setup>
  2. import { useCounterStore } from '@/stores/counter'
  3. const counter = useCounterStore()
  4. </script>
  5. <template>
  6.   <div>{{ counter.count }}</div>
  7.   <div>{{ counter.doubleCount }}</div>
  8.   <button @click="counter.increment()">+</button>
  9. </template>
复制代码
8. 路由 (Vue Router 4)

安装

  1. npm install vue-router@4
复制代码
根本设置

  1. // router/index.js
  2. import { createRouter, createWebHistory } from 'vue-router'
  3. import Home from '../views/Home.vue'
  4. const routes = [
  5.   {
  6.     path: '/',
  7.     name: 'Home',
  8.     component: Home
  9.   },
  10.   {
  11.     path: '/about',
  12.     name: 'About',
  13.     component: () => import('../views/About.vue')
  14.   }
  15. ]
  16. const router = createRouter({
  17.   history: createWebHistory(),
  18.   routes
  19. })
  20. export default router
复制代码
在组件中使用

  1. <script setup>
  2. import { useRouter, useRoute } from 'vue-router'
  3. const router = useRouter()
  4. const route = useRoute()
  5. function goToAbout() {
  6.   router.push('/about')
  7. }
  8. </script>
  9. <template>
  10.   <div>当前路由: {{ route.path }}</div>
  11.   <button @click="goToAbout">前往关于页面</button>
  12.   <router-view />
  13. </template>
复制代码
9. 最佳实践

10. 资源


盼望这篇文档能资助你快速上手 Vue 3 开发!
Stream completed

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com ToB IT社区-企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.5