auto-save 2026-05-19 00:45 (~5)
This commit is contained in:
@@ -246,6 +246,19 @@
|
|||||||
"message": "auto-save 2026-05-19 00:34 (~2)",
|
"message": "auto-save 2026-05-19 00:34 (~2)",
|
||||||
"hash": "50fde2f",
|
"hash": "50fde2f",
|
||||||
"files_changed": 2
|
"files_changed": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-19T00:40:25+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-19 00:40 (~4)",
|
||||||
|
"hash": "a04284e",
|
||||||
|
"files_changed": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-18T16:43:51Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 5 项未提交变更 · 最近提交:auto-save 2026-05-19 00:40 (~4)",
|
||||||
|
"files_changed": 5
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
PACK_ORDER,
|
PACK_ORDER,
|
||||||
PACK_TEMPLATES,
|
PACK_TEMPLATES,
|
||||||
TEMPLATE_FREEZE_VERSION,
|
TEMPLATE_FREEZE_VERSION,
|
||||||
|
TEMPLATE_SLOT_SUMMARY,
|
||||||
VIDEO_TEMPLATES,
|
VIDEO_TEMPLATES,
|
||||||
} from '@/lib/templates';
|
} from '@/lib/templates';
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ export async function GET() {
|
|||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
templateFreezeVersion: TEMPLATE_FREEZE_VERSION,
|
templateFreezeVersion: TEMPLATE_FREEZE_VERSION,
|
||||||
filenameSchema: FILENAME_SCHEMA,
|
filenameSchema: FILENAME_SCHEMA,
|
||||||
|
summary: TEMPLATE_SLOT_SUMMARY,
|
||||||
characterSpecFields: CHARACTER_SPEC_FIELDS,
|
characterSpecFields: CHARACTER_SPEC_FIELDS,
|
||||||
packs: PACK_ORDER.map(kind => ({
|
packs: PACK_ORDER.map(kind => ({
|
||||||
kind,
|
kind,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import type { AssetPack, AssetTemplate, GenImage, GenSession, PackKind, ToyAsset } from '@/lib/types';
|
import type { AssetPack, AssetTemplate, GenImage, GenSession, PackKind, ToyAsset } from '@/lib/types';
|
||||||
import { PACK_LABELS, PACK_ORDER, PACK_TEMPLATES, VIDEO_TEMPLATES } from '@/lib/templates';
|
import { PACK_LABELS, PACK_ORDER, PACK_TEMPLATES, TEMPLATE_SLOT_SUMMARY, VIDEO_TEMPLATES } from '@/lib/templates';
|
||||||
|
|
||||||
const PACK_DESCRIPTIONS: Record<PackKind, string> = {
|
const PACK_DESCRIPTIONS: Record<PackKind, string> = {
|
||||||
patent: '六面视图、45° 立体图、局部放大——外观专利素材',
|
patent: '六面视图、45° 立体图、局部放大——外观专利素材',
|
||||||
@@ -287,6 +287,26 @@ function VideoSection({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SlotOverview() {
|
||||||
|
const stats = [
|
||||||
|
{ label: '图片/脚本资产位', value: TEMPLATE_SLOT_SUMMARY.imageAssetCount },
|
||||||
|
{ label: '必备图位', value: TEMPLATE_SLOT_SUMMARY.requiredImageAssetCount },
|
||||||
|
{ label: '可选扩展位', value: TEMPLATE_SLOT_SUMMARY.optionalImageAssetCount },
|
||||||
|
{ label: 'Seedance 视频任务', value: TEMPLATE_SLOT_SUMMARY.videoTaskCount },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="grid grid-cols-4 gap-2">
|
||||||
|
{stats.map(item => (
|
||||||
|
<div key={item.label} className="rounded-2xl bg-white/[0.035] ring-1 ring-white/[0.08] p-3">
|
||||||
|
<div className="text-lg font-semibold text-white font-mono">{item.value}</div>
|
||||||
|
<div className="mt-1 text-[10px] text-white/40">{item.label}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function PackPanel({
|
export default function PackPanel({
|
||||||
session,
|
session,
|
||||||
loadingKind,
|
loadingKind,
|
||||||
@@ -379,6 +399,8 @@ export default function PackPanel({
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<SlotOverview />
|
||||||
|
|
||||||
{session.characterSpec && (
|
{session.characterSpec && (
|
||||||
<div className="card-2 p-4">
|
<div className="card-2 p-4">
|
||||||
<div className="flex items-center justify-between gap-3 mb-3">
|
<div className="flex items-center justify-between gap-3 mb-3">
|
||||||
|
|||||||
@@ -722,6 +722,24 @@ export const PACK_TEMPLATES: Record<PackKind, AssetTemplate[]> = {
|
|||||||
marketing: MARKETING_TEMPLATES,
|
marketing: MARKETING_TEMPLATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const PACK_TEMPLATE_SUMMARY = PACK_ORDER.map(kind => ({
|
||||||
|
kind,
|
||||||
|
label: PACK_LABELS[kind],
|
||||||
|
totalCount: PACK_TEMPLATES[kind].length,
|
||||||
|
requiredCount: PACK_TEMPLATES[kind].filter(template => template.required).length,
|
||||||
|
optionalCount: PACK_TEMPLATES[kind].filter(template => !template.required).length,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const TEMPLATE_SLOT_SUMMARY = {
|
||||||
|
templateFreezeVersion: TEMPLATE_FREEZE_VERSION,
|
||||||
|
imageAssetCount: PACK_TEMPLATE_SUMMARY.reduce((sum, pack) => sum + pack.totalCount, 0),
|
||||||
|
requiredImageAssetCount: PACK_TEMPLATE_SUMMARY.reduce((sum, pack) => sum + pack.requiredCount, 0),
|
||||||
|
optionalImageAssetCount: PACK_TEMPLATE_SUMMARY.reduce((sum, pack) => sum + pack.optionalCount, 0),
|
||||||
|
videoTaskCount: VIDEO_TEMPLATES.length,
|
||||||
|
storyboardAssetCount: MARKETING_TEMPLATES.filter(template => template.id.startsWith('video_')).length,
|
||||||
|
packSummary: PACK_TEMPLATE_SUMMARY,
|
||||||
|
};
|
||||||
|
|
||||||
export function getPackTemplates(kind: PackKind): AssetTemplate[] {
|
export function getPackTemplates(kind: PackKind): AssetTemplate[] {
|
||||||
return PACK_TEMPLATES[kind];
|
return PACK_TEMPLATES[kind];
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user