日报按开工情况裁剪(v1.2): 双账号均无数据→不发空消息; 单账号开工→只发该账号(总览/小节/资源表均剔除未开工账号)

This commit is contained in:
hermes
2026-09-11 13:00:04 +00:00
parent 4e4cec3e1b
commit e6f5fd61bd
4 changed files with 50 additions and 19 deletions
+25 -14
View File
@@ -60,33 +60,42 @@ const ACCT_META = {
hr2: { label: 'hr2(Edge)', chatLeft: () => process.env.CHAT_LEFT_HR2 ? `剩 ${process.env.CHAT_LEFT_HR2} 次` : '—', status: () => process.env.HR2_STATUS || '✅ 在线' },
};
// ---------- 开工判断(2026-09-02 用户定稿)----------
// 未开工 = 当日无任何筛选数据。两个都没开工 → 输出空串(不发日报);
// 只有一个开工 → 日报只包含该账号,未开工的整块剔除。
const activeAccts = ['hr1', 'hr2'].filter(a => (byAcct[a]?.n || 0) > 0);
const md = [];
if (activeAccts.length > 0) {
md.push(`# 📊 智联简历筛选日报`);
md.push('');
md.push(`**${day} 周${wk}** · 岗位:二手车出口外贸业务员`);
md.push('---');
md.push('');
// 总览
// 总览(只列开工账号;单账号时省略对比表)
md.push(`## ■ 今日总览`);
md.push('');
md.push(`| 指标 | hr1 Chrome | hr2 Edge | 合计 |`);
md.push(`|:---|---:|---:|---:|`);
md.push(`| 新增筛选 | ${byAcct.hr1?.n || 0} | ${byAcct.hr2?.n || 0} | **${total.n}** |`);
md.push(`| 打招呼 | ${byAcct.hr1?.greeted || 0} | ${byAcct.hr2?.greeted || 0} | **${total.greeted}** |`);
if (activeAccts.length === 2) {
md.push(`| 指标 | hr1 Chrome | hr2 Edge | 合计 |`);
md.push(`|:---|---:|---:|---:|`);
md.push(`| 新增筛选 | ${byAcct.hr1?.n || 0} | ${byAcct.hr2?.n || 0} | **${total.n}** |`);
md.push(`| 打招呼 | ${byAcct.hr1?.greeted || 0} | ${byAcct.hr2?.greeted || 0} | **${total.greeted}** |`);
} else {
const a = activeAccts[0];
md.push(`| 指标 | ${ACCT_META[a].label} |`);
md.push(`|:---|---:|`);
md.push(`| 新增筛选 | **${byAcct[a].n}** |`);
md.push(`| 打招呼 | **${byAcct[a].greeted}** |`);
}
md.push('');
// 分账号小节
for (const acct of ['hr1', 'hr2']) {
// 分账号小节(只列开工账号,2026-09-02)
for (const acct of activeAccts) {
const meta = ACCT_META[acct];
const v = byAcct[acct];
md.push(`## ■ ${meta.label}`);
md.push('');
if (!v || v.n === 0) {
md.push(`> 今日无筛选数据 · ${meta.status()}`);
md.push('');
continue;
}
const p = (n) => ((n / v.n) * 100).toFixed(1) + '%';
md.push(`| 结果 | 人数 | 占比 |`);
md.push(`|:---|---:|---:|`);
@@ -115,10 +124,12 @@ md.push(`## ■ 资源与状态`);
md.push('');
md.push(`| 账号 | 聊天剩余 | 状态 |`);
md.push(`|:---|---:|:---|`);
md.push(`| hr1 Chrome | ${ACCT_META.hr1.chatLeft()} | ${ACCT_META.hr1.status()} |`);
md.push(`| hr2 Edge | ${ACCT_META.hr2.chatLeft()} | ${ACCT_META.hr2.status()} |`);
for (const a of activeAccts) {
md.push(`| ${ACCT_META[a].label.replace('(', ' ').replace(')', '')} | ${ACCT_META[a].chatLeft()} | ${ACCT_META[a].status()} |`);
}
md.push('');
md.push(`- 历史累计:${histTotal.toLocaleString()} 人`);
} // end if (activeAccts.length > 0)
console.log(md.join('\n'));
db.close();
+7
View File
@@ -100,11 +100,18 @@ const sentFlag = path.join(STATE_DIR, `report-sent-${today()}`);
} catch { }
}
const md = execSync(`node ${SCRIPTS}/daily-report.js`, { cwd: SCRIPTS, encoding: 'utf8', timeout: 60000, env });
// v1.2(2026-09-02 用户定稿):两个账号都没开工 → 日报输出为空 → 不发送
if (!md.trim()) {
log('双账号今日均无数据,日报不发送(不发空消息)');
fs.writeFileSync(sentFlag, new Date().toISOString());
reportSent = 'skipped_empty';
} else {
fs.writeFileSync(`/tmp/daily-report-enforce-${today()}.md`, md);
execSync(`${HERMES} send -t "feishu:${GROUP}" -f /tmp/daily-report-enforce-${today()}.md`, { stdio: ['pipe', 'pipe', 'pipe'], timeout: 60000 });
fs.writeFileSync(sentFlag, new Date().toISOString());
reportSent = true;
log('日报已发送到群 ✅');
}
} catch (e) { findings.push(`日报发送失败: ${String(e.message).slice(0, 150)}`); }
}
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
# hr2 daily-runner 启动脚本(cron 用)
cd /opt/data/skills/recruitment-resume-screener/scripts || exit 1
LOG=/opt/data/logs/recruitment/runner-hr2-$(date +%F).log
ACCOUNT=hr2 CDP_PORT=9225 nohup node daily-runner.js hr2 9225 >> "$LOG" 2>&1 &
echo $! > /opt/data/logs/recruitment/runner-hr2.pid
echo "hr2 runner started PID=$!"
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
# hr1 daily-runner launcher (cron-safe, self-detaching)
cd /opt/data/skills/recruitment-resume-screener/scripts || exit 1
export ACCOUNT=hr1
export CDP_PORT=9223
exec nohup node daily-runner.js hr1 9223 > /opt/data/logs/recruitment/runner-hr1-$(date +%F).log 2>&1