当前位置: 代码网 > it编程>编程语言>Java > 基于SpringBoot+Vue实现DeepSeek对话效果的详细步骤

基于SpringBoot+Vue实现DeepSeek对话效果的详细步骤

2025年07月20日 Java 我要评论
spring boot + vue 实现 deepseek 对话效果详细步骤一、整体架构设计我们需要构建一个前后端分离的应用:​​后端​​:spring boot 提供 api 接口,处理与 ai 模

spring boot + vue 实现 deepseek 对话效果详细步骤

一、整体架构设计

我们需要构建一个前后端分离的应用:

  • ​后端​​:spring boot 提供 api 接口,处理与 ai 模型的交互
  • ​前端​​:vue 实现聊天界面,展示对话内容并发送用户输入

二、后端实现 (spring boot)

1. 创建 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. 定义数据传输对象

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. 实现对话服务

@service
public class chatservice {
    
    // 可以使用 map 临时存储会话,生产环境建议使用数据库
    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) {
        // 这里实现与 deepseek api 的实际交互
        // 可以使用 resttemplate 或 webclient
        // 示例代码:
        try {
            // 实际开发中替换为真实 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);
    }
}

三、前端实现 (vue)

1. 创建 vue 项目

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

# 安装必要的依赖
npm install axios

2. 创建聊天组件

<!-- 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()">
        发送
      </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: '抱歉,发生了错误,请稍后再试。' 
        });
      } 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 参数或本地存储获取 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. 开发环境配置

​启动后端服务​

./mvnw spring-boot:run

​启动前端开发服务器​

npm run dev

2. 生产环境部署

​构建前端应用​

npm run build

​配置后端服务提供静态文件​

// 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");
                    }
                });
    }
}

​将前端构建文件复制到后端资源目录​

五、进阶优化

1. websocket 实现实时通信

// 后端 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 {
      // ... 其他数据 ...
      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();
  }
}

总结

通过上述步骤,你可以实现一个基于 spring boot 和 vue 的对话系统,类似 deepseek 的交互效果。这个实现包含了:

  1. 后端 api 设计与实现
  2. 前端聊天界面设计
  3. 会话管理与历史记录
  4. websocket 实现实时通信(可选)
  5. 部署配置

根据实际需求,你可以进一步扩展功能,如支持 markdown 渲染、代码高亮、对话导出等高级特性。

以上就是基于springboot+vue实现deepseek对话效果的详细步骤的详细内容,更多关于springboot vue deepseek对话的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com