# 《AI智能客服系统》落地实现-第04节:前端页面的实现与整体测试

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码获取地址:https://t.zsxq.com/0dhvFs5oR (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

  • 本章难度:★★☆☆☆
  • 本章重点:对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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

# 四、功能测试

将项目application.yml配置文件中的spring.ai.openai.api-key的值替换为自己的DeepSeek API Key,随后,运行AiBotStarter类启动项目,如果打印如下日志,则说明项目启动成功。

==============================================
AI智能客服系统启动成功:访问信息如下:
访问地址: http://localhost:8080
==============================================
1
2
3
4

随后,在浏览器输入: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 扫二维码,或者去公众号 冰河技术 回复 星球 扫二维码加入星球。

好了,今天就到这儿吧,我是冰河,我们下期见~~