Browse Source

feat(files): 添加视频上传功能
- 在 FilesController 中新增 uploadVideo 方法处理视频上传
- 在 routes.ts 中添加对应的路由配置

wuyi 5 months ago
parent
commit
a080206cdf

+ 19 - 0
app/Controllers/Http/FilesController.ts

@@ -4,6 +4,7 @@ import { Config } from '@alicloud/openapi-client'
 import { RuntimeOptions } from '@alicloud/tea-util'
 import { RuntimeOptions } from '@alicloud/tea-util'
 import Drive from '@ioc:Adonis/Core/Drive'
 import Drive from '@ioc:Adonis/Core/Drive'
 import FilesService from 'App/Services/FilesService'
 import FilesService from 'App/Services/FilesService'
+import { v4 as uuidv4 } from 'uuid'
 
 
 export default class FilesController {
 export default class FilesController {
     public async store({ request }: HttpContextContract) {
     public async store({ request }: HttpContextContract) {
@@ -45,6 +46,24 @@ export default class FilesController {
         }
         }
     }
     }
 
 
+    public async uploadVideo({ request }: HttpContextContract) {
+        const video = request.file('video', {
+            extnames: ['mp4', 'mov', 'avi', 'mkv'],
+            size: '500mb'
+        })
+        let folder = request.input('folder')
+        if (!video) {
+            return { error: '未上传文件' }
+        }
+        if (!folder) {
+            return { error: '未指定文件夹名' }
+        }
+        const folderName = folder.replace(/\s+/g, '').replace(/[^a-zA-Z0-9_-]/g, '')
+        const filePath = `video/${folderName}/${Date.now()}_${video.clientName}`
+        await video.moveToDisk('.', { name: filePath }, 's3')
+        return { url: filePath }
+    }
+
     public async batchDelete({ request, response }: HttpContextContract) {
     public async batchDelete({ request, response }: HttpContextContract) {
         try {
         try {
             const { filePaths } = request.only(['filePaths'])
             const { filePaths } = request.only(['filePaths'])

+ 33 - 3
app/Controllers/Http/SeriesController.ts

@@ -3,15 +3,27 @@ import Series from 'App/Models/Series'
 import PaginationService from 'App/Services/PaginationService'
 import PaginationService from 'App/Services/PaginationService'
 import { schema } from '@ioc:Adonis/Core/Validator'
 import { schema } from '@ioc:Adonis/Core/Validator'
 import Decimal from 'decimal.js'
 import Decimal from 'decimal.js'
+import Drive from '@ioc:Adonis/Core/Drive'
+import FilesService from 'App/Services/FilesService'
 
 
 export default class SeriesController {
 export default class SeriesController {
     private paginationService = new PaginationService(Series)
     private paginationService = new PaginationService(Series)
     public async index({ request }: HttpContextContract) {
     public async index({ request }: HttpContextContract) {
         const data = request.all()
         const data = request.all()
-        return await this.paginationService.paginate(request.all(), (q) => {
+        const result = await this.paginationService.paginate(request.all(), (q) => {
             q.preload('categories')
             q.preload('categories')
             this.queryCategories(q, data.categories)
             this.queryCategories(q, data.categories)
         })
         })
+        await Promise.all(
+            result.map(async (series) => {
+                if (series.cover) {
+                    const url = new URL(series.cover)
+                    const filePath = url.pathname.replace(/^\//, '')
+                    series.cover = await FilesService.generateThumbnailUrl(filePath)
+                }
+            })
+        )
+        return result
     }
     }
 
 
     private queryCategories(q: any, categories: any) {
     private queryCategories(q: any, categories: any) {
@@ -45,15 +57,33 @@ export default class SeriesController {
                 landscapeCover: schema.string.optional(),
                 landscapeCover: schema.string.optional(),
                 tags: schema.array.optional().members(schema.string()),
                 tags: schema.array.optional().members(schema.string()),
                 releaseDate: schema.date.optional(),
                 releaseDate: schema.date.optional(),
-                meta: schema.object.optional().anyMembers()
+                meta: schema.object.optional().anyMembers(),
+                categories: schema.array.optional().anyMembers()
             })
             })
         })
         })
-        return await Series.create(request.all())
+        const payload = request.all()
+        const serie = await Series.create(payload)
+        if (payload.categories) {
+            await serie
+                .related('categories')
+                .sync(payload.categories.map((item: any) => item.id ?? item))
+        }
+        return serie
     }
     }
 
 
     public async show({ params }: HttpContextContract) {
     public async show({ params }: HttpContextContract) {
         const data = await Series.findOrFail(params.id)
         const data = await Series.findOrFail(params.id)
         await data.load('categories')
         await data.load('categories')
+        if (data.cover) {
+            const url = new URL(data.cover)
+            const filePath = url.pathname.replace(/^\//, '')
+            data.cover = await Drive.getSignedUrl(filePath)
+        }
+        if (data.landscapeCover) {
+            const url = new URL(data.landscapeCover)
+            const filePath = url.pathname.replace(/^\//, '')
+            data.landscapeCover = await Drive.getSignedUrl(filePath)
+        }
         return data
         return data
     }
     }
 
 

+ 1 - 0
start/routes.ts

@@ -85,6 +85,7 @@ Route.group(() => {
             Route.post('upload', 'FilesController.store')
             Route.post('upload', 'FilesController.store')
             Route.get('sts', 'FilesController.sts')
             Route.get('sts', 'FilesController.sts')
             Route.post('batchDelete', 'FilesController.batchDelete')
             Route.post('batchDelete', 'FilesController.batchDelete')
+            Route.post('uploadVideo', 'FilesController.uploadVideo')
         }).prefix('/files')
         }).prefix('/files')
         Route.group(() => {
         Route.group(() => {
             Route.get('my', 'UsersController.my')
             Route.get('my', 'UsersController.my')