// ==UserScript== // @name BOSS快投 // @namespace https://gitee.com/yangshengzhou // @version 1.0.0 // @description BOSS快投&BOSS海投助手 - BOSS直聘官方认证求职工具,微软/谷歌/360/联想联合审核上架,安全合规不封号!一键批量投递沟通,自动发简历、智能关键词筛选、HR活跃排序、防重复投递,求职效率提升10倍,找工作必备神器! // @author Yangshengzhou // @icon https://www.zhipin.com/desktop/images/favicon.ico // @match https://www.zhipin.com/web/geek/jobs* // @match https://zhipin.com/web/geek/jobs* // @grant none // @license MIT // ==/UserScript== (function () { "use strict"; const CONFIG = { BASIC_INTERVAL: 1000, OPERATION_INTERVAL: 1200, DELAYS: { SHORT: 30, MEDIUM_SHORT: 200, }, UI: { ANIMATION_DURATION: 300, DEBOUNCE_DELAY: 300 }, STORE_URL: 'https://microsoftedge.microsoft.com/addons/detail/boss%E5%BF%AB%E6%8A%95/eliaelcadhfbmeijgflobgkkomolaoog' }; const state = { isRunning: false, currentIndex: 0, jobList: [], ui: { isMinimized: false, }, }; const elements = { panel: null, controlBtn: null, log: null, miniIcon: null, }; const UI = { PAGE_TYPES: { JOB_LIST: "jobList", }, currentPageType: "jobList", init() { this.currentPageType = this.PAGE_TYPES.JOB_LIST; this._applyTheme(); this.createControlPanel(); this.createMiniIcon(); }, createControlPanel() { if (document.getElementById("boss-pro-panel")) { document.getElementById("boss-pro-panel").remove(); } elements.panel = this._createPanel(); const header = this._createHeader(); const controls = this._createJobListControls(); 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); }, _applyTheme() { document.documentElement.style.setProperty("--primary-color", "#2563eb"); document.documentElement.style.setProperty("--secondary-color", "#f8fafc"); document.documentElement.style.setProperty("--accent-color", "#dbeafe"); document.documentElement.style.setProperty("--neutral-color", "#64748b"); this._injectGlobalScrollbarStyles(); }, _injectGlobalScrollbarStyles() { if (document.getElementById('boss-global-scrollbar-styles')) { return; } const style = document.createElement('style'); style.id = 'boss-global-scrollbar-styles'; style.textContent = ` #boss-pro-panel::-webkit-scrollbar, #boss-pro-panel *::-webkit-scrollbar, #pro-log::-webkit-scrollbar, #pro-log *::-webkit-scrollbar { width: 6px !important; height: 6px !important; } #boss-pro-panel::-webkit-scrollbar-track, #boss-pro-panel *::-webkit-scrollbar-track, #pro-log::-webkit-scrollbar-track, #pro-log *::-webkit-scrollbar-track { background: transparent !important; } #boss-pro-panel::-webkit-scrollbar-thumb, #boss-pro-panel *::-webkit-scrollbar-thumb, #pro-log::-webkit-scrollbar-thumb, #pro-log *::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.15) !important; border-radius: 3px !important; } #boss-pro-panel::-webkit-scrollbar-thumb:hover, #boss-pro-panel *::-webkit-scrollbar-thumb:hover, #pro-log::-webkit-scrollbar-thumb:hover, #pro-log *::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.25) !important; } #boss-pro-panel::-webkit-scrollbar-thumb:active, #boss-pro-panel *::-webkit-scrollbar-thumb:active, #pro-log::-webkit-scrollbar-thumb:active, #pro-log *::-webkit-scrollbar-thumb:active { background: rgba(0, 0, 0, 0.35) !important; } #boss-pro-panel::-webkit-scrollbar-corner, #boss-pro-panel *::-webkit-scrollbar-corner, #pro-log::-webkit-scrollbar-corner, #pro-log *::-webkit-scrollbar-corner { background: transparent !important; } #boss-pro-panel, #boss-pro-panel *, #pro-log, #pro-log * { scrollbar-width: thin !important; scrollbar-color: rgba(0, 0, 0, 0.15) transparent !important; } `; document.head.appendChild(style); }, _createPanel() { const panel = document.createElement("div"); panel.id = "boss-pro-panel"; panel.className = "boss-joblist-panel"; const baseStyles = ` position: fixed; top: 32px; right: 20px; width: clamp(300px, 80vw, 380px); border-radius: 16px; padding: 14px; font-family: 'Segoe UI', system-ui, sans-serif; z-index: 2147483647; display: flex; flex-direction: column; transition: all 0.3s ease; background: #ffffff; box-shadow: 0 8px 24px rgba(var(--primary-rgb), 0.12); border: 1px solid var(--accent-color); cursor: default; `; panel.style.cssText = baseStyles; const rgbColor = this._hexToRgb("#2563eb"); document.documentElement.style.setProperty("--primary-rgb", rgbColor); return panel; }, _createHeader() { const header = document.createElement("div"); header.className = "boss-header"; header.style.cssText = ` display: flex; justify-content: space-between; align-items: center; padding: 0 10px 15px; margin-bottom: 15px; border-bottom: 1px solid var(--accent-color); `; const title = this._createTitle(); const buttonContainer = document.createElement("div"); buttonContainer.style.cssText = ` display: flex; gap: 8px; align-items: center; `; const storeBtn = this._createStoreIconButton(); const closeBtn = this._createIconButton( "✕", () => { state.ui.isMinimized = true; elements.panel.style.transform = "translateY(160%)"; elements.miniIcon.style.display = "flex"; }, "最小化快投面板" ); buttonContainer.append(storeBtn, closeBtn); header.append(title, buttonContainer); return header; }, _createStoreIconButton() { const svgContent = ``; const btn = document.createElement("a"); btn.href = CONFIG.STORE_URL; btn.target = "_blank"; btn.rel = "noopener"; btn.title = "前往扩展商店安装正式版(更多功能)"; btn.className = "boss-icon-btn"; btn.innerHTML = svgContent; btn.style.cssText = ` width: 30px; height: 30px; border-radius: 50%; border: none; background: var(--accent-color); cursor: pointer; font-size: 15px; transition: all 0.2s ease; display: flex; justify-content: center; align-items: center; color: var(--primary-color); text-decoration: none; `; const pathEl = btn.querySelector("path"); pathEl.setAttribute("fill", "#2563eb"); btn.addEventListener("mouseenter", () => { btn.style.backgroundColor = "var(--primary-color)"; pathEl.setAttribute("fill", "#ffffff"); }); btn.addEventListener("mouseleave", () => { btn.style.backgroundColor = "var(--accent-color)"; pathEl.setAttribute("fill", "#2563eb"); }); return btn; }, _createIconButton(icon, onClick, title) { const btn = document.createElement("button"); btn.className = "boss-icon-btn"; btn.innerHTML = icon; btn.title = title; btn.style.cssText = ` width: 30px; height: 30px; border-radius: 50%; border: none; background: var(--accent-color); cursor: pointer; font-size: 15px; transition: all 0.2s ease; display: flex; justify-content: center; align-items: center; color: var(--primary-color); `; btn.addEventListener("click", onClick); btn.addEventListener("mouseenter", () => { btn.style.backgroundColor = "var(--primary-color)"; btn.style.color = "#fff"; }); btn.addEventListener("mouseleave", () => { btn.style.backgroundColor = "var(--accent-color)"; btn.style.color = "var(--primary-color)"; }); return btn; }, _createTitle() { const title = document.createElement("div"); title.style.display = "flex"; title.style.alignItems = "center"; title.style.gap = "10px"; const customSvg = ` `; const titleConfig = { main: `BOSS快投`, sub: "高效求职,智能投递", }; title.innerHTML = `
${customSvg}

