#!/usr/bin/env node // 智能工牌录音管道 API 工具(零依赖, Node >=18) // 用法: // node api.mjs login [<密码>] # 登录并缓存 token 到 scripts/.token(密码可取自 .env/环境变量) // node api.mjs get /api/archive/missing // node api.mjs post /api/archive/run '{"dates":["2026-09-03"]}' // node api.mjs env # 查看连接诊断(BASE / 是否已登录) // node api.mjs get /api/reports --raw # 输出完整响应(含 code/message) // node api.mjs get /api/reports --base http://localhost:3002 # 指定接口地址 // 环境变量: SMARTBADGE_API_BASE(默认线上 https://recording.sh-lami.com)、 // SMARTBADGE_USERNAME(默认 lami123456)、SMARTBADGE_PASSWORD(或参数传入) import { baseUrl, fail, login, httpJson, loadToken, TOKEN_FILE, findEnvFile, loadEnv } from './lib.mjs'; // .env 密码回退(与 check-online 同链): 已有环境变量优先,不覆盖 const env = findEnvFile(); if (env.hit) loadEnv(env.hit); const args = process.argv.slice(2); const positional = []; let baseOverride; let rawFlag = false; for (let i = 0; i < args.length; i++) { const a = args[i]; if (a === '--raw') rawFlag = true; else if (a === '--base') baseOverride = args[++i]; else positional.push(a); } const [cmd, apiPath, bodyStr] = positional; async function main() { if (cmd === 'login') { const token = await login({ base: baseUrl(baseOverride), username: process.env.SMARTBADGE_USERNAME, password: process.env.SMARTBADGE_PASSWORD || apiPath, }); console.log(`登录成功, token 已缓存(${token.slice(0, 8)}...)`); return; } if (cmd === 'env') { const token = loadToken(); console.log(`BASE = ${baseUrl(baseOverride)}`); console.log(`USERNAME= ${process.env.SMARTBADGE_USERNAME || 'lami123456'}`); console.log(`TOKEN = ${token ? `已登录 (${token.slice(0, 8)}... @ ${TOKEN_FILE})` : '未登录(先: node api.mjs login <密码>)'}`); return; } if (!cmd || !apiPath) fail('用法: node api.mjs login|env|get|post|put|delete <路径> [JSON体] [--raw] [--base URL]'); const body = bodyStr !== undefined && bodyStr.trim() ? JSON.parse(bodyStr) : undefined; const r = await httpJson(cmd, apiPath, body, { base: baseOverride, raw: rawFlag }); if (r.status >= 400 && r.json?.code !== 0 && !rawFlag) { fail(`请求失败(${r.status}): ${JSON.stringify(r.json)}`); } if (rawFlag) { console.log(JSON.stringify(r.json, null, 2)); } else { const data = r.json?.data; console.log(data === undefined || data === null ? `(${r.status}) ${r.json?.message || 'no data'}` : JSON.stringify(data, null, 2)); } if (!r.ok && process.env.SMARTBADGE_DEBUG) fail(`HTTP ${r.status}`, 1); } main().catch((err) => { if (err instanceof SyntaxError && /JSON/i.test(err.message)) { fail(`JSON 体解析失败: ${err.message}\n 示例: node api.mjs post /api/archive/run '{"dates":["2026-09-03"]}'`); } fail(err.message); });