Greasy Fork is available in English.

【堆雪球】辅助脚本

堆雪球&豆包知道

// ==UserScript==
// @name         【堆雪球】辅助脚本
// @namespace    http://tampermonkey.net/
// @version      0.11
// @author       巅峰未来-昵称
// @license      MIT
// @description  堆雪球&豆包知道
// @icon         https://scrm.duixueqiu.cn/user/favicon_new4.ico
// @match        https://scrm.duixueqiu.cn/user/main/index.html
// @match        https://scrm.duixueqiu.cn/admin/*
// @match        https://wisdomhtml.doutuimao.net/login
// @connect      wisdom.doutuimao.net
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_notification
// @grant        GM_addStyle
// ==/UserScript==

GM_addStyle(`
    @media screen and (max-height: 800px), screen and (max-width: 1280px) {#sidebar {height: 100vh !important;border-radius: 0px !important;}}
    #sidebar {width: 90px;height: 800px;margin-left: -10px;border-radius: 7px;background: #343338;overflow: hidden;box-shadow: 10px 10px 60px 0 rgba(1,65,45,.5);display: flex;flex-direction: column;}
    #sidebar>div {margin-left: 10px;display: flex;align-items: center;justify-content: center;border-bottom: 1px solid #242329;color: #929292;font-size: 14px;}
    #sidebar>div.buttons:hover {background: #4d4c52;}
    #sidebar>div.buttons:active {background: #ece9e8;}
    .wins {position: fixed;left: 0px;top: 0px;width: 100%;height: 100%;background: rgba(0, 0, 0, 0.5);display: flex;justify-content: center;align-items: center;z-index: 2;}
    .contents {background: #ffffff;padding: 20px;border-radius: 7px;box-sizing: content-box;}
    #logins {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);}
    #logins>div {font-size: 14px;letter-spacing: 8px;text-align: left;}
    #logins>input {width: 170px;height: 30px;margin: 10px 0px 20px 0px;background: #ece9e8;font-size: 14px;padding: 0px 10px;}
    #logins>button {width: 170px;height: 30px;margin-top: 15px;background: #58aa44;border: none;border-radius: 3px;font-size: 14px;letter-spacing: 8px;color: #ffffff;}
    #logins>button:hover {background: #548049;}
    #logins>button:active {background: #343338;}
    #labels>select {height: 55px;width: 350px;border: 1px solid #ece9e8;}
    #labels>textarea {height: 135px;width: 350px;resize: none; border: 1px solid #ece9e8;font-size: 14px;}
    #labels>input {width: 150px;height: 25px;background: #ece9e8;font-size: 14px;padding: 0px 10px;}
    #labels>button {width: 150px;height: 22px;background: #58aa44;border: none;border-radius: 3px;font-size: 14px;letter-spacing: 6px;color: #ffffff;}
    #labels>button:hover {background: #548049;}
    #labels>button:active {background: #343338;}
    #td {height: 5px;background: #dedede;cursor: n-resize;border-top: 2px solid #f5f5f5;border-bottom: 2px solid #f5f5f5;}
    #jl {color: #606266;background: #f5f5f5;height: 200px;padding: 10px;font-size: 14px;line-height: 1.4;user-select: text;overflow: hidden;}
    #zd {color: #606266;background: #f5f5f5;height: 35px;font-size: 14px;border-top: 1px solid #dedede;display: flex;align-items: center;justify-content: center;}
    `);

