<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">

    <title>webchat即时在线聊天室</title>

    <link rel="stylesheet" href="/css/common/common.css">
    <link rel="stylesheet" href="/css/client/chat.css">
    <link rel="stylesheet" href="/css/client/search.css">
    <link href="/ref/layui-v2.6.8/layui/css/layui.css" rel="stylesheet" type="text/css" />

    <script src="/ref/jquery/jquery-3.4.1.js" type="text/javascript"></script>
    <script src="/ref/layui-v2.6.8/layui/layui.js" type="text/javascript"></script>
    <script src="/ref/jquery/jquery.qqFace.js" type="text/javascript"></script>
    <script src="/js/common/marked.min.js"></script>
    <script>
        if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {
            window.location.href = "/h5/list";
        }
    </script>
</head>
<body>
<center>
    <div class="chat-container">
        <div class="chat-left-menu-container">
            <p class="chat-window-icon">
                WebChat
            </p>
            <img class="curr-user-photo" id="curr-user-photo">

            <a><img title="聊天会话" class="chat-menu-icon chat-icon fun-icon selected-icon" src="http://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_6309ed247a544cac8cb812d3b8e61d2f.png"></a>
            <a><img title="好友列表" class="chat-menu-icon friend-list-icon fun-icon" src="http://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_b91980c31f6a4f6ca20e29b579d65ebd.png"></a>
            <a><img title="消息提醒" class="chat-menu-icon message-icon fun-icon" src="http://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_b06158e70f0544749c62a3efc771843e.png"></a>
            <a><img title="朋友圈" id="moments" class="chat-menu-icon moment-icon fun-icon" src="https://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_60a54f2b4da74a36bfb415ccb11caf8f.png"></a>
            <a><img title="手机扫码" id="phone" class="chat-menu-icon phone-icon fun-icon" src="https://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_cbf3780b685f4b33a9fa3a6ba18eafee.png"></a>
            <a href="/admin" target="_blank" style="display: none" id="admin-icon"><img title="管理后台" class="chat-menu-icon admin-icon" src="http://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_b4d0496dbbaf486e994922150ecc2774.png"></a>
            <a onclick="loginOut()"><img title="退出登录" class="chat-menu-icon logout-icon" src="http://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_d555969e726846e49d564b7a3e62ad54.png"></a>
            <button id="momentRedPoint">
                <svg t="1730999364143" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13000" width="20" height="20"><path d="M512 512m-170.91558262 0a170.91558262 170.91558262 0 1 0 341.83116524 0 170.91558262 170.91558262 0 1 0-341.83116525 0Z" fill="#FF4141" p-id="13001"></path></svg>
            </button>
            <?xml version="1.0" encoding="UTF-8"?><svg class="new-message-icon" width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M24 33C28.9706 33 33 28.9706 33 24C33 19.0294 28.9706 15 24 15C19.0294 15 15 19.0294 15 24C15 28.9706 19.0294 33 24 33Z" fill="#ff7070" stroke="#ff7070" stroke-width="4"/></svg>
        </div>
        <div class="chat-list-container">
            <div class="chat-main-list-title">
                <input id="search-input" placeholder="搜索" autocomplete="off">
                <svg id="delete-search-btn" t="1731928962844" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6867" width="16" height="16"><path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0z m0 921.6c-226.304 0-409.6-183.296-409.6-409.6s183.296-409.6 409.6-409.6 409.6 183.296 409.6 409.6-183.296 409.6-409.6 409.6z" fill="#8a8a8a" p-id="6868"></path><path d="M638.464 312.832L512 439.808 385.536 312.832 312.832 385.536 439.808 512l-126.976 126.464 72.704 72.704L512 584.192l126.464 126.976 72.704-72.704L584.192 512l126.976-126.464z" fill="#8a8a8a" p-id="6869"></path></svg>
                <button class="add-btn" id="add-btn">
                    <svg t="1730112209518" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10200" width="32" height="32"><path d="M533.333333 288a10.666667 10.666667 0 0 0-10.666666-10.666667h-42.666667a10.666667 10.666667 0 0 0-10.666667 10.666667v192h-192a10.666667 10.666667 0 0 0-10.666666 10.666667v42.666666a10.666667 10.666667 0 0 0 10.666666 10.666667h192v192a10.666667 10.666667 0 0 0 10.666667 10.666667h42.666667a10.666667 10.666667 0 0 0 10.666666-10.666667v-192h192a10.666667 10.666667 0 0 0 10.666667-10.666667v-42.666666a10.666667 10.666667 0 0 0-10.666667-10.666667h-192v-192z" fill="#2c2c2c" p-id="10201"></path></svg>
                </button>
                <div id="search-results"></div>
            </div>
            <!-- 聊天列表 -->
            <div class="chat-user-list-container chat-main-list-container" style="display: block">
                <div class="chat-user-list" id="chat-group-banner" style="display: none; min-height: 50px; height: auto">
                    <div id="chat-group-list" style="padding: 10px; min-height: 50px; height: auto"></div>
                    <div style="clear: both"></div>
                </div>
                <div class="chat-user-list" id="chat-user-list">

                </div>
            </div>
            <!-- 好友列表 -->
            <div class="friend-list-container chat-main-list-container">
                <div class="friend-list"></div>
            </div>
            <!-- 好友列表 -->
            <div class="apply-list-container chat-main-list-container">
                <p class="chat-main-list-title">好友申请</p>
                <div class="apply-unhandle-list"></div>
            </div>
        </div>

        <!-- 消息内容 -->
        <div class="chat-message-container" id="chat-message-container"></div>
        <!-- 消息编辑器 -->
        <div class="chat-editor">
            <!-- 消息编辑器菜单 -->
            <div class="chat-editor-menu">
                <a class="chat-editor-menu-icon" id="mess-emoji-menu"><?xml version="1.0" encoding="UTF-8"?><svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="none" stroke="#333" stroke-width="4" stroke-linejoin="round"/><path d="M31 18V19" stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M17 18V19" stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M31 31C31 31 29 35 24 35C19 35 17 31 17 31" stroke="#333" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg></a>
                <a class="chat-editor-menu-icon" id="mess-video-menu" style="top: -5px;"><svg t="1730287583228" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4300" width="30" height="30"><path d="M607.9232 227.84a144.4864 144.4864 0 0 1 143.744 137.728l0.0768 3.2768 52.48-36.6592a61.2352 61.2352 0 0 1 76.8256 8.2688l3.0976 3.328 2.7648 3.4816c5.1712 8.6016 8.8832 17.9968 11.0336 28.032l1.1008 6.0672v276.5824a58.8032 58.8032 0 0 1-58.9056 58.7008c-10.496 0-20.7616-2.7136-29.8496-7.8336l-4.4288-2.7648-54.528-37.0176-0.1792 1.5872a144.3584 144.3584 0 0 1-131.3792 125.0816l-5.9904 0.3584-5.888 0.1024H268.8512a144.4864 144.4864 0 0 1-143.744-137.728l-0.1536-5.632V371.1744a144.4864 144.4864 0 0 1 138.2656-143.2064l5.632-0.128h339.072z m0 61.2608H268.8256a82.56 82.56 0 0 0-82.2528 77.44l-0.1536 4.6592v281.5744A82.56 82.56 0 0 0 264.192 734.72l4.6592 0.1536h338.2016a82.56 82.56 0 0 0 82.2528-77.44l0.1792-4.6592 0.8192-0.8704V371.2a82.56 82.56 0 0 0-77.7472-81.9456l-4.6592-0.1536z m227.0976 96.9728l-84.0448 57.1904-1.1008 149.5808 85.1456 59.2384V386.0736z" fill="#515151" p-id="4301"></path><path d="M529.0752 534.1184l-128.2816 74.624a25.6 25.6 0 0 1-38.4768-22.1184v-149.248a25.6 25.6 0 0 1 38.4768-22.1184l128.256 74.624a25.6 25.6 0 0 1 0 44.2368z" fill="#515151" p-id="4302"></path></svg></a>
                <a class="chat-editor-menu-icon" id="mess-file-menu" style="top: -1px;">
                    <svg t="1731138986021" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4798" width="22" height="22"><path d="M191.4 765.1c0 22.6 18.3 41 41 41h158.1c22.6 0 41-18.3 41-41 0-22.6-18.3-41-41-41H232.3c-22.6 0-40.9 18.3-40.9 41zM889.3 855.1h-40.9 16.2c13.8-0.8 24.7-12.2 24.7-26.2v26.2zM141.3 855.2h40.9H166c-13.8-0.8-24.7-12.2-24.7-26.2v26.2zM889.3 549.6h-40.9 16.2c13.8 0.8 24.7 12.2 24.7 26.2v-26.2zM809.6 346.9h-40.9 16.2c13.8 0.8 24.7 12.2 24.7 26.2v-26.2zM141.6 244h40.9-16.2c-13.8 0.8-24.7 12.2-24.7 26.2V244z" fill="#515151" p-id="4799"></path><path d="M906.1 468.1H232.3c-22.6 0-41 18.3-41 41 0 22.6 18.3 41 41 41h657v305.1h-748V244.1h287.3l52.7 81.4a40.98 40.98 0 0 0 36.1 21.5h291.9v63.4c0 22.6 18.3 41 41 41s41-18.3 41-41v-83.2c-3.2-34.7-32.3-61.8-67.8-61.8H769v-0.2H539.9L486 181.9l-0.6-0.9c-7.3-11.3-20-18.9-34.5-18.9H182.3v0.1h-54.5c-37.6 0-68.1 30.5-68.1 68.1v0.5h-0.1v643.6c2.4 32.8 28 59.1 60.5 62.6h787c33.1-1.5 60-26.6 64.3-58.9V529.7c-3.3-33.7-31.1-60.3-65.3-61.6z" fill="#515151" p-id="4800"></path></svg>
                </a>
                <a class="chat-editor-menu-icon" id="mess-red-packet-menu" style="top: -5px;">
                    <svg t="1731102694873" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5409" width="32" height="32"><path d="M678.889739 338.16487c-50.242783 28.93913-101.175652 38.578087-146.743652 38.578087-88.086261 0-156.093217-36.018087-160.345044-38.333218-9.438609-5.12-13.133913-17.274435-8.281043-27.158261 4.897391-9.906087 16.450783-13.801739 25.84487-8.681739 1.424696 0.734609 141.890783 74.573913 271.092869 0.222609a18.743652 18.743652 0 0 1 26.045218 8.013913c5.12 9.750261 1.691826 22.016-7.613218 27.380869zM611.06087 635.481043c10.596174 0 19.18887 9.015652 19.188869 20.168348 0 11.130435-8.592696 20.168348-19.188869 20.168348h-66.715827v51.912348c0 11.130435-8.592696 20.168348-19.188869 20.168348s-19.21113-9.037913-19.211131-20.168348v-51.912348H439.206957c-10.596174 0-19.18887-9.037913-19.18887-20.168348s8.592696-20.168348 19.18887-20.168348h66.715826v-33.992347H439.206957c-10.596174 0-19.18887-9.037913-19.18887-20.190609 0-11.130435 8.592696-20.168348 19.18887-20.168348h50.086956l-52.98087-83.678609a20.813913 20.813913 0 0 1 5.342609-27.981913 18.67687 18.67687 0 0 1 26.646261 5.60974l55.785739 88.153043 55.808-88.153043a18.67687 18.67687 0 0 1 26.624-5.60974c8.815304 6.166261 11.219478 18.69913 5.342609 27.981913l-52.98087 83.70087h52.157218c10.596174 0 19.18887 9.015652 19.188869 20.146087s-8.592696 20.190609-19.188869 20.190609h-66.715826v33.992347h66.715826zM656.962783 200.347826H389.298087C321.936696 200.347826 267.130435 257.936696 267.130435 328.726261v388.808348C267.130435 788.324174 321.936696 845.913043 389.298087 845.913043h267.664696C724.324174 845.913043 779.130435 788.324174 779.130435 717.534609V328.726261C779.130435 257.936696 724.324174 200.347826 656.962783 200.347826z" fill="#FF7241" p-id="5410"></path></svg>
                </a>
            </div>
            <!-- 消息编辑器输入 -->
            <textarea id="chat-editor-input" autofocus="autofocus" placeholder="发私信"></textarea>
            <span class="chat-enter-words"><span id="input-words">0</span> / 500</span>
            <button class="chat-mess-send-btn">按下Enter发送内容</button>
        </div>
        <!-- 选中私信的用户 头部信息区域 -->
        <div class="chat-user-header" id="chat-user-header">
            <a href="" target="_blank" id="selectUserCenterUrl"><span id="selectUserName"></span></a>
            <img src="https://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_3efccfef65fd40caaa2d298484d16215.png" id="group-ctrl">
        </div>
    </div>

    <div class="header-container">
        <img src="/image/icon/logo_title.png" class="logo">
        <ul class="header-menus">
            <li>
                <a target="_blank" href="https://www.coderutil.com">编程导航</a>
                <a target="_blank" href="https://www.coderutil.com/mall/item?itemId=167069788431873">购买源代码</a>
                <a target="_blank" href="https://www.coderutil.com/star/28">项目学习社区</a>
                <a target="_blank" href="https://www.coderutil.com/star/qa/1858">VIP交流群</a>
            </li>
        </ul>
    </div>

    <!-- 音视频通话邀请 -->
    <div class="video-chat-offer-card" style="display: none" id="video-chat-offer-card">
        <img src="https://coderutil.oss-cn-beijing.aliyuncs.com/bbs-image/file_011df09866634d90962c42ba31802f54.png" class="video-chat-offer-icon"> <span style="color: #0755e3" id="offerSenderName">-</span>发来了音视频通话邀请
        <div style="width: 100%; height: 30px; margin-top: 10px; text-align: right">
            <button id="rejectOffer">拒绝</button>
            <button id="acceptOffer">接通</button>
        </div>
    </div>