${titleConfig.main}

${titleConfig.sub}
`; return title; }, _createJobListControls() { const container = document.createElement("div"); container.className = "boss-joblist-controls"; container.style.marginBottom = "12px"; container.style.padding = "0 8px"; const filterContainer = document.createElement("div"); filterContainer.style.cssText = ` background: var(--secondary-color); border-radius: 12px; padding: 14px; margin-bottom: 0px; `; elements.controlBtn = this._createTextButton( "启动快投", "var(--primary-color)", () => { toggleProcess(); } ); filterContainer.append(elements.controlBtn); container.append(filterContainer); return container; }, _createLogger() { const log = document.createElement("div"); log.id = "pro-log"; log.className = "boss-joblist-log"; const height = "260px"; log.style.cssText = ` height: ${height}; overflow-y: auto; background: var(--secondary-color); border-radius: 12px; padding: 12px; font-size: 13px; line-height: 1.5; margin-bottom: 15px; margin-left: 10px; margin-right: 10px; transition: all 0.3s ease; user-select: text; `; return log; }, _createFooter() { const footer = document.createElement("div"); footer.className = "boss-joblist-footer"; footer.style.cssText = ` text-align: center; font-size: 0.8em; color: var(--neutral-color); padding-top: 15px; border-top: 1px solid var(--accent-color); margin-top: auto; padding: 0px; `; footer.append( document.createTextNode(`© ${new Date().getFullYear()} Yangshengzhou · All Rights Reserved`) ); return footer; }, _createTextButton(text, bgColor, onClick) { const btn = document.createElement("button"); btn.className = "boss-btn"; btn.textContent = text; btn.style.cssText = ` width: 100%; padding: 11px 16px; background: ${bgColor}; color: #fff; border: none; border-radius: 10px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.2s ease; display: flex; justify-content: center; align-items: center; box-shadow: 0 2px 8px rgba(0,0,0,0.08); transform: translateY(0px); margin: 0 auto; `; this._addButtonHoverEffects(btn); btn.addEventListener("click", onClick); return btn; }, _createIconButton(icon, onClick, title) { const btn = document.createElement("button"); btn.className = "boss-icon-btn"; btn.innerHTML = icon; btn.title = title; btn.style.cssText = ` width: 30px; height: 30px; border-radius: 50%; border: none; background: var(--accent-color); cursor: pointer; font-size: 15px; transition: all 0.2s ease; display: flex; justify-content: center; align-items: center; color: var(--primary-color); `; btn.addEventListener("click", onClick); btn.addEventListener("mouseenter", () => { btn.style.backgroundColor = "var(--primary-color)"; btn.style.color = "#fff"; }); btn.addEventListener("mouseleave", () => { btn.style.backgroundColor = "var(--accent-color)"; btn.style.color = "var(--primary-color)"; }); return btn; }, _addButtonHoverEffects(btn) { btn.addEventListener("mouseenter", () => { btn.style.boxShadow = `0 6px 15px rgba(var(--primary-rgb), 0.3)`; }); btn.addEventListener("mouseleave", () => { btn.style.boxShadow = "0 4px 10px rgba(0,0,0,0.1)"; }); }, _makeDraggable(panel) { const header = panel.querySelector(".boss-header"); if (!header) return; header.style.cursor = "move"; let isDragging = false; let startX = 0, startY = 0; let initialX = panel.offsetLeft, initialY = panel.offsetTop; header.addEventListener("mousedown", (e) => { isDragging = true; startX = e.clientX; startY = e.clientY; initialX = panel.offsetLeft; initialY = panel.offsetTop; panel.style.transition = "none"; panel.style.zIndex = "2147483647"; }); 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"; panel.style.zIndex = "2147483646"; } }); }, createMiniIcon() { const sideEntry = document.querySelector(".zp-side-entry"); elements.miniIcon = document.createElement("div"); elements.miniIcon.id = "boss-quick-deliver-mini"; elements.miniIcon.title = "BOSS快投"; elements.miniIcon.style.cssText = ` width: 48px; height: 48px; cursor: pointer; display: none; justify-content: center; align-items: center; transition: all 0.3s ease; position: relative; `; const innerDiv = document.createElement("div"); innerDiv.className = "side-entry2-inner-boss"; innerDiv.style.cssText = ` width: 48px; height: 48px; background: var(--primary-color); border-radius: 50%; box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.4); display: flex; justify-content: center; align-items: center; color: #fff; overflow: hidden; `; const customSvg = ` `; innerDiv.innerHTML = customSvg; elements.miniIcon.appendChild(innerDiv); elements.miniIcon.addEventListener("mouseenter", () => { innerDiv.style.boxShadow = "0 6px 16px rgba(var(--primary-rgb), 0.5)"; }); elements.miniIcon.addEventListener("mouseleave", () => { innerDiv.style.boxShadow = "0 4px 12px rgba(var(--primary-rgb), 0.4)"; }); elements.miniIcon.addEventListener("click", () => { state.ui.isMinimized = false; elements.panel.style.transform = "translateY(0)"; elements.miniIcon.style.display = "none"; }); if (sideEntry) { const entryDiv = document.createElement("div"); entryDiv.className = "zp-side-entry-question side-entry boss-quick-deliver-entry"; entryDiv.style.cssText = ` display: flex; flex-direction: column; align-items: center; gap: 1px; `; const secondEntry = document.createElement("div"); secondEntry.className = "side-second-entry"; secondEntry.style.cssText = ` display: flex; flex-direction: column; gap: 1px; `; elements.miniIcon.className = "side-entry2"; secondEntry.appendChild(elements.miniIcon); entryDiv.appendChild(secondEntry); sideEntry.appendChild(entryDiv); } else { elements.miniIcon.style.position = "fixed"; elements.miniIcon.style.right = "30px"; elements.miniIcon.style.bottom = "150px"; elements.miniIcon.style.zIndex = "2147483647"; document.body.appendChild(elements.miniIcon); } }, _hexToRgb(hex) { hex = hex.replace("#", ""); const r = parseInt(hex.substring(0, 2), 16); const g = parseInt(hex.substring(2, 4), 16); const b = parseInt(hex.substring(4, 6), 16); return `${r}, ${g}, ${b}`; }, }; const Core = { CONFIG, processedCards: new Set(), processedJobNames: [], domCache: {}, getCachedElement(selector, forceRefresh = false) { if (forceRefresh || !this.domCache[selector]) { this.domCache[selector] = document.querySelector(selector); } return this.domCache[selector]; }, async startProcessing() { while (state.isRunning) { await this.processJobList(); await this.delay(CONFIG.BASIC_INTERVAL); } }, getCardKey(card) { const jobLink = card.querySelector(".job-name"); return jobLink ? jobLink.href : card.innerText.slice(0, 50); }, getFilteredCards() { const allCards = Array.from(document.querySelectorAll("li.job-card-box")); return allCards.filter((card) => { const cardKey = this.getCardKey(card); return !this.processedCards.has(cardKey); }); }, async processJobList() { const filteredCards = this.getFilteredCards(); if (filteredCards.length === 0) { const beforeCount = document.querySelectorAll("li.job-card-box").length; window.scrollTo({ top: document.documentElement.scrollHeight, behavior: "smooth" }); await this.delay(CONFIG.BASIC_INTERVAL * 2); const afterCount = document.querySelectorAll("li.job-card-box").length; const newFiltered = this.getFilteredCards(); if (afterCount <= beforeCount && newFiltered.length === 0) { this.resetCycle(); this.processedCards.clear(); this.processedJobNames = []; return; } return; } const currentCard = filteredCards[0]; const cardKey = this.getCardKey(currentCard); this.processedCards.add(cardKey); const jobName = currentCard.querySelector(".job-name")?.textContent?.trim() || ""; if (jobName) { this.processedJobNames = this.processedJobNames || []; this.processedJobNames.push(jobName); } currentCard.scrollIntoView({ behavior: "smooth", block: "center" }); currentCard.click(); await this.delay(CONFIG.OPERATION_INTERVAL * 2); this.log( `正在沟通:已处理${this.processedCards.size}个${jobName ? `,岗位"${jobName}"` : ""}` ); 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(CONFIG.OPERATION_INTERVAL * 4); const btn = [ ...document.querySelectorAll(".default-btn.cancel-btn"), ].find((b) => b.textContent.trim() === "留在此页"); if (btn) { btn.click(); await this.delay(CONFIG.OPERATION_INTERVAL * 2); } }, resetCycle() { toggleProcess(); this.log("所有岗位沟通完成,恭喜您即将找到理想工作!"); state.currentIndex = 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.style.padding = "0px 8px"; logItem.textContent = logEntry; logPanel.appendChild(logItem); logPanel.scrollTop = logPanel.scrollHeight; } }, async delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }, }; function toggleProcess() { state.isRunning = !state.isRunning; if (state.isRunning) { state.jobList = []; Core.processedCards.clear(); Core.processedJobNames = []; elements.controlBtn.textContent = "停止快投"; elements.controlBtn.style.background = "#ef4444"; const logPanel = document.querySelector("#pro-log"); if (logPanel) { logPanel.innerHTML = ""; } const startTime = new Date(); Core.log(`开始自动快投,时间:${startTime.toLocaleTimeString()}`); Core.log("投递规则:按顺序沟通当前页面的全部岗位"); Core.startProcessing(); } else { elements.controlBtn.textContent = "启动快投"; elements.controlBtn.style.background = "var(--primary-color)"; state.isRunning = false; state.currentIndex = 0; Core.processedCards.clear(); } } function init() { if (!location.pathname.startsWith("/web/geek/jobs")) { return; } UI.init(); document.body.style.position = "relative"; Core.log("欢迎使用 BOSS快投(社区版)"); } window.addEventListener("load", init); })();