import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' import Series from 'App/Models/Series' import PaginationService from 'App/Services/PaginationService' import { schema } from '@ioc:Adonis/Core/Validator' import Decimal from 'decimal.js' import Drive from '@ioc:Adonis/Core/Drive' export default class SeriesController { private paginationService = new PaginationService(Series) public async index({ request }: HttpContextContract) { const data = request.all() const result = await this.paginationService.paginate(request.all(), (q) => { q.preload('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 Drive.getSignedUrl(filePath) } }) ) return result } private queryCategories(q: any, categories: any) { if (categories) { if (categories instanceof Array) { categories.forEach((item, index) => { if (index === 0) q.whereHas('categories', (wh) => { wh.where('categories.id', item) }) else q.orWhereHas('categories', (wh) => { wh.where('categories.id', item) }) }) } else { q.whereHas('categories', (wh) => { wh.where('categories.id', categories) }) } } } public async store({ request, bouncer }: HttpContextContract) { await bouncer.authorize('admin') await request.validate({ schema: schema.create({ title: schema.string(), description: schema.string.optional(), cover: schema.string.optional(), landscapeCover: schema.string.optional(), tags: schema.array.optional().members(schema.string()), releaseDate: schema.date.optional(), meta: schema.object.optional().anyMembers(), categories: schema.array.optional().anyMembers() }) }) 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) { const data = await Series.findOrFail(params.id) 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 } public async update({ params, request, bouncer }: HttpContextContract) { await bouncer.authorize('admin') const serie = await Series.findOrFail(params.id) const payload = (await request.validate({ schema: schema.create({ title: schema.string.optional(), description: schema.string.optional(), cover: schema.string.optional(), landscapeCover: schema.string.optional(), tags: schema.array.optional().members(schema.string()), releaseDate: schema.date.optional(), meta: schema.object.optional().anyMembers(), price: schema.string.optional(), categories: schema.array.optional().anyMembers(), totalEpisodes: schema.number.optional() }) })) as any if (payload.price) { payload.price = new Decimal(payload.price) } if (payload.categories) { await serie.related('categories').sync(payload.categories.map((item: any) => item.id)) delete payload.categories } serie.merge(payload) return await serie.save() } public async destroy({ params, bouncer }: HttpContextContract) { await bouncer.authorize('admin') const serie = await Series.findOrFail(params.id) await serie.delete() } public async search({ request }: HttpContextContract) { const data = request.all() return await this.paginationService.paginate(data, (q) => { if (data.title) { q.where('title', 'like', `%${data.title}%`) } this.queryCategories(q, data.categories) }) } }