</center>
<input type="file" id="fileInput" style="display: none;" />
<input type="file" id="photoInput" style="display: none;" />
</body>
<script src="/js/client/auth.js" type="text/javascript"></script>
<script src="/js/client/chat.js" type="text/javascript"></script>
<script src="/js/client/user.js" type="text/javascript"></script>
<script src="/js/client/search.js" type="text/javascript"></script>
<script>
    var me;
    var userId;
    var webSocket;
    // 心跳检测的间隔时间（毫秒）
    const heartbeatInterval = 30000;
    // 重连尝试的时间间隔（毫秒）
    var reconnectInterval = 5000;
    // 最大重连尝试间隔时间
    var maxReconnectInterval = 300000; // 5分钟
    var heartbeatTimer;
    var reconnectTimer;
    var selectCardUserId;
    var selectCardUser = null;
    var robotLastMessId = "";
    var videoChatting = false;
    var fixedMessageId = "";
    loadCurrUserInfo();
    function loadCurrUserInfo() {
        $.ajax({
            url:"/api/user/getCurrentUserInfo",
            type:"get",
            success:function (data) {
                data = eval(data);
                if (data.success){
                    $("#login-user").show();
                    $("#login-menu").hide();
                    data = data.data;
                    me = data;
                    userId = data.userId;
                    $("#curr-user-photo").attr("src", data.photo+"?x-oss-process=image/resize,m_fill,w_40,h_40");
                    if (data.roleCode == 2) {
                        $("#admin-icon").show();
                    }
                    initWebSocket();
                } else {
                    location.href="/auth";
                }
            },error:function () {
                location.href="/auth";
            }
        })
    }

    /**
     * 初始化websocket对象及ws管理
     */
    function initWebSocket() {
        if ("WebSocket" in window) {
            webSocket = new WebSocket("ws://"+wsHost+":"+wsPort+"/ws/chat/" + userId);
            // 发送心跳函数
            function sendHeartbeat() {
                if (webSocket.readyState === WebSocket.OPEN) {
                    webSocket.send('heartbeat');
                }
            }
            // 重连函数
            function reconnect() {
                reconnectTimer = setTimeout(function () {
                    webSocket = null;
                    initWebSocket();
                    reconnectInterval = Math.min(maxReconnectInterval, reconnectInterval * 2);
                }, reconnectInterval);
            }
            // 连接打开时
            webSocket.onopen = function () {
                console.log('WebSocket connection established');
                // 连接成功后启动心跳检测
                heartbeatTimer = setInterval(sendHeartbeat, heartbeatInterval);
                reconnectInterval = 5000; // 重置重连间隔时间
            };
            //接收后台服务端的消息
            webSocket.onmessage = function (evt) {
                if (evt.data == "ok") {
                    // 跳过心跳检测
                    console.log("心跳检测成功！");
                    return;
                }
                var mess = JSON.parse(evt.data);
                if (mess.momentMessage) {
                    $("#momentRedPoint").show();
                    return;
                } else if (mess.videoOffer) {
                    // 来自用户音视频请求
                    showVideoOfferNotify(mess.senderId, mess.receiverId, mess.senderName);
                    return;
                } else if (mess.rejectVideoOffer) {
                    hideVideoOfferNotify();
                    return;
                } else if (mess.type == 5) {
                    // 申请添加好友消息提醒，显示红点信息
                    $(".new-message-icon").show();
                    return;
                }
                showReceiverMsg(mess);
                setTimeout('loadChat(false)', 1000);
            };
            //连接关闭的回调事件
            webSocket.onclose = function () {
                console.log("连接已关闭...");
                clearInterval(heartbeatTimer);
                clearTimeout(reconnectTimer);
                reconnect(); // 调用重连函数
            };
        } else {
            // 浏览器不支持 WebSocket
            alert("您的浏览器不支持 WebSocket!");
        }
    }

    function closeWebSocket() {
        //直接关闭websocket的连接
        webSocket.close();
    }

    function sendChatWebSocket(message) {
        webSocket.send(message);
    }

    // 获取URL请求参数
    function getUserParamByName(key) {
        var url = window.location.search;
        var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
        var result = url.substr(1).match(reg);
        return result ? decodeURIComponent(result[2]) : "";
    }

    function showReceiverMsg(chat) {
        var message;
        var proxy = chat.proxySender != null;
        var sender = proxy ? chat.proxySender : chat.sender;
        var isMe = sender.userId == me.userId;
        if (selectCardUserId != chat.sender.userId) {
            // 不是当前点开的窗口，不显示消息
            return;
        }
        if (isMe) {
            if (chat.type === 3) {
                message = buildRedPacketMess(chat.redPacketDetail.id, me.photo, "right");
            } else if (chat.type === 2) {
                message = buildFileMess(JSON.parse(chat.message), me.photo, "right");
            } else {
                // 当前用户
                message ="                <p class=\"chat-mess-time\">"+formatMsgTime(chat.time)+"</p>\n" +
                    "                <div class=\"chat-mess-container chat-mess-me\">\n" +
                    "                    <div class=\"chat-mess-avatar\">\n" +
                    "                        <a href='/coder?userid="+sender.userId+"' target='_blank'><img src=\""+sender.photo+"?x-oss-process=image/resize,m_fill,w_50,h_50\"></a>\n" +
                    "                    </div>\n" +
                    "          <div class=\"chat-mess-triangle-right\"></div>\n" +
                    "                    <div class=\"chat-mess-box\">"+messContentEnCode(chat.message)+"</div>\n" +
                    "                </div>\n";
            }
        } else {
            if (chat.type === 3) {
                message = buildRedPacketMess(chat.redPacketDetail.id, sender.photo, "left");
            } else if (chat.type === 2) {
                message = buildFileMess(JSON.parse(chat.message), me.photo, "right");
            } else if (chat.type === 4) {
                var article = JSON.parse(chat.message);
                message = buildPublicAccountMess(article.articleId, article.cover, article.title, article.description);
            } else {
                // 当前用户
                message =" <p class=\"chat-mess-time\">"+formatMsgTime(chat.time)+"</p>\n" +
                    "                <div class=\"chat-mess-container chat-mess-user\">\n" +
                    "                    <div class=\"chat-mess-avatar\">\n" +
                    "                        <a href='/coder?userid="+sender.userId+"' target='_blank'><img src=\""+sender.photo+"?x-oss-process=image/resize,m_fill,w_50,h_50\"></a>\n" +
                    "                    </div>\n";
                var topTip = 10;
                var topMessage = 0;
                if (proxy) {
                    topTip = 20;
                    topMessage = 15;
                    message += "<span style='color: #9e9e9e;font-size: 10px;position: absolute;top: 0px;left: 65px'>"+sender.userName+"</span>";
                }
                message += "                    <div class=\"chat-mess-triangle-left\" style='top: "+topTip+"px'></div>\n" +
                    "                    <div class=\"chat-mess-box\" style='top: "+topMessage+"px'>"+messContentEnCode(chat.message)+"</div>\n" +
                    "                </div>\n";
            }
        }
        $("#chat-message-container").append(message);
        initOpenRedPacketEvent();
        // 刷新消息区滚动条
        refreshChatMessContainerScrollBar2Bottom();
    }

    // 获取好友id
    var chatId = getUserParamByName("chatid");
    var chatUserListUrl;
    if (chatId != '') {
        chatUserListUrl = "/api/chat/mess/users?selectUser=" + chatId;
    } else {
        chatUserListUrl = "/api/chat/mess/users";
    }
    loadChat(true);
    function loadChat(selectFirstUser) {
        $("#chat-user-list").empty();
        $.ajax({
            url: chatUserListUrl,
            type:"get",
            success:function (data) {
                data = eval(data);
                if (data.success){
                    if (data.data.length == 0) {
                        $("#chat-user-list").append("<p style='line-height: 300px; color: gray'>暂无聊天记录</p>");
                        return;
                    }
                    $.each(data.data, function (index, chatUser) {
                        var user = chatUser.user;
                        var firstChatCard = index == 0;
                        if (selectFirstUser && firstChatCard) {
                            selectChatUser(user.userId, user.userName, "无签名", true);
                        }
                        var unReadTag = chatUser.unReadMess ?
                            "<button class='unReadMessTag' id='unreadTag-"+user.userId+"'></button>" : "";
                        var chatUserCard = "<div class=\"chat-user-card\" id='card-"+user.userId+"'>\n" +
                            "<a onclick=\"deleteChatCard('"+user.userId+"')\" class='deleteChatCardIcon'><?xml version=\"1.0\" encoding=\"UTF-8\"?><svg width=\"15\" height=\"15\" viewBox=\"0 0 48 48\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8 8L40 40\" stroke=\"#424242\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M8 40L40 8\" stroke=\"#424242\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></a>"+
                            "<a onclick=\"selectChatUser('"+user.userId+"', '"+user.userName+"', '无签名', true)\"><div style='widht: 200px; height: 60px; background-color: transparent'>";

                        var groupIcon = "";
                        if (user.roleCode == 4) {
                            // 群管理
                            groupIcon = "<span class='group-icon'>群</span>";
                            chatUserCard += "<button class=\"chat-user-card-photo line2ppp\" style='border: 0; color: white; font-size: 10px; background-color: "+colors[user.id%5]+"'>"+user.userName+"</button>";
                        } else if (user.roleCode == 5) {
                            // 机器人
                            groupIcon = "<span class='robot-icon'>机器人</span>";
                            chatUserCard += "<img src=\""+user.photo+"\" class=\"chat-user-card-photo\">";
                        } else if (user.roleCode == 6) {
                            // 公众号
                            groupIcon = "<span class='group-icon'>号</span>";
                            chatUserCard += "<img src=\""+user.photo+"\" class=\"chat-user-card-photo\">";
                        }  else {
                            chatUserCard += "<img src=\""+user.photo+"\" class=\"chat-user-card-photo\">\n";
                        }
                        chatUserCard += "<p class=\"chat-user-card-username\">"+groupIcon+user.userName+unReadTag+"</p>\n" +
                            "                    <p class=\"chat-user-card-last-msg line1ppp\">"+codeContentEnCode(chatUser.lastMessage)+"</p>\n" +
                            "                    <span class=\"chat-user-card-last-time\">"+formatMsgTime(chatUser.time)+"</span>\n" +
                            "</div></a></div>";
                        $("#chat-user-list").append(chatUserCard);
                    })
                    $(".chat-user-card").css("background-color", "transparent");
                    $("#card-"+selectCardUserId).css("background-color", "white");
                }
                $(".chat-user-card").hover(function(){
                    $(this).children(".deleteChatCardIcon").show();
                },function(){
                    $(this).children(".deleteChatCardIcon").hide();
                });
            }
        })
    }
    function selectChatUser(userId, userName, signature, focusUser) {
        selectCardUserId = userId;
        this.refreshSelectUserInfo(selectCardUserId);
        $("#selectUserName").html(userName+"  <span style='color: #afadad; font-size: 13px;'>(好友)</span>");
        $("#selectUserCenterUrl").attr("href", "/coder?userid="+userId);
        $("#chat-user-header").show();
        $(".chat-user-card").css("background-color", "transparent");
        $("#card-"+userId).css("background-color", "white");
        // 加载消息
        loadChatMessage();
        $("#unreadTag-"+userId).hide();
    }

    function refreshSelectUserInfo(selectUserId) {
        selectCardUser = null;
        $.ajax({
            url: "/api/user/getUserInfo?userId=" + selectUserId,
            type:"get",
            success:function (data) {
                data = eval(data);
                if (data.success){
                    selectCardUser = data.data;
                    if (selectCardUser.roleCode === 5) {
                        chatChannel();
                        return;
                    }
                    if (selectCardUser.roleCode === 6) {
                        $(".chat-editor").hide();
                        $("#chat-message-container").css("height", "calc(100% - 67px)");
                        $("#chat-message-container").css("background-color", "whitesmoke");
                    } else {
                        $(".chat-editor").show();
                        $("#chat-message-container").css("height", "calc(100% - 260px)");
                        $("#chat-message-container").css("background-color", "white");
                    }
                }
            }
        })
    }

    function loadChatMessage() {
        $("#chat-message-container").empty();
        $(".chat-user-card").css("background-color", "transparent");
        $("#card-"+selectCardUserId).css("background-color", "white");
        $.ajax({
            url: "/api/chat/mess/query/"+selectCardUserId+"/100?fixedMessageId="+fixedMessageId,
            type:"get",
            success:function (data) {
                data = eval(data);
                if (data.success){
                    $.each(data.data, function (index, chat) {
                        var message;
                        var groupMessage = chat.groupMessage;
                        var sender = groupMessage ? chat.proxySender : chat.sender;
                        var isMe = sender.userId == me.userId;

                        // 显示群管理
                        if (groupMessage) {
                            $("#group-ctrl").show();
                        } else {
                            $("#group-ctrl").hide();
                        }
                        var fixedClass = "";
                        if (fixedMessageId == chat.messId) {
                            fixedClass = "background-color: #faa34a;";
                        }
                        if (isMe) {
                            if (chat.type === 3) {
                                message = buildRedPacketMess(chat.redPacketDetail.id, me.photo, "right");
                            } else if (chat.type === 2) {
                                message = buildFileMess(JSON.parse(chat.message), me.photo, "right");
                            } else {
                                // 当前用户
                                message = "                <p class=\"chat-mess-time\">" + formatMsgTime(chat.time) + "</p>\n" +
                                    "                <div class=\"chat-mess-container chat-mess-me\">\n" +
                                    "                    <div class=\"chat-mess-avatar\">\n" +
                                    "                        <a href='/coder?userid=" + sender.userId + "' target='_blank'><img src=\"" + sender.photo + "?x-oss-process=image/resize,m_fill,w_50,h_50\"></a>\n" +
                                    "                    </div>\n" +
                                    "                    <div class=\"chat-mess-triangle-right\"></div>\n" +
                                    "                    <div class=\"chat-mess-box\" style='"+fixedClass+"'>" + messContentEnCode(chat.message) + "</div>\n" +
                                    "                </div>\n";
                            }
                        } else {
                            if (chat.type === 3) {
                                message = buildRedPacketMess(chat.redPacketDetail.id, sender.photo, "left");
                            } else if (chat.type === 2) {
                                message = buildFileMess(JSON.parse(chat.message), sender.photo, "left");
                            } else if (chat.type === 4) {
                                var article = chat.publicAccountArticle;
                                message = buildPublicAccountMess(article.articleId, article.cover, article.title, article.description);
                            } else {
                                message =" <p class=\"chat-mess-time\">"+formatMsgTime(chat.time)+"</p>\n" +
                                    "                <div class=\"chat-mess-container chat-mess-user\">\n" +
                                    "                    <div class=\"chat-mess-avatar\">\n" +
                                    "                        <a href='/coder?userid="+sender.userId+"' target='_blank'><img src=\""+sender.photo+"?x-oss-process=image/resize,m_fill,w_50,h_50\"></a>\n" +
                                    "                    </div>\n";
                                var topTip = 10;
                                var topMessage = 0;
                                if (groupMessage) {
                                    topTip = 20;
                                    topMessage = 15;
                                    message += "<span style='color: #9e9e9e;font-size: 10px;position: absolute;top: 0px;left: 65px'>"+sender.userName+"</span>";
                                }

                                // 特殊处理机器人消息（html直接显示）
                                var messageContent = sender.roleCode != 5 ? messContentEnCode(chat.message) : chat.message;
                                message +="                    <div class=\"chat-mess-triangle-left\" style='top: "+topTip+"px'></div>\n" +
                                    "                    <div class=\"chat-mess-box\" style='top: "+topMessage+"px;"+fixedClass+"'>"+messageContent+"</div>\n" +
                                    "                </div>\n";
                            }
                        }
                        $("#chat-message-container").append(message);
                    })
                    fixedMessageId = "";
                    initOpenRedPacketEvent();
                    // 刷新消息区滚动条
                    refreshChatMessContainerScrollBar2Bottom();
                }
            }
        })
    }

    function deleteChatCard(cardUserId) {
        $("#card-"+cardUserId).remove();
        if (cardUserId == selectCardUserId) {
            $("#chat-user-header").hide();
        }
    }

    /***
     * 发送消息
     */
    $("#chat-editor-input").keydown(function(event) {
        if (event.keyCode == 13) {
            // 阻止默认的换行行为
            event.preventDefault();
            var content = $("#chat-editor-input").val();
            $("#chat-editor-input").val('');
            if (content != '' && content.length > 500) {
                layer.msg("消息内容上限500字");
                return;
            }
            var meMess = buildTextMess(content);
            content = content.replace(/\r\n/g,"<br>")
            content = content.replace(/\n/g,"<br>");
            content = content.replace(/"/g,"'");
            if (content == '') {
                layer.msg("消息内容为空");
                return;
            }

            sendMeMess2Local(meMess);

            if (selectCardUser.roleCode == 5) {
                robotLastMessId = new Date().getTime();
                // 同机器人对话，需要特殊处理
                var robotMess = "<p class=\"chat-mess-time\"></p>\n" +
                "                <div class=\"chat-mess-container chat-mess-user\">\n" +
                "                    <div class=\"chat-mess-avatar\">\n" +
                "                        <a href=\"/coder?userid="+selectCardUser.userId+"\" target=\"_blank\"><img src=\""+selectCardUser.photo+"\"></a>\n" +
                "                    </div>\n" +
                "                    <div class=\"chat-mess-triangle-left\"></div>\n" +
                "                    <div class=\"chat-mess-box\" style='min-height: 30px' id=\""+robotLastMessId+"\"></div>\n" +
                "                </div>\n"
                $("#chat-message-container").append(robotMess);
                // 刷新消息区滚动条
                refreshChatMessContainerScrollBar2Bottom();
            }
            var data = "{\"receiverId\":\""+selectCardUserId+"\",\"type\": 1, \"senderId\":\""+me.userId+"\", \"message\": \""+content+"\"}";

            sendChatWebSocket(data);

            $.ajax({
                url:"/api/chat/mess/send",
                type: "post",
                dataType: "json",
                contentType: "application/json;charset=utf-8",
                data: JSON.stringify({
                    receiverId: selectCardUserId,
                    senderId: me.userId,
                    message: content,
                    type: 1
                }),
                success:function (data) {
                    data = eval(data);
                    if (!data.success){
                        layer.msg(data.msg);
                    } else {
                        if (selectCardUser.roleCode != 5) {
                            loadChat(false);
                        }
                    }
                },error:function () {}
            })
        }
    })

    function sendMeMess2Local(meMess) {
        $("#chat-message-container").append(meMess);
        // 清空输入框
        $("#chat-editor-input").val("");
        // 刷新消息区滚动条
        refreshChatMessContainerScrollBar2Bottom();
    }

    // 一进来就滚动到底部
    $("#chat-message-container").scrollTop($("#chat-message-container")[0].scrollHeight);
    // 刷新消息区滚动态到底部
    function refreshChatMessContainerScrollBar2Bottom() {
        $("#chat-message-container").scrollTop($("#chat-message-container")[0].scrollHeight);
    }

    function buildTextMess(message) {
        // 这里没做xss防注入，可能存在注入问题
        message = replace_em(message);
        return "<p class=\"chat-mess-time\">刚刚</p>\n" +
            "              <div class=\"chat-mess-container chat-mess-me\">\n" +
            "                    <div class=\"chat-mess-avatar\">\n" +
            "                        <img src=\""+me.photo+"\">\n" +
            "                    </div>\n" +
            "                    <div class=\"chat-mess-triangle-right\"></div>\n" +
            "                    <div class=\"chat-mess-box\">"+message+"</div>\n" +
            "             </div>\n";
    }

    function buildRedPacketMess(redPacketId, photo, float) {
        // 这里没做xss防注入，可能存在注入问题
        var userClass = float == 'right' ? "chat-mess-me" : "chat-mess-user";
        var redPacketClass = float == 'right' ? "float: right; margin-right: 60px;" : "float: left; margin-left: 60px;";
        return "<p class=\"chat-mess-time\">刚刚</p>\n" +
            "              <div class=\"chat-mess-container red-packet-card "+userClass+"\" data-id='"+redPacketId+"' id='red-packet-"+redPacketId+"'>\n" +
            "                    <div class=\"chat-mess-avatar\">\n" +
            "                        <img src=\""+photo+"\">\n" +
            "                    </div>\n" +
            "                    <div class=\"chat-mess-triangle-"+float+"\" style='border-"+(float == 'right' ? "left" : "right")+": 16px solid #f37444'></div>\n" +
            "                    <div class=\"chat-mess-red-packet\" style='"+redPacketClass+"'>" +
            "                       <img class='red-packet-icon' src=\"/image/icon/red_packet.png\"> <span class='red-packet-text'>恭喜发财</span>" +
            "                    </div>\n" +
            "             </div>\n";
    }

    function buildPublicAccountMess(id, img, title, description) {
        return "<p class=\"chat-mess-time\">刚刚</p>\n" +
            "              <a href='/article/"+id+"' target='_blank'>" +
            "                <div class=\"public-account-mess-container\">" +
            "                   <div class=\"public-account-mess-cover-container\">" +
            "                       <img src=\""+img+"\" class='public-account-mess-cover'>"+
            "                   </div>"+
            "                   <div class=\"public-account-mess-title line1ppp\">"+title+"</div>"+
            "                   <div class=\"public-account-mess-description line2ppp\">"+description+"</div>"+
            "               </div>" +
            "             </a>";
    }

    function buildFileMess(file, photo, float) {
        // 这里没做xss防注入，可能存在注入问题
        var userClass = float == 'right' ? "chat-mess-me" : "chat-mess-user";
        var redPacketClass = float == 'right' ? "float: right; margin-right: 60px;" : "float: left; margin-left: 60px;";
        var width = file.type == 'IMAGE' ? "width: 80px;" : "width: 160px;";
        var padding = file.type == 'IMAGE' ? "padding: 1px;" : "padding: 5px 12px;";
        var card = "<p class=\"chat-mess-time\">刚刚</p>\n" +
            "              <div style='margin-bottom: 20px' class=\"chat-mess-container "+userClass+"\">\n" +
            "                    <a href='"+file.url+"' target='_blank'><div class=\"chat-mess-avatar\">\n" +
            "                        <img src=\""+photo+"\">\n" +
            "                    </div>\n" +
            "                    <div class=\"chat-mess-triangle-"+float+"\" style='border-"+(float == 'right' ? "left" : "right")+": 16px solid #e8f3fa'></div>\n" +
            "                    <div class=\"chat-mess-red-packet\" style='background-color: #e8f3fa; overflow: hidden; height: 60px; "+width+redPacketClass+padding+"'>";
        if (file.type == 'IMAGE') {
            card += "<img style='width: 80px; margin-top: -10px' src=\""+file.url+"\">";
        } else {
            card += "                       <img class='red-packet-icon' src=\"/image/icon/file.png\"> <span class='red-packet-text line2ppp' style='color: #2828ea; font-size: 13px; top: 10px;'>点击下载文件:"+file.name+"</span>";
        }
        card += "                    </div></a>\n" +
            "             </div>\n";
        return card;
    }
</script>

<!-- 视频通话 -->
<script>

    function acceptVideoChat(userId, targetUserId) {
        if (videoChatting) {
            // 音视频中
            return;
        }
        videoChatting = true;
        // 视频通话呼叫
        layer.open({
            type: 2,
            title: '视频通话',
            shadeClose: true,
            resize: false,
            shade: 0.6,
            maxmin: false, //开启最大化最小化按钮
            area: ['450px', '700px'],
            content: '/client/video-chat?userId='+userId+'&targetUserId='+targetUserId
        });
    }

    /**
     * 显示音视频邀请通知
     *
     * @param senderId
     * @param receiverId
     */
    function showVideoOfferNotify(senderId, receiverId, senderName) {
        if (videoChatting) {
            // 音视频中不提醒，目前提醒的话会有BUG，可能导致死循环，内存溢出问题
            return;
        }
        $("#offerSenderName").text(senderName);
        $("#video-chat-offer-card").show();

        $("#acceptOffer").on("click", function () {
            $("#video-chat-offer-card").hide();
            acceptVideoChat(receiverId, senderId);
        })

        $("#rejectOffer").on("click", function () {
            $("#video-chat-offer-card").hide();
            var data = "{\"receiverId\":\""+senderId+"\", \"senderId\":\""+receiverId+"\", \"rejectVideoOffer\": true}";
            webSocket.send(data);
        })
    }

    function hideVideoOfferNotify() {
        videoChatting = false;
        layer.closeAll();
        layer.msg("对方拒绝了你的通话邀请！");
    }

    $("#mess-video-menu").on("click", function () {
        if (selectCardUser.roleCode != 1 && selectCardUser.roleCode != 2) {
            layer.msg("不支持音视频");
            return;
        }
        videoChatting = false;
        acceptVideoChat(me.userId, selectCardUserId);
    })


    $(function(){
        $('#mess-emoji-menu').qqFace({
            assign:'chat-editor-input',    //给那个控件赋值
            path:'/ref/jquery/face/',        //表情存放的路径
            tip : 'em'
        });
        //提交后显示表情
        $(".sub_btn").click(function(){
            var str = $("#chat-editor-input").val();
            $("#show").html(replace_em(str));
        });
    });

    <!-- 查看朋友圈 -->
    $("#moments").on('click', function () {
        layer.closeAll();
        layer.open({
            type: 2,
            title: '朋友圈',
            shadeClose: true,
            resize: false,
            shade: 0.6,
            maxmin: false, //开启最大化最小化按钮
            area: ['440px', '780px'],
            content: '/h5/moment'
        });
    })

    $("#phone").on("click", function () {
        var url = location.href;
        layer.open({
            type: 1,
            title: false,
            closeBtn: 0,
            shadeClose: true,
            skin: 'yourclass',
            content: '<div style=\"width: 350px; height: 350px; background-color: white\"> <p style=\"line-height: 60px; text-align: center\">手机扫码 - 跳转至移动端访问</p> ' +
                '<img src=\"/api/qr/create?url='+url+'\" style=\"margin-top: 10px; margin-left: 75px; width: 200px;\" alt=\"稍等，移动二维码生成中……\"> ' +
                '<p style=\"line-height: 50px; text-align: center; color: darkgray; font-size: 12px;\">webchat - Java在线聊天室</p> </div>'
        });
    })

    var balance = "0.00";
    refreshMalletBalance();
    function refreshMalletBalance() {
        $.ajax({
            url: "/api/user/wallet/balance",
            type: "get",
            success:function (data) {
                data = eval(data);
                if (data.success){
                    balance = data.data;
                }
            }
        })
    }
    // 发红包
    $("#mess-red-packet-menu").on("click", function () {
        // 刷新红包余额
        refreshMalletBalance();

        var redPacketConfig = "<div style='width: 250px; height: 350px; background-color: white; padding: 10px 30px;'>" +
            "<div style='line-height: 45px;'>红包发送配置，当前钱包余额（<b style='color: orangered'>"+balance+"</b>）</div>" +
            "<div style='margin-top: 10px'><input style='width: 100%; line-height: 45px; height: 45px; border-radius: 3px; border: 1px solid #f4b4b4; text-indent: 2em' placeholder='配置红包金额' id='totalMoney'></div>" +
            "<div style='margin-top: 10px'><input style='width: 100%; line-height: 45px; height: 45px; border-radius: 3px; border: 1px solid #f3b4b4; text-indent: 2em' placeholder='红包个数' id='count'></div>" +
            "<div style='line-height: 20px; margin: 10px 0px; font-size: 12px; text-align: left'>ps: 如果接收方为个人账号则默认普通红包，如果为群组则默认为拼手气红包！</div>" +
            "<div style='margin: 10px 0px;'><button id='sendRedPacket' style='width: 100%; height: 45px; color: white; border: none; background-color: orangered; border-radius: 4px;'>塞钱进红包（别慌~ 没让你塞真钱）</button></div>" +
            "</div>";
        layer.open({
            type: 1,
            title: false,
            closeBtn: 0,
            shadeClose: true,
            skin: 'yourclass',
            content: redPacketConfig
        });

        $("#sendRedPacket").on('click', function () {
            var roleCode = selectCardUser.roleCode;
            if (roleCode >= 5) {
                layer.msg("仅支持给用户和群组发红包~");
                return;
            }
            var totalMoney = $("#totalMoney").val();
            var count = $("#count").val();
            var type = 1;
            if (roleCode == 4) {
                if (count <= 0) {
                    layer.msg("群聊红包个数必须大于1个");
                    return;
                }
                // 拼手气
                type = 2;
            } else if (count != 1) {
                layer.msg("专属红包个数只能配置：1");
                return;
            }
            $.ajax({
                url: "/api/red-packet/send",
                type: "post",
                dataType: "json",
                contentType: "application/json;charset=utf-8",
                data: JSON.stringify({
                    receiverUserId: selectCardUserId,
                    type: type,
                    totalMoney: totalMoney,
                    count: count
                }),
                success: function (data) {
                    data = eval(data);
                    if (data.success) {
                        layer.closeAll();
                        // 红包发送成功
                        $("#chat-message-container").append(buildRedPacketMess(data.data, me.photo, 'right'));
                        // 刷新消息区滚动条
                        refreshChatMessContainerScrollBar2Bottom();
                    } else {
                        layer.msg(data.msg);
                    }
                }, error: function () {
                    layer.msg("服务端异常");
                }
            })
        })
    })

    function initOpenRedPacketEvent() {
        $(".red-packet-card").on("click", function () {
            var redPacketId = $(this).attr("data-id");
            $.ajax({
                url: "/api/red-packet/open/"+redPacketId,
                type: "get",
                success: function (data) {
                    data = eval(data);
                    if (data.success) {
                        var redPacketResult = "<div style='width: 200px; height: 100px; background-color: white; padding: 10px 30px;'>" +
                            "<div style='line-height: 100px; font-size: 20px; color: gray'>恭喜你，抢到<b style='color: orangered'>￥"+data.data+"</b></div>" +
                            "</div>";
                        layer.open({
                            type: 1,
                            title: false,
                            closeBtn: 0,
                            shadeClose: true,
                            skin: 'redPacketResult',
                            content: redPacketResult
                        });
                    } else {
                        layer.msg(data.msg);
                    }
                }, error: function () {
                    layer.msg("服务端异常");
                }
            })
        });
    }

</script>
</html>