134 lines
3.5 KiB
JavaScript
Executable File
134 lines
3.5 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
// 用法:
|
||
// OPEN_API_APP_KEY="robot_dalongxia" OPEN_API_APP_SECRET="你的secret" node dalongxia_analytics_client.js progress
|
||
// OPEN_API_APP_KEY="robot_dalongxia" OPEN_API_APP_SECRET="你的secret" node dalongxia_analytics_client.js overview
|
||
|
||
const crypto = require("crypto");
|
||
|
||
const BASE_URL = process.env.OPEN_API_BASE_URL || process.env.OPEN_API_BASE || "https://qd.yydd.ai";
|
||
const APP_KEY = process.env.OPEN_API_APP_KEY;
|
||
const APP_SECRET = process.env.OPEN_API_APP_SECRET;
|
||
|
||
if (!APP_KEY || !APP_SECRET) {
|
||
console.error("缺少环境变量:OPEN_API_APP_KEY / OPEN_API_APP_SECRET");
|
||
process.exit(1);
|
||
}
|
||
|
||
function hmacSha256Hex(secret, payload) {
|
||
return crypto.createHmac("sha256", secret).update(payload, "utf8").digest("hex");
|
||
}
|
||
|
||
function nowTs() {
|
||
return String(Date.now());
|
||
}
|
||
|
||
async function postJson(path, body) {
|
||
const resp = await fetch(`${BASE_URL}${path}`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(body),
|
||
});
|
||
|
||
const text = await resp.text();
|
||
let data = {};
|
||
try {
|
||
data = text ? JSON.parse(text) : {};
|
||
} catch (err) {
|
||
throw new Error(`HTTP ${resp.status} 非JSON响应: ${text.slice(0, 300)}`);
|
||
}
|
||
|
||
if (!resp.ok || data.code !== 200) {
|
||
throw new Error(`HTTP ${resp.status} / code=${data.code} / msg=${data.message}`);
|
||
}
|
||
return data.data;
|
||
}
|
||
|
||
async function queryTaskProgressOverview({ dateRange = "month", month = "", deptId = "" } = {}) {
|
||
const timestamp = nowTs();
|
||
const payload = [
|
||
"analytics_task_progress_overview",
|
||
APP_KEY,
|
||
dateRange,
|
||
month || "",
|
||
String(deptId || ""),
|
||
timestamp,
|
||
].join("|");
|
||
const sign = hmacSha256Hex(APP_SECRET, payload);
|
||
|
||
return postJson("/api/open/analytics/task-progress/overview", {
|
||
appKey: APP_KEY,
|
||
timestamp,
|
||
sign,
|
||
dateRange,
|
||
month,
|
||
deptId: deptId || undefined,
|
||
});
|
||
}
|
||
|
||
async function queryOverview({
|
||
dateRange = "month",
|
||
month = "",
|
||
deptId = "",
|
||
userId = "",
|
||
includeTaskProgress = false,
|
||
} = {}) {
|
||
const timestamp = nowTs();
|
||
const includeStr = String(Boolean(includeTaskProgress));
|
||
|
||
const payload = [
|
||
"analytics_overview",
|
||
APP_KEY,
|
||
dateRange,
|
||
month || "",
|
||
String(deptId || ""),
|
||
String(userId || ""),
|
||
includeStr,
|
||
timestamp,
|
||
].join("|");
|
||
const sign = hmacSha256Hex(APP_SECRET, payload);
|
||
|
||
return postJson("/api/open/analytics/overview", {
|
||
appKey: APP_KEY,
|
||
timestamp,
|
||
sign,
|
||
dateRange,
|
||
month,
|
||
deptId: deptId || undefined,
|
||
userId: userId || undefined,
|
||
includeTaskProgress: Boolean(includeTaskProgress),
|
||
});
|
||
}
|
||
|
||
(async () => {
|
||
try {
|
||
const mode = process.argv[2] || "progress";
|
||
|
||
if (mode === "progress") {
|
||
const data = await queryTaskProgressOverview({
|
||
dateRange: process.env.ANALYTICS_DATE_RANGE || "month",
|
||
month: process.env.ANALYTICS_MONTH || "",
|
||
});
|
||
console.log("任务进度总览查询成功:");
|
||
console.log(JSON.stringify(data, null, 2));
|
||
return;
|
||
}
|
||
|
||
if (mode === "overview") {
|
||
const data = await queryOverview({
|
||
dateRange: process.env.ANALYTICS_DATE_RANGE || "month",
|
||
month: process.env.ANALYTICS_MONTH || "",
|
||
includeTaskProgress: String(process.env.ANALYTICS_INCLUDE_TASK_PROGRESS || "false").toLowerCase() === "true",
|
||
});
|
||
console.log("数据分析总览查询成功:");
|
||
console.log(JSON.stringify(data, null, 2));
|
||
return;
|
||
}
|
||
|
||
throw new Error(`未知模式: ${mode},可用 progress / overview`);
|
||
} catch (err) {
|
||
console.error("查询失败:", err.message);
|
||
process.exit(1);
|
||
}
|
||
})();
|
||
|