diff --git a/.gitignore b/.gitignore index 797bead..2fe7c0c 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,7 @@ web_modules/ # Optional eslint cache .eslintcache -.vscode/settings.json +.vscode/* # Optional prettier cache .prettiercache diff --git a/app/admin/manage/page.tsx b/app/admin/manage/page.tsx index b48bc54..486155f 100644 --- a/app/admin/manage/page.tsx +++ b/app/admin/manage/page.tsx @@ -218,7 +218,7 @@ const useFontList = (filters: { const res: ApiResponse = await requestPost('/api/fonts/list', { pageData: { page, size: PAGE_SIZE }, tags: filters.tags || undefined, - keywords: debouncedKeywords || undefined, + keyword: debouncedKeywords || undefined, languages: filters.languages || undefined, category: filters.category || undefined, }); diff --git a/app/api/css/route.ts b/app/api/css/route.ts index 30076a0..7eb6de9 100644 --- a/app/api/css/route.ts +++ b/app/api/css/route.ts @@ -194,7 +194,7 @@ export async function GET(request: NextRequest): Promise { }, }); } catch (error: any) { - Logger.error('CSS生成页面 - CSS生成接口错误:', error); + Logger.error('[API-css] CSS生成接口错误', error); return new NextResponse('/* 内部服务器错误 */', { status: 500, headers: { @@ -296,8 +296,8 @@ async function generateCSSResponseOriginal( const staticBaseRaw = APP_CONFIG.fontStaticUrl; if (!staticBaseRaw) { Logger.error( - 'CSS生成页面 - 缺少字体静态资源基础 URL。请在环境变量中设置 NEXT_PUBLIC_FONT_STATIC_URL 或 OSS_ENDPOINT。' - ); + '[API-css] 缺少字体静态资源基础 URL。请在环境变量中设置 NEXT_PUBLIC_FONT_STATIC_URL 或 OSS_ENDPOINT。' + ); throw new Error('缺少字体静态资源基础 URL'); } const staticBase = staticBaseRaw.replace(/\/+$/g, ''); @@ -342,7 +342,7 @@ async function generateCSSResponseOriginal( return cssContent; } catch (error: any) { - Logger.error('CSS生成页面 - 生成CSS响应时出错:', error); + Logger.error('[API-css] 生成CSS响应时出错', error); throw error; } } diff --git a/app/api/fonts/auto_update/[id]/route.ts b/app/api/fonts/auto_update/[id]/route.ts index 2d01910..e0356eb 100644 --- a/app/api/fonts/auto_update/[id]/route.ts +++ b/app/api/fonts/auto_update/[id]/route.ts @@ -32,7 +32,7 @@ export async function GET( message: 'success', }); } catch (error: any) { - Logger.error('字体管理页面 - 自动更新字体接口错误:', error); + Logger.error('[API-fonts/auto_update] 自动更新字体接口错误', error); return NextResponse.json( { code: 500, diff --git a/app/api/fonts/create/route.ts b/app/api/fonts/create/route.ts index 0a82fa3..51848e1 100644 --- a/app/api/fonts/create/route.ts +++ b/app/api/fonts/create/route.ts @@ -61,7 +61,7 @@ export async function POST( message: 'success', }); } catch (error: any) { - Logger.error('字体管理页面 - 创建字体接口错误:', error); + Logger.error('[API-fonts/create] 创建字体接口错误', error); return NextResponse.json( { code: 500, diff --git a/app/api/fonts/delete/route.ts b/app/api/fonts/delete/route.ts index 5007738..de5030a 100644 --- a/app/api/fonts/delete/route.ts +++ b/app/api/fonts/delete/route.ts @@ -32,7 +32,7 @@ export async function POST( message: 'success', }); } catch (error: any) { - Logger.error('字体管理页面 - 删除字体接口错误:', error); + Logger.error('[API-fonts/delete] 删除字体接口错误', error); return NextResponse.json( { code: 500, diff --git a/app/api/fonts/detail/[id]/route.ts b/app/api/fonts/detail/[id]/route.ts index b0d3f97..f6bf433 100644 --- a/app/api/fonts/detail/[id]/route.ts +++ b/app/api/fonts/detail/[id]/route.ts @@ -39,7 +39,7 @@ export async function GET( message: 'success', }); } catch (error: any) { - Logger.error('字体详情页面 - 获取字体详情接口错误:', error); + Logger.error('[API-fonts/detail] 获取字体详情接口错误', error); return NextResponse.json( { code: 500, @@ -94,7 +94,7 @@ export async function POST( message: 'success', }); } catch (error: any) { - Logger.error('字体详情页面 - 根据名称获取字体详情接口错误:', error); + Logger.error('[API-fonts/detail] 根据名称获取字体详情接口错误', error); return NextResponse.json( { code: 500, diff --git a/app/api/fonts/list/route.ts b/app/api/fonts/list/route.ts index 09afc24..d66fdfd 100644 --- a/app/api/fonts/list/route.ts +++ b/app/api/fonts/list/route.ts @@ -14,6 +14,43 @@ export async function POST( const typefaceService = new TypefaceService(); const body: ListTypefaceDto = await request.json(); + + // 验证必需的参数 + if (!body.pageData || typeof body.pageData !== 'object') { + return NextResponse.json( + { + code: 400, + message: 'pageData 参数是必需的', + status: 'fail', + }, + { status: 200 } + ); + } + + const { page, size } = body.pageData; + if (typeof page !== 'number' || typeof size !== 'number' || page < 1 || size < 1) { + return NextResponse.json( + { + code: 400, + message: 'pageData.page 和 pageData.size 必须是大于0的数字', + status: 'fail', + }, + { status: 200 } + ); + } + + // 限制每页最大数量,防止性能问题 + if (size > 100) { + return NextResponse.json( + { + code: 400, + message: '每页最多只能查询100条数据', + status: 'fail', + }, + { status: 200 } + ); + } + const result = await typefaceService.findAll(body); // Convert Paging instance to IPageData format @@ -35,7 +72,7 @@ export async function POST( message: 'success', }); } catch (error: any) { - Logger.error('字体列表页面 - 获取字体列表接口错误:', error); + Logger.error('[API-fonts/list] 获取字体列表接口错误', error); return NextResponse.json( { code: 500, @@ -60,7 +97,7 @@ export async function GET(): Promise>> { message: 'success', }); } catch (error: any) { - Logger.error('字体列表页面 - 获取所有字体接口错误:', error); + Logger.error('[API-fonts/list] 获取字体列表接口错误', error); return NextResponse.json( { code: 500, diff --git a/app/api/fonts/update/route.ts b/app/api/fonts/update/route.ts index e98f111..87693d8 100644 --- a/app/api/fonts/update/route.ts +++ b/app/api/fonts/update/route.ts @@ -33,7 +33,7 @@ export async function POST( message: 'success', }); } catch (error: any) { - Logger.error('字体管理页面 - 更新字体接口错误:', error); + Logger.error('[API-fonts/update] 更新字体接口错误', error); return NextResponse.json( { code: 500, diff --git a/app/fonts/page.tsx b/app/fonts/page.tsx index 5bfc0a2..3ed4eba 100644 --- a/app/fonts/page.tsx +++ b/app/fonts/page.tsx @@ -29,7 +29,7 @@ async function fetchFonts(): Promise { Logger.info('获取字体列表成功,字体列表长度:', result.dataList.length); return []; } catch (error) { - Logger.error('字体展示页面 - 获取字体列表失败:', error); + Logger.error('[页面-fonts] 获取字体列表失败', error); return []; } } diff --git a/src/lib/database/index.ts b/src/lib/database/index.ts index b0439ac..c2ade0e 100644 --- a/src/lib/database/index.ts +++ b/src/lib/database/index.ts @@ -57,7 +57,7 @@ export async function testConnection() { Logger.info('Database connection established successfully'); return true; } catch (error) { - Logger.error('数据库服务 - 数据库连接失败:', error); + Logger.error('[数据库服务] 数据库连接失败', error); throw error; } } @@ -68,7 +68,7 @@ export async function closeDatabase() { await client.end(); Logger.info('Database connection closed'); } catch (error) { - Logger.error('数据库服务 - 关闭数据库连接错误:', error); + Logger.error('[数据库服务] 关闭数据库连接错误', error); throw error; } } diff --git a/src/lib/services/typeface.service.ts b/src/lib/services/typeface.service.ts index a9cba74..15cee9c 100644 --- a/src/lib/services/typeface.service.ts +++ b/src/lib/services/typeface.service.ts @@ -255,9 +255,17 @@ export class TypefaceService { conditions.push(like(typefaces.languages, `%${languages}%`)); } - const query = db.select().from(typefaces).where(and(...conditions)); + // 构建查询条件 + const whereCondition = conditions.length > 0 ? and(...conditions) : undefined; - const data = await query.limit(size).offset(offset); + // 查询数据 + const baseQuery = db.select().from(typefaces); + const query = whereCondition ? baseQuery.where(whereCondition) : baseQuery; + + const data = await query + .orderBy(desc(typefaces.createdAt)) + .limit(size) + .offset(offset); // 转换字段名以匹配前端期望的格式 const transformedData = data.map(font => ({ @@ -266,9 +274,10 @@ export class TypefaceService { updated_at: font.updatedAt, })); - const [{ count }] = await db - .select({ count: sql`count(*)` }) - .from(typefaces); + // 获取符合条件的总数 + const countBaseQuery = db.select({ count: sql`count(*)` }).from(typefaces); + const countQuery = whereCondition ? countBaseQuery.where(whereCondition) : countBaseQuery; + const [{ count }] = await countQuery; return new Paging(transformedData, Number(count), page, size); } catch (error) { @@ -432,7 +441,7 @@ export class TypefaceService { const processedVariants = []; let finalMetaInfo = null; - + console.log(fontSubfamilies); // 遍历每个fontSubfamily变体 for (const subfamily of fontSubfamilies) { try { @@ -441,7 +450,7 @@ export class TypefaceService { const fontBuffer = await this.ossClient.get(ossFilePath); if (!fontBuffer || !fontBuffer.content) { - Logger.warn(`Font file not found in OSS for variant: ${subfamily}`); + Logger.warn(`[字体服务-autoUpdate] OSS文件不存在 - 字体变体: ${subfamily}, 路径: ${ossFilePath}`); // eslint-disable-next-line no-continue continue; } @@ -500,7 +509,7 @@ export class TypefaceService { if (licenseFileBuffer) break; } } catch (licenseError) { - Logger.warn(`字体服务 - 获取许可证文件失败 ${subfamily}:`, licenseError); + Logger.warn(`[字体服务-autoUpdate] 获取许可证文件失败 - 字体变体: ${subfamily}`, licenseError); } // 上传处理后的文件到 OSS @@ -513,9 +522,9 @@ export class TypefaceService { licenseFileBuffer, licenseFileName, }); - Logger.info(`字体服务 - 成功上传字体变体到OSS: ${subfamily}`); + Logger.info(`[字体服务-autoUpdate] OSS上传成功 - 字体变体: ${subfamily}`); } catch (uploadError) { - Logger.error(`字体服务 - OSS上传字体变体失败: ${subfamily}`, uploadError); + Logger.error(`[字体服务-autoUpdate] OSS上传失败 - 字体变体: ${subfamily}`, uploadError); // 继续处理,不因为上传失败而中断整个流程 } @@ -526,17 +535,17 @@ export class TypefaceService { finalMetaInfo = metaInfo; } - Logger.info(`字体服务 - 成功处理字体变体: ${subfamily}`); + Logger.info(`[字体服务-autoUpdate] 字体变体处理成功: ${subfamily}`); // 清理临时文件目录 try { await rm(fontPackageDir, { recursive: true, force: true }); - Logger.info(`字体服务 - 清理临时目录: ${fontPackageDir}`); + Logger.info(`[字体服务-autoUpdate] 临时目录清理成功: ${fontPackageDir}`); } catch (cleanupError) { - Logger.warn(`字体服务 - 清理临时目录失败: ${fontPackageDir}`, cleanupError); + Logger.warn(`[字体服务-autoUpdate] 临时目录清理失败: ${fontPackageDir}`, cleanupError); } } catch (variantError) { - Logger.error(`字体服务 - 处理字体变体失败: ${subfamily}`, variantError); + Logger.error(`[字体服务-autoUpdate] 字体变体处理失败: ${subfamily}`, variantError); // 继续处理下一个变体,不中断整个流程 } } @@ -577,7 +586,7 @@ export class TypefaceService { metaInfo: finalMetaInfo, }; } catch (error) { - Logger.error('字体服务 - 自动更新失败:', error); + Logger.error(`[字体服务-autoUpdate] 自动更新失败 - 字体ID: ${id}`, error); throw error; } }); @@ -723,9 +732,9 @@ export class TypefaceService { if (fontPackageDir) { try { await rm(fontPackageDir, { recursive: true, force: true }); - Logger.info(`字体服务 - 清理临时目录: ${fontPackageDir}`); + Logger.info(`[字体服务-create] 临时目录清理成功: ${fontPackageDir}`); } catch (cleanupError) { - Logger.warn(`字体服务 - 清理临时目录失败: ${fontPackageDir}`, cleanupError); + Logger.warn(`[字体服务-create] 临时目录清理失败: ${fontPackageDir}`, cleanupError); } } @@ -735,7 +744,7 @@ export class TypefaceService { return result; } catch (error) { - Logger.error('字体服务 - 创建字体失败:', error); + Logger.error('[字体服务-create] 创建字体失败', error); throw error; } }); @@ -853,7 +862,7 @@ export class TypefaceService { ); if (failedFiles.length > 0) { - Logger.warn('以下文件上传失败:', failedFiles.map(f => `${f.fileName}: ${f.error}`)); + Logger.warn(`[字体服务-uploadToOSS] 部分文件上传失败 - 字体: ${fontFamily}-${fontSubfamily}`, failedFiles.map(f => `${f.fileName}: ${f.error}`)); // 如果关键文件上传失败,抛出错误 const criticalFiles = [`${fontFamily}-${fontSubfamily}.ttf`, `${OSS_CONFIG.subFolderWeb}.zip`]; const failedCriticalFiles = failedFiles.filter(f => @@ -865,7 +874,7 @@ export class TypefaceService { } } } catch (error: any) { - Logger.error('字体服务 - OSS上传失败:', error); + Logger.error(`[字体服务-uploadToOSS] OSS上传失败 - 字体: ${fontFamily}-${fontSubfamily}`, error); throw new Error(`OSS upload failed: ${error.message}`); } } @@ -979,7 +988,7 @@ export class TypefaceService { errors: undefined, }; } catch (error) { - Logger.error('字体服务 - 批量更新事务失败:', error); + Logger.error('[字体服务-batchUpdate] 批量更新事务失败', error); return { success: false, results, diff --git a/src/lib/utils/concurrent-uploader.ts b/src/lib/utils/concurrent-uploader.ts index 03640b4..2dda9bf 100644 --- a/src/lib/utils/concurrent-uploader.ts +++ b/src/lib/utils/concurrent-uploader.ts @@ -29,7 +29,7 @@ export class ConcurrentUploader { } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; this.results.push({ success: false, fileName, error: errorMessage }); - Logger.error(`字体服务 - 文件上传失败 ${fileName}:`, error); + Logger.error(`[字体服务-concurrent-uploader] 文件上传失败 - 文件: ${fileName}`, error); resolve(); // 不要 reject,让其他文件继续上传 } });