fix: 修复日期比较逻辑 + SMTP超时清理 + 安全临时目录

Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/c5b8b0a2-c3fb-437f-bd6f-07549f2c5709

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-04-06 04:29:58 +00:00 committed by GitHub
parent c10556b6d3
commit 76c104e99e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 46 additions and 27 deletions

View File

@ -81,18 +81,21 @@ jobs:
deploy-infinity) deploy-infinity)
echo "部署∞版本..." echo "部署∞版本..."
# 先同步最新代码到服务器 # 先同步最新代码到服务器
$SSH_CMD "mkdir -p $PROXY_DIR/.deploy-tmp"
scp -i ~/.ssh/brain_key -o StrictHostKeyChecking=no \ scp -i ~/.ssh/brain_key -o StrictHostKeyChecking=no \
server/proxy/service/auto-evolution.js \ server/proxy/service/auto-evolution.js \
server/proxy/service/email-hub.js \ server/proxy/service/email-hub.js \
server/proxy/service/protocol-mirror.js \ server/proxy/service/protocol-mirror.js \
server/proxy/ecosystem.brain-proxy-v3.config.js \ server/proxy/ecosystem.brain-proxy-v3.config.js \
${{ secrets.ZY_BRAIN_USER }}@${{ secrets.ZY_BRAIN_HOST }}:/tmp/ ${{ secrets.ZY_BRAIN_USER }}@${{ secrets.ZY_BRAIN_HOST }}:$PROXY_DIR/.deploy-tmp/
$SSH_CMD " $SSH_CMD "
cp /tmp/auto-evolution.js $PROXY_DIR/service/ cp $PROXY_DIR/.deploy-tmp/auto-evolution.js $PROXY_DIR/service/
cp /tmp/email-hub.js $PROXY_DIR/service/ cp $PROXY_DIR/.deploy-tmp/email-hub.js $PROXY_DIR/service/
cp /tmp/protocol-mirror.js $PROXY_DIR/service/ cp $PROXY_DIR/.deploy-tmp/protocol-mirror.js $PROXY_DIR/service/
cp /tmp/ecosystem.brain-proxy-v3.config.js $PROXY_DIR/ cp $PROXY_DIR/.deploy-tmp/ecosystem.brain-proxy-v3.config.js $PROXY_DIR/
rm -rf $PROXY_DIR/.deploy-tmp
mkdir -p $PROXY_DIR/data/evolution-reports mkdir -p $PROXY_DIR/data/evolution-reports
cd $PROXY_DIR && pm2 startOrRestart ecosystem.brain-proxy-v3.config.js --update-env && pm2 save cd $PROXY_DIR && pm2 startOrRestart ecosystem.brain-proxy-v3.config.js --update-env && pm2 save
echo '✅ ∞版本已部署' echo '✅ ∞版本已部署'

View File

@ -372,8 +372,9 @@ async function checkTrafficPoolAlert() {
const lastRun = status.schedules.traffic_alert_70.last_run; const lastRun = status.schedules.traffic_alert_70.last_run;
const currentPeriod = pool.period || new Date().toISOString().slice(0, 7); const currentPeriod = pool.period || new Date().toISOString().slice(0, 7);
// 检查本月是否已发过 // 检查本月是否已发过 (比较YYYY-MM)
if (!lastRun || !lastRun.startsWith(currentPeriod.replace('-', '').slice(0, 6))) { const lastRunMonth = lastRun ? lastRun.slice(0, 7) : '';
if (lastRunMonth !== currentPeriod) {
await handleTrafficAlert(Math.round(pct)); await handleTrafficAlert(Math.round(pct));
status.schedules.traffic_alert_70.last_run = new Date().toISOString(); status.schedules.traffic_alert_70.last_run = new Date().toISOString();
saveEvolutionStatus(status); saveEvolutionStatus(status);
@ -408,19 +409,16 @@ async function checkSchedule() {
// ── 月度进化 (每月1号 00:00-00:04) ── // ── 月度进化 (每月1号 00:00-00:04) ──
if (day === 1 && hour === 0 && minute < 5) { if (day === 1 && hour === 0 && minute < 5) {
const lastMonthly = status.schedules.monthly_evolution.last_run; const lastMonthly = status.schedules.monthly_evolution.last_run;
const today = now.toISOString().slice(0, 10); // 比较YYYY-MM确保本月未执行过
if (!lastMonthly || !lastMonthly.startsWith(today.slice(0, 4))) { const lastRunDate = lastMonthly ? new Date(lastMonthly) : null;
// 进一步检查: 确保本月还没执行过 const lastRunMonth = lastRunDate ? `${lastRunDate.getFullYear()}-${String(lastRunDate.getMonth() + 1).padStart(2, '0')}` : '';
const lastRunDate = lastMonthly ? new Date(lastMonthly) : null; const currentMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
const lastRunMonth = lastRunDate ? `${lastRunDate.getFullYear()}-${String(lastRunDate.getMonth() + 1).padStart(2, '0')}` : '';
const currentMonth = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
if (lastRunMonth !== currentMonth) { if (lastRunMonth !== currentMonth) {
try { try {
await monthlyEvolution(); await monthlyEvolution();
} catch (err) { } catch (err) {
console.error('[自主进化] 月度进化调度异常:', err.message); console.error('[自主进化] 月度进化调度异常:', err.message);
}
} }
} }
} }

View File

@ -86,6 +86,15 @@ async function sendEmail(to, subject, htmlBody) {
const smtpPort = 465; const smtpPort = 465;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let settled = false;
const timeoutId = setTimeout(() => {
if (!settled) {
settled = true;
try { socket.destroy(); } catch { /* ignore */ }
reject(new Error('SMTP超时(30s)'));
}
}, 30000);
const socket = tls.connect(smtpPort, smtpHost, {}, () => { const socket = tls.connect(smtpPort, smtpHost, {}, () => {
let step = 0; let step = 0;
const from = config.smtp_user; const from = config.smtp_user;
@ -107,20 +116,29 @@ async function sendEmail(to, subject, htmlBody) {
socket.write(commands[step]); socket.write(commands[step]);
step++; step++;
} }
if (step >= commands.length) { if (step >= commands.length && !settled) {
settled = true;
clearTimeout(timeoutId);
resolve(true); resolve(true);
} }
}); });
socket.on('error', (err) => { reject(err); }); socket.on('error', (err) => {
if (!settled) {
settled = true;
clearTimeout(timeoutId);
reject(err);
}
});
}); });
socket.on('error', (err) => { reject(err); }); socket.on('error', (err) => {
if (!settled) {
setTimeout(() => { settled = true;
try { socket.destroy(); } catch { /* ignore */ } clearTimeout(timeoutId);
reject(new Error('SMTP超时(30s)')); reject(err);
}, 30000); }
});
}); });
} }