feat: 剪辑规划器完整交互 — 7大配置面板 + 时间轴拖拽/缩放/播放头 + 预览播放器 (#284)
CI/CD Pipeline / Build Staging API Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Failing after 1533h11m48s
CI/CD Pipeline / Build Production Web Image (push) Failing after 1533h11m51s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 1533h11m51s
CI/CD Pipeline / Build Production API Image (push) Failing after 1533h11m51s
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been skipped
CI/CD Pipeline / Unit Tests (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Failing after 1533h43m28s

This commit was merged in pull request #284.
This commit is contained in:
2026-07-14 18:15:55 +08:00
parent c88be032c1
commit 78d1c88ca1
53 changed files with 13521 additions and 894 deletions
+80 -3
View File
@@ -5,6 +5,32 @@
import apiClient from "./client";
import { getOrCreateDefaultProject } from "./projects";
/** 素材元数据 */
export interface AssetMetadata {
/** 时长(秒) */
duration?: number;
/** 宽度(像素) */
width?: number;
/** 高度(像素) */
height?: number;
/** 比特率(bps) */
bitrate?: number;
/** 编码格式 */
codec?: string;
/** 帧率 */
fps?: number;
/** 采样率(Hz) */
sample_rate?: number;
/** 声道数 */
channels?: number;
/** 其他扩展字段 */
[key: string]: unknown;
}
/** 素材分类状态 */
export type AssetClassificationStatus =
"pending" | "processing" | "completed" | "failed";
/** 素材条目 */
export interface AssetItem {
id: string;
@@ -12,12 +38,14 @@ export interface AssetItem {
name: string;
storage_key: string;
mime_type: string;
metadata: Record<string, unknown>;
metadata: AssetMetadata;
file_size?: number;
file_url?: string;
thumbnail_url?: string;
/** 时长(秒),视频/音频素材由后端从 metadata 提取到顶层 */
duration?: number;
status?: string;
classification_status?: string | null;
classification_status?: AssetClassificationStatus | null;
quality_score?: number | null;
tag_ids?: string[];
created_at?: string;
@@ -167,7 +195,7 @@ export const createAsset = async (data: {
name: string;
storage_key: string;
mime_type: string;
metadata?: Record<string, unknown>;
metadata?: AssetMetadata;
}): Promise<AssetItem> => {
const response = await apiClient.post("/assets", data);
return response.data;
@@ -350,3 +378,52 @@ export const getClassificationJob = async (
const response = await apiClient.get(`/classification-jobs/${jobId}`);
return response.data;
};
// ─── 批量操作 ───────────────────────────────────────────────
/** 批量操作结果 */
export interface BatchOperationResult {
succeeded: string[];
failed: string[];
total: number;
success_count: number;
failure_count: number;
}
/** 批量删除素材 */
export const batchDeleteAssets = async (
assetIds: string[],
): Promise<BatchOperationResult> => {
const response = await apiClient.post("/assets/batch-delete", {
asset_ids: assetIds,
});
return response.data;
};
/** 批量打标签 */
export const batchTagAssets = async (data: {
asset_ids: string[];
tags: string[];
mode: "add" | "replace";
}): Promise<BatchOperationResult> => {
const response = await apiClient.post("/assets/batch-tag", data);
return response.data;
};
/** 批量改分类 */
export const batchClassifyAssets = async (data: {
asset_ids: string[];
category: string;
}): Promise<BatchOperationResult> => {
const response = await apiClient.post("/assets/batch-classify", data);
return response.data;
};
/** 批量智能标记 */
export const batchMarkAssets = async (data: {
asset_ids: string[];
smart_view: "recommended" | "caution" | "high_risk";
}): Promise<BatchOperationResult> => {
const response = await apiClient.post("/assets/batch-mark", data);
return response.data;
};