优化:
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>
通过以上优化,你的智能客服系统将更加完善和实用!