后台详情弹窗展示原图
素材查询详情弹窗并列展示原图与当前结果 精选审核详情弹窗保留原有元信息并补充原图 管理快照与后台 DTO 传递源资源媒体字段 限制源资源字段仅在后台审核读取路径回填 更新后台素材预览的架构踩坑说明
This commit is contained in:
@@ -362,6 +362,10 @@ export interface AdminEditorAssetPayload {
|
||||
assetKind?: string | null;
|
||||
generationInputs?: Record<string, unknown> | null;
|
||||
sourceResourceId?: string | null;
|
||||
sourceImageSrc?: string | null;
|
||||
sourceObjectKey?: string | null;
|
||||
sourceAssetObjectId?: string | null;
|
||||
sourceLabel?: string | null;
|
||||
thumbnailSrc?: string | null;
|
||||
generationCostMudPoints: number;
|
||||
createdAt: string;
|
||||
@@ -404,6 +408,11 @@ export interface AdminEditorShowcaseAssetPayload {
|
||||
model?: string | null;
|
||||
provider?: string | null;
|
||||
taskId?: string | null;
|
||||
sourceResourceId?: string | null;
|
||||
sourceImageSrc?: string | null;
|
||||
sourceObjectKey?: string | null;
|
||||
sourceAssetObjectId?: string | null;
|
||||
sourceLabel?: string | null;
|
||||
assetKind?: string | null;
|
||||
generationInputs?: Record<string, unknown> | null;
|
||||
thumbnailSrc?: string | null;
|
||||
|
||||
@@ -25,6 +25,11 @@ export interface AdminPreviewableEditorAsset {
|
||||
thumbnailSrc?: string | null;
|
||||
imageSequenceFrames?: AdminEditorImageSequenceFramePayload[] | null;
|
||||
imageSequenceDurationMs?: number | null;
|
||||
sourceResourceId?: string | null;
|
||||
sourceImageSrc?: string | null;
|
||||
sourceObjectKey?: string | null;
|
||||
sourceAssetObjectId?: string | null;
|
||||
sourceLabel?: string | null;
|
||||
}
|
||||
|
||||
export function AdminEditorAssetThumbnail({
|
||||
@@ -70,6 +75,15 @@ export function AdminEditorAssetPreviewDialog({
|
||||
token: string;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const sourceEntry = entry.sourceImageSrc?.trim()
|
||||
? {
|
||||
assetId: entry.sourceResourceId ?? `${entry.assetId}-source`,
|
||||
label: entry.sourceLabel?.trim() || '原图',
|
||||
imageSrc: entry.sourceImageSrc,
|
||||
objectKey: entry.sourceObjectKey,
|
||||
}
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div className="admin-confirm-backdrop" role="presentation">
|
||||
<section
|
||||
@@ -91,13 +105,19 @@ export function AdminEditorAssetPreviewDialog({
|
||||
<X size={17} aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
{sourceEntry ? (
|
||||
<div className="admin-asset-query-source-preview">
|
||||
<h4>原图</h4>
|
||||
<AdminEditorAssetPreviewMedia entry={sourceEntry} token={token} />
|
||||
</div>
|
||||
) : null}
|
||||
<AdminEditorAssetPreviewMedia entry={entry} token={token} />
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AdminEditorAssetPreviewMedia({
|
||||
export function AdminEditorAssetPreviewMedia({
|
||||
entry,
|
||||
token,
|
||||
}: {
|
||||
@@ -716,7 +736,7 @@ function isAdminImageSequenceFrameUrlUsable(
|
||||
): cached is AdminImageSequenceFrameCacheEntry {
|
||||
return Boolean(
|
||||
cached?.resolvedUrl &&
|
||||
(cached.expiresAtMs === null || cached.expiresAtMs > Date.now()),
|
||||
(cached.expiresAtMs === null || cached.expiresAtMs > Date.now()),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {
|
||||
} from '../api/adminApiTypes';
|
||||
import {
|
||||
AdminEditorAssetPreviewDialog,
|
||||
AdminEditorAssetPreviewMedia,
|
||||
AdminEditorAssetThumbnail,
|
||||
} from '../components/AdminEditorAssetMedia';
|
||||
import { AdminUserReferenceButton } from '../components/AdminUserReferenceButton';
|
||||
@@ -561,14 +562,34 @@ function AdminAssetDetailDialog({
|
||||
</button>
|
||||
</div>
|
||||
<div className="admin-asset-query-detail-layout">
|
||||
<button
|
||||
className="admin-asset-query-thumb-button admin-asset-query-detail-thumb-button"
|
||||
title="预览素材"
|
||||
type="button"
|
||||
onClick={() => onPreview(entry)}
|
||||
>
|
||||
<AdminEditorAssetThumbnail entry={entry} token={token} />
|
||||
</button>
|
||||
<div className="admin-asset-query-detail-media">
|
||||
{entry.sourceImageSrc?.trim() ? (
|
||||
<div className="admin-asset-query-detail-media-card">
|
||||
<h4>原图</h4>
|
||||
<AdminEditorAssetPreviewMedia
|
||||
entry={{
|
||||
assetId:
|
||||
entry.sourceResourceId ?? `${entry.assetId}-source`,
|
||||
label: entry.sourceLabel?.trim() || '原图',
|
||||
imageSrc: entry.sourceImageSrc,
|
||||
objectKey: entry.sourceObjectKey,
|
||||
}}
|
||||
token={token}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="admin-asset-query-detail-media-card">
|
||||
<h4>当前结果</h4>
|
||||
<button
|
||||
className="admin-asset-query-thumb-button admin-asset-query-detail-thumb-button"
|
||||
title="预览素材"
|
||||
type="button"
|
||||
onClick={() => onPreview(entry)}
|
||||
>
|
||||
<AdminEditorAssetThumbnail entry={entry} token={token} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<dl className="admin-info-list admin-detail-list">
|
||||
<AdminInfoItem label="作者">
|
||||
<div className="admin-inline-identity">
|
||||
|
||||
@@ -17,6 +17,7 @@ import type {
|
||||
} from '../api/adminApiTypes';
|
||||
import {
|
||||
AdminEditorAssetPreviewDialog,
|
||||
AdminEditorAssetPreviewMedia,
|
||||
AdminEditorAssetThumbnail,
|
||||
} from '../components/AdminEditorAssetMedia';
|
||||
import { AdminUserReferenceButton } from '../components/AdminUserReferenceButton';
|
||||
@@ -709,18 +710,38 @@ function AdminShowcaseDetailDialog({
|
||||
</button>
|
||||
</div>
|
||||
<div className="admin-asset-query-detail-layout">
|
||||
<button
|
||||
className="admin-asset-query-thumb-button admin-asset-query-detail-thumb-button"
|
||||
title="预览素材"
|
||||
type="button"
|
||||
onClick={() => onPreview(entry)}
|
||||
>
|
||||
<AdminEditorAssetThumbnail
|
||||
entry={entry}
|
||||
token={token}
|
||||
altPrefix="精选素材"
|
||||
/>
|
||||
</button>
|
||||
<div className="admin-asset-query-detail-media">
|
||||
{entry.sourceImageSrc?.trim() ? (
|
||||
<div className="admin-asset-query-detail-media-card">
|
||||
<h4>原图</h4>
|
||||
<AdminEditorAssetPreviewMedia
|
||||
entry={{
|
||||
assetId:
|
||||
entry.sourceResourceId ?? `${entry.assetId}-source`,
|
||||
label: entry.sourceLabel?.trim() || '原图',
|
||||
imageSrc: entry.sourceImageSrc,
|
||||
objectKey: entry.sourceObjectKey,
|
||||
}}
|
||||
token={token}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="admin-asset-query-detail-media-card">
|
||||
<h4>当前结果</h4>
|
||||
<button
|
||||
className="admin-asset-query-thumb-button admin-asset-query-detail-thumb-button"
|
||||
title="预览素材"
|
||||
type="button"
|
||||
onClick={() => onPreview(entry)}
|
||||
>
|
||||
<AdminEditorAssetThumbnail
|
||||
entry={entry}
|
||||
token={token}
|
||||
altPrefix="精选素材"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<dl className="admin-info-list admin-detail-list">
|
||||
<AdminInfoItem label="作者">
|
||||
<div className="admin-inline-identity">
|
||||
|
||||
@@ -1655,6 +1655,18 @@ button:disabled {
|
||||
width: min(100%, 860px);
|
||||
}
|
||||
|
||||
.admin-asset-query-source-preview {
|
||||
margin: 0 20px 16px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.admin-asset-query-source-preview h4 {
|
||||
margin: 0 0 8px;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.admin-asset-query-prompt-dialog .admin-panel-heading > div,
|
||||
.admin-asset-query-detail-dialog .admin-panel-heading > div,
|
||||
.admin-asset-query-preview-dialog .admin-panel-heading > div {
|
||||
@@ -1683,6 +1695,27 @@ button:disabled {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.admin-asset-query-detail-media {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.admin-asset-query-detail-media-card {
|
||||
display: grid;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.admin-asset-query-detail-media-card h4 {
|
||||
margin: 0;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.admin-asset-query-detail-media-card .admin-asset-query-preview-media {
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
}
|
||||
|
||||
.admin-asset-query-detail-thumb-button .admin-asset-query-thumb {
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
@@ -2332,6 +2365,10 @@ button:disabled {
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.admin-asset-query-detail-media {
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.admin-dashboard-tabs {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -548,6 +548,8 @@
|
||||
|
||||
## 后台素材查询不要用 SQL 直查 editor_asset
|
||||
|
||||
- 后台审核与素材查询的图片预览若要显示像素化原图,应由后台 read model 在 `sourceResourceId` 关联的项目资源上预先透传原图媒体引用,再复用管理员换签;不要让 admin-web 直接查询私有 `editor_project_resource`。
|
||||
|
||||
- 现象:后台“素材查询”报 `HTTP 400:no such table: editor_asset. If the table exists, it may be marked private.`。
|
||||
- 原因:`editor_asset` 是私有 SpacetimeDB 表,后台 SQL / schema HTTP 查询面看不到私有表;即使 api-server 有后台身份,也不能把私有表当 Dashboard SQL 表直接查。
|
||||
- 处理:后台素材查询走 `spacetime-module` 内的 `admin_list_editor_assets_and_return` procedure,由 `spacetime-client` typed facade 调用后再在 `api-server` 映射作者展示名和陶泥号。新增类似后台只读能力时,优先补窄 procedure / read model,不要复用 `fetch_admin_dashboard_rows` 直查私有源表。
|
||||
|
||||
@@ -1096,6 +1096,11 @@ fn admin_editor_showcase_asset_payload_from_record(
|
||||
model: record.model,
|
||||
provider: record.provider,
|
||||
task_id: record.task_id,
|
||||
source_resource_id: record.source_resource_id,
|
||||
source_image_src: record.source_image_src,
|
||||
source_object_key: record.source_object_key,
|
||||
source_asset_object_id: record.source_asset_object_id,
|
||||
source_label: record.source_label,
|
||||
asset_kind,
|
||||
generation_inputs: sanitize_editor_generation_inputs(record.generation_inputs),
|
||||
thumbnail_src: record.thumbnail_src,
|
||||
@@ -1250,6 +1255,10 @@ fn admin_editor_asset_payload_from_record(
|
||||
asset_kind,
|
||||
generation_inputs: sanitize_editor_generation_inputs(record.generation_inputs),
|
||||
source_resource_id: record.source_resource_id,
|
||||
source_image_src: record.source_image_src,
|
||||
source_object_key: record.source_object_key,
|
||||
source_asset_object_id: record.source_asset_object_id,
|
||||
source_label: record.source_label,
|
||||
thumbnail_src: record.thumbnail_src,
|
||||
generation_cost_mud_points: record.generation_cost_mud_points,
|
||||
created_at: record.created_at,
|
||||
@@ -4136,6 +4145,10 @@ mod tests {
|
||||
provider: None,
|
||||
task_id: None,
|
||||
source_resource_id: None,
|
||||
source_image_src: None,
|
||||
source_object_key: None,
|
||||
source_asset_object_id: None,
|
||||
source_label: None,
|
||||
asset_kind: Some("character".to_string()),
|
||||
generation_inputs: None,
|
||||
thumbnail_src: None,
|
||||
@@ -4187,6 +4200,10 @@ mod tests {
|
||||
asset_kind: Some("character".to_string()),
|
||||
generation_inputs: None,
|
||||
source_resource_id: None,
|
||||
source_image_src: None,
|
||||
source_object_key: None,
|
||||
source_asset_object_id: None,
|
||||
source_label: None,
|
||||
thumbnail_src: None,
|
||||
generation_cost_mud_points,
|
||||
created_at: "2026-07-04T10:00:00Z".to_string(),
|
||||
|
||||
@@ -14612,6 +14612,10 @@ mod tests {
|
||||
provider: None,
|
||||
task_id: None,
|
||||
source_resource_id: None,
|
||||
source_image_src: None,
|
||||
source_object_key: None,
|
||||
source_asset_object_id: None,
|
||||
source_label: None,
|
||||
asset_kind: None,
|
||||
generation_inputs: None,
|
||||
thumbnail_src: None,
|
||||
|
||||
@@ -247,6 +247,10 @@ pub struct AdminEditorAssetPayload {
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs: Option<Value>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
pub generation_cost_mud_points: u64,
|
||||
pub created_at: String,
|
||||
@@ -295,6 +299,11 @@ pub struct AdminEditorShowcaseAssetPayload {
|
||||
pub model: Option<String>,
|
||||
pub provider: Option<String>,
|
||||
pub task_id: Option<String>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs: Option<Value>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
|
||||
@@ -166,6 +166,10 @@ pub struct AdminEditorAssetRecord {
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs: Option<serde_json::Value>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
pub generation_cost_mud_points: u64,
|
||||
pub created_at: String,
|
||||
@@ -198,6 +202,10 @@ pub struct EditorShowcaseAssetRecord {
|
||||
pub provider: Option<String>,
|
||||
pub task_id: Option<String>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs: Option<serde_json::Value>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
@@ -1496,6 +1504,10 @@ fn map_admin_editor_asset_snapshot(
|
||||
asset_kind: snapshot.asset_kind,
|
||||
generation_inputs,
|
||||
source_resource_id: snapshot.source_resource_id,
|
||||
source_image_src: snapshot.source_image_src,
|
||||
source_object_key: snapshot.source_object_key,
|
||||
source_asset_object_id: snapshot.source_asset_object_id,
|
||||
source_label: snapshot.source_label,
|
||||
thumbnail_src: snapshot.thumbnail_src,
|
||||
generation_cost_mud_points: snapshot.generation_cost_mud_points,
|
||||
created_at: format_timestamp_micros(snapshot.created_at_micros),
|
||||
@@ -1533,6 +1545,10 @@ fn map_editor_showcase_asset_snapshot(
|
||||
provider: snapshot.provider,
|
||||
task_id: snapshot.task_id,
|
||||
source_resource_id: snapshot.source_resource_id,
|
||||
source_image_src: snapshot.source_image_src,
|
||||
source_object_key: snapshot.source_object_key,
|
||||
source_asset_object_id: snapshot.source_asset_object_id,
|
||||
source_label: snapshot.source_label,
|
||||
asset_kind: snapshot.asset_kind,
|
||||
generation_inputs,
|
||||
thumbnail_src: snapshot.thumbnail_src,
|
||||
|
||||
@@ -165,6 +165,10 @@ pub struct AdminEditorAssetRecord {
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs: Option<serde_json::Value>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
pub generation_cost_mud_points: u64,
|
||||
pub created_at: String,
|
||||
@@ -197,6 +201,10 @@ pub struct EditorShowcaseAssetRecord {
|
||||
pub provider: Option<String>,
|
||||
pub task_id: Option<String>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs: Option<serde_json::Value>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
@@ -1380,6 +1388,10 @@ fn map_editor_project_resource_snapshot(
|
||||
provider: snapshot.provider,
|
||||
task_id: snapshot.task_id,
|
||||
source_resource_id: snapshot.source_resource_id,
|
||||
source_image_src: snapshot.source_image_src,
|
||||
source_object_key: snapshot.source_object_key,
|
||||
source_asset_object_id: snapshot.source_asset_object_id,
|
||||
source_label: snapshot.source_label,
|
||||
asset_kind: snapshot.asset_kind,
|
||||
generation_inputs,
|
||||
public_showcase_enabled: snapshot.public_showcase_enabled,
|
||||
@@ -1532,6 +1544,10 @@ fn map_editor_showcase_asset_snapshot(
|
||||
provider: snapshot.provider,
|
||||
task_id: snapshot.task_id,
|
||||
source_resource_id: snapshot.source_resource_id,
|
||||
source_image_src: snapshot.source_image_src,
|
||||
source_object_key: snapshot.source_object_key,
|
||||
source_asset_object_id: snapshot.source_asset_object_id,
|
||||
source_label: snapshot.source_label,
|
||||
asset_kind: snapshot.asset_kind,
|
||||
generation_inputs,
|
||||
thumbnail_src: snapshot.thumbnail_src,
|
||||
|
||||
+4
@@ -25,6 +25,10 @@ pub struct AdminEditorAssetSnapshot {
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs_json: Option<String>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
pub generation_cost_mud_points: u64,
|
||||
pub created_at_micros: i64,
|
||||
|
||||
+4
@@ -23,6 +23,10 @@ pub struct EditorShowcaseAssetSnapshot {
|
||||
pub provider: Option<String>,
|
||||
pub task_id: Option<String>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs_json: Option<String>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
|
||||
@@ -879,6 +879,10 @@ pub struct AdminEditorAssetSnapshot {
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs_json: Option<String>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
pub generation_cost_mud_points: u64,
|
||||
pub created_at_micros: i64,
|
||||
@@ -912,6 +916,10 @@ pub struct EditorShowcaseAssetSnapshot {
|
||||
pub provider: Option<String>,
|
||||
pub task_id: Option<String>,
|
||||
pub source_resource_id: Option<String>,
|
||||
pub source_image_src: Option<String>,
|
||||
pub source_object_key: Option<String>,
|
||||
pub source_asset_object_id: Option<String>,
|
||||
pub source_label: Option<String>,
|
||||
pub asset_kind: Option<String>,
|
||||
pub generation_inputs_json: Option<String>,
|
||||
pub thumbnail_src: Option<String>,
|
||||
@@ -3217,9 +3225,13 @@ fn admin_list_editor_assets(
|
||||
Ok(groups
|
||||
.into_iter()
|
||||
.flat_map(|(_, group_task_id, assets)| {
|
||||
assets
|
||||
.into_iter()
|
||||
.map(move |row| admin_asset_snapshot_from_row(row, group_task_id.clone()))
|
||||
assets.into_iter().map(move |row| {
|
||||
let source = row
|
||||
.source_resource_id
|
||||
.as_ref()
|
||||
.and_then(|id| ctx.db.editor_project_resource().resource_id().find(id));
|
||||
admin_asset_snapshot_from_row(row, group_task_id.clone(), source.as_ref())
|
||||
})
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
@@ -6405,7 +6417,7 @@ fn admin_list_editor_showcase_assets(
|
||||
cursor.as_ref(),
|
||||
)
|
||||
})
|
||||
.map(showcase_snapshot_from_row)
|
||||
.map(|asset| showcase_snapshot_from_row_with_ctx(Some(ctx), asset))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assets.sort_by(|left, right| {
|
||||
@@ -6436,7 +6448,7 @@ fn admin_review_editor_showcase_asset(
|
||||
if asset.review_status == EDITOR_SHOWCASE_STATUS_APPROVED
|
||||
&& review_status == EDITOR_SHOWCASE_STATUS_APPROVED
|
||||
{
|
||||
return Ok(showcase_snapshot_from_row(asset));
|
||||
return Ok(showcase_snapshot_from_row_with_ctx(Some(ctx), asset));
|
||||
}
|
||||
return Err("只有待审核素材可以审核".to_string());
|
||||
}
|
||||
@@ -7835,6 +7847,16 @@ fn asset_folder_snapshot_from_row(row: EditorAssetFolder) -> EditorAssetFolderSn
|
||||
}
|
||||
|
||||
fn showcase_snapshot_from_row(row: EditorShowcaseAsset) -> EditorShowcaseAssetSnapshot {
|
||||
showcase_snapshot_from_row_with_ctx(None, row)
|
||||
}
|
||||
|
||||
fn showcase_snapshot_from_row_with_ctx(
|
||||
ctx: Option<&ReducerContext>,
|
||||
row: EditorShowcaseAsset,
|
||||
) -> EditorShowcaseAssetSnapshot {
|
||||
let source = row.source_resource_id.as_ref().and_then(|id| {
|
||||
ctx.and_then(|value| value.db.editor_project_resource().resource_id().find(id))
|
||||
});
|
||||
EditorShowcaseAssetSnapshot {
|
||||
showcase_id: row.showcase_id,
|
||||
asset_id: row.asset_id,
|
||||
@@ -7852,6 +7874,12 @@ fn showcase_snapshot_from_row(row: EditorShowcaseAsset) -> EditorShowcaseAssetSn
|
||||
provider: row.provider,
|
||||
task_id: row.task_id,
|
||||
source_resource_id: row.source_resource_id,
|
||||
source_image_src: source.as_ref().map(|value| value.image_src.clone()),
|
||||
source_object_key: source.as_ref().and_then(|value| value.object_key.clone()),
|
||||
source_asset_object_id: source
|
||||
.as_ref()
|
||||
.and_then(|value| value.asset_object_id.clone()),
|
||||
source_label: source.as_ref().and_then(|value| value.prompt.clone()),
|
||||
asset_kind: row.asset_kind,
|
||||
generation_inputs_json: row.generation_inputs_json,
|
||||
thumbnail_src: row.thumbnail_src,
|
||||
@@ -8362,6 +8390,7 @@ fn asset_snapshot_from_row(ctx: &ReducerContext, row: EditorAsset) -> EditorAsse
|
||||
fn admin_asset_snapshot_from_row(
|
||||
row: EditorAsset,
|
||||
group_task_id: Option<String>,
|
||||
source: Option<&EditorProjectResource>,
|
||||
) -> AdminEditorAssetSnapshot {
|
||||
AdminEditorAssetSnapshot {
|
||||
asset_id: row.asset_id,
|
||||
@@ -8382,6 +8411,10 @@ fn admin_asset_snapshot_from_row(
|
||||
asset_kind: row.asset_kind,
|
||||
generation_inputs_json: row.generation_inputs_json,
|
||||
source_resource_id: row.source_resource_id,
|
||||
source_image_src: source.map(|value| value.image_src.clone()),
|
||||
source_object_key: source.and_then(|value| value.object_key.clone()),
|
||||
source_asset_object_id: source.and_then(|value| value.asset_object_id.clone()),
|
||||
source_label: source.and_then(|value| value.prompt.clone()),
|
||||
thumbnail_src: row.thumbnail_src,
|
||||
generation_cost_mud_points: row.generation_cost_mud_points,
|
||||
created_at_micros: row.created_at.to_micros_since_unix_epoch(),
|
||||
@@ -20685,7 +20718,7 @@ mod tests {
|
||||
admin_editor_asset_group_task_id_with(&slice, &mut task_id_aliases, |_, _| {
|
||||
panic!("persisted group must not depend on project resources")
|
||||
});
|
||||
let snapshot = admin_asset_snapshot_from_row(slice, group_task_id);
|
||||
let snapshot = admin_asset_snapshot_from_row(slice, group_task_id, None);
|
||||
|
||||
assert_eq!(snapshot.task_id.as_deref(), Some(split_task_id));
|
||||
assert_eq!(snapshot.group_task_id.as_deref(), Some(source_task_id));
|
||||
|
||||
Reference in New Issue
Block a user