dalongxia/remote_sync/dalongxia_open_analytics.js
2026-03-04 13:25:48 +08:00

258 lines
7.9 KiB
JavaScript
Executable File

#!/usr/bin/env node
// file: dalongxia_open_analytics.js
// Node 18+
// 用法示例:
// OPEN_API_APP_KEY="robot_dalongxia" OPEN_API_APP_SECRET="你的secret" node dalongxia_open_analytics.js designerPerformance
// OPEN_API_APP_KEY="robot_dalongxia" OPEN_API_APP_SECRET="你的secret" node dalongxia_open_analytics.js dimensionAnalysis
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 nowTs() {
return String(Date.now());
}
function sign(payload) {
return crypto.createHmac("sha256", APP_SECRET).update(payload, "utf8").digest("hex");
}
function payload(action, ...parts) {
return [action, APP_KEY, ...parts].join("|");
}
async function post(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 json = {};
try {
json = text ? JSON.parse(text) : {};
} catch (err) {
throw new Error(`HTTP=${resp.status}, 非JSON响应: ${text.slice(0, 300)}`);
}
if (!resp.ok || json.code !== 200) {
throw new Error(`HTTP=${resp.status}, code=${json.code}, msg=${json.message}`);
}
return json.data;
}
async function callOverview({ dateRange = "month", month = "", deptId = "", userId = "", includeTaskProgress = false } = {}) {
const ts = nowTs();
const includeStr = String(Boolean(includeTaskProgress));
const p = payload("analytics_overview", dateRange, month, String(deptId), String(userId), includeStr, ts);
return post("/api/open/analytics/overview", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
dateRange,
month,
deptId: deptId || undefined,
userId: userId || undefined,
includeTaskProgress: !!includeTaskProgress,
});
}
async function callTaskProgressOverview({ dateRange = "month", month = "", deptId = "" } = {}) {
const ts = nowTs();
const p = payload("analytics_task_progress_overview", dateRange, month, String(deptId), ts);
return post("/api/open/analytics/task-progress/overview", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
dateRange,
month,
deptId: deptId || undefined,
});
}
async function callDemandStatistics({ dateRange = "month", month = "", deptId = "", userId = "" } = {}) {
const ts = nowTs();
const p = payload("analytics_demand_statistics", dateRange, month, String(deptId), String(userId), ts);
return post("/api/open/analytics/demand-statistics", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
dateRange,
month,
deptId: deptId || undefined,
userId: userId || undefined,
});
}
async function callDesignerPerformance({ month = "", deptId = "" } = {}) {
const ts = nowTs();
const p = payload("analytics_designer_performance", month, String(deptId), ts);
return post("/api/open/analytics/designer-performance", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
month,
deptId: deptId || undefined,
});
}
async function callProcessEfficiency({ month = "" } = {}) {
const ts = nowTs();
const p = payload("analytics_process_efficiency", month, ts);
return post("/api/open/analytics/process-efficiency", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
month,
});
}
async function callWarnings() {
const ts = nowTs();
const p = payload("analytics_warnings", ts);
return post("/api/open/analytics/warnings", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
});
}
async function callDimensionAnalysis({ dateRange = "month", month = "" } = {}) {
const ts = nowTs();
const p = payload("analytics_dimension_analysis", dateRange, month, ts);
return post("/api/open/analytics/dimension-analysis", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
dateRange,
month,
});
}
async function callDesignerDeductionDetails({ userId, month = "" }) {
const ts = nowTs();
const p = payload("analytics_designer_deduction_details", String(userId), month, ts);
return post("/api/open/analytics/designer-deduction-details", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
userId,
month,
});
}
async function callDesignerScoreDetails({ userId, month = "" }) {
const ts = nowTs();
const p = payload("analytics_designer_score_details", String(userId), month, ts);
return post("/api/open/analytics/designer-score-details", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
userId,
month,
});
}
async function callPrimaryDeptStatistics({ startTime, endTime, deptId = "" }) {
const ts = nowTs();
const p = payload("analytics_primary_dept_statistics", startTime, endTime, String(deptId), ts);
return post("/api/open/analytics/primary-dept/statistics", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
startTime,
endTime,
deptId: deptId || undefined,
});
}
async function callPrimaryDeptRanking({ startTime, endTime }) {
const ts = nowTs();
const p = payload("analytics_primary_dept_ranking", startTime, endTime, ts);
return post("/api/open/analytics/primary-dept/ranking", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
startTime,
endTime,
});
}
async function callPrimaryTaskFlowEfficiency({ startTime, endTime }) {
const ts = nowTs();
const p = payload("analytics_primary_task_flow_efficiency", startTime, endTime, ts);
return post("/api/open/analytics/primary-task/flow-efficiency", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
startTime,
endTime,
});
}
async function callPrimaryTaskBrandDistribution({ startTime, endTime }) {
const ts = nowTs();
const p = payload("analytics_primary_task_brand_distribution", startTime, endTime, ts);
return post("/api/open/analytics/primary-task/brand-distribution", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
startTime,
endTime,
});
}
async function callPrimaryDeptUserRanking({ startTime, endTime }) {
const ts = nowTs();
const p = payload("analytics_primary_dept_user_ranking", startTime, endTime, ts);
return post("/api/open/analytics/primary-dept/user-ranking", {
appKey: APP_KEY,
timestamp: ts,
sign: sign(p),
startTime,
endTime,
});
}
(async () => {
const mode = process.argv[2] || "designerPerformance";
const month = process.argv[3] || "2026-02";
const startTime = process.argv[4] || "2026-02-01T00:00:00";
const endTime = process.argv[5] || "2026-02-27T23:59:59";
const map = {
overview: () => callOverview({ month }),
taskProgressOverview: () => callTaskProgressOverview({ month }),
demandStatistics: () => callDemandStatistics({ month }),
designerPerformance: () => callDesignerPerformance({ month }),
processEfficiency: () => callProcessEfficiency({ month }),
warnings: () => callWarnings(),
dimensionAnalysis: () => callDimensionAnalysis({ month }),
designerDeduction: () => callDesignerDeductionDetails({ userId: 38, month }),
designerScore: () => callDesignerScoreDetails({ userId: 38, month }),
primaryDeptStatistics: () => callPrimaryDeptStatistics({ startTime, endTime }),
primaryDeptRanking: () => callPrimaryDeptRanking({ startTime, endTime }),
primaryTaskFlowEfficiency: () => callPrimaryTaskFlowEfficiency({ startTime, endTime }),
primaryTaskBrandDistribution: () => callPrimaryTaskBrandDistribution({ startTime, endTime }),
primaryDeptUserRanking: () => callPrimaryDeptUserRanking({ startTime, endTime }),
};
if (!map[mode]) {
console.error("未知 mode:", mode);
process.exit(1);
}
const data = await map[mode]();
console.log(JSON.stringify(data, null, 2));
})().catch((err) => {
console.error("查询失败:", err.message);
process.exit(1);
});