@@ -13,6 +13,8 @@ const {
1313 imageMimeTypes,
1414 tinifySupportedMimeTypes,
1515} = require ( "../constants/file" ) ;
16+ const { FILES_UPLOAD_POST_QUERY , FILES_LIST_GET_QUERY , FILES_REST_ID , FILES_BODY_BATCH_IDS } = require ( "../types/schema/files" ) ;
17+ const { validateQuery, validateBody, validateFormData, validateParams } = require ( "../types" ) ;
1618
1719tinify . key = process . env . TINIFY_KEY ;
1820
@@ -44,17 +46,17 @@ const getDefaultThumbPath = (mime) => {
4446} ;
4547
4648// 处理文件上传
47- router . post ( "/files" , async ( ctx ) => {
49+ router . post ( "/files" , validateFormData , validateQuery ( FILES_UPLOAD_POST_QUERY ) , async ( ctx ) => {
4850 try {
4951 const files = ctx . request . files . file ;
5052 const fileList = Array . isArray ( files ) ? files : [ files ] ;
5153 const responses = [ ] ;
54+ const { compress, keepTemp, isThumb, isPublic, type : responseType } = ctx . query ;
5255
53- const shouldCompress = ctx . query . compress !== "false" ;
54- const shouldKeepTemp = ctx . query . keepTemp === "true" ;
55- const shouldGenerateThumb = ctx . query . isThumb === "true" ;
56- const isFilePublic = ctx . query . isPublic === "true" ;
57- const responseType = ctx . query . type ;
56+ const shouldCompress = compress === 'true' ;
57+ const shouldKeepTemp = keepTemp === 'true' ;
58+ const shouldGenerateThumb = isThumb === 'true' ;
59+ const isFilePublic = isPublic === 'true' ;
5860
5961 for ( const file of fileList ) {
6062 const fileId = uuidv4 ( ) ;
@@ -65,16 +67,20 @@ router.post("/files", async (ctx) => {
6567 let realThumbPath = null ;
6668
6769 if ( shouldGenerateThumb && imageMimeTypes . includes ( mime ) ) {
70+ console . time ( 'thumb' )
6871 realThumbPath = getRealThumbPath ( fileId ) ;
6972 await sharp ( file . filepath )
7073 . resize ( 200 , 200 )
7174 . toFile ( realThumbPath ) ;
75+ console . timeEnd ( 'thumb' ) ;
7276 } else if ( shouldGenerateThumb ) {
7377 realThumbPath = getDefaultThumbPath ( mime ) ;
7478 }
7579
7680 if ( shouldCompress && tinifySupportedMimeTypes . includes ( mime ) ) {
81+ console . time ( 'compress' )
7782 await tinify . fromFile ( file . filepath ) . toFile ( realFilePath ) ;
83+ console . timeEnd ( 'compress' )
7884 } else {
7985 if ( shouldKeepTemp ) {
8086 await fsp . copyFile ( file . filepath , realFilePath ) ;
@@ -131,7 +137,8 @@ router.post("/files", async (ctx) => {
131137} ) ;
132138
133139// 获取文件列表
134- router . get ( "/files" , async ( ctx ) => {
140+ router . get ( "/files" , validateQuery ( FILES_LIST_GET_QUERY ) , async ( ctx ) => {
141+ console . log ( ctx . query ) ;
135142 try {
136143 const limit = parseInt ( ctx . query . limit , 10 ) || 10 ; // 每页数量,默认为 10
137144 const offset = parseInt ( ctx . query . offset , 10 ) || 0 ; // 偏移量,默认为 0
@@ -199,7 +206,7 @@ router.get("/files", async (ctx) => {
199206} ) ;
200207
201208// 获取单个文件信息
202- router . get ( "/files/:id" , async ( ctx ) => {
209+ router . get ( "/files/:id" , validateParams ( FILES_REST_ID ) , async ( ctx ) => {
203210 const { id } = ctx . params ;
204211
205212 try {
@@ -248,7 +255,7 @@ router.get("/files/:id", async (ctx) => {
248255} ) ;
249256
250257// 编辑文件信息接口
251- router . put ( ' /files/:id' , async ( ctx ) => {
258+ router . put ( " /files/:id" , validateParams ( FILES_REST_ID ) , async ( ctx ) => {
252259 const { id } = ctx . params ;
253260 const {
254261 filename,
@@ -264,12 +271,12 @@ router.put('/files/:id', async (ctx) => {
264271 where : {
265272 id,
266273 is_delete : false ,
267- }
274+ } ,
268275 } ) ;
269276
270277 if ( ! file ) {
271278 ctx . status = 404 ;
272- ctx . body = { message : ' File not found' } ;
279+ ctx . body = { message : " File not found" } ;
273280 return ;
274281 }
275282
@@ -304,13 +311,16 @@ router.put('/files/:id', async (ctx) => {
304311 ctx . body = updatedFile ;
305312 } catch ( error ) {
306313 ctx . status = 500 ;
307- ctx . body = { message : 'Error updating file information' , error : error . message } ;
308- console . error ( 'Update file error:' , error ) ;
314+ ctx . body = {
315+ message : "Error updating file information" ,
316+ error : error . message ,
317+ } ;
318+ console . error ( "Update file error:" , error ) ;
309319 }
310320} ) ;
311321
312322// 文件删除接口
313- router . delete ( ' /files/:id' , async ( ctx ) => {
323+ router . delete ( " /files/:id" , validateParams ( FILES_REST_ID ) , async ( ctx ) => {
314324 const { id } = ctx . params ;
315325
316326 try {
@@ -319,48 +329,48 @@ router.delete('/files/:id', async (ctx) => {
319329 where : {
320330 id,
321331 is_delete : false ,
322- }
332+ } ,
323333 } ) ;
324334
325335 if ( ! file ) {
326336 ctx . status = 404 ;
327- ctx . body = { message : ' File not found' } ;
337+ ctx . body = { message : " File not found" } ;
328338 return ;
329339 }
330340
331341 // 执行软删除,将 is_delete 字段设置为 true
332342 await file . update ( {
333343 is_delete : true ,
334344 updated_at : new Date ( ) , // 更新更新时间
335- updated_by : ctx . query . updated_by || ' anonymous' // 可以通过查询参数传递更新者
345+ updated_by : ctx . query . updated_by || " anonymous" , // 可以通过查询参数传递更新者
336346 } ) ;
337347
338348 // 返回删除成功的信息
339349 ctx . status = 204 ;
340350 } catch ( error ) {
341351 ctx . status = 500 ;
342- ctx . body = { message : ' Error deleting file' , error : error . message } ;
343- console . error ( ' Delete file error:' , error ) ;
352+ ctx . body = { message : " Error deleting file" , error : error . message } ;
353+ console . error ( " Delete file error:" , error ) ;
344354 }
345355} ) ;
346356
347357// 文件批量删除接口
348- router . delete ( ' /files' , async ( ctx ) => {
358+ router . delete ( " /files" , validateBody ( FILES_BODY_BATCH_IDS ) , async ( ctx ) => {
349359 const { ids } = ctx . request . body ; // 获取要删除的文件 ID 列表
350- const updated_by = ctx . query . updated_by || ' anonymous' ; // 获取更新者,默认为匿名
360+ const updated_by = ctx . query . updated_by || " anonymous" ; // 获取更新者,默认为匿名
351361 console . log ( ctx . request . body ) ;
352362 console . log ( JSON . stringify ( ctx . request . body ) ) ;
353363
354364 if ( ! ids || ! Array . isArray ( ids ) || ids . length === 0 ) {
355365 ctx . status = 400 ;
356- ctx . body = { message : ' No file ids provided for deletion' } ;
366+ ctx . body = { message : " No file ids provided for deletion" } ;
357367 return ;
358368 }
359369
360370 try {
361371 // 查找并更新指定的文件
362372 const [ numberOfAffectedRows ] = await Files . update (
363- {
373+ {
364374 is_delete : true ,
365375 updated_by : updated_by ,
366376 updated_at : new Date ( ) ,
@@ -377,21 +387,21 @@ router.delete('/files', async (ctx) => {
377387
378388 if ( numberOfAffectedRows === 0 ) {
379389 ctx . status = 404 ;
380- ctx . body = { message : ' No files found to delete' } ;
390+ ctx . body = { message : " No files found to delete" } ;
381391 return ;
382392 }
383393
384394 // 返回删除成功的信息
385395 ctx . status = 204 ;
386396 } catch ( error ) {
387397 ctx . status = 500 ;
388- ctx . body = { message : ' Error deleting files' , error : error . message } ;
389- console . error ( ' Delete files error:' , error ) ;
398+ ctx . body = { message : " Error deleting files" , error : error . message } ;
399+ console . error ( " Delete files error:" , error ) ;
390400 }
391401} ) ;
392402
393403// 文件预览
394- router . get ( "/files/:id/preview" , async ( ctx ) => {
404+ router . get ( "/files/:id/preview" , validateParams ( FILES_REST_ID ) , async ( ctx ) => {
395405 const { id } = ctx . params ;
396406 const { type } = ctx . query ; // 获取查询参数 'type',可以是 'thumb' 或 'original'
397407
@@ -454,7 +464,7 @@ router.get("/files/:id/preview", async (ctx) => {
454464} ) ;
455465
456466// 单文件下载
457- router . get ( "/files/:id/export" , async ( ctx ) => {
467+ router . get ( "/files/:id/download" , validateParams ( FILES_REST_ID ) , async ( ctx ) => {
458468 const { id } = ctx . params ;
459469
460470 try {
@@ -506,8 +516,8 @@ router.get("/files/:id/export", async (ctx) => {
506516} ) ;
507517
508518// 批量下载
509- router . get ( "/files/export/batch" , async ( ctx ) => {
510- const ids = ctx . query . ids ? ctx . query . ids . split ( "," ) : [ ] ;
519+ router . post ( "/files/download" , validateBody ( FILES_BODY_BATCH_IDS ) , async ( ctx ) => {
520+ const ids = ctx . request . body . ids ;
511521
512522 if ( ids . length === 0 ) {
513523 ctx . status = 400 ;
0 commit comments