蛋蛋蛋蛋小蛋蛋 发表于 2024-9-10 20:52

网页在线客服

想给网页做一个在线客服系统,但苦于搜索半天都是收费的,但一想到只是一个客服系统而已,便动手尝试了一下。

当然自己写之后才发现确实不容易。

目前实现了其他网站只需要导入js 便可以在网站右下角窗口联系客服

其他功能还没有完善,发出来 请大家给点经验和思路

小生先行在此谢过

先上代码 使用nodejs 和socket.io
目录结构可以自行下载查看,就不放出来了
#服务端


var express = require('express');
    var app = express();
    var http = require('http').createServer(app);
    var io = require('socket.io').listen(http);

      app.use(express.static('public'));

      //请求首页返回index.html
      app.get('/', function (req, res) {
            res.sendFile( __dirname + "/index.html" );
      });

      //开启http服务器,监听8080端口
      var server = http.listen(8080, function () {
             console.log("server start");
      });

      var j = 0;//1客服在线,0客服不在线


       //分配客服和客户命名空间
      var service = io.of('/service');
      var custom = io.of('/custom');

      //监听客服端链接
      service.on('connection', function(client){
          console.log('a service connected');

            //监听客服发来的信息
            client.on('message_service', function (msg) {
                custom.to(msg.destination_id).emit("new_message", msg);//把客服发来的数据转发给对应id客户
            });

         //监听客服断开链接
         client.on('disconnect', function () {
            console.log('a service leave');
         });
      });


      //监听客户链接
         custom.on('connection', function(client){
          console.log('a user connected');

          //判断客服在不在线,不在线则输入框不能选取
          isOnline();
          if(j == 0) {
            custom.to(client.id).emit('isOnline', false);
          } else {
            custom.to(client.id).emit('isOnline', true);
          }

      //监听客户发来的信息
      client.on('message_custom', function (msg) {
            msg.id = client.id;                //socketId存入msg对象一起转发给客服
            service.emit('new_message', msg);//把信息转发给客服
      });

      //监听客户断开连接
      client.on('disconnect', function(){
         console.log('a user leave');
         });
   });




//判断当前客服在不在线
function isOnline() {

    io.of('/service').clients(function(error, clients){
      if (error) throw error;
      j = clients.length;   //客服分组长度为0,证明没有客服在线
    });
}
#客服页面
```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>客服端</title>
    <link href="css/reset.css" type="text/css" rel="stylesheet">
    <link href="css/chatServer.css" type="text/css" rel="stylesheet">
</head>
<body>
<div id="choose">
    <select id="choose_chat">
   <option value="chat_message">默认</option>
    </select>
</div>
<!--在线客服-->
<div id="chat">
    <div id="chat_top"><img src="images/service.svg" id="service">在线客服</div>
    <div id="chat_message" class="chat_message">

      <div class="message_service" id="message0">
            <div class="service_left">
                <img src="images/custom_head.jpg" class="service_head">
            </div>
            <div class="service_right">
                <div class="message_time"></div>
                <div class="service_message_contain">sss</div>
            </div>
      </div>
      <div style='clear:both'></div>

      <div class="message_custom" id="message1">
            <div class="custom_right">
                <img src="images/service_head.jpeg" class="service_head">
            </div>

            <div class="custom_left">
                <div class="message_time"></div>
                <div class="custom_message_contain"></div>
            </div>
      </div>
      <div style='clear:both'></div>

    </div>
    <div id="chat_tools">
      <img src="images/face_choose.svg" id="face_choose">
      <img src="images/pic_choose.svg" id="pic_choose">
    </div>
    <textarea id="chat_input"></textarea>
    <input type="button" value="发送" id="send">

</div>
<!--在线客服结束-->

<script src="js/jquery-2.1.4.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="js/chatServer.js"></script>
</body>
</html>
```

