聊天窗口关键词回复、定时发送、获取手机号发送到服务器

代码逻辑介绍:

isUserTyping记录用户是否输入消息,用setInterval定时50秒检测并改变用户状态为false,发送消息、或者自动打印一轮完毕后,置为true。

sendMessage是处理发送消息的函数;

appendMessage是将消息追加到聊天框的函数;

sendUserDataToServer是将用户信息发送大服务器的函数;

getCurrentTime为时间戳字符串拼接函数,为了格式的统一,建议客户端、服务器(windows开发环境/linux上线)均使用此格式。

preventDefault阻止默认事件,回车时不添加换行。

messageInput.addEventListener('keydown', function (event) {if (event.keyCode === 13) { // 回车键event.preventDefault();sendMessage();}
});

 以下为全部代码:

document.addEventListener('DOMContentLoaded', function () {// 关键词-回复映射表const replies = {"你好": "你好,请问有什么可以帮助您的?","订单查询": "请提供订单号,我将为您查询订单信息。","产品问题": "请详细描述您遇到的问题,我会尽快帮您解决。","投诉": "抱歉让您不满意,请您提供详细信息,我们将尽快处理。","钱": "这边是成人学历提升咨询窗口,目前是报考高峰期,您可以先留下【手机+姓名】,老师给您转发入学申请条件,院校专业,报考流程,优惠信息,费用明细等相关信息。","价格": "这边是成人学历提升咨询窗口,目前是报考高峰期,您可以先留下【手机+姓名】,老师给您转发入学申请条件,院校专业,报考流程,优惠信息,费用明细等相关信息。","成考": "这边是成人学历提升咨询窗口,目前是报考高峰期,您可以先留下【手机+姓名】,老师给您转发入学申请条件,院校专业,报考流程,优惠信息,费用明细等相关信息。","国家开放大学": "这边是成人学历提升咨询窗口,目前是报考高峰期,您可以先留下【手机+姓名】,老师给您转发入学申请条件,院校专业,报考流程,优惠信息,费用明细等相关信息。","国开": "这边是成人学历提升咨询窗口,目前是报考高峰期,您可以先留下【手机+姓名】,老师给您转发入学申请条件,院校专业,报考流程,优惠信息,费用明细等相关信息。","电大": "您可以先留下【手机+姓名】,老师给您转发入学申请条件,院校专业,报考流程,优惠信息,费用明细等相关信息。","成人大学": "这边是成人学历提升咨询窗口,目前是报考高峰期,您可以先留下【手机+姓名】,老师给您转发入学申请条件,院校专业,报考流程,优惠信息,费用明细等相关信息。","在的": "请您放心,我们不会透露您的个人隐私,请问您的【手机号】是?方便我们进一步向您介绍","再见": "再见,祝您生活愉快!"};const over20s = ['您好,还在吗?','那我将院校专业、报考条件、报名时间、报考流程和费用明细发您','您先了解看看,报不报名再决定哈,您接收资料的【手机号码或者微信】是?','免费短信,您说下您的【手机号】,建议您看看,是系统发不会打扰您的','是这样的,内容是保存在短信系统的,我复制不了,只是发给您先了解,您了解后有需要再联系我们。','我们是正规机构,不会泄露您的信息,可以放心的,您的【手机号码】是?',];// 获取聊天容器、消息输入框和发送按钮元素const chatContainer = document.querySelector('.chat_history');const messageInput = document.querySelector('.inputWindow');const sendButton = document.querySelector('.btn');let isUserTyping = false;// 监听发送按钮点击事件sendButton.addEventListener('click', sendMessage);// 监听消息输入框的键盘事件messageInput.addEventListener('keydown', function (event) {if (event.keyCode === 13) { // 回车键event.preventDefault();sendMessage();}});// 发送消息的函数function sendMessage() {isUserTyping = true;let message = messageInput.innerHTML.trim();const regex = /\s+/g; // \s 匹配任何空白字符,包括空格、制表符、换页符等,+ 表示匹配一个或多个  message = message.replace(regex, '');if (message === '') {return; // 如果消息为空则不处理}appendMessage('user', message); // 添加用户发送的消息到聊天窗口// 检测用户输入的是否是手机号if (message.match(/\d{11}/)) {let reply = "感谢您留下手机号,我们的专业顾问会尽快与您联系,为您提供详细的咨询服务。";appendMessage('agent', reply);sendUserDataToServer(message); //将手机号发送到服务器} else {const reply = getReply(message); // 获取客服回复的消息setTimeout(() => { appendMessage('agent', reply); }, 1500); // 延迟一秒后添加客服回复的消息}messageInput.innerHTML = ''; // 清空输入框}// 根据用户消息获取客服回复的函数function getReply(message) {for (const keyword in replies) { // 遍历关键词-回复映射表if (message.includes(keyword)) { // 如果用户消息包含关键词return replies[keyword]; // 返回对应的回复消息}}return "抱歉,是这样的,内容是保存在短信系统的,我复制不了,只是发给您先了解,您了解后有需要再联系我们。所以您的【电话号码】是?"; // 默认回复消息}/*** 添加消息到聊天窗口的函数* chatContainer(.chat_history)*    messageDiv(消息框)*        avatarImg(头像)*        messageContentDiv(消息容器)*            timestampSpan(时间戳)*            textDiv(文本信息)* * @param sender 发送消息的类型,user或者agent* @param text 需要添加到聊天窗口的字符串 * */function appendMessage(sender, text) {const messageDiv = document.createElement('div'); // 创建消息容器元素messageDiv.classList.add('box-message', sender + '-message');const avatarImg = document.createElement('img'); // 创建头像元素avatarImg.src = sender === 'user' ? './image/beauty.png' : './image/beauty.png';messageDiv.appendChild(avatarImg);const messageContentDiv = document.createElement('div'); // 创建消息内容容器元素messageContentDiv.classList.add('message-content');messageDiv.appendChild(messageContentDiv);const timestampSpan = document.createElement('span');timestampSpan.classList.add('timestamp');timestampSpan.textContent = getCurrentTime();messageContentDiv.appendChild(timestampSpan);const textDiv = document.createElement('div');textDiv.textContent = text;messageContentDiv.appendChild(textDiv);chatContainer.appendChild(messageDiv);chatContainer.scrollTop = chatContainer.scrollHeight;}/*** 如果用户超过20秒没有发送消息,自动打印消息*/let printOver20 = setInterval(fn, 20 * 1000);function fn() {if (!isUserTyping) {clearInterval(printOver20); // 先暂停检测定时器,避免在打印时间内也计入检测时间let index = 0;// 间歇性定时器是非阻塞的const replyPrintIntervalId = setInterval(() => {if (isUserTyping) { // 如果用户开始输入,那么停止打印console.log("isUserTyping === true");clearInterval(replyPrintIntervalId);}appendMessage('agent', over20s[index++]);if (index === over20s.length) { // 停止循环打印clearInterval(replyPrintIntervalId);console.log('定时器结束...');}}, 5000);setTimeout(() => { // 打印结束后重新开启定时器isUserTyping = true; // 循环走完用户输入状态为trueprintOver20 = setInterval(fn, 30 * 1000);}, 25 * 1000);}}/*** 定时检查用户输入*/setInterval(() => {if (messageInput.innerHTML === "" && isUserTyping !== false) {isUserTyping = false;}}, 50 * 1000)function getCurrentTime() {const date = new Date(); // 获取当前时间const year = date.getFullYear();const month = `${date.getMonth() + 1}`.padStart(2, '0'); // 月份是从0开始的,所以要加1  const day = `${date.getDate()}`.padStart(2, '0');const hours = date.getHours();const minutes = `${date.getMinutes()}`.padStart(2, '0');const seconds = `${date.getSeconds()}`.padStart(2, '0');return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;}// 发送用户信息到服务器端function sendUserDataToServer(userData) {const nowTime = getCurrentTime();// 将用户对象转换为JSON字符串let userDataString = {phone: `${userData}`};userDataString = JSON.stringify(userDataString);console.log(userDataString);console.log("This is in typeof ---", typeof userDataString);// 发送POST请求到服务器  fetch('http://xxx.xx.xx.xxx:3333', {mode: 'no-cors',method: 'post',headers: {'Content-Type': 'application/json',},body: userDataString,}).then(response => {if (!response.ok) {// throw new Error('Network response was not ok');console.log('then')}return response.json();}).then(data => {console.log('Success:', data);// 这里可以添加其他成功处理逻辑,比如更新UI等  }).catch(error => {// console.error('Error:', error);console.log('catch')// 这里可以添加错误处理逻辑,比如显示错误消息等  });}
});

代码中有三个定时器:

一个定时器负责间隔5s打印一次;

一个定时器负责每隔25检测一下用户是否输入;

一个定时器负责50s检查一下将用户输入状态变为false。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/5036.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[C++][数据结构]二叉搜索树:介绍和实现

二叉搜索树 概念 二叉搜索树又称二叉排序树,它是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值它的左右子树也…

IoT Scenario: Smart Retail System-Multiple Sources and Multiple Terminals

物联网/大数据可视化领域发文可以联系:nascimsina.com IoT Scenario: Smart Retail System Overview The use of IoT in the retail industry enhances customer experiences, optimizes inventory management, and provides valuable insights into consumer beh…

Vue+ElementUI实现文件照片音频视频预览

1. 需求是点击预览按钮 根据文件名的后缀去实现预览 2. 具体实现代码及逻辑 1.预览弹框 <el-dialog:visible.sync"visibleFile"width"40%":close-on-click-modal"false"close"cancelHandler":append-to-body"true">…

【架构】后端项目如何分层及分层领域模型简化

文章目录 一. 如何分层1. 阿里规范2. 具体案例分析 二. 分层领域模型的转换1. 阿里规范2. 模型种类简化分析 三. 小结 本文描述后端项目中如何进行分层&#xff0c;以及分层领域模型简化 一. 如何分层 1. 阿里规范 阿里的编码规范中约束分层逻辑如下: 开放接口层&#xff1a…

pinia持久化

安装 pinia-plugin-persistedstate npm i pinia-plugin-persistedstate main.ts import App from ./App.vue import { createPersistedState } from pinia-plugin-persistedstate import { createPinia } from piniaconst pinia createPinia() pinia.use(createPersistedSt…

Java全栈开发前端+后端(全栈工程师进阶之路)-环境搭建

在课程开始前我们要配置好我们的开发环境&#xff0c;这里我的电脑太乱了&#xff0c;我使用vm虚拟机进行搭建开发环境&#xff0c;如果有需要环境的或者安装包&#xff0c;可以私信我。 那我们开始 首先我们安装数据库 这里我们使用小皮面板 小皮面板(phpstudy) - 让天下没…

【计算机毕业设计】基于SSM++jsp的社区管理与服务系统【源码+lw+部署文档+讲解】

目录 摘 要 Abstract 第一章 绪论 第二章 系统关键技术 第三章 系统分析 3.1.1技术可行性 3.1.2经济可行性 3.1.3运行可行性 3.1.4法律可行性 3.4.1注册流程 3.4.2登录流程 3.4.3活动报名流程 第四章 系统设计 4.3.1登录模块顺序图 4.3.2添加信息模块顺序图 4.4.1 数据库E-…

【Node.js工程师养成计划】之express框架

一、Express 官网&#xff1a;http://www.expressjs.com.cn express 是一个基于内置核心 http 模块的&#xff0c;一个第三方的包&#xff0c;专注于 web 服务器的构建。 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用&…

使用LocalGPT+cpolar打造可远程访问的本地私有类chatgpt服务

文章目录 前言环境准备1. localGPT部署2. 启动和使用3. 安装cpolar 内网穿透4. 创建公网地址5. 公网地址访问6. 固定公网地址 前言 本文主要介绍如何本地部署LocalGPT并实现远程访问&#xff0c;由于localGPT只能通过本地局域网IP地址端口号的形式访问&#xff0c;实现远程访问…

iOS 实现视图遮罩效果

有时候&#xff0c;我们会遇到这种需求&#xff0c;只讲视图的某个部分展示出来 这时候&#xff0c;我们可以通过设置该视图layer.mask layerb来实现&#xff0c;需要注意的是&#xff0c;这里的layerb必须要设置backgroundColor&#xff0c;渐变layer有colors,否则达不到效果…

Java学习3:程序流程控制

Java程序流程控制 1.执行顺序 顺序结构分支顺序 if,switch 循环结构 for ,while ,do-while 2.if分支 三种形式 if(条件表达式){} else if(){} else{}3.switch分支 string week "周一"; switch(week){case "周一":stem.out.println("周一&qu…

UG NX二次开发(C++)-获取模型中所有的拉伸(Extrude)特征

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、在UG 12中创建几个拉伸特征3、UFun中获取对象类型4、通过NXOpen过渡5.测试结果1、前言 在采用UG NX二次开发时,有时需要在模型中获取特定的对象,比如拉伸特征、关联特征等等。但是通过…

vue2 实现echarts图表进入可视区域后再加载动画,以及 使用了resize之后,动画失效问题解决

Intersection Observer API 是一个现代的浏览器 API&#xff0c;用于监测一个或多个目标元素与其祖先元素或视窗&#xff08;viewport&#xff09;之间的交叉状态&#xff08;intersection&#xff09;的变化。它可以有效地监听元素是否进入或离开可视区域&#xff0c;从而实现…

【氮化镓】AlGaN/GaN HEMTs沟道温度测量

文章是关于AlGaN/GaN HEMTs&#xff08;高电子迁移率晶体管&#xff09;在不同基底&#xff08;如蓝宝石和硅&#xff09;上生长时&#xff0c;通过直流&#xff08;DC&#xff09;特性方法确定沟道温度的研究。文章由J. Kuzmk, P. Javorka, A. Alam, M. Marso, M. Heuken, 和 …

UWB人员实时定位系统,Spring boot +Vue框架开发的UWB源码

UWB定位技术最核心的优势就是定位精度&#xff0c;可达厘米级&#xff0c;是其它定位技术的成百上千倍&#xff0c;在此精度下&#xff0c;可以满足绝大多数行业精细化管理的需求。 有了精准的位置数据&#xff0c;就可以把人员和物资的轨迹进行数据化还原&#xff0c;通过人工…

改造BeanUtils,优雅实现List数据拷贝

BeanUtils.copyProperties();确实为我们做了很多事情&#xff0c;虽然不能完美完成深拷贝&#xff0c;但是对于 po、vo、dto 的拷贝已经足够用了。可还是有一些不够完美的地方。 不足几点如下&#xff1a; ①. 不能拷贝 list&#xff0c;而拷贝 list 的情况又大量存在&#x…

C++中读取文件模拟视频流并使用回调函数处理数据

C中读取文件模拟视频流并使用回调函数处理数据 flyfish 在 C 中&#xff0c;回调函数通常以函数指针、函数对象&#xff08;包括 std::function&#xff09;、成员函数指针或 Lambda 表达式的形式来实现。这里使用了 std::function<void(const std::vector<char>&am…

爬虫自动调用shell通过脚本运行scrapy爬虫(crawler API)

一、爬虫时如何同时调用shell 1)终端cd项目>>scrapy crawl example 2)打开example.py import scrapy from scrapy.shell import inspect_response#引入shellclass ExampleSpider(scrapy.Spider):name "example"allowed_domains ["example.com"]…

使用WSGI服务器在生产环境中运行Flask应用程序

文章目录 一、问题描述二、解决思路1、使用Gevent的WSGIServer2、使用WSGIRef的WSGIServer 一、问题描述 在开发Flask应用程序时&#xff0c;有时会在终端看到以下警告信息&#xff1a; WARNING: This is a development server. Do not use it in a production deployment. U…

从0开始学习制作一个微信小程序 学习部分(2)json文件的说明与app.json文件的操作

系列文章目录 本文是小程序制作系列的学习篇的第二篇 学习篇第一篇我们讲了编译器下载&#xff0c;项目、环境建立、文件说明与简单操作&#xff1a;第一篇链接 本篇将继续讲解一些基础的编码&#xff0c;分析json文件的作用,着重讲解app.json里可以对小程序进行的切换页面&am…