(function () {
    'use strict';
    const duixueqiu = "https://scrm.duixueqiu.cn/user/main/index.html";
    const doutuimao = "https://wisdomhtml.doutuimao.net/login";
    const index = "https://wisdom.doutuimao.net/login/login/index";
    const jobAddTagsDto = "https://scrm.duixueqiu.cn/admin/#/assistMarketing/jobAddTagsDto";
    const clue = "https://wisdom.doutuimao.net/user/order/v2/clue";
    const set = "https://wisdom.doutuimao.net/user/order/clue/set";
    const details = "https://wisdom.doutuimao.net/user/order/clue/details";
    let dbAccount = GM_getValue('dbAccount');
    let dbPassword = GM_getValue('dbPassword');
    let dbToken = GM_getValue('dbToken');
    let stateToken = GM_getValue('stateToken');
    let prompt = GM_getValue('prompt');
    let automatic = GM_getValue('automatic');
    let Tel = "";
    let stateLabel = GM_getValue('stateLabel');
    let wechatFriends = GM_getValue('wechatFriends');
    let wechatLabel = GM_getValue('wechatLabel');

    if (window.location.href === duixueqiu) {
        dxqSidebar();
        mountedDB();
    } else if (window.location.href === doutuimao) {
        transmitToken();
    } else if (window.location.href === jobAddTagsDto) {
        transmitLabel();
    }

    //堆雪球添加侧边栏
    function dxqSidebar() {
        let sidebar = document.createElement('div');
        document.body.appendChild(sidebar);
        sidebar.innerHTML = `
        <div id="sidebar">
            <div style="height:50px;">
                <img src="https://wisdomhtml.doutuimao.net/favicon.ico" style="height:40px;">
            </div>
            <div class=" buttons" id="dxqdlBtn" style="height:50px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:30px;"><path fill="currentColor" d="M512 512a192 192 0 1 0 0-384 192 192 0 0 0 0 384m0 64a256 256 0 1 1 0-512 256 256 0 0 1 0 512m320 320v-96a96 96 0 0 0-96-96H288a96 96 0 0 0-96 96v96a32 32 0 1 1-64 0v-96a160 160 0 0 1 160-160h448a160 160 0 0 1 160 160v96a32 32 0 1 1-64 0"></path></svg>
            </div>
            <div style="height:40px;">自动获取</div>
            <div class=" buttons" id="dxqjlBtn" style="height:50px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:30px;"><path fill="currentColor" d="M280.768 753.728 691.456 167.04a32 32 0 1 1 52.416 36.672L314.24 817.472a32 32 0 0 1-45.44 7.296l-230.4-172.8a32 32 0 0 1 38.4-51.2l203.968 152.96zM736 448a32 32 0 1 1 0-64h192a32 32 0 1 1 0 64zM608 640a32 32 0 0 1 0-64h319.936a32 32 0 1 1 0 64zM480 832a32 32 0 1 1 0-64h447.936a32 32 0 1 1 0 64z"></path></svg>
            </div>
            <div class=" buttons" id="dxqcxBtn" style="height:50px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:30px;"><path fill="currentColor" d="m795.904 750.72 124.992 124.928a32 32 0 0 1-45.248 45.248L750.656 795.904a416 416 0 1 1 45.248-45.248zM480 832a352 352 0 1 0 0-704 352 352 0 0 0 0 704"></path></svg>
            </div>
            <div style="height:40px;">剪贴板获取</div>
            <div class=" buttons" id="jtbjlBtn" style="height:50px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:30px;"><path fill="currentColor" d="M280.768 753.728 691.456 167.04a32 32 0 1 1 52.416 36.672L314.24 817.472a32 32 0 0 1-45.44 7.296l-230.4-172.8a32 32 0 0 1 38.4-51.2l203.968 152.96zM736 448a32 32 0 1 1 0-64h192a32 32 0 1 1 0 64zM608 640a32 32 0 0 1 0-64h319.936a32 32 0 1 1 0 64zM480 832a32 32 0 1 1 0-64h447.936a32 32 0 1 1 0 64z"></path></svg>
            </div>
            <div class=" buttons" id="jtbcxBtn" style="height:50px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:30px;"><path fill="currentColor" d="m795.904 750.72 124.992 124.928a32 32 0 0 1-45.248 45.248L750.656 795.904a416 416 0 1 1 45.248-45.248zM480 832a352 352 0 1 0 0-704 352 352 0 0 0 0 704"></path></svg>
            </div>
            <div style="height:40px;">辅助功能</div>
            <div class=" buttons" id="promptBtn" style="height:50px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:30px;"><path fill="currentColor" d="M512 128v64H256a64 64 0 0 0-64 64v512a64 64 0 0 0 64 64h512a64 64 0 0 0 64-64V512h64v256a128 128 0 0 1-128 128H256a128 128 0 0 1-128-128V256a128 128 0 0 1 128-128z"></path><path fill="currentColor" d="M768 384a128 128 0 1 0 0-256 128 128 0 0 0 0 256m0 64a192 192 0 1 1 0-384 192 192 0 0 1 0 384"></path></svg>
            </div>
            <div class=" buttons" id="deleteBtn" style="height:50px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:30px;"><path fill="currentColor" d="M160 256H96a32 32 0 0 1 0-64h256V95.936a32 32 0 0 1 32-32h256a32 32 0 0 1 32 32V192h256a32 32 0 1 1 0 64h-64v672a32 32 0 0 1-32 32H192a32 32 0 0 1-32-32zm448-64v-64H416v64zM224 896h576V256H224zm192-128a32 32 0 0 1-32-32V416a32 32 0 0 1 64 0v320a32 32 0 0 1-32 32m192 0a32 32 0 0 1-32-32V416a32 32 0 0 1 64 0v320a32 32 0 0 1-32 32"></path></svg>
            </div>
            <div style="height:40px;">其他功能</div>
            <div class=" buttons" id="qunliaoBtn" style="height:50px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:30px;"><path fill="currentColor" d="M273.536 736H800a64 64 0 0 0 64-64V256a64 64 0 0 0-64-64H224a64 64 0 0 0-64 64v570.88zM296 800 147.968 918.4A32 32 0 0 1 96 893.44V256a128 128 0 0 1 128-128h576a128 128 0 0 1 128 128v416a128 128 0 0 1-128 128z"></path><path fill="currentColor" d="M512 499.2a51.2 51.2 0 1 1 0-102.4 51.2 51.2 0 0 1 0 102.4zm192 0a51.2 51.2 0 1 1 0-102.4 51.2 51.2 0 0 1 0 102.4zm-384 0a51.2 51.2 0 1 1 0-102.4 51.2 51.2 0 0 1 0 102.4z"></path></svg>
            </div>
            <div class=" buttons" id="update" style="height: 72px;margin-top: auto;border-top: 1px solid #242329;">
                <img src="https://greasyfork.org/vite/assets/blacklogo96-sWE0jP07.png" style="height:35px;">
            </div>
        </div>
        `;
        let dxqdlBtn = document.getElementById('dxqdlBtn');
        dxqdlBtn.title = '豆包知道登录';
        dxqdlBtn.addEventListener('click', function () {
            loginWindow();
        });
        let dxqjlBtn = document.getElementById('dxqjlBtn');
        dxqjlBtn.title = '豆包知道建联\n快捷键: ctrl+shift+V';
        dxqjlBtn.addEventListener('click', function () {
            dxqTel(function () { getFunction(jlFunction) });
        });
        document.addEventListener('keydown', function (event) {
            if (event.ctrlKey && event.shiftKey && event.key === 'V') {
                dxqTel(function () { getFunction(jlFunction) });
            }
        });
        let dxqcxBtn = document.getElementById('dxqcxBtn');
        dxqcxBtn.title = '豆包知道查询\n快捷键: ctrl+shift+F';
        dxqcxBtn.addEventListener('click', function () {
            dxqTel(function () { getFunction(cxFunction) });
        });
        document.addEventListener('keydown', function (event) {
            if (event.ctrlKey && event.shiftKey && event.key === 'F') {
                dxqTel(function () { getFunction(cxFunction) });
            }
        });
        let jtbjlBtn = document.getElementById('jtbjlBtn');
        jtbjlBtn.title = '豆包知道建联';
        jtbjlBtn.addEventListener('click', function () {
            jtbTel(function () { getFunction(jlFunction) });
        });
        let jtbcxBtn = document.getElementById('jtbcxBtn');
        jtbcxBtn.title = '豆包知道查询';
        jtbcxBtn.addEventListener('click', function () {
            jtbTel(function () { getFunction(cxFunction) });
        });
        let promptBtn = document.getElementById('promptBtn');
        promptBtn.title = '建联提示';
        promptBtn.addEventListener('click', function () {
            if (prompt) { promptClose() }
            else { promptOpen() }
        });
        let deleteBtn = document.getElementById('deleteBtn');
        deleteBtn.title = '删除数据';
        deleteBtn.addEventListener('click', function () {
            let result = window.confirm("确定要删除本地数据吗?");
            if (result) {
                deleteDBAll();
            }
        });
        let qunliaoBtn = document.getElementById('qunliaoBtn');
        qunliaoBtn.title = '群聊标签';
        qunliaoBtn.addEventListener('click', function () {
            qunliaoWindow();
        });
        let update = document.getElementById('update');
        update.title = '检查更新';
        update.addEventListener('click', function () {
            window.open('https://greasyfork.org/zh-CN/scripts/495265-%E5%A0%86%E9%9B%AA%E7%90%83-%E8%BE%85%E5%8A%A9%E8%84%9A%E6%9C%AC');
        });
        let observer = new MutationObserver(() => {
            if (sidebar) {
                observer.disconnect();
                if (prompt) { promptOpen() }
            }
        })
        observer.observe(document.body, { childList: true, subtree: true })
    }

    //提示窗口
    let tdPanel = document.createElement('div');
    tdPanel.id = 'td';
    let startY, height;
    tdPanel.addEventListener('mousedown', function (e) {
        startY = e.clientY;
        height = parseInt(getComputedStyle(jlPanel).height, 10);
        document.documentElement.addEventListener('mousemove', resize);
        document.documentElement.addEventListener('mouseup', stopResize);
    })
    function resize(e) {
        let currentY = e.clientY;
        let diff = currentY - startY;
        jlPanel.style.height = `${height - diff}px`;
    }
    function stopResize() {
        document.documentElement.removeEventListener('mousemove', resize);
        document.documentElement.removeEventListener('mouseup', stopResize);
    }
    let jlPanel = document.createElement('div');
    jlPanel.id = 'jl';
    let zdPanel = document.createElement('div');
    zdPanel.id = 'zd';
    zdPanel.innerHTML = `
        <div style="margin-right: 10px;">不存在本地数据时</div>
        <div id="zdBtn" class="wechat_label el-tag el-tag--info el-tag--small el-tag--light">自动建联</div>
    `;
    //建联提示
    let observer1 = new MutationObserver(() => {
        mountedData();
    })
    function promptClose() {
        document.getElementById('promptBtn').style.color = '#929292';
        prompt = false;
        GM_setValue('prompt', false);
        let td = document.querySelector('div#td');
        td.parentNode.removeChild(td);
        let jl = document.querySelector('div#jl');
        jl.parentNode.removeChild(jl);
        let zdBtn = document.getElementById('zdBtn');
        zdBtn.removeEventListener('click', zdBtnFunction);
        let zd = document.querySelector('div#zd');
        zd.parentNode.removeChild(zd);
        observer1.disconnect();
    }
    function promptOpen() {
        document.getElementById('promptBtn').style.color = '#58aa44';
        prompt = true;
        GM_setValue('prompt', true);
        document.querySelector('div.info-panel-container.info-panel').appendChild(tdPanel);
        document.querySelector('div.info-panel-container.info-panel').appendChild(jlPanel);
        document.querySelector('div.info-panel-container.info-panel').appendChild(zdPanel);
        let zdBtn = document.getElementById('zdBtn');
        zdBtn.addEventListener('click', zdBtnFunction);
        if (automatic) { zdBtn.classList.remove("el-tag--info") }
        if (document.querySelector('span.target-name')) {
            mountedData();
            observer1.observe(document.querySelector('span.target-name'), { attributes: true });
        } else {
            let observer2 = new MutationObserver(() => {
                if (document.querySelector('span.target-name')) {
                    observer2.disconnect();
                    mountedData();
                    observer1.observe(document.querySelector('span.target-name'), { attributes: true });
                }
            })
            observer2.observe(document.querySelector('div.chat-panel-container.chat-panel'), { childList: true, subtree: true });
        }
    }
    function zdBtnFunction() {
        let zdBtn = document.getElementById('zdBtn');
        if (automatic) {
            automatic = false;
            GM_setValue('automatic', false);
            zdBtn.classList.add("el-tag--info");
        } else {
            automatic = true;
            GM_setValue('automatic', true);
            zdBtn.classList.remove("el-tag--info");
        }
    }
    //获取手机号
    function mountedData() {
        Tel = getTel(document.querySelector('span.target-name').innerText);
        if (Tel) {
            mountedgetData();
        } else {
            if (document.querySelector('div.friend-field-info:nth-child(2) div.friend-field-info__target')) {
                Tel = getTel(document.querySelector('div.friend-field-info:nth-child(2) div.friend-field-info__target').innerText);
                if (Tel) {
                    mountedgetData();
                } else {
                    jlPanel.textContent = '不存在手机号';
                }
            } else {
                if (document.querySelector('div.friend-info')) {
                    document.querySelector('div.friend-info').click();
                    setTimeout(function () {
                        Tel = getTel(document.querySelector('div.friend-field-info:nth-child(2) div.friend-field-info__target').innerText);
                        if (Tel) {
                            mountedgetData();
                        } else {
                            jlPanel.textContent = '不存在手机号';
                        }
                    }, 1000);
                } else {
                    jlPanel.textContent = '手机号标签不存在';
                }
            }
        }
    }
    //获取数据
    function mountedgetData(data) {
        getData(Tel, function (list) {
            if (list !== undefined && list.text) {
                jlPanel.innerHTML =
                    `<strong>此条内容为上一次查询数据</strong><br />
                    ` + list.text + `<br />`
            } else if (list !== undefined) {
                jlPanel.innerHTML =
                    `<strong>此条内容为上一次查询数据</strong><br />
                        购买平台: `+ convertComefrom(list.come_from) + `<br />
                        平台昵称: ` + list.user_nickname + `<br />
                        下单手机: `+ list.order_mobile + `<br />
                        授权手机: `+ list.user_mobile + `<br />
                        购买状态: `+ list.status_name + `<br />
                        课程标题: `+ list.product_title + `<br />
                        订单编号: `+ list.order_no + `<br />
                        支付时间: `+ list.pay_time + `<br />`
            } else {
                if (automatic) {
                    if (data) {
                        updateData({ text: '手机号并非下单手机号', order_mobile: Tel });
                    } else {
                        getFunction(jlFunction);
                    }
                } else {
                    jlPanel.textContent = '不存在本地数据';
                }
            }
        });
    }

    let db;
    //创建或打开数据库
    function mountedDB() {
        let requestDB = indexedDB.open('QueryDatabase', 1);
        requestDB.onsuccess = function (e) { db = requestDB.result; };
        requestDB.onerror = function (e) { };
        requestDB.onupgradeneeded = function (e) {
            db = e.target.result;
            let objStore;
            if (!db.objectStoreNames.contains('QueryTable')) {
                objStore = db.createObjectStore('QueryTable', { ketPath: 'order_mobile' });
            }
        }
    }
    //修改数据
    function updateData(person) {
        if (prompt) {
            let transaction = db.transaction(['QueryTable'], 'readwrite');
            let store = transaction.objectStore('QueryTable');
            let request = store.put(person, person.order_mobile);
            request.onsuccess = function (e) { mountedgetData(true); };
            request.onerror = function (e) { };
        }
    }
    //获取数据
    function getData(date, callback) {
        let transaction = db.transaction(['QueryTable'], 'readwrite');
        let store = transaction.objectStore('QueryTable');
        let request = store.get(date);
        request.onsuccess = function (e) { callback(e.target.result); };
        request.onerror = function (e) { };
    }
    //删除数据库
    function deleteDBAll() {
        let deleteRequest = window.indexedDB.deleteDatabase('QueryDatabase');
        GM_notification({ title: '提示', text: '删除数据库成功', timeout: 2500, });
        location.reload();
    }

    //登录窗口
    function loginWindow() {
        let loginwin = document.createElement('div');
        document.body.appendChild(loginwin);
        loginwin.innerHTML = `
        <div class="wins">
            <div class="contents" style="width: 200px;height: 250px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:20px;float: right;" id="close"><path fill="currentColor" d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z"></path></svg>
                <div id="logins">
                    <div>账号</div>
                    <input id="account" value="`+ dbAccount + `"></input>
                    <div>密码</div>
                    <input id="password" value="`+ dbPassword + `"></input>
                    <br />
                    <button id="login">登录</button>
                </div>
            </div>
        </div>
        `;
        let close = document.getElementById('close');
        close.addEventListener('click', function () {
            document.body.removeChild(loginwin);
        });
        let login = document.getElementById('login');
        login.addEventListener('click', function () {
            dbAccount = document.getElementById('account').value;
            dbPassword = document.getElementById('password').value;
            GM_setValue('dbAccount', dbAccount);
            GM_setValue('dbPassword', dbPassword);
            loginFunction();
        });
    }
    //获取豆包知道Token
    function loginFunction() {
        GM_xmlhttpRequest({
            method: "POST",
            url: index,
            data: JSON.stringify({ "phone": dbAccount, "password": dbPassword }),
            headers: { "Content-Type": "application/json" },
            onload: function (response) {
                let error = JSON.parse(response.responseText).error;
                if (error === 0) {
                    dbToken = JSON.parse(response.responseText).data.token;
                    GM_setValue('dbToken', dbToken);
                    GM_setValue('stateToken', true);
                    GM_notification({ title: '获取Token成功', text: '请等待豆包知道自动登录', timeout: 2500, });
                    let wins = document.querySelector('div.wins');
                    wins.parentNode.removeChild(wins);
                    setTimeout(function () {
                        window.open(doutuimao, 'doutuimao');
                    }, 1000);
                } else {
                    let message = JSON.parse(response.responseText).message;
                    GM_notification({ title: '失败', text: message, timeout: 2500, });
                }
            },
            onerror: function (error) {
                GM_notification({ title: '错误', text: error.error, timeout: 2500, });
            }
        });
    }
    //传递豆包知道Token
    function transmitToken() {
        setTimeout(function () {
            if (stateToken) {
                GM_setValue('stateToken', false);
                window.localStorage.setItem('token', dbToken);
                location.reload();
            }
        }, 1000);
    }
    //传递堆雪球Label
    function transmitLabel() {
        setTimeout(function () {
            if (stateLabel) {
                GM_setValue('stateLabel', false);
                let Token = 'bearer ' + JSON.parse(localStorage.getItem('workphone-token-admin')).access_token;
                let url = 'https://scrm.duixueqiu.cn:9991/jobAddTags?t=' + new Date().getTime();
                let dataobj = { "wechatFriendIds": wechatFriends, "labels": wechatLabel, "batchTaskMode": 0, "chooseNickname": true, "remarks": [] }
                POSTFunction(url, Token, dataobj, function (list) {
                    GM_setValue('wechatFriends', []);
                    GM_setValue('wechatLabel', []);
                    GM_notification({ title: '成功', text: '任务创建成功', timeout: 2500, });
                    location.reload();
                });
            }
        }, 1000);
    }
    //堆雪球获取手机号
    function dxqTel(callback) {
        if (document.querySelector('span.target-name')) {
            Tel = getTel(document.querySelector('span.target-name').innerText);
            if (Tel) {
                callback();
            } else {
                if (document.querySelector('div.friend-field-info:nth-child(2) div.friend-field-info__target')) {
                    Tel = getTel(document.querySelector('div.friend-field-info:nth-child(2) div.friend-field-info__target').innerText);
                    if (Tel) {
                        callback();
                    } else {
                        GM_notification({ title: '提示', text: '不存在手机号', timeout: 2500, });
                    }
                } else {
                    if (document.querySelector('div.friend-info')) {
                        document.querySelector('div.friend-info').click();
                        setTimeout(function () {
                            Tel = getTel(document.querySelector('div.friend-field-info:nth-child(2) div.friend-field-info__target').innerText);
                            if (Tel) {
                                callback();
                            } else {
                                GM_notification({ title: '提示', text: '不存在手机号', timeout: 2500, });
                            }
                        }, 1000);
                    } else {
                        GM_notification({ title: '提示', text: '手机号标签不存在', timeout: 2500, });
                    }
                }
            }
        } else {
            GM_notification({ title: '提示', text: '用户名标签不存在', timeout: 2500, });
        }
    }
    //剪贴板获取手机号
    function jtbTel(callback) {
        navigator.clipboard.readText()
            .then(text => {
            Tel = getTel(text);
            if (Tel) {
                callback();
            } else {
                GM_notification({ title: '失败', text: '剪贴板不存在手机号:\n' + text, timeout: 2500, });
            }
        })
            .catch(err => {
            GM_notification({ title: '错误', text: '无法获取剪贴板内容:\n' + err, timeout: 2500, });
        });
    }
    //获取手机号
    function getTel(text) {
        let regex = /\d{11}/;
        let match = regex.exec(text);
        return match ? match[0] : null;
    }

    let list1, count1;
    //获取数据
    function getFunction(callback) {
        let cluedata1 = { "is_call": 0, "nickname": "", "phone": Tel, "exec_status": 0, "private_sms_id": 0, "order_no": "", "select_status": 0, "channel_type": 1, "come_from": "", "pageSize": 10, "page": 1, "page_size": 10 }
        xhrFunction(clue, cluedata1, function (list) {
            list1 = list;
            count1 = list.page_info.total_count;
            callback();
        });
    }
    //统计建联
    function jlFunction() {
        if (count1 == 0) {
            updateData({ text: '没有购买记录', order_mobile: Tel });
            GM_notification({ title: '失败', text: '没有购买记录', timeout: 2500, });
        } else if (count1 >= 2) {
            updateData({ text: '多条购买记录', order_mobile: Tel });
            GM_notification({ title: '提示', text: '多条购买记录', timeout: 2500, });
        } else if (count1 === 1) {
            updateData(list1.list[0]);
            let id = list1.list[0].order_id;
            let is_call = list1.list[0].is_call;
            let comefrom = list1.list[0].come_from;
            let product_title = list1.list[0].product_title;
            if (is_call === 1) {
                GM_notification({ title: '重复建联-' + convertComefrom(comefrom), text: Tel + '\n' + product_title, timeout: 2500, });
            } else {
                let setdata = { "order_id": id, "come_from": comefrom, "is_call": 1, "des": "", "channel_type": 1 }
                xhrFunction(set, setdata, function (list) {
                    GM_notification({ title: '建联成功-' + convertComefrom(comefrom), text: Tel + '\n' + product_title, timeout: 2500, });
                });
            }
        }
    }
    //统计查询
    function cxFunction() {
        if (count1 == 0) {
            updateData({ text: '没有购买记录', order_mobile: Tel });
            GM_notification({ title: '失败', text: '没有购买记录', timeout: 2500, });
        } else if (count1 >= 2) {
            updateData({ text: '多条购买记录', order_mobile: Tel });
            GM_notification({ title: '提示', text: '多条购买记录', timeout: 2500, });
        } else if (count1 === 1) {
            updateData(list1.list[0]);
            let id = list1.list[0].order_id;
            let comefrom = list1.list[0].come_from;
            let detailsdata = { "channel_type": "", "come_from": comefrom, "order_id": id }
            xhrFunction(details, detailsdata, function (list) {
                cxWindow(comefrom, list);
            });
        }
    }
    //详情窗口
    function cxWindow(comefrom, list) {
        let cxwin = document.createElement('div');
        document.body.appendChild(cxwin);
        cxwin.innerHTML = `
        <div class="wins">
            <div class="contents" style="width: 350px;height: 450px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:20px;float: right;" id="close"><path fill="currentColor" d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z"></path></svg>
                <div style="user-select: text; line-height: 1.4;">
                    <strong>购买平台-` + convertComefrom(comefrom) + `</strong><br /><br />
                    <strong>基本信息</strong><br />
                    <img src="` + list.user_avatar_url + `" width="50"><br />
                    平台昵称: ` + list.user_nickname + `<br />
                    下单手机: ` + list.phone + `<br />
                    授权手机: ` + list.user_mobile + `<br />
                    购买状态: ` + list.status + `<br />
                    课程标题: ` + list.product_title + `<br />
                    订单编号: ` + list.order_no + `<br />
                    支付时间: ` + list.pay_time + `<br />
                    学习时长: ` + list.study_time + `<br /><br />
                    <strong>转私信息</strong><br />
                    是否建联: ` + convertBoolean(list.is_call) + `<br />
                    发送短信: ` + convertBoolean(list.is_send_sms) + `<br />
                    点击链接: ` + convertBoolean(list.is_click_link) + `<br />
                </div>
            </div>
        </div>
        `;
        let close = document.getElementById('close');
        close.addEventListener('click', function () {
            document.body.removeChild(cxwin);
        });
    }
    //转换布尔
    function convertBoolean(data) {
        if (data) { return '是'; }
        else { return '否'; }
    }
    //转换来源
    function convertComefrom(comefrom) {
        if (comefrom === 1) { return '抖音' }
        else if (comefrom === 2) { return '快手' }
        else if (comefrom === 3) { return '微信' }
        else if (comefrom === 4) { return '视频号' }
        else if (comefrom === 5) { return '小红书' }
    }
    //交互数据
    function xhrFunction(url, dataobj, callback) {
        let timestamp = Math.round(new Date().getTime() / 1000);
        let Signe = hex_md5(timestamp + dbToken);
        GM_xmlhttpRequest({
            method: "POST",
            url: url,
            data: JSON.stringify(dataobj),
            headers: { "Content-Type": "application/json", "Come-From": "1", "Token": dbToken, "Signe": Signe },
            onload: function (response) {
                let error = JSON.parse(response.responseText).error;
                if (error === 0) {
                    callback(JSON.parse(response.responseText).data);
                } else {
                    let message = JSON.parse(response.responseText).message;
                    GM_notification({ title: '失败', text: message, timeout: 2500, });
                }
            },
            onerror: function (error) {
                GM_notification({ title: '错误', text: error.error, timeout: 2500, });
            }
        });
    }
    //群聊窗口
    function qunliaoWindow() {
        let Token = 'bearer ' + JSON.parse(localStorage.getItem('workphone-token-admin')).access_token;
        let url = 'https://scrm.duixueqiu.cn:9991/wechatChatroom/pagelist?t=' + new Date().getTime();
        let dataobj = { "wechatAccountIds": [], "keyword": null, "ownerKeyword": null, "wechatAccountKeyword": null, "isDeleted": null, "allotAccountId": null, "groupId": null, "pageIndex": 0, "pageSize": 20 };
        POSTFunction(url, Token, dataobj, function (list) {
            let qlwin = document.createElement('div');
            document.body.appendChild(qlwin);
            qlwin.innerHTML = `
        <div class="wins">
            <div class="contents" style="width: 350px;height: 450px;">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" style="height:20px;float: right;" id="close"><path fill="currentColor" d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z"></path></svg>
                <div id="labels">
                    存在` + list.total + `个群聊<br /><br />
                    <select id="dynamic-dropdown" multiple>
                        <option>--请选择群聊--</option>
                    </select><br /><br />
                    <button id="cxuser">查询用户</button><br /><br />
                    <textarea id="userlist">请选择群聊</textarea><br /><br />
                    <input id="qllabel" value="请输入标签"></input><br /><br />
                    <div id="sumobj">存在x条数据</div>
                    <div style="font-size: 14px;color: #808080;">*一次最多只能执行1000条</div><br />
                    <button id="cjlabel">创建标签</button>
                </div>
            </div>
        </div>
        `;
            let select = document.getElementById('dynamic-dropdown');
            list.results.forEach(function (item) {
                let option = document.createElement("option");
                option.value = item.id;
                option.text = item.nickname + "(" + item.chatroomMemberCount + ")";
                select.appendChild(option);
            });
            let pageIndex = 0;
            select.addEventListener('scroll', function () {
                if (pageIndex !== -1) {
                    const scrollHeight = this.scrollHeight;
                    const scrollTop = this.scrollTop;
                    const height = this.offsetHeight;
                    const isScrolledToBottom = scrollHeight - (scrollTop + height) <= 0;
                    if (isScrolledToBottom) {
                        pageIndex++;
                        let url = 'https://scrm.duixueqiu.cn:9991/wechatChatroom/pagelist?t=' + new Date().getTime();
                        let dataobj = { "wechatAccountIds": [], "keyword": null, "ownerKeyword": null, "wechatAccountKeyword": null, "isDeleted": null, "allotAccountId": null, "groupId": 0, "pageIndex": pageIndex, "pageSize": 20 };
                        POSTFunction(url, Token, dataobj, function (list) {
                            if (list.results.length !== 0) {
                                list.results.forEach(function (item) {
                                    let option = document.createElement("option");
                                    option.value = item.id;
                                    option.text = item.nickname + "(" + item.chatroomMemberCount + ")";
                                    select.appendChild(option);
                                });
                            } else {
                                let option = document.createElement("option");
                                option.text = "--到底了--";
                                select.appendChild(option);
                                pageIndex = -1;
                            }
                        });
                    }
                }
            });
            wechatFriends = [];
            let cxuser = document.getElementById('cxuser');
            let userlist = document.getElementById('userlist');
            cxuser.addEventListener('click', function () {
                wechatFriends = [];
                if (select.options[select.selectedIndex].value !== '--请选择群聊--' && select.options[select.selectedIndex].value !== '--到底了--') {
                    let url = 'https://scrm.duixueqiu.cn:9991/WechatChatroom/listChatroomMember?t=' + new Date().getTime() + '&wechatChatroomId=' + select.options[select.selectedIndex].value;
                    GETFunction(url, Token, function (list2) {
                        if (list2.length !== 0) {
                            userlist.value = '';
                            list2.forEach(function (item) {
                                let url = 'https://scrm.duixueqiu.cn:9991/wechatFriend/friendlistData?t=' + new Date().getTime();
                                let dataobj = { "pageIndex": 0, "allotAccountId": null, "keyword": item.wechatId, "addFrom": null, "wechatAccountKeyword": null, "groupIds": [], "friendsFrom": [], "labels": [], "isDeleted": false, "isZombie": false, "isPass": true, "pageSize": 100, "extendFields": {}, "deviceType": 0 };
                                POSTFunction(url, Token, dataobj, function (list3) {
                                    userlist.value += '(' + list3.total + ')' + item.nickname + '\n' + item.wechatId + '\n\n';
                                    list3.results.forEach(function (item2) {
                                        wechatFriends.push(item2.id);
                                    });
                                });
                            });
                        } else {
                            userlist.value = '该群聊已删除';
                        }
                    });
                } else {
                    userlist.value = '请选择群聊';
                }
            });
            let qllabel = document.getElementById('qllabel');
            qllabel.addEventListener('input', function () {
                document.getElementById('sumobj').innerHTML = '存在' + wechatFriends.length + '条记录';
            });
            let cjlabel = document.getElementById('cjlabel');
            cjlabel.addEventListener('click', function () {
                if (wechatFriends.length !== 0) {
                    if (qllabel.value !== '请输入标签' && qllabel.value !== null && qllabel.value !== undefined && /\S/.test(qllabel.value)) {
                        GM_setValue('stateLabel', true);
                        GM_setValue('wechatFriends', wechatFriends);
                        GM_setValue('wechatLabel', [qllabel.value]);
                        window.open(jobAddTagsDto, 'jobAddTagsDto');
                    } else {
                        GM_notification({ title: '提示', text: '请输入标签', timeout: 2500, });
                    }
                } else {
                    GM_notification({ title: '提示', text: '不存在数据', timeout: 2500, });
                }
            });
            let close = document.getElementById('close');
            close.addEventListener('click', function () {
                document.body.removeChild(qlwin);
            });
        });
    }
    //POST方法
    function POSTFunction(url, Token, dataobj, callback) {
        fetch(url, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'Authorization': Token, 'Client': 'ADMIN_WEB' },
            body: JSON.stringify(dataobj)
        })
            .then(response => response.json())
            .then(data => callback(data))
            .catch(error => console.error('Error:', error));
    }
    //GET方法
    function GETFunction(url, Token, callback) {
        fetch(url, {
            method: 'GET',
            headers: { 'Content-Type': 'application/json', 'Authorization': Token, 'Client': 'ADMIN_WEB' }
        })
            .then(response => response.json())
            .then(data => callback(data))
            .catch(error => console.error('Error:', error));
    }
    //MD5加密
    var hexcase = 0;
    var b64pad = "";
    var chrsz = 8;
    function hex_md5(s) { return binl2hex(core_md5(str2binl(s), s.length * chrsz)); }
    function b64_md5(s) { return binl2b64(core_md5(str2binl(s), s.length * chrsz)); }
    function str_md5(s) { return binl2str(core_md5(str2binl(s), s.length * chrsz)); }
    function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
    function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
    function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
    function md5_vm_test() {
        return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
    }
    function core_md5(x, len) {
        x[len >> 5] |= 0x80 << ((len) % 32);
        x[(((len + 64) >>> 9) << 4) + 14] = len;
        var a = 1732584193;
        var b = -271733879;
        var c = -1732584194;
        var d = 271733878;
        for (var i = 0; i < x.length; i += 16) {
            var olda = a;
            var oldb = b;
            var oldc = c;
            var oldd = d;
            a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
            d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
            c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
            b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
            a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
            d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
            c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
            b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
            a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
            d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
            c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
            b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
            a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
            d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
            c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
            b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
            a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
            d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
            c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
            b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
            a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
            d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
            c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
            b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
            a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
            d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
            c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
            b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
            a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
            d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
            c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
            b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
            a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
            d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
            c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
            b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
            a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
            d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
            c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
            b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
            a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
            d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
            c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
            b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
            a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
            d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
            c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
            b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
            a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
            d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
            c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
            b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
            a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
            d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
            c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
            b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
            a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
            d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
            c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
            b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
            a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
            d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
            c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
            b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
            a = safe_add(a, olda);
            b = safe_add(b, oldb);
            c = safe_add(c, oldc);
            d = safe_add(d, oldd);
        }
        return Array(a, b, c, d);
    }
    function md5_cmn(q, a, b, x, s, t) {
        return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
    }
    function md5_ff(a, b, c, d, x, s, t) {
        return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
    }
    function md5_gg(a, b, c, d, x, s, t) {
        return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
    }
    function md5_hh(a, b, c, d, x, s, t) {
        return md5_cmn(b ^ c ^ d, a, b, x, s, t);
    }
    function md5_ii(a, b, c, d, x, s, t) {
        return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
    }
    function core_hmac_md5(key, data) {
        var bkey = str2binl(key);
        if (bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
        var ipad = Array(16), opad = Array(16);
        for (var i = 0; i < 16; i++) {
            ipad[i] = bkey[i] ^ 0x36363636;
            opad[i] = bkey[i] ^ 0x5C5C5C5C;
        }
        var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
        return core_md5(opad.concat(hash), 512 + 128);
    }
    function safe_add(x, y) {
        var lsw = (x & 0xFFFF) + (y & 0xFFFF);
        var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
        return (msw << 16) | (lsw & 0xFFFF);
    }
    function bit_rol(num, cnt) {
        return (num << cnt) | (num >>> (32 - cnt));
    }
    function str2binl(str) {
        var bin = Array();
        var mask = (1 << chrsz) - 1;
        for (var i = 0; i < str.length * chrsz; i += chrsz) {
            bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
        }
        return bin;
    }
    function binl2str(bin) {
        var str = "";
        var mask = (1 << chrsz) - 1;
        for (var i = 0; i < bin.length * 32; i += chrsz) {
            str += String.fromCharCode((bin[i >> 5] >>> (i % 32)) & mask);
        }
        return str;
    }
    function binl2hex(binarray) {
        var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
        var str = "";
        for (var i = 0; i < binarray.length * 4; i++) {
            str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) +
                hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
        }
        return str;
    }
    function binl2b64(binarray) {
        var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        var str = "";
        for (var i = 0; i < binarray.length * 4; i += 3) {
            var triplet = (((binarray[i >> 2] >> 8 * (i % 4)) & 0xFF) << 16)
            | (((binarray[i + 1 >> 2] >> 8 * ((i + 1) % 4)) & 0xFF) << 8)
            | ((binarray[i + 2 >> 2] >> 8 * ((i + 2) % 4)) & 0xFF);
            for (var j = 0; j < 4; j++) {
                if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
                else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
            }
        }
        return str;
    }
})();