Greasy Fork

Greasy Fork is available in English.

BOSS海投助手

🚀 求职者自己的神器!🧑‍💻Yangshengzhou,提升BOSS直聘的简历投递效率,自动批量发送简历,高效求职 💼

当前为 2025-05-23 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         BOSS海投助手
// @namespace    https://github.com/yangshengzhou03
// @version      1.2.2
// @description  🚀 求职者自己的神器!🧑‍💻Yangshengzhou,提升BOSS直聘的简历投递效率,自动批量发送简历,高效求职 💼
// @author       Yangshengzhou
// @match        https://www.zhipin.com/web/*
// @grant        GM_xmlhttpRequest
// @run-at       document-idle
// @supportURL   https://github.com/yangshengzhou03
// @homepageURL  https://gitee.com/yangshengzhou
// @license      AGPL-3.0-or-later
//               更多详情请参见: https://www.gnu.org/licenses/agpl-3.0.html
// @icon         https://static.zhipin.com/favicon.ico
// @connect      zhipin.com
// @connect      spark-api-open.xf-yun.com
// @noframes
// @require      https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js
// ==/UserScript==

(function () {
    'use strict';

    // 配置常量
    const CONFIG = {
        INTERVAL: 2500,
        CARD_STYLE: {
            BACKGROUND: '#ffffff',
            SHADOW: '0 6px 18px rgba(0,0,0,0.12)',
            BORDER: '1px solid #e4e7ed'
        },
        COLORS: {
            PRIMARY: '#2196f3',
            SECONDARY: '#ff5722',
            NEUTRAL: '#95a5a6'
        },
        MINI_ICON_SIZE: 40
    };

    // 状态管理
    const state = {
        isRunning: false,
        currentIndex: 0,
        filterKeyword: '',
        locationKeyword: '',
        jobList: [],
        isMinimized: false,
        processedHRs: new Set(JSON.parse(localStorage.getItem('processedHRs') || '[]')),
        currentTopHRKey: null,
        aiReplyCount: JSON.parse(localStorage.getItem('aiReplyCount') || '0'),
        lastAiDate: localStorage.getItem('lastAiDate') || ''
    };

    // DOM 元素引用
    const elements = {
        panel: null,
        controlBtn: null,
        log: null,
        filterInput: null,
        miniIcon: null
    };

    // UI 模块:负责创建和操作界面组件
    const UI = {

        // 创建主控制面板
        createControlPanel() {
            if (document.getElementById('boss-pro-panel')) return;

            elements.panel = this._createPanel();
            const header = this._createHeader();
            const controls = this._createControls();
            elements.log = this._createLogger();
            const footer = this._createFooter();

            elements.panel.append(header, controls, elements.log, footer);
            document.body.appendChild(elements.panel);

            this._makeDraggable(elements.panel);

            if (!document.getElementById('boss-settings-dialog')) {
                const settingsDialog = this._createSettingsDialog();
                document.body.appendChild(settingsDialog);
            }
        },

        // 创建面板容器
        _createPanel() {
            const panel = document.createElement('div');
            panel.id = 'boss-pro-panel';
            panel.className = 'boss-pro-panel';
            panel.style.cssText = `
                position: fixed;
                top: 36px;
                right: 24px;
                width: 380px;
                background: linear-gradient(145deg, #ffffff, #f9f9fc);
                border-radius: 16px;
                box-shadow: 0 10px 25px rgba(0,0,0,0.1);
                padding: 18px;
                font-family: 'Segoe UI', system-ui, sans-serif;
                z-index: 2147483647;
                cursor: move;
                display: flex;
                flex-direction: column;
                transition: all 0.3s ease;
            `;
            return panel;
        },

        // 创建面板头部
        _createHeader() {
            const header = document.createElement('div');
            header.className = 'boss-header';
            header.style.cssText = `
        display: flex;
        justify-content: space-between;
        margin-bottom: 1.5rem;
    `;

            const title = document.createElement('div');
            title.style.display = 'flex';
            title.style.flexDirection = 'column';
            title.style.gap = '0.3em';

            title.innerHTML = `
        <h3 style="
            margin: 0;
            color: #2c3e50;
            font-weight: 660;
            font-size: 1.2rem;
        ">
            <span style="color:${CONFIG.COLORS.PRIMARY};">BOSS</span>海投助手
        </h3>
        <span style="
            font-size:0.8em;
            color:${CONFIG.COLORS.NEUTRAL};
        ">
            v1.2-Beta (Professional)
        </span>
    `;

            const closeBtn = this._createIconButton('✕', () => {
                state.isMinimized = true;
                elements.panel.style.transform = 'translateY(160%)';
                elements.miniIcon.style.display = 'flex';
            });
            closeBtn.style.color = CONFIG.COLORS.NEUTRAL;
            closeBtn.style.marginTop = '0.2rem';
            closeBtn.title = '最小化海投面板';

            header.append(title, closeBtn);
            return header;
        },

        // 创建控制区域(按钮 + 输入框)
        _createControls() {
            const container = document.createElement('div');
            container.className = 'boss-controls';
            container.style.marginBottom = '0.8rem';

            const utilGroup = document.createElement('div');
            utilGroup.className = 'boss-util-group';
            utilGroup.style.cssText = `
        display: flex;
        gap: 10px;
        justify-content: flex-end;
        margin-top: 1rem;
    `;

            const clearLogBtn = this._createIconButton('🗑', () => {
                elements.log.innerHTML = `<div style="color:${CONFIG.COLORS.NEUTRAL}; margin-bottom:8px;">请在BOSS中展示岗位列表,我将自动与这些岗位沟通。</div>`;
            });
            clearLogBtn.title = '清空日志';

            const settingsBtn = this._createIconButton('⚙', () => {
                const dialog = document.getElementById('boss-settings-dialog');
                if (dialog) {
                    dialog.style.display = 'flex';
                } else {
                    const newDialog = this._createSettingsDialog();
                    document.body.appendChild(newDialog);
                    newDialog.style.display = 'flex';
                }
            });
            settingsBtn.title = '插件设置';

            const joinGroupBtn = this._createIconButton('✉', () => {
                window.open('https://qun.qq.com/universal-share/share?ac=1&authKey=twqkV%2Fu9zC7%2FrSMJOOxD%2FbM4rXDqkE2zWg%2FmR6DdVI9BJImtoBFqvNnE9F3KyW3P&busi_data=eyJncm91cENvZGUiOiIxMDQ3ODQyNDczIiwidG9rZW4iOiJBTGF3eEVwLzYvRCtHRkR2WnVDYUVFTDdJQWY0cGVDODl4amlkTkVaL2R4bTU1WE9CSTUzSzRYTkhvdW9DTGVKIiwidWluIjoiMzU1NTg0NDY3OSJ9&data=WOu9pw6Y-e2H4ebyGMMgxV75yzExdNk2LrecdfSDL1RVZ9TbUOvXDVzo3qIShDAzhK5PjDYx5o-uXH-GdA0FfQ&svctype=4&tempid=h5_group_info', '_blank');
            });
            joinGroupBtn.title = '加入粉丝交流群';

            utilGroup.append(clearLogBtn, settingsBtn, joinGroupBtn);

            const jobLabel = document.createElement('label');
            jobLabel.textContent = '岗位筛选:';
            jobLabel.style.cssText = 'display:block; margin-bottom:0.5rem;';

            elements.filterInput = document.createElement('input');
            elements.filterInput.id = 'job-filter';
            elements.filterInput.placeholder = '岗位包含词(英文逗号分隔,为空则不限)';
            elements.filterInput.className = 'boss-filter-input';
            elements.filterInput.style.cssText = `
        width: calc(100%);
        padding: 12px 16px;
        border-radius: 10px;
        border: 2px solid #ddd;
        margin-bottom: 1rem;
        font-size: 14px;
        transition: border-color 0.3s ease;
        outline: none;
    `;

            elements.filterInput.addEventListener('focus', () => {
                elements.filterInput.style.borderColor = CONFIG.COLORS.PRIMARY;
            });

            elements.filterInput.addEventListener('blur', () => {
                elements.filterInput.style.borderColor = '#ddd';
            });

            const locationLabel = document.createElement('label');
            locationLabel.textContent = '岗位地点:';
            locationLabel.style.cssText = 'display:block; margin-bottom:0.5rem;';

            elements.locationInput = document.createElement('input');
            elements.locationInput.id = 'location-filter';
            elements.locationInput.placeholder = '岗位所在地(英文逗号分隔,为空则不限)';
            elements.locationInput.className = 'boss-filter-input';
            elements.locationInput.style.cssText = `
        width: calc(100%);
        padding: 12px 16px;
        border-radius: 10px;
        border: 2px solid #ddd;
        margin-bottom: 1rem;
        font-size: 14px;
        transition: border-color 0.3s ease;
        outline: none;
    `;

            elements.locationInput.addEventListener('focus', () => {
                elements.locationInput.style.borderColor = CONFIG.COLORS.PRIMARY;
            });

            elements.locationInput.addEventListener('blur', () => {
                elements.locationInput.style.borderColor = '#ddd';
            });

            elements.controlBtn = this._createTextButton(
                '启动海投',
                `linear-gradient(45deg, ${CONFIG.COLORS.PRIMARY}, #4db6ac)`,
                () => {
                    toggleProcess();
                }
            );

            container.append(
                jobLabel,
                elements.filterInput,
                locationLabel,
                elements.locationInput,
                elements.controlBtn,
                utilGroup
            );

            return container;
        },



        // 创建日志区域
        _createLogger() {
            const log = document.createElement('div');
            log.id = 'pro-log';
            log.className = 'boss-log';
            log.style.cssText = `
                height: 200px;
                overflow-y: auto;
                background: #f8f9fa;
                border-radius: 10px;
                padding: 12px;
                border: 1px solid #eceff1;
                font-size: 13px;
                line-height: 1.5;
                margin-bottom: 1rem;
                transition: all 0.3s ease;
                user-select: text;
            `;

            log.innerHTML = `
                <div style="color:${CONFIG.COLORS.NEUTRAL}; margin-bottom:8px;">
                    请在BOSS中展示岗位列表,我将自动与这些岗位沟通。
                </div>
            `;

            return log;
        },

        // 创建底部版权信息
        _createFooter() {
            const footer = document.createElement('div');
            footer.textContent = '© 2025 Yangshengzhou · All Rights Reserved';
            footer.style.cssText = `
                text-align: center;
                font-size: 0.8em;
                color: ${CONFIG.COLORS.NEUTRAL};
                padding-top: 10px;
                border-top: 1px solid #eee;
                margin-top: auto;
                transition: color 0.3s ease;
            `;
            return footer;
        },

        // 创建文本按钮
        _createTextButton(text, bgColor, onClick) {
            const btn = document.createElement('button');
            btn.className = 'boss-btn';
            btn.textContent = text;
            btn.style.cssText = `
                width: 100%;
                padding: 12px 16px;
                background: ${bgColor};
                color: #fff;
                border: none;
                border-radius: 10px;
                cursor: pointer;
                font-size: 15px;
                font-weight: 500;
                transition: all 0.3s ease;
                display: flex;
                justify-content: center;
                align-items: center;
                box-shadow: 0 4px 10px rgba(0,0,0,0.1);
            `;

            btn.addEventListener('click', onClick);
            btn.addEventListener('mouseenter', () => {
                btn.style.transform = 'scale(1.03)';
                btn.style.boxShadow = '0 6px 15px rgba(0,0,0,0.15)';
            });
            btn.addEventListener('mouseleave', () => {
                btn.style.transform = 'scale(1)';
                btn.style.boxShadow = '0 4px 10px rgba(0,0,0,0.1)';
            });

            return btn;
        },

        // 创建图标按钮
        _createIconButton(icon, onClick) {
            const btn = document.createElement('button');
            btn.className = 'boss-icon-btn';
            btn.innerHTML = icon;
            btn.style.cssText = `
                width: 36px;
                height: 36px;
                border-radius: 50%;
                border: none;
                background: #f0f0f0;
                cursor: pointer;
                font-size: 18px;
                transition: all 0.2s ease;
                display: flex;
                justify-content: center;
                align-items: center;
                color: ${CONFIG.COLORS.PRIMARY};
                transform: translateY(8px);
            `;

            btn.addEventListener('click', onClick);
            btn.addEventListener('mouseenter', () => {
                btn.style.backgroundColor = CONFIG.COLORS.PRIMARY;
                btn.style.color = '#fff';
                btn.style.transform = 'translateY(8px) scale(1.1)';
            });
            btn.addEventListener('mouseleave', () => {
                btn.style.backgroundColor = '#f0f0f0';
                btn.style.color = CONFIG.COLORS.PRIMARY;
                btn.style.transform = 'translateY(8px)';
            });

            return btn;
        },

        // 设置面板可拖动功能
        _makeDraggable(panel) {
            const draggableAreaHeightRatio = 0.3;

            panel.addEventListener('mousemove', (e) => {
                const rect = panel.getBoundingClientRect();
                const relativeY = e.clientY - rect.top;
                const draggableHeight = rect.height * draggableAreaHeightRatio;

                if (relativeY <= draggableHeight) {
                    panel.style.cursor = 'move';
                } else {
                    panel.style.cursor = 'default';
                }
            });

            let isDragging = false;
            let startX = 0, startY = 0;
            let initialX = panel.offsetLeft, initialY = panel.offsetTop;

            panel.addEventListener('mousedown', (e) => {
                const rect = panel.getBoundingClientRect();
                const relativeY = e.clientY - rect.top;
                const draggableHeight = rect.height * draggableAreaHeightRatio;

                if (relativeY <= draggableHeight) {
                    isDragging = true;
                    startX = e.clientX;
                    startY = e.clientY;
                    initialX = panel.offsetLeft;
                    initialY = panel.offsetTop;
                    panel.style.transition = 'none';
                }
            });

            document.addEventListener('mousemove', (e) => {
                if (!isDragging) return;

                const dx = e.clientX - startX;
                const dy = e.clientY - startY;

                panel.style.left = `${initialX + dx}px`;
                panel.style.top = `${initialY + dy}px`;
                panel.style.right = 'auto';
            });

            document.addEventListener('mouseup', () => {
                if (isDragging) {
                    isDragging = false;
                    panel.style.transition = 'all 0.3s ease';
                }
            });
        },

        // 创建最小化图标
        createMiniIcon() {
            elements.miniIcon = document.createElement('div');
            elements.miniIcon.style.cssText = `
                width: ${CONFIG.MINI_ICON_SIZE}px;
                height: ${CONFIG.MINI_ICON_SIZE}px;
                position: fixed;
                bottom: 40px;
                left: 40px;
                background: linear-gradient(135deg, ${CONFIG.COLORS.PRIMARY}, #4db6ac);
                border-radius: 50%;
                box-shadow: 0 6px 16px rgba(33, 150, 243, 0.4);
                cursor: pointer;
                display: none;
                justify-content: center;
                align-items: center;
                color: #fff;
                font-size: 18px;
                z-index: 2147483647;
                transition: all 0.3s ease;
                overflow: hidden;
                text-align: center;
                line-height: 1;
            `;

            elements.miniIcon.innerHTML = '↗';

            elements.miniIcon.addEventListener('mouseenter', () => {
                elements.miniIcon.style.transform = 'scale(1.1)';
                elements.miniIcon.style.boxShadow = '0 8px 20px rgba(33, 150, 243, 0.5)';
            });

            elements.miniIcon.addEventListener('mouseleave', () => {
                elements.miniIcon.style.transform = 'scale(1)';
                elements.miniIcon.style.boxShadow = '0 6px 16px rgba(33, 150, 243, 0.4)';
            });

            elements.miniIcon.addEventListener('click', () => {
                state.isMinimized = false;
                elements.panel.style.transform = 'translateY(0)';
                elements.miniIcon.style.display = 'none';
            });

            document.body.appendChild(elements.miniIcon);
        },

        _createSettingsDialog() {
            const dialog = document.createElement('div');
            dialog.id = 'boss-settings-dialog';
            dialog.style.cssText = `
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 420px;
        background: #fff;
        border-radius: 12px;
        box-shadow: 0 10px 30px rgba(0,0,0,0.15);
        padding: 20px;
        z-index: 999999;
        display: none;
        flex-direction: column;
        gap: 12px;
        font-family: 'Segoe UI', sans-serif;
    `;

            // 标题
            const title = document.createElement('h4');
            title.textContent = '海投设置';
            title.style.marginTop = 0;
            title.style.color = CONFIG.COLORS.PRIMARY;

            // AI 人设输入框
            const roleLabel = document.createElement('label');
            roleLabel.textContent = 'AI 人设(如:“你是一位正在求职的资深全栈工程师”):';

            const roleInput = document.createElement('textarea');
            roleInput.id = 'ai-role-input';
            roleInput.rows = 4;
            roleInput.value = localStorage.getItem('aiRole') || '你是有工作经验的求职者,擅长交流。你会用一些口语化的表达(如“嗯”、“呃”)和语气词(如“啊”、“呢”),使对话听起来自然。遇到不清楚的问题,你会请求对方解释,确保准确理解。回复简洁明了,避免冗长复杂的句子结构。';
            roleInput.style.cssText = `
        width: 100%;
        padding: 10px;
        border-radius: 8px;
        border: 1px solid #ccc;
        resize: vertical;
        font-size: 13px;
        margin-bottom: 10px;
    `;

            // 保存按钮
            const saveBtn = this._createTextButton('保存设置', `linear-gradient(45deg, ${CONFIG.COLORS.PRIMARY}, #4db6ac)`, () => {
                const aiRole = roleInput.value.trim();
                if (aiRole) {
                    localStorage.setItem('aiRole', aiRole);
                    alert('设置保存成功!');
                    dialog.style.display = 'none';
                }
            });

            // 取消按钮
            const cancelBtn = this._createTextButton('取消', '#ccc', () => {
                dialog.style.display = 'none';
            });
            cancelBtn.style.marginLeft = '10px';

            const btnGroup = document.createElement('div');
            btnGroup.style.cssText = `
        display: flex;
        justify-content: flex-end;
        gap: 10px;
        margin-top: 10px;
    `;
            btnGroup.append(saveBtn, cancelBtn);

            // 前往 Gitee 按钮
            const giteeBtn = this._createTextButton('前往 Gitee 看源码', '#68130d', () => {
                window.open('https://gitee.com/Yangshengzhou', '_blank');
            });
            giteeBtn.style.width = '100%';
            giteeBtn.style.marginTop = '15px';

            // 插入元素
            dialog.append(title, roleLabel, roleInput, btnGroup, giteeBtn);

            return dialog;
        }
    };

    const Core = {
        async startProcessing() {
            if (location.pathname.includes('/jobs'))
                await this.autoScrollJobList();
            while (state.isRunning) {
                if (location.pathname.includes('/jobs'))
                    await this.processJobList();
                else if (location.pathname.includes('/chat'))
                    await this.handleChatPage();
                await this.delay(CONFIG.INTERVAL);
            }
        },

        async autoScrollJobList() {
            return new Promise((resolve) => {
                const cardSelector = 'li.job-card-box'; // 岗位卡片的选择器
                const maxHistory = 3; // 最大历史记录数,用于判断是否加载完成
                const waitTime = 550; // 等待时间(ms),每次滚动后等待的时间以便新内容加载
                let cardCountHistory = []; // 存储过去几次的岗位卡片数量
                let isStopped = false; // 标识是否应该停止滚动

                const scrollStep = async () => {
                    if (isStopped) return; // 如果标记为停止,则退出递归

                    window.scrollTo({
                        top: document.documentElement.scrollHeight,
                        behavior: 'smooth'
                    }); // 平滑滚动到底部

                    await this.delay(waitTime); // 等待指定时间让新内容加载

                    const cards = document.querySelectorAll(cardSelector); // 获取当前页面上所有岗位卡片
                    const currentCount = cards.length; // 当前岗位卡片的数量
                    cardCountHistory.push(currentCount); // 记录当前岗位卡片数量

                    if (cardCountHistory.length > maxHistory) cardCountHistory.shift(); // 维护历史记录长度

                    // 判断如果最近maxHistory次记录中的值都相同(即没有新岗位卡片加载进来)
                    if (cardCountHistory.length === maxHistory && new Set(cardCountHistory).size === 1) {
                        this.log("当前页面岗位加载完成,开始沟通");
                        resolve(cards); // 完成Promise,返回所有岗位卡片
                        return;
                    }

                    scrollStep(); // 递归调用自身,继续滚动
                };

                scrollStep(); // 开始首次滚动

                // 提供一个方法来从外部停止滚动
                this.stopAutoScroll = () => {
                    isStopped = true;
                    resolve(null);
                };
            });
        },

        // 点击Job页面的立即沟通按钮
        async processJobList() {
            state.jobList = Array.from(document.querySelectorAll('li.job-card-box'))
                .filter(card => {
                    const title = card.querySelector('.job-name')?.textContent?.toLowerCase() || '';
                    const location = card.querySelector('.company-location')?.textContent?.toLowerCase().trim() || '';

                    // 岗位名称匹配
                    const jobMatch = state.filterKeyword ?
                        state.filterKeyword.split(',').some(kw => title.includes(kw.trim())) :
                        true;

                    // 地区匹配(模糊包含)
                    const locationMatch = state.locationKeyword ?
                        state.locationKeyword.split(',').some(kw => location.includes(kw.trim())) :
                        true;

                    return jobMatch && locationMatch;
                });

            if (!state.jobList.length) {
                this.log('没有符合条件的职位');
                toggleProcess();
                return;
            }

            if (state.currentIndex >= state.jobList.length) {
                this.resetCycle();
                return;
            }

            const currentCard = state.jobList[state.currentIndex];
            currentCard.scrollIntoView({ behavior: 'smooth', block: 'center' });
            currentCard.click();
            this.log(`正在沟通:${++state.currentIndex}/${state.jobList.length}`);

            await this.delay(250);

            const chatBtn = document.querySelector('a.op-btn-chat');
            if (chatBtn) {
                const btnText = chatBtn.textContent.trim();
                if (btnText === '立即沟通') {
                    chatBtn.click();
                    await this.handleGreetingModal();
                }
            }
        },

        async handleGreetingModal() {
            await this.delay(200);

            const btn = [...document.querySelectorAll('.default-btn.cancel-btn')]
                .find(b => b.textContent.trim() === '留在此页');

            if (btn) {
                btn.click();
                await this.delay(200);
            }
        },

        async handleChatPage() {
            const chatList = await this.waitForElement('ul');

            if (!chatList) {
                this.log('没有聊天列表');
                return;
            }

            const observer = new MutationObserver(async () => {
                await this.clickLatestChat();
            });

            observer.observe(chatList, { childList: true });

            await this.clickLatestChat();
        },

        getLatestChatLi() {
            return document.querySelector('li[role="listitem"][class]:has(.friend-content-warp)');
        },
        async clickLatestChat() {
            try {
                const latestLi = await this.waitForElement(this.getLatestChatLi);
                if (!latestLi) return;

                const nameEl = latestLi.querySelector('.name-text');
                const companyEl = latestLi.querySelector('.name-box span:nth-child(2)');
                const name = (nameEl?.textContent || '未知').trim().replace(/\s+/g, ' ');
                const company = (companyEl?.textContent || '').trim().replace(/\s+/g, ' ');

                const hrKey = `${name}-${company}`.toLowerCase();

                if (state.currentTopHRKey === hrKey) return;
                state.currentTopHRKey = hrKey;

                if (state.processedHRs.has(hrKey)) {
                    this.log(`发过简历: ${name}${company ? ' - ' + company : ''}`);
                    const avatar = latestLi.querySelector('.figure');
                    await this.simulateClick(avatar);
                    latestLi.classList.add('last-clicked');
                    await this.aiReply();
                    return;
                }

                if (latestLi.classList.contains('last-clicked')) return;

                this.log(`开始沟通 ${name}${company ? ', 公司名: ' + company : ''}`);

                const avatar = latestLi.querySelector('.figure');
                await this.simulateClick(avatar);
                latestLi.classList.add('last-clicked');

                const isResumeSent = await this.processChatContent();
                if (isResumeSent) {
                    state.processedHRs.add(hrKey);
                    localStorage.setItem('processedHRs', JSON.stringify([...state.processedHRs]));
                }
            } catch (error) {
                this.log(`沟通出错: ${error.message}`);
            }
        },

        async aiReply() {
            try {
                await this.delay(100);
                const lastMessage = await this.getLastFriendMessageText();
                if (!lastMessage) return false;

                this.log(`对方: ${lastMessage}`);

                // AI回复
                const maxReplies = [5, 10].reduce((a, b) => a + b);
                if (state.aiReplyCount >= maxReplies) {
                    this.log('Ai回复已达上限,请开通会员')
                    return false;
                }

                const aiReplyText = await this.requestAi(lastMessage);
                if (!aiReplyText) return false;

                this.log(`AI回复: ${aiReplyText.slice(0, 30)}...`);
                state.aiReplyCount++;
                localStorage.setItem('aiReplyCount', state.aiReplyCount);
                localStorage.setItem('lastAiDate', state.lastAiDate);

                const inputBox = await this.waitForElement('#chat-input');
                if (!inputBox) return false;

                inputBox.textContent = '';
                inputBox.focus();
                document.execCommand('insertText', false, aiReplyText);
                await this.delay(120);

                const sendButton = document.querySelector('.btn-send');
                if (sendButton) {
                    await this.simulateClick(sendButton);
                } else {
                    const enterKeyEvent = new KeyboardEvent('keydown', {
                        key: 'Enter',
                        keyCode: 13,
                        code: 'Enter',
                        which: 13,
                        bubbles: true
                    });
                    inputBox.dispatchEvent(enterKeyEvent);
                }

                return true;
            } catch (error) {
                this.log(`AI回复出错: ${error.message}`);
                return false;
            }
        },

        async requestAi(a) {
            // 解码 Authorization Token
            const b = (function () {
                const c = [
                    0x73, 0x64, 0x56, 0x45, 0x44, 0x41, 0x42, 0x6a, 0x5a, 0x65, 0x49, 0x6b, 0x77,
                    0x58, 0x4e, 0x42, 0x46, 0x4e, 0x42, 0x73, 0x3a, 0x43, 0x71, 0x4d, 0x58, 0x6a,
                    0x71, 0x65, 0x50, 0x56, 0x43, 0x4a, 0x62, 0x55, 0x59, 0x4a, 0x50, 0x63, 0x69,
                    0x70, 0x4a
                ];
                return c.map(d => String.fromCharCode(d)).join('');
            })();

            // 解码 API 请求地址
            const d = (function () {
                const e = '68747470733a2f2f737061726b2d6170692d6f70656e2e78662d79756e2e636f6d2f76312f636861742f636f6d706c6574696f6e73';
                return e.replace(/../g, f => String.fromCharCode(parseInt(f, 16)));
            })();

            // 构建请求体
            const g = {
                model: 'lite',
                messages: [
                    {
                        role: 'system',
                        content: localStorage.getItem('aiRole') || '你是有工作经验的求职者,擅长交流。你会用一些口语化的表达(如“嗯”、“呃”)和语气词(如“啊”、“呢”),使对话听起来自然。遇到不清楚的问题,你会请求对方解释,确保准确理解。回复简洁明了,避免冗长复杂的句子结构。'
                    },
                    {
                        role: 'user',
                        content: a
                    }
                ],
                temperature: 0.9,
                top_p: 0.8,
                max_tokens: 512
            };

            return new Promise((h, i) => {
                GM_xmlhttpRequest({
                    method: 'POST',
                    url: d,
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': 'Bearer ' + b
                    },
                    data: JSON.stringify(g),
                    onload: (j) => {
                        console.log('API响应:', j.responseText);
                        try {
                            const k = JSON.parse(j.responseText);
                            if (k.code !== 0) {
                                throw new Error('API错误: ' + k.message + '(Code: ' + k.code + ')');
                            }
                            h(k.choices[0].message.content.trim());
                        } catch (l) {
                            i(new Error('响应解析失败: ' + l.message + '\n原始响应: ' + j.responseText));
                        }
                    },
                    onerror: (m) => {
                        i(new Error('网络请求失败: ' + m));
                    }
                });
            });
        },

        async getLastFriendMessageText() {
            try {
                await this.delay(120);

                const chatContainer = document.querySelector('.chat-message .im-list');
                if (!chatContainer) return null;

                const messageItems = Array.from(chatContainer.querySelectorAll('li.message-item'));
                const friendMessages = messageItems.filter(item =>
                    item.classList.contains('item-friend')
                );

                if (friendMessages.length === 0) return null;

                const lastFriendMessage = friendMessages[friendMessages.length - 1];
                const spanEl = lastFriendMessage.querySelector('.text span');

                if (!spanEl) return null;

                const textContent = spanEl.textContent.trim();
                return textContent;
            } catch (error) {
                return null;
            }
        },

        async processChatContent() {
            try {
                await this.delay(100);

                // 点击“常用语”按钮
                const dictBtn = await this.waitForElement('.btn-dict');
                if (!dictBtn) {
                    this.log('未找到常用语按钮');
                    return false;
                }
                await this.simulateClick(dictBtn);
                await this.delay(100);

                // 查找常用语列表
                const dictList = await this.waitForElement('ul[data-v-8e790d94=""]');
                if (!dictList) {
                    this.log('未找到常用语列表');
                    return false;
                }

                const dictItems = dictList.querySelectorAll('li');
                if (!dictItems || dictItems.length === 0) {
                    this.log('常用语列表为空');
                    return false;
                }

                // 遍历并点击每条常用语
                for (let i = 0; i < dictItems.length; i++) {
                    const item = dictItems[i];
                    this.log(`发送常用语:第${i + 1}条/共${dictItems.length}条`);
                    await this.simulateClick(item);
                    await this.delay(100);
                }

                // 查找“发简历”按钮
                const resumeBtn = await this.waitForElement(() => {
                    return [...document.querySelectorAll('.toolbar-btn')].find(
                        el => el.textContent.trim() === '发简历'
                    );
                });

                if (!resumeBtn) {
                    this.log('无法发送简历');
                    return false;
                }

                if (resumeBtn.classList.contains('unable')) {
                    this.log('对方未回复,您无权发送简历');
                    return false;
                }

                // 点击“发简历”
                await this.simulateClick(resumeBtn);
                await this.delay(160);

                // 查找确认发送按钮
                const confirmBtn = await this.waitForElement('span.btn-sure-v2');
                if (!confirmBtn) {
                    this.log('未找到发送按钮');
                    return false;
                }

                await this.simulateClick(confirmBtn);

                return true;

            } catch (error) {
                this.log(`处理出错: ${error.message}`);
                return false;
            }
        },

        async simulateClick(element) {
            if (!element) return;

            const rect = element.getBoundingClientRect();
            const x = rect.left + rect.width / 2;
            const y = rect.top + rect.height / 2;

            const dispatchMouseEvent = (type, options = {}) => {
                const event = new MouseEvent(type, {
                    bubbles: true,
                    cancelable: true,
                    view: document.defaultView,
                    clientX: x,
                    clientY: y,
                    ...options
                });
                element.dispatchEvent(event);
            };

            dispatchMouseEvent('mouseover');
            await this.delay(30);

            dispatchMouseEvent('mousemove');
            await this.delay(30);

            dispatchMouseEvent('mousedown', { button: 0 });
            await this.delay(30);

            dispatchMouseEvent('mouseup', { button: 0 });
            await this.delay(30);

            dispatchMouseEvent('click', { button: 0 });
        },

        async waitForElement(selectorOrFunction, timeout = 5000) {
            return new Promise((resolve) => {
                let element;
                if (typeof selectorOrFunction === 'function') {
                    element = selectorOrFunction();
                } else {
                    element = document.querySelector(selectorOrFunction);
                }

                if (element) {
                    return resolve(element);
                }

                const timeoutId = setTimeout(() => {
                    observer.disconnect();
                    resolve(null);
                }, timeout);

                const observer = new MutationObserver(() => {
                    if (typeof selectorOrFunction === 'function') {
                        element = selectorOrFunction();
                    } else {
                        element = document.querySelector(selectorOrFunction);
                    }

                    if (element) {
                        clearTimeout(timeoutId);
                        observer.disconnect();
                        resolve(element);
                    }
                });

                observer.observe(document.body, { childList: true, subtree: true });
            });
        },

        async delay(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        },

        resetCycle() {
            toggleProcess();
            this.log('所有岗位沟通完成,恭喜你即将找到理想工作!');
            state.currentIndex = 0;
            state.lastMessageTime = 0;
        },

        log(message) {
            const logEntry = `[${new Date().toLocaleTimeString()}] ${message}`;
            const logPanel = document.querySelector('#pro-log');

            if (logPanel) {
                const logItem = document.createElement('div');
                logItem.className = 'log-item';
                logItem.textContent = logEntry;
                logPanel.appendChild(logItem);
                logPanel.scrollTop = logPanel.scrollHeight;
            }
        }
    };

    /**
     * 切换海投助手的运行状态:启动或停止处理流程
     */
    function toggleProcess() {
        // 反转当前运行状态
        state.isRunning = !state.isRunning;

        if (state.isRunning) {
            // 如果是启动状态,则进行初始化设置并开始处理

            // 获取用户输入的关键字并转换为小写用于匹配
            state.filterKeyword = elements.filterInput.value.trim().toLowerCase();
            state.locationKeyword = elements.locationInput.value.trim().toLowerCase();

            // 更新按钮文本和样式
            elements.controlBtn.textContent = '停止海投';
            elements.controlBtn.style.backgroundColor = CONFIG.COLORS.SECONDARY;

            // 调用核心处理模块的启动方法
            Core.startProcessing();
        } else {
            // 如果是停止状态,则进行清理操作

            // 更新按钮文本和样式
            elements.controlBtn.textContent = '启动海投';
            elements.controlBtn.style.backgroundColor = CONFIG.COLORS.PRIMARY;

            // 强制将运行状态设为 false(虽然上面已经反转过)
            state.isRunning = false;

            // 清除本地存储中已处理的 HR 记录
            localStorage.removeItem('processedHRs');

            // 重置内存中的已处理记录集合
            state.processedHRs = new Set();
        }
    }

    /**
     * 显示一个自定义的弹窗提示框
     * @param {string} message - 要显示的消息内容(支持换行)
     */
    function showCustomAlert(message) {
        // 创建遮罩层
        const overlay = document.createElement('div');
        overlay.id = 'custom-alert-overlay';
        overlay.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.5);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 9999;
        backdrop-filter: blur(3px);
        animation: fadeIn 0.3s ease-out;
    `;

        // 创建弹窗主体容器
        const dialog = document.createElement('div');
        dialog.id = 'custom-alert-dialog';
        dialog.style.cssText = `
        background: white;
        border-radius: 16px;
        box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
        width: 90%;
        max-width: 400px;
        overflow: hidden;
        transform: scale(0.95);
        animation: scaleIn 0.3s ease-out forwards;
    `;

        // 创建标题栏
        const header = document.createElement('div');
        header.style.cssText = `
        padding: 16px 24px;
        background: #2196f3;
        color: white;
        font-size: 18px;
        font-weight: 500;
        display: flex;
        justify-content: space-between;
        align-items: center;
    `;
        header.innerHTML = `<span>BOSS海投助手</span><i class="fa fa-bolt" style="color: #ffeb3b;"></i>`;

        // 创建内容区域
        const content = document.createElement('div');
        content.style.cssText = `
        padding: 24px;
        font-size: 16px;
        line-height: 1.8;
        color: #333;
    `;
        content.innerHTML = message.replace(/\n/g, '<br>'); // 支持换行符转换为 <br>

        // 创建底部按钮区域
        const footer = document.createElement('div');
        footer.style.cssText = `
        padding: 12px 24px;
        display: flex;
        justify-content: center;
        border-top: 1px solid #eee;
    `;

        // 创建确认按钮
        const confirmBtn = document.createElement('button');
        confirmBtn.style.cssText = `
        background: #2196f3;
        color: white;
        border: none;
        border-radius: 8px;
        padding: 10px 24px;
        font-size: 16px;
        cursor: pointer;
        transition: all 0.3s;
        box-shadow: 0 4px 12px rgba(33, 150, 243, 0.4);
    `;
        confirmBtn.textContent = '开始使用';

        // 点击确认按钮后关闭弹窗
        confirmBtn.addEventListener('click', () => {
            overlay.remove();
        });

        // 悬浮动画效果
        confirmBtn.addEventListener('mouseenter', () => {
            confirmBtn.style.transform = 'translateY(-2px)';
            confirmBtn.style.boxShadow = '0 6px 16px rgba(33, 150, 243, 0.5)';
        });

        // 移出鼠标恢复样式
        confirmBtn.addEventListener('mouseleave', () => {
            confirmBtn.style.transform = 'translateY(0)';
            confirmBtn.style.boxShadow = '0 4px 12px rgba(33, 150, 243, 0.4)';
        });

        // 将按钮加入底部区域
        footer.appendChild(confirmBtn);

        // 组装弹窗结构
        dialog.appendChild(header);
        dialog.appendChild(content);
        dialog.appendChild(footer);

        // 将弹窗加入遮罩层
        overlay.appendChild(dialog);

        // 插入到页面中
        document.body.appendChild(overlay);

        // 添加关键帧动画样式
        const style = document.createElement('style');
        style.textContent = `
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }

        @keyframes scaleIn {
            from {
                transform: scale(0.95);
                opacity: 0;
            }
            to {
                transform: scale(1);
                opacity: 1;
            }
        }
    `;
        document.head.appendChild(style);
    }

    function showCustomAlert() {
        // 创建遮罩层
        const overlay = document.createElement("div");
        overlay.id = "custom-alert-overlay";
        overlay.style.cssText = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0,0,0,0.7);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 9999;
        backdrop-filter: blur(5px);
        animation: fadeIn 0.3s ease-out;
    `;

        // 创建信封容器
        const envelopeContainer = document.createElement("div");
        envelopeContainer.id = "envelope-container";
        envelopeContainer.style.cssText = `
        position: relative;
        width: 90%;
        max-width: 500px;
        height: 350px;
        perspective: 1000px;
    `;

        // 创建信封主体
        const envelope = document.createElement("div");
        envelope.id = "envelope";
        envelope.style.cssText = `
        position: absolute;
        width: 100%;
        height: 100%;
        transform-style: preserve-3d;
        transition: transform 0.6s ease;
    `;

        // 创建信封背面(封面)
        const envelopeBack = document.createElement("div");
        envelopeBack.id = "envelope-back";
        envelopeBack.style.cssText = `
        position: absolute;
        width: 100%;
        height: 100%;
        background: #f8f9fa;
        border-radius: 10px;
        box-shadow: 0 15px 35px rgba(0,0,0,0.2);
        backface-visibility: hidden;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 30px;
        cursor: pointer;
        transition: all 0.3s;
    `;
        envelopeBack.innerHTML = `
        <div style="font-size:24px;font-weight:600;color:#2196f3;margin-bottom:10px;">
            <i class="fa fa-envelope-o mr-2"></i>致海投用户的一封信
        </div>
        <div style="font-size:16px;color:#666;text-align:center;">
            点击加速您的求职之旅
        </div>
        <div style="position:absolute;bottom:20px;font-size:14px;color:#999;">
            © 2025 BOSS海投助手 | Yangshengzhou 版权所有
        </div>
    `;
        envelopeBack.addEventListener("click", () => {
            envelope.style.transform = "rotateY(180deg)";
            setTimeout(() => {
                document.getElementById("letter-content").style.display = "block";
                document.getElementById("letter-content").style.animation = "fadeInUp 0.5s ease-out forwards";
            }, 300);
        });

        // 创建信封正面(打开后的内容页)
        const envelopeFront = document.createElement("div");
        envelopeFront.id = "envelope-front";
        envelopeFront.style.cssText = `
        position: absolute;
        width: 100%;
        height: 100%;
        background: #fff;
        border-radius: 10px;
        box-shadow: 0 15px 35px rgba(0,0,0,0.2);
        transform: rotateY(180deg);
        backface-visibility: hidden;
        display: flex;
        flex-direction: column;
    `;

        // 创建标题栏
        const titleBar = document.createElement("div");
        titleBar.style.cssText = `
        padding: 20px 30px;
        background: #2196f3;
        color: white;
        font-size: 20px;
        font-weight: 600;
        border-radius: 10px 10px 0 0;
        display: flex;
        align-items: center;
    `;
        titleBar.innerHTML = `<i class="fa fa-envelope-open-o mr-2"></i>致海投助手用户:`;

        // 创建信件内容区域
        const letterContent = document.createElement("div");
        letterContent.id = "letter-content";
        letterContent.style.cssText = `
        flex: 1;
        padding: 15px;
        overflow-y: auto;
        font-size: 16px;
        line-height: 1.8;
        color: #333;
        background: url('https://picsum.photos/id/1068/1000/1000') center / cover no-repeat;
        background-blend-mode: overlay;
        background-color: rgba(255,255,255,0.95);
        display: none;
    `;
        letterContent.innerHTML = `
        <div style="margin-bottom:20px;">
            <p>亲爱的朋友:</p>
            <p class="mt-3">&emsp;&emsp;见字如面,展信佳。</p>
            <p class="mt-3">
                &emsp;&emsp;我是Yangshengzhou,一个找实习近崩溃的学生,也是海投插件的作者。
                还记得我第一次投简历的场景:期待、不安和憧憬。
                后来,我在无数深夜里反复打磨简历、通勤路上刷招聘App,
                效率低到崩溃————这便是海投助手诞生的初衷。
            </p>
            <p class="mt-3">
                &emsp;&emsp;经济下行,求职像在漫漫黑夜里跑马拉松。
                但请相信,你从来不是孤军奋战。
                这个免费的小工具,愿能成为你路上的烛光:
            </p>
            <ul class="mt-2 ml-5 list-disc" style="text-indent:0;">
                <li>&emsp;&emsp;海投助手会自动发送简历和自我介绍,接入AI回复HR。</li>
                <li>&emsp;&emsp;如果能给我一个5星好评,我将感激不尽。</li>
            </ul>
            <p class="mt-3">
                &emsp;&emsp;求职路上的每一次开始,都是向理想靠近的脚印。
                也许现在的你正迷茫,但那些看似波澜不惊的日复一日,
                终将某一天让你看见坚持的意义。
            </p>
            <p class="mt-3">
                &emsp;&emsp;点击"开始使用",把焦虑交给代码,把希望留给自己。
                愿你能收到心仪的offer,让所有努力都有回响。
            </p>
        </div>
        <div style="text-align:right;font-style:italic;color:#666;text-indent:0;">
            2025年5月11日凌晨<br>
            Yangshengzhou<br>
        </div>
    `;

        // 创建按钮区域
        const buttonArea = document.createElement("div");
        buttonArea.style.cssText = `
        padding: 20px 30px;
        display: flex;
        justify-content: center;
        border-top: 1px solid #eee;
        background: #f8f9fa;
        border-radius: 0 0 10px 10px;
    `;

        // 创建“开始使用”按钮
        const startButton = document.createElement("button");
        startButton.style.cssText = `
        background: linear-gradient(135deg, #2196f3, #1976d2);
        color: white;
        border: none;
        border-radius: 8px;
        padding: 12px 30px;
        font-size: 16px;
        font-weight: 500;
        cursor: pointer;
        transition: all 0.3s;
        box-shadow: 0 6px 16px rgba(33,150,243,0.3);
        outline: none;
        display: flex;
        align-items: center;
    `;
        startButton.innerHTML = `<i class="fa fa-rocket mr-2"></i>开始使用`;
        startButton.addEventListener("click", () => {
            envelopeContainer.style.animation = "scaleOut 0.3s ease-in forwards";
            overlay.style.animation = "fadeOut 0.3s ease-in forwards";
            setTimeout(() => {
                overlay.remove();
                if (location.pathname.includes("/chat")) {
                    UI.createControlPanel();
                    UI.createMiniIcon();
                }
            }, 300);
        });

        // 将按钮插入按钮区域
        buttonArea.appendChild(startButton);

        // 构建信封正面结构
        envelopeFront.appendChild(titleBar);
        envelopeFront.appendChild(letterContent);
        envelopeFront.appendChild(buttonArea);

        // 把封面和内页加入信封
        envelope.appendChild(envelopeBack);
        envelope.appendChild(envelopeFront);

        // 把信封放入信封容器中
        envelopeContainer.appendChild(envelope);

        // 把信封容器放入遮罩层
        overlay.appendChild(envelopeContainer);

        // 把遮罩层插入页面
        document.body.appendChild(overlay);

        // 添加动画样式
        const style = document.createElement("style");
        style.textContent = `
        @keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
        @keyframes fadeOut { from { opacity: 1 } to { opacity: 0 } }
        @keyframes scaleOut { from { transform: scale(1); opacity: 1 } to { transform: scale(.9); opacity: 0 } }
        @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px) } to { opacity: 1; transform: translateY(0) } }

        #envelope-back:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 40px rgba(0,0,0,0.25);
        }

        #envelope-front button:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 20px rgba(33,150,243,0.4);
        }

        #envelope-front button:active {
            transform: translateY(1px);
        }
    `;
        document.head.appendChild(style);
    }

    function init() {
        // 获取当前时间
        const now = new Date();

        // 计算到午夜的时间
        const night = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 0, 0, 0);
        const msToMidnight = night - now;

        // 设置定时器,在午夜清除 localStorage 中的特定项
        setTimeout(() => {
            localStorage.removeItem('aiReplyCount');
            localStorage.removeItem('lastAiDate');
            localStorage.removeItem('hasShownLetterToday');
            localStorage.removeItem('letterLastShown');
        }, msToMidnight);

        // 创建控制面板和最小化图标
        UI.createControlPanel();
        UI.createMiniIcon();

        // 设置 body 的 position 属性为 relative
        document.body.style.position = 'relative';

        // 检查是否今天已显示过信件
        const today = new Date().toISOString().split('T')[0]; // 格式:YYYY-MM-DD
        const lastShown = localStorage.getItem('letterLastShown');

        function showLetterOncePerDay() {
            if (lastShown !== today) {
                // 第一次运行或不是今天
                showCustomAlert();

                // 更新本地存储记录
                localStorage.setItem('letterLastShown', today);
            }
        }

        // 根据当前页面路径执行不同操作
        if (location.pathname.includes('/jobs')) {
            // 如果在 /jobs 页面,询问是否打开chat窗口
            const confirmOpen = confirm("海投插件可以自动回复HR信息,是否需要打开聊天页面?");
            if (confirmOpen) {
                window.open('https://www.zhipin.com/web/geek/chat', '_blank');
            }
        } else if (location.pathname.includes('/chat')) {
            // 如果在 /chat 页面:
            // 1. 显示至用户的一封信
            showLetterOncePerDay();

            // 2. 禁用输入框
            if (elements.filterInput) {
                elements.filterInput.disabled = true;
                elements.filterInput.placeholder = '聊天页面岗位筛选功能无效';
                elements.filterInput.title = "当前页面该功能无效";
            }
            if (elements.locationInput) {
                elements.locationInput.disabled = true;
                elements.locationInput.placeholder = '聊天页面地点筛选功能无效';
                elements.locationInput.title = "当前页面该功能无效";
            }

            Core.log('在聊天页面,海投插件能自动发送您的自我介绍(常用语)和简历,之后用AI智能回复HR的消息。');
        }
    }

    // 当页面加载完成后调用 init 函数
    window.addEventListener('load', init);

})();