Initial commit: OmniAI Web Frontend
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import type { WebAssetItem } from "../types";
|
||||
import { isRecord, serverRequest } from "./serverConnection";
|
||||
|
||||
export interface ServerAssetItem extends WebAssetItem {
|
||||
id: string;
|
||||
url?: string | null;
|
||||
ossKey?: string | null;
|
||||
tags: string[];
|
||||
sourceTaskId?: string | null;
|
||||
sourceProjectId?: string | null;
|
||||
metadata?: Record<string, unknown>;
|
||||
createdAt?: string;
|
||||
}
|
||||
|
||||
export interface CreateAssetInput {
|
||||
type: WebAssetItem["type"] | "image" | "asset" | "other";
|
||||
name: string;
|
||||
description?: string;
|
||||
url?: string;
|
||||
imageUrl?: string;
|
||||
ossKey?: string;
|
||||
tags?: string[];
|
||||
status?: WebAssetItem["status"] | "pending" | "failed";
|
||||
sourceTaskId?: string;
|
||||
sourceProjectId?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface DeleteAssetOptions {
|
||||
cleanupUserData?: boolean;
|
||||
}
|
||||
|
||||
function toStringValue(value: unknown, fallback = ""): string {
|
||||
if (typeof value === "string") return value.trim() || fallback;
|
||||
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
||||
return fallback;
|
||||
}
|
||||
|
||||
function normalizeAssetType(value: unknown): WebAssetItem["type"] {
|
||||
const type = toStringValue(value);
|
||||
if (
|
||||
type === "character" ||
|
||||
type === "scene" ||
|
||||
type === "prop" ||
|
||||
type === "video" ||
|
||||
type === "image" ||
|
||||
type === "asset" ||
|
||||
type === "other"
|
||||
) {
|
||||
return type;
|
||||
}
|
||||
return "other";
|
||||
}
|
||||
|
||||
function normalizeAssetStatus(value: unknown): WebAssetItem["status"] {
|
||||
const status = toStringValue(value);
|
||||
if (
|
||||
status === "ready" ||
|
||||
status === "draft" ||
|
||||
status === "reviewing" ||
|
||||
status === "pending" ||
|
||||
status === "failed"
|
||||
) {
|
||||
return status;
|
||||
}
|
||||
return "ready";
|
||||
}
|
||||
|
||||
function normalizeTags(value: unknown): string[] {
|
||||
return Array.isArray(value) ? value.map((item) => toStringValue(item)).filter(Boolean) : [];
|
||||
}
|
||||
|
||||
function normalizeAsset(raw: unknown): ServerAssetItem {
|
||||
const item = isRecord(raw) ? raw : {};
|
||||
const url = toStringValue(item.url ?? item.imageUrl) || null;
|
||||
return {
|
||||
id: toStringValue(item.id, `asset-${Date.now()}`),
|
||||
type: normalizeAssetType(item.type),
|
||||
name: toStringValue(item.name, "未命名素材"),
|
||||
description: toStringValue(item.description, "从服务器资产库同步的素材。"),
|
||||
imageUrl: url || "",
|
||||
url,
|
||||
ossKey: toStringValue(item.ossKey ?? item.oss_key) || null,
|
||||
tags: normalizeTags(item.tags),
|
||||
status: normalizeAssetStatus(item.status),
|
||||
sourceTaskId: toStringValue(item.sourceTaskId ?? item.source_task_id) || null,
|
||||
sourceProjectId: toStringValue(item.sourceProjectId ?? item.source_project_id) || null,
|
||||
metadata: isRecord(item.metadata) ? item.metadata : {},
|
||||
createdAt: toStringValue(item.createdAt ?? item.created_at),
|
||||
updatedAt: toStringValue(item.updatedAt ?? item.updated_at, "刚刚"),
|
||||
};
|
||||
}
|
||||
|
||||
function extractAssets(payload: unknown): ServerAssetItem[] {
|
||||
if (Array.isArray(payload)) return payload.map(normalizeAsset);
|
||||
if (!isRecord(payload)) return [];
|
||||
const rows = payload.assets ?? payload.items;
|
||||
return Array.isArray(rows) ? rows.map(normalizeAsset) : [];
|
||||
}
|
||||
|
||||
export const assetClient = {
|
||||
async list(params?: { type?: string; q?: string; status?: string }): Promise<ServerAssetItem[]> {
|
||||
const search = new URLSearchParams();
|
||||
if (params?.type && params.type !== "all") search.set("type", params.type);
|
||||
if (params?.q) search.set("q", params.q);
|
||||
if (params?.status) search.set("status", params.status);
|
||||
const query = search.toString();
|
||||
return extractAssets(await serverRequest<unknown>(`assets${query ? `?${query}` : ""}`));
|
||||
},
|
||||
|
||||
async create(input: CreateAssetInput): Promise<ServerAssetItem> {
|
||||
const payload = await serverRequest<{ asset: unknown }>("assets", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
});
|
||||
return normalizeAsset(payload.asset ?? payload);
|
||||
},
|
||||
|
||||
async delete(id: string, options?: DeleteAssetOptions): Promise<void> {
|
||||
const path = options?.cleanupUserData ? `assets/${encodeURIComponent(id)}?cleanupUserData=1` : `assets/${encodeURIComponent(id)}`;
|
||||
await serverRequest(path, { method: "DELETE" });
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user