2026-10-15 09:47:31 +08:00
|
|
|
const assert = require('node:assert/strict');
|
|
|
|
|
const fs = require('node:fs');
|
|
|
|
|
const vm = require('node:vm');
|
|
|
|
|
const ts = require('../admin-web/node_modules/typescript');
|
|
|
|
|
|
|
|
|
|
(async () => {
|
|
|
|
|
let pending = 2;
|
2026-10-25 09:06:15 +08:00
|
|
|
let workbench = null;
|
2026-10-15 09:47:31 +08:00
|
|
|
const responses = {
|
|
|
|
|
'/operator/analytics/dashboard': { totalUsers: 12, approvedProfiles: 10 },
|
|
|
|
|
'/operator/analytics/v11-dashboard': { localEligibility: { pending: 99 } },
|
|
|
|
|
'/operator/activities': [],
|
|
|
|
|
'/operator/matchmaker/management/services': [
|
|
|
|
|
{ serviceId: 'demo', status: 'waiting_user', userDisplayNumber: 'YH2026051502', latestFollowupContent: 'Demo验收跟进', latestFollowupAt: new Date().toISOString() },
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
const exports = {};
|
|
|
|
|
const source = fs.readFileSync('admin-web/src/services/dashboard.ts', 'utf8');
|
|
|
|
|
vm.runInNewContext(ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS } }).outputText, {
|
|
|
|
|
exports,
|
|
|
|
|
require: () => ({ default: { get: async url => ({ success: true, data:
|
2026-10-25 09:06:15 +08:00
|
|
|
url === '/operator/workbench/dashboard' ? workbench : (url === '/operator/reviews/stats' ? { pending, processing: 1 } : responses[url]) }) } }),
|
2026-10-15 09:47:31 +08:00
|
|
|
});
|
|
|
|
|
const perms = ['analytics.view', 'activity.view', 'matchmaker.view', 'matchmaker.assign', 'review.view'];
|
|
|
|
|
let model = await exports.loadDashboard(perms);
|
2026-10-25 09:30:13 +08:00
|
|
|
const failedWorkbenchMetrics = ['pending_reviews', 'matchmaker_todos', 'counseling_todos', 'station_appointments', 'effective_matches', 'activity_registrations'];
|
|
|
|
|
for (const key of failedWorkbenchMetrics) {
|
|
|
|
|
const metric = model.metrics.find(m => m.key === key);
|
|
|
|
|
assert.equal(metric.value, 0, `${key} workbench 失败时不得使用旧接口 fallback`);
|
|
|
|
|
assert.equal(metric.available, false);
|
|
|
|
|
assert.equal(metric.status, 'error');
|
|
|
|
|
assert.equal(metric.route, '');
|
|
|
|
|
}
|
2026-10-15 09:47:31 +08:00
|
|
|
assert.equal(model.followups[0].content, 'Demo验收跟进');
|
|
|
|
|
assert.equal(exports.summarizeMatchmakerServices(responses['/operator/matchmaker/management/services']).total, 1);
|
2026-10-25 09:30:13 +08:00
|
|
|
assert.equal(model.metrics.find(m => m.key === 'matchmaker_todos').route, '');
|
2026-10-15 09:47:31 +08:00
|
|
|
pending = 1;
|
|
|
|
|
model = await exports.loadDashboard(perms);
|
2026-10-25 09:30:13 +08:00
|
|
|
assert.equal(model.metrics.find(m => m.key === 'pending_reviews').value, 0);
|
2026-10-25 09:06:15 +08:00
|
|
|
workbench = { metrics: {
|
|
|
|
|
pendingReviews: { value: 7, available: false },
|
|
|
|
|
matchmakerTodos: { value: 0, available: true },
|
|
|
|
|
} };
|
|
|
|
|
model = await exports.loadDashboard(perms);
|
|
|
|
|
const unavailableReview = model.metrics.find(m => m.key === 'pending_reviews');
|
|
|
|
|
assert.equal(unavailableReview.value, 7);
|
|
|
|
|
assert.equal(unavailableReview.available, false);
|
|
|
|
|
assert.equal(unavailableReview.route, '');
|
|
|
|
|
assert.equal(model.metrics.find(m => m.key === 'matchmaker_todos').value, 0);
|
2026-10-15 09:47:31 +08:00
|
|
|
assert.match(fs.readFileSync('admin-web/src/views/DashboardView.vue', 'utf8'), /onActivated\(retryLoad\)/);
|
|
|
|
|
console.log('PASS: 审核队列真实计数、审核后减一、管理服务待办与跟进、缓存返回刷新');
|
|
|
|
|
})().catch(error => { console.error(error); process.exitCode = 1; });
|