chenpei 4712175cb0 feat(素材链路): 发布白底图双轨与AI生图回传能力
- 完成白底图 WebP 双轨接口、上传链路与预览缓存改造
- 新增 AI 生图平台成品回传接口、任务状态与表单规则
- 补齐 AI 生成标签、任务详情补全、相关测试与对接文档
2026-03-25 10:28:02 +08:00

76 lines
2.7 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { updateMaterialWithSharedRules, type MaterialUpdateInput } from '@/lib/material-update';
import { isWebFileLike } from '@/lib/web-file';
// PUT /api/materials/update - 更新素材(包括预览图)
export async function PUT(request: NextRequest) {
try {
const session = await getServerSession(authOptions);
if (!session?.user) {
return NextResponse.json({ error: '请先登录' }, { status: 401 });
}
const contentType = request.headers.get('content-type') || '';
let id = '';
let input: MaterialUpdateInput;
let previewImage: File | null = null;
if (contentType.includes('multipart/form-data')) {
const formData = await request.formData();
id = String(formData.get('id') || '');
input = {
productModel: String(formData.get('productModel') || ''),
categoryName: formData.get('categoryName') as string | null,
sceneName: formData.get('sceneName') as string | null,
platformName: formData.get('platformName') as string | null,
productCategoryName: formData.get('productCategoryName') as string | null,
materialType: String(formData.get('materialType') || ''),
renderer: formData.get('renderer') as string | null,
authorName: String(formData.get('authorName') || ''),
userId: formData.get('userId') as string | null,
taskNo: formData.get('taskNo') as string | null,
isFullSet: formData.get('isFullSet') as string | null,
};
const formPreview = formData.get('previewImage');
previewImage = isWebFileLike(formPreview) ? formPreview : null;
} else {
const json = await request.json();
id = String(json.id || '');
input = json;
}
if (!id) {
return NextResponse.json({ error: '缺少素材ID' }, { status: 400 });
}
const user = session.user as any;
const result = await updateMaterialWithSharedRules({
materialId: id,
operatorUserId: user.id,
operatorRole: user.role,
input,
previewImage,
});
if ('error' in result) {
return NextResponse.json({ error: result.error }, { status: result.status });
}
const response = {
...result.material,
zipFileSize: result.material.zipFileSize.toString(),
isFullSet: Boolean((result.material as any).isFullSet),
};
return NextResponse.json(
{ message: '更新成功', material: response },
{ status: 200 }
);
} catch (error) {
console.error('Update error:', error);
return NextResponse.json({ error: '更新失败,请稍后再试' }, { status: 500 });
}
}