feat: add media access analytics

This commit is contained in:
Codex
2026-06-29 20:30:00 +08:00
parent e0393126a1
commit 38db867d58
11 changed files with 749 additions and 5 deletions

View File

@@ -273,6 +273,82 @@ export interface ImportTemplateItem {
fields?: Record<string, unknown>[];
}
export interface MediaAnalyticsSummary {
scope?: Record<string, unknown>;
assetAccess?: {
totalEvents?: number;
grantedEvents?: number;
deniedEvents?: number;
downloads?: number;
previews?: number;
uploadSigns?: number;
uploadConfirms?: number;
uniqueUsers?: number;
watermarkEvents?: number;
};
videoPlay?: {
totalEvents?: number;
issuedEvents?: number;
startedEvents?: number;
completedEvents?: number;
freePlays?: number;
svipPlays?: number;
quotaPlays?: number;
consumedQuota?: number;
uniqueUsers?: number;
watermarkEvents?: number;
};
assetTop?: Record<string, unknown>[];
videoTop?: Record<string, unknown>[];
daily?: Record<string, number | string>[];
traceMatches?: { assets?: number; videos?: number } | null;
}
export interface MediaAssetAccessEvent {
id: string;
assetId?: string | null;
assetTitle?: string | null;
assetType?: string | null;
userId?: string | null;
userLabel?: string | null;
actorRole?: string;
accessType?: string;
visibility?: string | null;
storageProvider?: string | null;
disposition?: string | null;
expiresInSec?: number | null;
signatureMode?: string | null;
result?: string;
denyCode?: string | null;
ipAddress?: string | null;
userAgent?: string | null;
watermarkTraceId?: string | null;
watermark?: Record<string, unknown> | null;
createdAt?: string;
}
export interface MediaVideoPlayEvent {
id: string;
videoId?: string;
videoTitle?: string | null;
assetId?: string | null;
questionId?: string | null;
userId?: string;
userLabel?: string | null;
status?: string;
accessMode?: string;
consumedQuota?: number;
signedUrlExpiresAt?: string | null;
ipAddress?: string | null;
userAgent?: string | null;
signatureMode?: string | null;
provider?: string | null;
watermarkTraceId?: string | null;
watermark?: Record<string, unknown> | null;
createdAt?: string;
updatedAt?: string;
}
export interface ImportPreviewResult {
job?: {
id: string;
@@ -811,6 +887,45 @@ export async function loadImportTemplate(importType: string, format: 'json' | 'c
});
}
export async function loadMediaAnalyticsSummary(query: {
timeRange?: '7d' | '30d' | '90d';
assetId?: string;
videoId?: string;
userId?: string;
traceId?: string;
limit?: number;
} = {}) {
return apiRequest<MediaAnalyticsSummary>('/api/tenant-content/media-analytics/summary', { query });
}
export async function loadMediaAssetAccessEvents(query: {
timeRange?: '7d' | '30d' | '90d';
assetId?: string;
userId?: string;
accessType?: string;
result?: 'granted' | 'denied';
traceId?: string;
limit?: number;
} = {}) {
return apiRequest<{ scope?: Record<string, unknown>; items?: MediaAssetAccessEvent[] }>('/api/tenant-content/media-analytics/asset-events', {
query: { ...query, limit: query.limit || 100 },
});
}
export async function loadMediaVideoPlayEvents(query: {
timeRange?: '7d' | '30d' | '90d';
videoId?: string;
userId?: string;
accessMode?: 'free' | 'svip' | 'video_quota';
status?: 'issued' | 'started' | 'completed' | 'expired' | 'revoked';
traceId?: string;
limit?: number;
} = {}) {
return apiRequest<{ scope?: Record<string, unknown>; items?: MediaVideoPlayEvent[] }>('/api/tenant-content/media-analytics/video-events', {
query: { ...query, limit: query.limit || 100 },
});
}
export async function previewContentImport(importType: ImportType, body: ImportRequestBody) {
return apiRequest<ImportPreviewResult>(`/api/tenant-content/imports/preview/${importType}`, {
method: 'POST',