Vue与Java集成DeepSeek智能客服(继续优化)

优化:

1.用户身份验证

2.消息历史记录

3.优化UI/UX设计

1. 用户身份验证

为了确保只有授权用户可以使用智能客服功能,我们可以添加用户身份验证机制。常见的做法是使用JWT(JSON Web Token)进行身份验证。

1.1 后端实现JWT验证

在Spring Boot中,可以使用​​spring-security​​​和​​jjwt​​库来实现JWT验证。

在​​pom.xml​​中添加以下依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
配置Spring Security

在​​src/main/java/com/example/demo/config/​​​目录下创建​​SecurityConfig.java​​。

scala 复制代码
package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/auth/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .addFilter(new JwtAuthenticationFilter(authenticationManager()));
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
实现JWT工具类

在​​src/main/java/com/example/demo/util/​​​目录下创建​​JwtUtil.java​​。

typescript 复制代码
package com.example.demo.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

@Component
public class JwtUtil {

    private String SECRET_KEY = "secret";

    public String extractUsername(String token) {
        return extractClaim(token, Claims::getSubject);
    }

    public Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }

    private Claims extractAllClaims(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
    }

    private Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, userDetails.getUsername());
    }

    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10小时有效期
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
    }

    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }
}
实现登录接口

在​​src/main/java/com/example/demo/controller/​​​目录下创建​​AuthController.java​​。

kotlin 复制代码
package com.example.demo.controller;

import com.example.demo.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/api/auth/login")
    public String login(@RequestBody AuthRequest authRequest) {
        authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
        );
        final UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());
        return jwtUtil.generateToken(userDetails);
    }

    static class AuthRequest {
        private String username;
        private String password;

        // Getters and Setters
    }
}

1.2 前端实现登录功能

在Vue前端中,添加登录页面并存储JWT。

创建登录组件

在​​src/components/​​​目录下创建​​Login.vue​​。

xml 复制代码
<template>
  <div class="login-container">
    <input v-model="username" placeholder="Username" />
    <input v-model="password" type="password" placeholder="Password" />
    <button @click="login">Login</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: '',
      password: ''
    };
  },
  methods: {
    async login() {
      try {
        const response = await this.$http.post('/api/auth/login', {
          username: this.username,
          password: this.password
        });
        localStorage.setItem('token', response.data);
        this.$router.push('/chat');
      } catch (error) {
        console.error('Login failed:', error);
      }
    }
  }
};
</script>