#客服功能实现
```
$(function () {

    var socket = io('http://127.0.0.1:8080/service');
    var IDS = []; //该数组保存正在聊天的客户id

    //监听服务器转发的客户消息
    socket.on("new_message", function (msg) {
      var length = IDS.length;

      for(var i = 0; i <= length; i++) {
          var id = msg.id.replace('/custom#', '');

          //新消息的用户id聊天框已经有了
          if(id == IDS) {
               var $chat = $('#' + id);   //获取对应id聊天框
               var $message = $chat.find('#message0').clone();
               $message.attr('id', '');
               $message.find('.message_time').text(msg.time);
               $message.find('.service_message_contain').text(msg.message);
               $chat.append($message).append("<div style='clear:both'></div>");
               $chat.scrollTop($chat.scrollHeight);//滚动条置底
               break;
          }

          //新消息的用户id聊天框还没有,动态生成
          if(i == length){
            var $pause =$('#chat_message').clone();    //克隆大聊天框
            var $message_pause = $pause.find("#message0").clone();   //克隆聊天框内客户发来的消息

            $pause.attr('id', id);      //客户socketId做为大聊天框id
            $message_pause.attr('id', '');
            $message_pause.find('.message_time').text(msg.time);   //插入信息发送时间
            $message_pause.find('.service_message_contain').text(msg.message); //插入消息内容
            $pause.css('display', 'none');
            $pause.append($message_pause).append("<div style='clear:both'></div>");
            $('#chat_top').after($pause);
            $('#choose_chat').append("<option value=" + id + ">" + id + "</option>");//聊天框选择增加新选项
            IDS.push(id);
            $pause.scrollTop($pause.scrollHeight);//滚动条置底
          }
      }
    });

    //点击发送按钮,发送信息给在线客服
    $("#send").bind("click", function () {
      var $this = $(this);

      //如果输入框不为空
      if ($this.prev().val() != "") {
            var choosed = $("#choose_chat option:selected").val();
            var destination_id = "/custom#" + choosed;   //要发送到的客户端id
            console.log(destination_id);
            var message = $this.prev().val();
            var $pause = $("#message1").clone();
            var time = new Date().toLocaleTimeString();//获得发送时间
            var $chat_pause = $("#" + choosed);   //获得聊天信息框准备插入新数据

            //把数据通过socket.io发送给后台
            socket.emit('message_service', {'message': message,
                                          'time': time,
                                          'destination_id': destination_id});

            $this.prev().val("");         //点发送,清空输入框
            $pause.find(".custom_message_contain").text(message);
            $pause.css("display", "block");
            $pause.attr("id", "");
            $pause.find(".message_time").text(time);

            $chat_pause.append($pause).append("<div style='clear:both'></div>");
            $chat_pause.scrollTop($chat_pause.scrollHeight);//滚动条置底
      }
      $('#chat_input').focus();
    });

    //聊天框选择绑定
    $('#choose_chat').change(function () {
      var choosed =$("#choose_chat option:selected").val();
      var unChoosed =$("#choose_chat option").not(':selected');

      unChoosed.each(function () {
         var val = $(this).val();
            $('#' + val).hide();
      });

      $('#' + choosed).show();
    });

});

```

