《AI智能客服系统》落地实现-第04节:前端页面的实现与整体测试
作者:冰河
星球:http://m6z.cn/6aeFbs
博客:https://binghe.gitcode.host
文章汇总:https://binghe.gitcode.host/md/all/all.html
源码获取地址:https://t.zsxq.com/0dhvFs5oR
沉淀,成长,突破,帮助他人,成就自我。
- 本章难度:★★☆☆☆
- 本章重点:对AI智能客服系统的前端页面进行设计与实现,并对AI智能客服系统的整体功能进行测试,从全局角度掌握AI智能客服系统的整体项目结构。重点掌握AI智能客服系统的通用设计思路和设计方法,并能够将其灵活应用到自身实际项目中。
大家好,我是冰河~~
截止到目前,我们已经设计和实现了AI智能客服系统的后端业务逻辑代码,并通过SpringAI对接了AI大模型。接下来,我们就一起实现AI智能客服系统的前端页面,并对整体功能进行测试。
一、前言
AI智能客服系统后端整体逻辑已经实现完毕,对接了AI大模型,会对聊天记录进行存储,并在需要的时候能够查询聊天记录,并实现了健康检查等功能。同时,后端服务提供了各种接口供前端页面调用。接下来,就需要对前端页面进行设计和实现。
二、本节诉求
对AI智能客服系统的前端页面进行设计与实现,并对AI智能客服系统的整体功能进行测试,从全局角度掌握AI智能客服系统的整体项目结构。重点掌握AI智能客服系统的通用设计思路和设计方法,并能够将其灵活应用到自身实际项目中。
三、页面实现
在项目的src/main/resources目录下新建index.html文件。由于前端页面的代码比较多,这里只给出页面总体布局和核心javascript代码,其他部分代码大家到本节源码分支进行查看。
首先,实现页面的主体布局部分,如下所示。
<section class="hero-section">
<div class="container">
<div class="hero-content text-center">
<h1 class="hero-title">🤖 AI智能客服系统</h1>
<p class="hero-subtitle">基于 Spring Boot + Spring AI + DeepSeek 智能化AI客服助手</p>
<p class="hero-subtitle">沉淀 · 成长 · 突破 · 每天进步一点点</p>
</div>
</div>
</section>
<!-- 统计信息 -->
<section class="stats-grid">
<div class="container">
<div class="row g-4">
<div class="col-md-4">
<div class="stat-card">
<div class="stat-icon system">
<i class="bi bi-server"></i>
</div>
<div class="stat-value" id="systemStatus">运行正常</div>
<div class="stat-label">系统状态</div>
</div>
</div>
<div class="col-md-4">
<div class="stat-card">
<div class="stat-icon chat">
<i class="bi bi-chat-dots"></i>
</div>
<div class="stat-value" id="totalChats">0</div>
<div class="stat-label">总对话数</div>
</div>
</div>
<div class="col-md-4">
<div class="stat-card">
<div class="stat-icon time">
<i class="bi bi-lightning"></i>
</div>
<div class="stat-value" id="avgResponseTime">425ms</div>
<div class="stat-label">平均响应时间</div>
</div>
</div>
</div>
</div>
</section>
<!-- 主要内容区域 -->
<section class="main-container">
<div class="container">
<div class="row g-4">
<!-- 聊天主区域 -->
<div class="col-lg-8">
<div class="chat-wrapper">
<!-- 聊天头部 -->
<div class="chat-header">
<div class="chat-header-content">
<div class="ai-avatar">
<i class="bi bi-robot"></i>
</div>
<div class="chat-header-text">
<h3>DeepSeek AI智能助手</h3>
<p>基于最新AI技术,7x24小时为您服务</p>
</div>
</div>
<div class="status-badge">
<i class="bi bi-circle-fill me-1" style="color: #43e97b;"></i>
在线
</div>
</div>
<!-- 消息区域 -->
<div class="chat-messages" id="chatMessages">
<div class="message bot">
<div class="message-avatar">
<i class="bi bi-robot"></i>
</div>
<div class="message-content">
<div class="message-bubble">
您好!我是DeepSeek AI智能客服助手,很高兴为您服务。我可以帮助您解答技术问题、提供产品信息或协助解决使用中的疑问。请问有什么可以帮助您的吗?
</div>
<div class="response-time">刚刚</div>
</div>
</div>
</div>
<!-- 输入区域 -->
<div class="chat-input-area">
<div class="input-group">
<input type="text"
class="message-input"
id="messageInput"
placeholder="输入您的问题(最多500字)..."
maxlength="500">
<button class="send-button" id="sendButton">
<i class="bi bi-send"></i> 发送
</button>
</div>
<div class="typing-indicator" id="typingIndicator">
<div class="typing-text">
<span>AI思考中,请稍后...</span>
<div class="typing-dots">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 侧边栏 -->
<div class="col-lg-4">
<div class="sidebar">
<!-- 会话统计 -->
<div class="sidebar-card">
<div class="card-header">
<div class="card-icon">
<i class="bi bi-graph-up"></i>
</div>
<h4 class="card-title">会话统计</h4>
</div>
<div class="stats-grid-small">
<div class="stat-small">
<div class="stat-value-small" id="messageCount">1</div>
<div class="stat-label-small">消息数量</div>
</div>
<div class="stat-small">
<div class="stat-value-small" id="sessionResponseTime">0ms</div>
<div class="stat-label-small">响应时间</div>
</div>
</div>
</div>
<!-- 快捷提问 -->
<div class="sidebar-card">
<div class="card-header">
<div class="card-icon">
<i class="bi bi-lightning"></i>
</div>
<h4 class="card-title">快捷提问</h4>
</div>
<div class="quick-chat-buttons">
<button class="quick-btn" onclick="sendQuickMessage('你好,我想了解你们的产品功能')">
<i class="bi bi-laptop"></i>
<span>产品功能介绍</span>
</button>
<button class="quick-btn" onclick="sendQuickMessage('请问如何技术支持人员?')">
<i class="bi bi-person-arms-up"></i>
<span>技术支持联系</span>
</button>
<button class="quick-btn" onclick="sendQuickMessage('请问你们提供哪些服务流程')">
<i class="bi bi-tools"></i>
<span>服务流程说明</span>
</button>
<button class="quick-btn" onclick="sendQuickMessage('你们的产品价格和优惠信息如何')">
<i class="bi bi-list-task"></i>
<span>价格方案咨询</span>
</button>
<button class="quick-btn" onclick="sendQuickMessage('我可以先接入和试用你们的产品吗')">
<i class="bi bi-tag"></i>
<span>接入与试用</span>
</button>
</div>
</div>
<!-- 系统功能 -->
<div class="sidebar-card">
<div class="card-header">
<div class="card-icon">
<i class="bi bi-stars"></i>
</div>
<h4 class="card-title">核心功能</h4>
</div>
<div class="feature-list">
<div class="feature-item">
<div class="feature-icon">
<i class="bi bi-chat-left-text"></i>
</div>
<span class="feature-text">基于DeepSeek大模型技术</span>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="bi bi-cpu"></i>
</div>
<span class="feature-text">智能上下文理解能力</span>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="bi bi-speedometer2"></i>
</div>
<span class="feature-text">毫秒级响应</span>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="bi bi-clock-history"></i>
</div>
<span class="feature-text">企业级安全与稳定</span>
</div>
</div>
</div>
<!-- 使用提示 -->
<div class="tips-alert">
<h6><i class="bi bi-info-circle me-2"></i>使用提示</h6>
<ul>
<li>输入问题后按回车或点击发送</li>
<li>支持多轮对话,AI会记住上下文</li>
<li>消息最长支持500个字符</li>
<li>点击快捷问题快速开始对话</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- 页脚 -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-text">
© 2026 AI智能客服系统 | 基于 Spring AI + DeepSeek | @冰河技术知识星球
</div>
<div class="footer-links">
<a href="#" class="footer-link">使用条款</a>
<a href="#" class="footer-link">隐私政策</a>
<a href="#" class="footer-link">帮助中心</a>
</div>
</div>
</div>
</footer>
javascript部分代码如下所示。
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
let sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
let messageCount = 1;
let totalResponseTime = 0;
// DOM元素
const messagesContainer = document.getElementById('chatMessages');
const messageInput = document.getElementById('messageInput');
const sendButton = document.getElementById('sendButton');
const typingIndicator = document.getElementById('typingIndicator');
// 初始化
document.addEventListener('DOMContentLoaded', function() {
messageInput.focus();
scrollToBottom();
// 添加欢迎消息动画
const welcomeMessage = messagesContainer.querySelector('.message.bot .message-bubble');
if (welcomeMessage) {
welcomeMessage.style.animation = 'messageSlide 0.5s ease-out';
}
});
// 快捷消息发送函数
function sendQuickMessage(message) {
messageInput.value = message;
sendMessage();
// 给按钮添加点击反馈
event.target.style.transform = 'scale(0.95)';
setTimeout(() => {
event.target.style.transform = '';
}, 150);
}
// 发送消息
function sendMessage() {
const message = messageInput.value.trim();
if (!message) {
// 添加输入框抖动效果
messageInput.style.animation = 'shake 0.5s';
setTimeout(() => {
messageInput.style.animation = '';
}, 500);
return;
}
// 清空输入框
messageInput.value = '';
messageInput.focus();
// 显示用户消息
addMessage(message, 'user');
// 显示正在输入指示器
showTypingIndicator();
const startTime = Date.now();
// 发送到后端
fetch('/api/chat/bot/send-message', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: message,
sessionId: sessionId
})
})
.then(response => response.json())
.then(data => {
hideTypingIndicator();
const responseTime = Date.now() - startTime;
// 模拟AI回复
setTimeout(() => {
if (data.success) {
addMessage(data.message || "我收到了您的消息,正在为您思考最佳回复...", 'bot', responseTime);
} else {
addMessage(data.error || '抱歉,服务暂时不可用,请稍后重试。', 'bot', responseTime);
}
updateSessionStats(responseTime);
// 更新统计信息
updateTotalChats();
}, 800);
})
.catch(error => {
hideTypingIndicator();
console.error('发送消息失败:', error);
// 模拟AI回复
setTimeout(() => {
addMessage('网络错误,请检查连接后重试。我正在学习更好地为您服务!', 'bot');
updateSessionStats(800);
}, 800);
});
}
// 添加消息到聊天区域
function addMessage(content, type, responseTime = null) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${type}`;
const avatarDiv = document.createElement('div');
avatarDiv.className = 'message-avatar';
avatarDiv.innerHTML = type === 'user' ? '<i class="bi bi-person"></i>' : '<i class="bi bi-robot"></i>';
const contentDiv = document.createElement('div');
contentDiv.className = 'message-content';
const bubbleDiv = document.createElement('div');
bubbleDiv.className = 'message-bubble';
bubbleDiv.textContent = content;
contentDiv.appendChild(bubbleDiv);
if (responseTime && type === 'bot') {
const timeDiv = document.createElement('div');
timeDiv.className = 'response-time';
timeDiv.textContent = `响应时间: ${responseTime}ms`;
contentDiv.appendChild(timeDiv);
}
messageDiv.appendChild(avatarDiv);
messageDiv.appendChild(contentDiv);
messagesContainer.appendChild(messageDiv);
// 添加消息动画
messageDiv.style.animation = 'messageSlide 0.3s ease-out';
scrollToBottom();
if (type === 'user') {
messageCount++;
document.getElementById('messageCount').textContent = messageCount;
}
}
// 显示正在输入指示器
function showTypingIndicator() {
typingIndicator.style.display = 'block';
}
// 隐藏正在输入指示器
function hideTypingIndicator() {
typingIndicator.style.display = 'none';
}
// 滚动到底部
function scrollToBottom() {
messagesContainer.scrollTo({
top: messagesContainer.scrollHeight,
behavior: 'smooth'
});
}
// 更新会话统计
function updateSessionStats(responseTime) {
totalResponseTime += responseTime;
const avgTime = Math.round(totalResponseTime / Math.max(1, messageCount - 1));
document.getElementById('sessionResponseTime').textContent = avgTime + 'ms';
}
// 更新总对话数(模拟)
function updateTotalChats() {
const totalChats = document.getElementById('totalChats');
const current = parseInt(totalChats.textContent.replace(',', ''));
totalChats.textContent = (current + 1).toLocaleString();
// 更新平均响应时间(模拟)
const avgResponseTime = document.getElementById('avgResponseTime');
const currentAvg = parseInt(avgResponseTime.textContent);
const newAvg = Math.max(300, Math.min(800, currentAvg + (Math.random() > 0.5 ? 1 : -1) * Math.floor(Math.random() * 20)));
avgResponseTime.textContent = newAvg + 'ms';
}
// 事件监听器
sendButton.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
});
// 输入框获得焦点时的效果
messageInput.addEventListener('focus', function() {
this.parentElement.style.borderColor = '#667eea';
this.parentElement.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
});
messageInput.addEventListener('blur', function() {
this.parentElement.style.borderColor = '#eef2ff';
this.parentElement.style.boxShadow = 'none';
});
// 添加抖动动画
const style = document.createElement('style');
style.textContent = `
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
`;
document.head.appendChild(style);
// 模拟系统状态更新
setInterval(() => {
const status = document.getElementById('systemStatus');
status.style.opacity = '0.8';
setTimeout(() => {
status.style.opacity = '1';
}, 300);
}, 10000);
</script>
四、功能测试
将项目application.yml配置文件中的spring.ai.openai.api-key的值替换为自己的DeepSeek API Key,随后,运行AiBotStarter类启动项目,如果打印如下日志,则说明项目启动成功。
==============================================
AI智能客服系统启动成功:访问信息如下:
访问地址: http://localhost:8080
==============================================
随后,在浏览器输入:http://localhost:8080。

输入“你好”,AI系统客服系统回复如下所示。

点击技术支持联系快捷提问,AI系统客服系统回复如下所示。

其他部分,大家拉取代码,自行体验吧。
注意:后端接口预留了不少功能性接口,大家可以对照前端页面的功能对接接口实现。
五、本节总结
本节,主要对AI智能客服系统的前面页面进行了设计和实现,并对主要的核心功能进行了简单的测试。
最后,可以在评论区写下你学完本章节的收获,祝大家都能学有所成,我们一起AI智能客服系统项目。
六、写在最后
在冰河技术知识星球,《智流助手平台》已完结,《实战Claude Code》项目热更中,还有其他二十几个项目,像智能成语挑战赛项目、多轮AI智能对话系统、一站式AI智能平台、AI智能客服系统、AI智能问答系统、实战AI大模型、手写高性能敏组件、手写线程池、手写高性能SQL引擎、手写高性能Polaris网关、手写高性能熔断组件、手写通用指标上报组件、手写高性能数据库路由组件、手写分布式IM即时通讯系统、手写Seckill分布式秒杀系统、手写高性能RPC、实战高并发设计模式、简易商城系统等等。
这些项目的需求、方案、架构、落地等均来自互联网真实业务场景,让你真正学到互联网大厂的业务与技术落地方案,并将其有效转化为自己的知识储备。
值得一提的是:冰河自研的Polaris高性能网关比某些开源网关项目性能更高,目前正在热更AI一体化项目,也正在实现MCP,全程带你分析原理和手撸代码。
你还在等啥?不少小伙伴经过星球硬核技术和项目的历练,早已成功跳槽加薪,实现薪资翻倍,而你,还在原地踏步,抱怨大环境不好。抛弃焦虑和抱怨,我们一起塌下心来沉淀硬核技术和项目,让自己的薪资更上一层楼。
🚀PS:星球原价129,目前已开通最大优惠:长按或扫码加入星球立减30,注意:随着OpenClaw专栏的更新,星球也即将涨价!!

目前,领券加入星球就可以跟冰河一起学习《实战Claude Code》、《多轮AI智能对话系统》、《一站式AI智能平台》、《AI智能客服系统》、《AI智能问答系统》、《实战AI大模型》、《手写高性能Redis组件》、《手写高性能脱敏组件》、《手写线程池》、《手写高性能SQL引擎》、《手写高性能Polaris网关》、《手写高性能RPC项目》、《分布式Seckill秒杀系统》、《分布式IM即时通讯系统》《手写高性能通用熔断组件项目》、《手写高性能通用监控指标上报组件》、《手写高性能数据库路由组件》、《手写简易商城脚手架项目》、《Spring6核心技术与源码解析》和《实战高并发设计模式》,从零开始介绍原理、设计架构、手撸代码。
花很少的钱就能学这么多硬核技术、中间件项目和大厂秒杀系统、分布式IM即时通讯系统,AI大模型项目,比其他培训机构不知便宜多少倍,硬核多少倍,如果是我,我会买他个十年!
加入要趁早,后续还会随着项目和加入的人数涨价,而且只会涨,不会降,先加入的小伙伴就是赚到。
另外,还有一个限时福利,邀请一个小伙伴加入,冰河就会给一笔 分享有奖 ,有些小伙伴都邀请了50+人,早就回本了!
七、其他方式加入星球
- 链接 :打开链接 http://m6z.cn/6aeFbs 加入星球。
- 回复 :在公众号 冰河技术 回复 星球 领取优惠券加入星球。
特别提醒: 苹果用户进圈或续费,请加微信 hacker_binghe 扫二维码,或者去公众号 冰河技术 回复 星球 扫二维码加入星球。
好了,今天就到这儿吧,我是冰河,我们下期见~~