<style>
.login-container {
  max-width: 300px;
  margin: 0 auto;
  padding: 20px;
  border: 1px solid #ccc;
  border-radius: 10px;
}
input {
  width: 100%;
  padding: 10px;
  margin-bottom: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
}
button {
  width: 100%;
  padding: 10px;
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
</style>
修改HTTP请求以携带JWT

在​​src/main.js​​中配置Axios拦截器,自动添加JWT到请求头。

ini 复制代码
axios.interceptors.request.use(config => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

2. 消息历史记录

为了保存用户的聊天记录,可以在后端使用数据库(如MySQL)存储消息。

2.1 后端实现消息存储

在​​pom.xml​​中添加MySQL和JPA依赖。

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
配置数据库

在​​application.properties​​中添加数据库配置。

ini 复制代码
spring.datasource.url=jdbc:mysql://localhost:3306/chatdb
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
创建消息实体

在​​src/main/java/com/example/demo/model/​​​目录下创建​​Message.java​​。

java 复制代码
package com.example.demo.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date;

@Entity
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String sender;
    private String text;
    private Date timestamp;

    // Getters and Setters
}
创建消息仓库

在​​src/main/java/com/example/demo/repository/​​​目录下创建​​MessageRepository.java​​。

java 复制代码
package com.example.demo.repository;

import com.example.demo.model.Message;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;

public interface MessageRepository extends JpaRepository<Message, Long> {
    List<Message> findBySenderOrderByTimestampAsc(String sender);
}
修改ChatController

在​​ChatController​​中保存和获取消息。

java 复制代码
@Autowired
private MessageRepository messageRepository;

@PostMapping("/api/chat")
public ChatResponse chat(@RequestBody ChatRequest request) {
    // 保存用户消息
    Message userMessage = new Message();
    userMessage.setSender("User");
    userMessage.setText(request.getMessage());
    userMessage.setTimestamp(new Date());
    messageRepository.save(userMessage);

    // 调用DeepSeek API
    RestTemplate restTemplate = new RestTemplate();
    DeepSeekRequest deepSeekRequest = new DeepSeekRequest(request.getMessage());
    DeepSeekResponse deepSeekResponse = restTemplate.postForObject(DEEPSEEK_API_URL, deepSeekRequest, DeepSeekResponse.class);

    // 保存机器人消息
    Message botMessage = new Message();
    botMessage.setSender("Bot");
    botMessage.setText(deepSeekResponse != null ? deepSeekResponse.getReply() : "Sorry, I couldn't process your request.");
    botMessage.setTimestamp(new Date());
    messageRepository.save(botMessage);

    return new ChatResponse(botMessage.getText());
}

@GetMapping("/api/chat/history")
public List<Message> getChatHistory() {
    return messageRepository.findBySenderOrderByTimestampAsc("User");
}

2.2 前端显示消息历史

在​​Chat.vue​​中加载消息历史。

javascript 复制代码
async mounted() {
  try {
    const response = await this.$http.get('/api/chat/history');
    this.messages = response.data.map(msg => ({
      sender: msg.getSender(),
      text: msg.getText()
    }));
  } catch (error) {
    console.error('Error loading chat history:', error);
  }
}

3. 优化UI/UX设计

可以使用UI框架(如Element Plus)美化界面。

3.1 安装Element Plus

复制代码
npm install element-plus

3.2 在Vue中使用Element Plus

在​​src/main.js​​中引入Element Plus。

javascript 复制代码
import ElementPlus from 'element-plus';
import 'element-plus/lib/theme-chalk/index.css';

Vue.use(ElementPlus);

3.3 美化聊天界面

使用Element Plus的组件优化​​Chat.vue​​。

xml 复制代码
<template>
  <el-container class="chat-container">
    <el-main class="messages">
      <el-card v-for="(message, index) in messages" :key="index" :class="message.sender">
        <strong>{{ message.sender }}:</strong> {{ message.text }}
      </el-card>
    </el-main>
    <el-footer>
      <el-input v-model="userInput" @keyup.enter="sendMessage" placeholder="Type your message..." />
    </el-footer>
  </el-container>
</template>

通过以上优化,你的智能客服系统将更加完善和实用!

相关推荐
小周同学:5 分钟前
在 Vue2 中使用 pdf.js + pdf-lib 实现 PDF 预览、手写签名、文字批注与高保真导出
开发语言·前端·javascript·vue.js·pdf
m0_4947166823 分钟前
CSS中实现一个三角形
前端·css
VUE26 分钟前
借助trea开发浏览器自动滚动插件
trae
teeeeeeemo1 小时前
跨域及解决方案
开发语言·前端·javascript·笔记
JSON_L1 小时前
Vue Vant应用-数据懒加载
前端·javascript·vue.js
可爱小仙子1 小时前
vue-quill-editor上传图片vue3
前端·javascript·vue.js
IT毕设实战小研1 小时前
基于Spring Boot校园二手交易平台系统设计与实现 二手交易系统 交易平台小程序
java·数据库·vue.js·spring boot·后端·小程序·课程设计
じòぴé南冸じょうげん1 小时前
解决ECharts图表上显示的最小刻度不是设置的min值的问题
前端·javascript·echarts
小高0071 小时前
第一章 桃园灯火初燃,响应义旗始揭
前端·javascript·vue.js
小高0071 小时前
第二章 虎牢关前初试Composition,吕布持v-model搦战
前端·javascript·vue.js