UNPKG

zhilian-auto-hi

Version:

智联招聘自动打招呼工具 - 自动化招聘流程的命令行工具

356 lines (355 loc) 16 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.logger = void 0; const chalk_1 = __importDefault(require("chalk")); const boxen_1 = __importDefault(require("boxen")); const index_1 = require("../types/index"); // 定义日志级别样式 const styles = { info: chalk_1.default.blue, success: chalk_1.default.green, warning: chalk_1.default.yellow, error: chalk_1.default.red.bold, highlight: chalk_1.default.cyan.bold, dim: chalk_1.default.gray, title: chalk_1.default.magenta.bold, stats: chalk_1.default.white.bold }; // 定义图标 const icons = { info: '🔍', success: '✅', warning: '⚠️', error: '❌', loading: '⏳', rocket: '🚀', target: '🎯', chart: '📊', page: '📄', robot: '🤖', handshake: '🤝', camera: '📸', book: '📖' }; class Logger { // 基础日志方法 info(message, icon) { console.log(`${icon || icons.info} ${styles.info(message)}`); } success(message, icon) { console.log(`${icon || icons.success} ${styles.success(message)}`); } warning(message, icon) { console.log(`${icon || icons.warning} ${styles.warning(message)}`); } error(message, icon) { console.log(`${icon || icons.error} ${styles.error(message)}`); } // 高亮显示重要信息 highlight(message, icon) { console.log(`${icon || icons.target} ${styles.highlight(message)}`); } // 显示标题 title(message) { console.log('\n' + (0, boxen_1.default)(styles.title(message), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'magenta' })); } // 显示分隔线 separator(title) { const line = '='.repeat(50); if (title) { console.log(`\n${styles.dim(line)} ${styles.highlight(title)} ${styles.dim(line)}`); } else { console.log(`\n${styles.dim(line)}`); } } // 显示统计信息 stats(stats) { const matchRate = stats.totalProcessed > 0 ? ((stats.matchedCount / stats.totalProcessed) * 100).toFixed(1) : '0'; const greetRate = stats.matchedCount > 0 ? ((stats.greetedCount / stats.matchedCount) * 100).toFixed(1) : '0'; const statsBox = (0, boxen_1.default)([ `${icons.chart} ${styles.stats('处理统计信息')}`, '', `${icons.page} 总处理页数: ${styles.highlight(stats.currentPage.toString())}`, `📋 总处理简历数: ${styles.highlight(stats.totalProcessed.toString())}`, `${icons.success} 匹配简历数: ${styles.highlight(stats.matchedCount.toString())}`, `${icons.handshake} 成功打招呼数: ${styles.highlight(stats.greetedCount.toString())}`, `📈 匹配率: ${styles.highlight(matchRate + '%')}`, `${icons.target} 打招呼成功率: ${styles.highlight(greetRate + '%')}` ].join('\n'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'green' }); console.log('\n' + statsBox); } // 显示配置信息 config(config) { const configItems = [ `${icons.target} ${styles.stats('配置信息')}`, '' ]; // 如果有运行模式信息,显示在最前面 if (config.runMode) { configItems.push(`🚀 运行模式: ${styles.highlight(config.runMode)}`); } configItems.push(`🔍 筛选关键字: ${styles.highlight(config.keywords.join(', '))}`, `📅 年龄限制: ${styles.highlight((config.minAge || '无限制') + ' - ' + (config.maxAge || '无限制') + ' 岁')}`, `⚧️ 性别筛选: ${styles.highlight(config.gender === 'male' ? '仅男性' : config.gender === 'female' ? '仅女性' : '不限制')}`, `📋 最大页数: ${styles.highlight(config.maxPages.toString())}`, `⏱️ 翻页延迟: ${styles.highlight(config.pageDelay + 'ms')}`); // 添加优雅关闭配置显示 configItems.push(`📊 显示统计: ${styles.highlight(config.gracefulShutdown.showStats ? '是' : '否')}`); const configBox = (0, boxen_1.default)(configItems.join('\n'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'cyan' }); console.log('\n' + configBox); } // 显示简历筛选结果 resumeResult(isMatch, matchedKeywords, age, gender) { const genderText = gender === 'male' ? '男性' : gender === 'female' ? '女性' : '未知'; const resultBox = (0, boxen_1.default)([ `${icons.target} ${styles.stats('简历筛选结果')}`, '', `${isMatch ? icons.success : icons.error} 筛选结果: ${isMatch ? styles.success('匹配成功') : styles.error('不匹配')}`, `🎯 匹配到的关键字: ${styles.highlight(matchedKeywords.join(', ') || '无')}`, `📅 候选人年龄: ${styles.highlight(age !== undefined ? age + '岁' : '未知')}`, `⚧️ 候选人性别: ${styles.highlight(genderText)}` ].join('\n'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: isMatch ? 'green' : 'red' }); console.log('\n' + resultBox); } // 显示页面处理信息 pageInfo(pageNum) { console.log(`\n${icons.page} ${styles.highlight(`正在处理第 ${pageNum} 页...`)}`); } // 显示简历详情 resumeDetails(resumeText) { console.log('\n' + (0, boxen_1.default)([ `${icons.info} ${styles.stats('简历详情信息')}`, '', styles.dim(resumeText.trim()) ].join('\n'), { padding: 1, margin: 1, borderStyle: 'single', borderColor: 'blue' })); } // 浏览模式专用方法 // 显示浏览模式页面进度 browsePageInfo(pageNum) { console.log(`\n${icons.book} ${styles.highlight(`正在浏览第 ${pageNum} 页...`)}`); } // 显示浏览模式统计信息 browseStats(stats) { const duration = stats.endTime ? Math.round((stats.endTime.getTime() - stats.startTime.getTime()) / 1000) : Math.round((new Date().getTime() - stats.startTime.getTime()) / 1000); const statsItems = [ `${icons.book} ${styles.stats('浏览统计信息')}`, '', `${icons.page} 当前页数: ${styles.highlight(stats.currentPage.toString())}`, `${icons.camera} 已浏览页面数: ${styles.highlight(stats.totalBrowsed.toString())}`, `⏱️ 浏览时长: ${styles.highlight(duration + '秒')}`, `📈 平均浏览速度: ${stats.totalBrowsed > 0 ? styles.highlight((duration / stats.totalBrowsed).toFixed(1) + '秒/页') : styles.highlight('0秒/页')}` ]; // 如果有筛选统计信息,添加筛选相关的统计 if (stats.totalFiltered !== undefined && stats.matchedCount !== undefined) { statsItems.push('', `🔍 筛选统计信息:`, `📋 已筛选简历数: ${styles.highlight(stats.totalFiltered.toString())}`, `✅ 匹配简历数: ${styles.highlight(stats.matchedCount.toString())}`); if (stats.totalFiltered > 0) { const matchRate = ((stats.matchedCount / stats.totalFiltered) * 100).toFixed(1); statsItems.push(`📊 匹配率: ${styles.highlight(matchRate + '%')}`); } } const statsBox = (0, boxen_1.default)(statsItems.join('\n'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'blue' }); console.log('\n' + statsBox); } // 显示浏览模式进度更新 browseProgress(currentPage, totalBrowsed) { console.log(`${icons.camera} ${styles.info(`页面 ${currentPage} 浏览完成,累计浏览: ${totalBrowsed} 页`)}`); } // 显示浏览模式开始信息 browseStart() { console.log(`\n${icons.rocket} ${styles.success('开始浏览模式...')}`); } // 显示浏览模式完成信息 browseComplete(totalBrowsed) { console.log(`\n${icons.success} ${styles.success(`浏览模式完成!总共浏览了 ${totalBrowsed} 页`)}`); } // 显示浏览模式错误但继续执行 browseError(error, currentPage) { console.log(`${icons.warning} ${styles.warning(`第 ${currentPage} 页浏览出错,继续下一页: ${error}`)}`); } // 显示浏览模式筛选结果(简化版,不显示详细简历信息) browseFilterResult(pageNum, isMatch, matchedKeywords, age, gender) { const genderText = gender === 'male' ? '男性' : gender === 'female' ? '女性' : '未知'; const statusIcon = isMatch ? '✅' : '❌'; const statusText = isMatch ? styles.success('匹配') : styles.dim('不匹配'); console.log(`${statusIcon}${pageNum}页 - ${statusText} | 年龄: ${styles.highlight(age !== undefined ? age + '岁' : '未知')} | 性别: ${styles.highlight(genderText)} | 关键字: ${styles.highlight(matchedKeywords.join(', ') || '无')}`); } // 优雅关闭相关方法 // 显示关闭开始信息 shutdownStart(signal) { const shutdownBox = (0, boxen_1.default)([ `🛑 ${styles.warning('正在关闭程序...')}`, '', `📡 接收信号: ${styles.highlight(signal)}`, `⏰ 开始时间: ${styles.dim(new Date().toLocaleString('zh-CN'))}`, '', `${styles.info('正在安全清理资源,请稍候...')}` ].join('\n'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'yellow' }); console.log('\n' + shutdownBox); } // 显示清理进度 cleanupProgress(step) { console.log(`🧹 ${styles.info(step)}`); } // 显示清理步骤开始 cleanupStepStart(stepName) { console.log(`🔄 ${styles.info(`开始清理: ${stepName}`)}`); } // 显示清理步骤完成 cleanupStepComplete(stepName) { console.log(`✅ ${styles.success(`完成清理: ${stepName}`)}`); } // 显示清理步骤失败 cleanupStepFailed(stepName, error) { console.log(`❌ ${styles.warning(`清理失败: ${stepName} - ${error}`)}`); } // 显示关闭完成信息(带详细统计) shutdownComplete(shutdownStats) { if (!shutdownStats) { // 简单的关闭完成消息 const simpleBox = (0, boxen_1.default)([ `✅ ${styles.success('程序已安全退出')}`, '', `🕐 退出时间: ${styles.dim(new Date().toLocaleString('zh-CN'))}` ].join('\n'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: 'green' }); console.log('\n' + simpleBox); return; } // 计算关闭耗时 const duration = shutdownStats.endTime ? Math.round((shutdownStats.endTime.getTime() - shutdownStats.startTime.getTime()) / 1000) : 0; // 构建统计信息内容 const statsContent = [ `✅ ${styles.success('程序已安全退出')}`, '' ]; // 基本信息 statsContent.push(`📡 触发信号: ${styles.highlight(shutdownStats.signal)}`, `🕐 关闭耗时: ${styles.highlight(duration + '秒')}`, `📊 关闭阶段: ${styles.highlight(this.getPhaseDisplayName(shutdownStats.phase))}`); // 清理步骤信息 if (shutdownStats.cleanupSteps.length > 0) { statsContent.push('', `🧹 完成的清理步骤 (${shutdownStats.cleanupSteps.length}个):`); shutdownStats.cleanupSteps.forEach(step => { statsContent.push(` • ${styles.dim(step)}`); }); } // 错误信息 if (shutdownStats.errors.length > 0) { statsContent.push('', `⚠️ 清理过程中的错误 (${shutdownStats.errors.length}个):`); shutdownStats.errors.forEach(error => { statsContent.push(` • ${styles.warning(error)}`); }); } // 处理统计信息 if (shutdownStats.processingStats) { const stats = shutdownStats.processingStats; const matchRate = stats.totalProcessed > 0 ? ((stats.matchedCount / stats.totalProcessed) * 100).toFixed(1) : '0'; statsContent.push('', `📈 执行统计信息:`, ` • 处理页数: ${styles.highlight(stats.currentPage.toString())}`, ` • 处理简历: ${styles.highlight(stats.totalProcessed.toString())}`, ` • 匹配简历: ${styles.highlight(stats.matchedCount.toString())}`, ` • 成功打招呼: ${styles.highlight(stats.greetedCount.toString())}`, ` • 匹配率: ${styles.highlight(matchRate + '%')}`, ` • 完成状态: ${stats.isCompleted ? styles.success('正常完成') : styles.warning('提前终止')}`); if (stats.shutdownReason) { statsContent.push(` • 终止原因: ${styles.highlight(stats.shutdownReason)}`); } } const completionBox = (0, boxen_1.default)(statsContent.join('\n'), { padding: 1, margin: 1, borderStyle: 'round', borderColor: shutdownStats.errors.length > 0 ? 'yellow' : 'green' }); console.log('\n' + completionBox); } // 显示强制关闭警告 forceShutdownWarning(reason = 'repeated_signal') { const warningMessage = reason === 'timeout' ? '清理超时,正在强制关闭程序...' : '检测到重复信号,正在强制关闭程序...'; const warningBox = (0, boxen_1.default)([ `⚡ ${styles.error('强制关闭警告')}`, '', `${styles.warning(warningMessage)}`, '', `${styles.dim('注意: 强制关闭可能导致资源未完全清理')}` ].join('\n'), { padding: 1, margin: 1, borderStyle: 'double', borderColor: 'red' }); console.log('\n' + warningBox); } // 显示超时提示 shutdownTimeoutWarning(timeoutSeconds) { console.log(`⏰ ${styles.warning(`清理操作将在 ${timeoutSeconds} 秒后超时`)}`); } // 显示关闭进度概览 shutdownProgress(completedSteps, totalSteps, currentStep) { const progress = totalSteps > 0 ? Math.round((completedSteps / totalSteps) * 100) : 0; const progressBar = '█'.repeat(Math.floor(progress / 5)) + '░'.repeat(20 - Math.floor(progress / 5)); console.log(`📊 ${styles.info(`关闭进度: [${progressBar}] ${progress}% (${completedSteps}/${totalSteps})`)}`); if (currentStep) { console.log(`🔄 ${styles.dim(`当前步骤: ${currentStep}`)}`); } } // 获取阶段显示名称 getPhaseDisplayName(phase) { switch (phase) { case index_1.ShutdownPhase.RUNNING: return '运行中'; case index_1.ShutdownPhase.INITIATED: return '开始关闭'; case index_1.ShutdownPhase.CLEANING_UP: return '清理中'; case index_1.ShutdownPhase.COMPLETED: return '正常完成'; case index_1.ShutdownPhase.FORCED: return '强制关闭'; default: return '未知状态'; } } } // 导出单例实例 exports.logger = new Logger(); exports.default = exports.logger;