gongxiangp2/scripts/test-api-call.ts

171 lines
6.3 KiB
TypeScript

/**
* 模拟任务平台 API 调用测试
*/
import { prisma } from '../lib/prisma';
import { validateTaskNo, getMaterialByTaskNo } from '../lib/product-package';
import { generateDownloadUrl } from '../lib/download-token';
import { rewriteStorageUrlForClient } from '../lib/url-rewrite';
import { ASSET_TYPE, TASK_STATUS } from '../lib/product-package';
const TASK_NO = 'TASK202601141713525624-01';
const API_KEY = 'b78af0ec58a078105f63aaca3256918f'; // 从测试结果中获取的 API Key
async function testApiCall() {
console.log('==== 模拟任务平台 API 调用测试 ====\n');
try {
// 1. 验证任务号格式
console.log('1. 验证任务号格式...');
if (!validateTaskNo(TASK_NO)) {
console.log(' ❌ 任务号格式错误');
return;
}
console.log(' ✅ 任务号格式正确\n');
// 2. 查询素材
console.log('2. 查询素材...');
const material: any = await getMaterialByTaskNo(TASK_NO);
if (!material) {
console.log(' ❌ 未找到素材');
return;
}
console.log(' ✅ 找到素材:', {
id: material.id,
taskNo: material.taskNo,
materialType: material.materialType,
taskStatus: material.taskStatus,
assetsCount: material.assets?.length || 0,
});
console.log('');
// 3. 模拟接口处理逻辑
console.log('3. 模拟接口处理逻辑...');
if (material.materialType === '任务-详情') {
const mainAssets = (material.assets || []).filter((a: any) => a.assetType === ASSET_TYPE.MAIN);
const skuAssets = (material.assets || []).filter((a: any) => a.assetType === ASSET_TYPE.SKU);
const detailAssets = (material.assets || []).filter((a: any) => a.assetType === ASSET_TYPE.DETAIL);
const psdAssets = (material.assets || []).filter((a: any) => a.assetType === ASSET_TYPE.PSD);
console.log(` 资产分组: main=${mainAssets.length}, sku=${skuAssets.length}, detail=${detailAssets.length}, psd=${psdAssets.length}`);
// 模拟 formatAsset 函数
const baseUrl = 'https://3d.yydd.ai';
const formatAsset = (asset: any, downloadType: string) => {
try {
console.log(` 处理资产: ${asset.id}, type=${asset.assetType}, fileUrl=${asset.fileUrl || 'null'}`);
if (!asset || !asset.id) {
throw new Error(`Invalid asset data: ${JSON.stringify(asset)}`);
}
if (!asset.fileUrl) {
console.warn(` ⚠️ Asset has no fileUrl:`, {
assetId: asset.id,
assetType: asset.assetType,
fileName: asset.fileName,
});
}
if (!material.id) {
throw new Error(`Material has no id`);
}
// 模拟 request 对象
const mockRequest = {
headers: {
get: (name: string) => {
if (name === 'host') return '3d.yydd.ai';
if (name === 'x-forwarded-proto') return 'https';
return null;
},
},
} as any;
const rewrittenUrl = rewriteStorageUrlForClient(asset.fileUrl || '', mockRequest);
console.log(` rewrittenUrl: ${rewrittenUrl}`);
const downloadUrl = generateDownloadUrl(baseUrl, {
materialId: material.id,
downloadType: asset.assetType === ASSET_TYPE.PSD ? 'psd' : downloadType,
assetId: asset.assetType === ASSET_TYPE.PSD ? asset.id : undefined,
});
console.log(` downloadUrl: ${downloadUrl}`);
return {
id: asset.id,
url: rewrittenUrl,
downloadUrl,
fileName: asset.fileName || '',
fileSize: Number(asset.fileSize || 0),
...(asset.assetType === ASSET_TYPE.DETAIL && { sortOrder: asset.sortOrder || 0 }),
};
} catch (formatError) {
console.error(` ❌ Error formatting asset:`, formatError);
throw formatError;
}
};
console.log(' 开始格式化资产...');
const formattedMain = mainAssets.map((a: any) => formatAsset(a, 'main'));
const formattedSku = skuAssets.map((a: any) => formatAsset(a, 'sku'));
const formattedDetail = detailAssets.map((a: any) => formatAsset(a, 'detail'));
const formattedPsd = psdAssets.map((a: any) => formatAsset(a, 'psd'));
console.log(' ✅ 资产格式化完成');
console.log('');
// 生成下载链接
console.log('4. 生成下载链接...');
const downloadUrls = {
all: generateDownloadUrl(baseUrl, { materialId: material.id, downloadType: 'all' }),
main: generateDownloadUrl(baseUrl, { materialId: material.id, downloadType: 'main' }),
sku: generateDownloadUrl(baseUrl, { materialId: material.id, downloadType: 'sku' }),
detail: generateDownloadUrl(baseUrl, { materialId: material.id, downloadType: 'detail' }),
psd: psdAssets.length > 0 ? generateDownloadUrl(baseUrl, { materialId: material.id, downloadType: 'psd' }) : null,
};
console.log(' ✅ 下载链接生成完成');
console.log('');
// 构建响应数据
console.log('5. 构建响应数据...');
const responseData = {
taskNo: material.taskNo,
productModel: material.productModel,
categoryName: material.categoryName,
sceneName: material.sceneName,
status: TASK_STATUS.FETCHED,
createdAt: material.createdAt.toISOString(),
updatedAt: material.updatedAt.toISOString(),
assets: {
main: formattedMain,
sku: formattedSku,
detail: formattedDetail,
psd: formattedPsd,
},
downloadUrls,
};
console.log(' ✅ 响应数据构建完成');
console.log('');
console.log('==== 测试成功 ====');
console.log(JSON.stringify(responseData, null, 2));
} else {
console.log(' ⚠️ 素材类型不是任务-详情,跳过处理');
}
} catch (error) {
console.error('==== 测试失败 ====');
console.error('错误:', error);
if (error instanceof Error) {
console.error('错误消息:', error.message);
console.error('错误堆栈:', error.stack);
}
} finally {
await prisma.$disconnect();
}
}
testApiCall();