mirror of
https://github.com/sergeyyarkov/educt-server.git
synced 2026-10-11 10:19:20 +03:00
feat: assets controller & serve course image
This commit is contained in:
parent
30fdfa08b6
commit
ee25d495e1
39
app/Controllers/Http/Api/AssetsController.ts
Normal file
39
app/Controllers/Http/Api/AssetsController.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
|
||||
import { Exception, inject, Ioc } from '@adonisjs/core/build/standalone';
|
||||
|
||||
/**
|
||||
* Services
|
||||
*/
|
||||
import AssetsService from 'App/Services/AssetsService';
|
||||
|
||||
import BaseController from '../BaseController';
|
||||
|
||||
@inject()
|
||||
export default class AssetsController extends BaseController {
|
||||
private assetsService: AssetsService;
|
||||
|
||||
constructor(assetsService: AssetsService) {
|
||||
super();
|
||||
this.assetsService = assetsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send background image of course
|
||||
* GET /media/images/courses/:fileName
|
||||
*/
|
||||
public async serveCourseImage(ctx: HttpContextContract) {
|
||||
const result = await this.assetsService.getCourseImagePath(ctx.params.fileName);
|
||||
|
||||
if (typeof result !== 'string') {
|
||||
if (!result.success && result.error) {
|
||||
throw new Exception(result.message, result.status, result.error.code);
|
||||
}
|
||||
|
||||
return this.sendResponse(ctx, result.data, result.message, result.status);
|
||||
}
|
||||
|
||||
return this.sendFile(ctx, result);
|
||||
}
|
||||
}
|
||||
|
||||
new Ioc().make(AssetsController);
|
||||
@ -12,4 +12,8 @@ export default class BaseController {
|
||||
|
||||
return ctx.response.status(response.status).send(response);
|
||||
}
|
||||
|
||||
public sendFile(ctx: HttpContextContract, path: string) {
|
||||
return ctx.response.download(path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ export default class Image extends BaseModel {
|
||||
@column({ isPrimary: true })
|
||||
public id: number;
|
||||
|
||||
@column()
|
||||
@column({ serializeAs: null })
|
||||
public path: string;
|
||||
|
||||
@column()
|
||||
|
||||
@ -209,9 +209,11 @@ export default class CourseRepository {
|
||||
*/
|
||||
public async delete(id: string | number): Promise<Course | null> {
|
||||
const course = await this.Course.query()
|
||||
.preload('teacher')
|
||||
.preload('category')
|
||||
.preload('lessons')
|
||||
.preload('image')
|
||||
.withCount('students')
|
||||
.withCount('likes')
|
||||
.withCount('lessons')
|
||||
.where('id', id)
|
||||
.first();
|
||||
|
||||
|
||||
@ -15,14 +15,26 @@ export default class ImageRepository {
|
||||
return image;
|
||||
}
|
||||
|
||||
public async getByFileName(name: string): Promise<Image | null> {
|
||||
const image = await this.Image.query().where('name', name).first();
|
||||
return image;
|
||||
}
|
||||
|
||||
public async getAll(): Promise<Image[]> {
|
||||
const images = await this.Image.query();
|
||||
return images;
|
||||
}
|
||||
|
||||
public async create(file: MultipartFileContract): Promise<Image> {
|
||||
await file.moveToDisk('./images');
|
||||
const image = await this.Image.create({ name: file.clientName, path: file.filePath, ext: file.extname });
|
||||
/**
|
||||
* Save image to disk
|
||||
*/
|
||||
await file.moveToDisk('images/courses');
|
||||
|
||||
/**
|
||||
* Save image to database
|
||||
*/
|
||||
const image = await this.Image.create({ name: file.fileName, path: file.filePath, ext: file.extname });
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -30,7 +42,14 @@ export default class ImageRepository {
|
||||
const image = await this.Image.query().where('id', id).first();
|
||||
|
||||
if (image) {
|
||||
/**
|
||||
* Delete from drive
|
||||
*/
|
||||
await Drive.delete(image.path);
|
||||
|
||||
/**
|
||||
* Delete from database
|
||||
*/
|
||||
await image.delete();
|
||||
return image;
|
||||
}
|
||||
|
||||
47
app/Services/AssetsService.ts
Normal file
47
app/Services/AssetsService.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { inject, Ioc } from '@adonisjs/core/build/standalone';
|
||||
import Application from '@ioc:Adonis/Core/Application';
|
||||
|
||||
/**
|
||||
* Datatypes
|
||||
*/
|
||||
import IResponse from 'App/Datatypes/Interfaces/IResponse';
|
||||
import HttpStatusEnum from 'App/Datatypes/Enums/HttpStatusEnum';
|
||||
|
||||
/**
|
||||
* Reposirories
|
||||
*/
|
||||
import ImageRepository from 'App/Repositories/ImageRepository';
|
||||
|
||||
@inject()
|
||||
export default class AssetsService {
|
||||
private imageRepository: ImageRepository;
|
||||
|
||||
constructor(imageRepository: ImageRepository) {
|
||||
this.imageRepository = imageRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name Image name
|
||||
* @returns Pathname
|
||||
*/
|
||||
public async getCourseImagePath(name: string): Promise<IResponse | string> {
|
||||
const image = await this.imageRepository.getByFileName(name);
|
||||
|
||||
if (!image) {
|
||||
return {
|
||||
success: false,
|
||||
status: HttpStatusEnum.NOT_FOUND,
|
||||
message: 'Image not found.',
|
||||
data: {},
|
||||
error: {
|
||||
code: 'E_NOT_FOUND',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return Application.tmpPath(`uploads/images/courses/${image.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
new Ioc().make(AssetsService);
|
||||
@ -2,7 +2,15 @@
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.group(() => {
|
||||
/**
|
||||
* v1
|
||||
*/
|
||||
require('./apis/v1/index');
|
||||
|
||||
/**
|
||||
* Assets routes
|
||||
*/
|
||||
require('./apis/assets/index');
|
||||
})
|
||||
.prefix('api')
|
||||
.as('api');
|
||||
|
||||
10
routes/apis/assets/index.ts
Normal file
10
routes/apis/assets/index.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import Route from '@ioc:Adonis/Core/Route';
|
||||
|
||||
Route.group(() => {
|
||||
/**
|
||||
* Serve background image for course
|
||||
*/
|
||||
Route.get('/images/courses/:fileName', 'Api/AssetsController.serveCourseImage').as('serve.course.image');
|
||||
})
|
||||
.prefix('assets')
|
||||
.as('assets');
|
||||
@ -22,5 +22,8 @@ import Route from '@ioc:Adonis/Core/Route';
|
||||
*/
|
||||
|
||||
Route.group(() => {
|
||||
/**
|
||||
* Api routes
|
||||
*/
|
||||
require('./api');
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user