Spaces:
Paused
Paused
| const express = require('express'); | |
| const { exec } = require('child_process'); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const app = express(); | |
| const port = process.env.PORT || 8080; | |
| // 使用 HOME 环境变量来创建日志目录 | |
| const logDir = path.join(process.env.HOME, 'logs'); | |
| if (!fs.existsSync(logDir)) { | |
| fs.mkdirSync(logDir, { recursive: true }); | |
| } | |
| let lastRunTime = null; | |
| let nextRunTime = null; | |
| let lastRunResults = null; | |
| function log(message) { | |
| const timestamp = new Date().toISOString(); | |
| const logMessage = `${timestamp}: ${message}\n`; | |
| console.log(logMessage); | |
| fs.appendFileSync(path.join(logDir, 'app.log'), logMessage); | |
| } | |
| app.get('/', (req, res) => { | |
| let tableHtml = ''; | |
| let summaryHtml = ''; | |
| if (lastRunResults) { | |
| tableHtml = '<h2>上次登录结果:</h2>'; | |
| tableHtml += '<table border="1"><tr><th>账号</th><th>类型</th><th>状态</th><th>消息</th></tr>'; | |
| lastRunResults.forEach(result => { | |
| tableHtml += `<tr><td>${result.username}</td><td>${result.type}</td><td>${result.success ? '成功' : '失败'}</td><td>${result.message}</td></tr>`; | |
| }); | |
| tableHtml += '</table>'; | |
| const successfulLogins = lastRunResults.filter(r => r.success); | |
| const failedLogins = lastRunResults.filter(r => !r.success); | |
| summaryHtml = '<h2>登录结果统计:</h2>'; | |
| summaryHtml += `<p>成功登录的账号:${successfulLogins.length}</p>`; | |
| summaryHtml += `<p>登录失败的账号:${failedLogins.length}</p>`; | |
| if (failedLogins.length > 0) { | |
| summaryHtml += '<h3>登录失败的账号列表:</h3><ul>'; | |
| failedLogins.forEach(({ username, type }) => { | |
| summaryHtml += `<li>${username} (${type})</li>`; | |
| }); | |
| summaryHtml += '</ul>'; | |
| } | |
| } | |
| res.send(` | |
| <h1>登录脚本状态</h1> | |
| <p>上次执行时间:${lastRunTime || '尚未执行'}</p> | |
| <p>下次执行时间:${nextRunTime || '未设置'}</p> | |
| <a href="/run">立即执行脚本</a> | |
| <br><br> | |
| <a href="/logs">查看日志</a> | |
| ${tableHtml} | |
| ${summaryHtml} | |
| `); | |
| }); | |
| app.get('/logs', (req, res) => { | |
| const logPath = path.join(logDir, 'app.log'); | |
| fs.readFile(logPath, 'utf8', (err, data) => { | |
| if (err) { | |
| res.status(500).send('无法读取日志文件'); | |
| return; | |
| } | |
| res.send(`<pre>${data}</pre>`); | |
| }); | |
| }); | |
| function runLoginScript() { | |
| log('开始执行登录脚本'); | |
| exec('node login.js', (error, stdout, stderr) => { | |
| if (error) { | |
| log(`执行错误: ${error.message}`); | |
| return; | |
| } | |
| if (stderr) { | |
| log(`脚本错误输出: ${stderr}`); | |
| return; | |
| } | |
| log(`脚本输出:\n${stdout}`); | |
| // 解析输出以获取结果 | |
| const lines = stdout.split('\n'); | |
| const resultStartIndex = lines.findIndex(line => line.includes('| 账号 | 类型 | 状态 | 消息 |')); | |
| if (resultStartIndex !== -1) { | |
| lastRunResults = lines.slice(resultStartIndex + 2) | |
| .filter(line => line.trim().startsWith('|')) | |
| .map(line => { | |
| const [, username, type, status, message] = line.split('|').map(item => item.trim()); | |
| return { username, type, success: status === '成功', message }; | |
| }); | |
| } | |
| }); | |
| lastRunTime = new Date().toISOString(); | |
| nextRunTime = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(); | |
| } | |
| app.get('/run', (req, res) => { | |
| runLoginScript(); | |
| res.send('脚本执行已启动,请稍后刷新页面查看结果。'); | |
| }); | |
| // 每7天自动运行一次脚本 | |
| setInterval(runLoginScript, 7 * 24 * 60 * 60 * 1000); | |
| app.listen(port, () => { | |
| log(`服务器运行在 http://localhost:${port}`); | |
| runLoginScript(); // 启动时立即运行一次 | |
| }); |