#引入其他网站的js
```
(function ($) {
    // 加载聊天窗口样式
    var style = document.createElement('style');
    style.innerHTML = `
      #chat {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 300px;
            height: 400px;
            border-radius: 10px;
            border: 1px solid rgba(0, 0, 0, 0.1);
            background: rgba(255, 255, 255, 0.9);
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
            z-index: 9999;
            display: flex;
            flex-direction: column;
            transition: all 0.4s ease-in-out;
            overflow: hidden;
      }
      #chat.minimized {
            height: 40px;
            background: rgba(255, 255, 255, 0.7);
      }
      #chat_top {
            background: linear-gradient(45deg, rgba(76, 175, 80, 0.9), rgba(56, 142, 60, 0.9));
            color: rgba(255, 255, 255, 0.9);
            padding: 10px;
            text-align: center;
            cursor: pointer;
            font-weight: bold;
            font-size: 16px;
            transition: background 0.3s ease-in-out;
      }
      #chat_top:hover {
            background: linear-gradient(45deg, rgba(76, 175, 80, 1), rgba(56, 142, 60, 1));
      }
      #chat_message {
            flex: 1;
            padding: 10px;
            overflow-y: auto;
            border-top: 1px solid rgba(0, 0, 0, 0.1);
            border-bottom: 1px solid rgba(0, 0, 0, 0.1);
            background-color: rgba(245, 245, 245, 0.9);
            transition: background-color 0.3s ease;
      }
      .message_service, .message_custom {
            margin-bottom: 10px;
            padding: 10px;
            border-radius: 8px;
            background: rgba(255, 255, 255, 0.85);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
      }
      #chat_input {
            width: calc(100% - 20px);
            margin: 10px;
            padding: 10px;
            border-radius: 6px;
            border: 1px solid rgba(0, 0, 0, 0.1);
            background: rgba(255, 255, 255, 0.8);
            box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.05);
      }
      #send {
            margin: 10px;
            padding: 10px;
            background: linear-gradient(45deg, rgba(76, 175, 80, 0.8), rgba(56, 142, 60, 0.8));
            color: white;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            transition: background 0.3s ease;
      }
      #send:hover {
            background: linear-gradient(45deg, rgba(76, 175, 80, 1), rgba(56, 142, 60, 1));
      }
      #close-btn {
            position: absolute;
            top: 5px;
            right: 10px;
            cursor: pointer;
            font-size: 18px;
            color: rgba(255, 255, 255, 0.8);
            transition: color 0.3s ease;
      }
      #close-btn:hover {
            color: rgba(255, 255, 255, 1);
      }
    `;
    document.head.appendChild(style);

    // 创建聊天窗口HTML结构
    var chatWidget = document.createElement('div');
    chatWidget.id = 'chat';
    chatWidget.innerHTML = `
      <div id="chat_top">
            <span id="isOnline">在线客服为您服务(在线)</span>
            <span id="close-btn">-</span>
      </div>
      <div id="chat_message"></div>
      <textarea id="chat_input" placeholder="请输入您的消息..."></textarea>
      <button id="send">发送</button>
    `;
    document.body.appendChild(chatWidget);

    // 点击顶部栏收起或展开聊天窗口
    $('#chat_top').on('click', function () {
      $('#chat').toggleClass('minimized');
      $('#close-btn').text($('#chat').hasClass('minimized') ? '+' : '-');
    });

    // 连接到Socket.io的客服命名空间
    var socket = io('http://127.0.0.1:8080/custom'); // 替换为你的服务器地址

    // 检查客服是否在线
    socket.on("isOnline", function (msg) {
      if(msg == false) {
         $('#isOnline').text("客服当前不在线");
         $('#chat_input').attr('disabled', 'disabled');
      }
    });

    // 监听服务器发来的客服消息
    socket.on("new_message", function (msg) {
      var $chat = $('#chat_message');   //获取聊天框
      var $message = $('<div class="message_service"></div>');
      $message.append(`
            <div class="service_left">
                <img src="http://127.0.0.1:8080/images/service_head.jpeg" class="service_head">
            </div>
            <div class="service_right">
                <div class="message_time">${msg.time}</div>
                <div class="service_message_contain">${msg.message}</div>
            </div>
      `);
      $chat.append($message).append("<div style='clear:both'></div>"); //清除浮动用的div
      $chat.scrollTop($chat.scrollHeight);//滚动条置底
    });

    // 点击发送按钮,发送信息给在线客服
    $("#send").bind("click", function () {
      var message = $('#chat_input').val();
      if (message.trim() !== "") {
            var time = new Date().toLocaleTimeString();// 获得发送时间
            var $chat = $('#chat_message');   // 获得聊天信息框准备插入新数据

            // 把数据通过socket.io发送给后台
            socket.emit('message_custom', {'message': message, 'time': time});

            // 清空输入框
            $('#chat_input').val("");         

            // 在页面上显示用户消息
            var $message = $('<div class="message_custom"></div>');
            $message.append(`
                <div class="custom_right">
                  <img src="http://127.0.0.1:8080/images/custom_head.jpg" class="service_head">
                </div>
                <div class="custom_left">
                  <div class="message_time">${time}</div>
                  <div class="custom_message_contain">${message}</div>
                </div>
            `);
            $chat.append($message).append("<div style='clear:both'></div>"); // 清除浮动用的div
            $chat.scrollTop($chat.scrollHeight);// 滚动条置底
            $('#chat_input').focus();// 聚焦到输入框
      }
    });

})(jQuery);

```
#使用-安装
```
npm i
```
#使用-运行
```
node chatserver.js
```
#使用-访问
```
http://127.0.0.1:8080/kfhoutai.html

#访问测试页面

http://127.0.0.1:8080/test.html
```
#其他网站导入客户端js
```
<!-- 引入jQuery -->
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<!-- 引入Socket.io -->
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<!-- 引入在线客服的JS -->
<script src="http://127.0.0.1:8080/js/chat_client.js"></script>
```


gayhub:https://github.com/abxian/kf_system
如有违规,请管理员删帖

蛋蛋蛋蛋小蛋蛋 发表于 2024-9-11 10:30

Marken888 发表于 2024-9-11 09:44
没有后端服务,只能自己跟自己聊

客户端的js 有连接后端相关设置

Wangxiaoer 发表于 2024-9-12 09:47

想请问下,比如10个人同时跟客服聊天,怎么判断是哪个人跟客服发的消息;以及客服的回复消息怎么判断是发给某个人的?

开创者 发表于 2024-9-10 21:28

是直接能使用了吗?

jaffa 发表于 2024-9-10 21:28

高手啊厉害

ww197514 发表于 2024-9-10 21:37

没有关键词回复和自动回复

我在路上 发表于 2024-9-10 21:53

有没有成品

xxnn520 发表于 2024-9-10 22:50

真的是学无止境

蛋蛋蛋蛋小蛋蛋 发表于 2024-9-10 23:08

开创者 发表于 2024-9-10 21:28
是直接能使用了吗?

可以,不过完善度不高

蛋蛋蛋蛋小蛋蛋 发表于 2024-9-10 23:09

我在路上 发表于 2024-9-10 21:53
有没有成品

本来想上传附件的

蛋蛋蛋蛋小蛋蛋 发表于 2024-9-10 23:10

ww197514 发表于 2024-9-10 21:37
没有关键词回复和自动回复

感谢提供意见

娟然俊逸 发表于 2024-9-11 07:42

{:1_921:}厉害了 大神哦
页: [1] 2 3 4 5
查看完整版本: 网页在线客服