feat: upd deps & image attaching to course

This commit is contained in:
Sergey Yarkov 2021-10-24 17:57:56 +03:00
parent 98a67f1744
commit 987fafd440
14 changed files with 367 additions and 343 deletions

View File

@ -23,7 +23,11 @@
"Database": "database",
"Contracts": "contracts"
},
"preloads": ["./routes/index", "./start/kernel", "./start/event"],
"preloads": [
"./routes/index",
"./start/kernel",
"./start/event"
],
"providers": [
"./providers/AppProvider",
"./providers/CloudinaryProvider",
@ -32,9 +36,12 @@
"@adonisjs/auth",
"@adonisjs/redis",
"@adonisjs/mail",
"@adonisjs/view"
"@adonisjs/view",
"@adonisjs/attachment-lite"
],
"aceProviders": [
"@adonisjs/repl"
],
"aceProviders": ["@adonisjs/repl"],
"metaFiles": [
{
"pattern": "resources/views/**/*.edge",

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ coverage
.DS_STORE
.env
tmp
uploads

View File

@ -1,39 +0,0 @@
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 /assets/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);

View File

@ -13,18 +13,18 @@ import {
ManyToMany,
manyToMany,
} from '@ioc:Adonis/Lucid/Orm';
import { attachment, AttachmentContract } from '@ioc:Adonis/Addons/AttachmentLite';
import Category from 'App/Models/Category';
import Lesson from 'App/Models/Lesson';
import User from 'App/Models/User';
import CourseStatusEnum from 'App/Datatypes/Enums/CourseStatusEnum';
// import Image from './Image';
export default class Course extends BaseModel {
@column({ isPrimary: true })
public id: string;
@column()
public bg_image_path: string;
@attachment({ folder: 'images/courses', preComputeUrl: true })
public image: AttachmentContract | null;
@column()
public title: string;
@ -46,11 +46,6 @@ export default class Course extends BaseModel {
})
public category: BelongsTo<typeof Category>;
// @belongsTo(() => Image, {
// foreignKey: 'bg_image_id',
// })
// public image: BelongsTo<typeof Image>;
@belongsTo(() => User, {
foreignKey: 'teacher_id',
})

View File

@ -1,8 +1,10 @@
/* eslint-disable @typescript-eslint/naming-convention */
import Database from '@ioc:Adonis/Lucid/Database';
import { Attachment } from '@ioc:Adonis/Addons/AttachmentLite';
/**
* Datatypes
*/
import Database from '@ioc:Adonis/Lucid/Database';
import CourseStatusEnum from 'App/Datatypes/Enums/CourseStatusEnum';
/**
@ -183,14 +185,19 @@ export default class CourseRepository {
/**
* Create new course
*/
const course = await this.Course.create({
bg_image_path: data.image?.filePath,
title: data.title,
description: data.description,
status: data.status,
teacher_id: data.teacher_id,
category_id: data.category_id,
});
const course = new this.Course();
course.title = data.title;
course.description = data.description;
course.status = data.status;
course.teacher_id = data.teacher_id;
course.category_id = data.category_id;
if (data.image) {
course.image = Attachment.fromFile(data.image);
}
await course.save();
return course;
}

View File

@ -1,47 +0,0 @@
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);

View File

@ -42,7 +42,7 @@ const driveConfig: DriveConfig = {
*/
local: {
driver: 'local',
visibility: 'public',
visibility: 'private',
/*
|--------------------------------------------------------------------------
@ -53,7 +53,7 @@ const driveConfig: DriveConfig = {
| files.
|
*/
root: Application.tmpPath('uploads'),
root: Application.makePath('uploads'),
/*
|--------------------------------------------------------------------------

View File

@ -16,33 +16,27 @@ import LessonContent from 'App/Models/LessonContent';
import Role from 'App/Models/Role';
import User from 'App/Models/User';
const makeFakeUser = (faker: Faker.FakerStatic) => {
return {
first_name: faker.name.firstName(),
last_name: faker.name.lastName(),
login: `${faker.lorem.word(12)}${faker.datatype.number(100)}`,
email: faker.internet.exampleEmail(),
password: '123456',
};
};
export const ContactFactory = Factory.define(Contact, ({ faker }) => {
return {
phone_number: faker.phone.phoneNumber(),
};
}).build();
export const UserFactory = Factory.define(User, ({ faker }) => {
return {
first_name: faker.name.firstName(),
last_name: faker.name.lastName(),
login: `${faker.lorem.word(12)}${faker.datatype.number(100)}`,
email: faker.internet.exampleEmail(),
password: '123456',
};
})
export const UserFactory = Factory.define(User, ({ faker }) => makeFakeUser(faker))
.relation('contacts', () => ContactFactory)
.build();
export const TeacherFactory = Factory.define(User, ({ faker }) => {
return {
first_name: faker.name.firstName(),
last_name: faker.name.lastName(),
login: `${faker.lorem.word(12)}${faker.datatype.number(100)}`,
email: faker.internet.exampleEmail(),
password: '123456',
};
})
export const TeacherFactory = Factory.define(User, ({ faker }) => makeFakeUser(faker))
.relation('contacts', () => ContactFactory)
.after('create', async (_, user: User) => {
/**

View File

@ -11,11 +11,11 @@ export default class Courses extends BaseSchema {
public async up() {
this.schema.createTable(this.tableName, table => {
table.string('id', 21).primary();
table.string('bg_image_path');
table.json('image');
table.string('title').notNullable();
table.string('description').notNullable();
table.string('teacher_id', 21).unsigned().references('users.id').onDelete('CASCADE');
table.string('category_id', 21).unsigned().references('categories.id').onDelete('CASCADE');
table.string('teacher_id', 21).unsigned().references('users.id').notNullable().onDelete('CASCADE');
table.string('category_id', 21).unsigned().references('categories.id').notNullable().onDelete('CASCADE');
table
.enu('status', Object.values(CourseStatusEnum), {
useNative: true,

545
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -32,14 +32,15 @@
"youch-terminal": "^1.1.1"
},
"dependencies": {
"@adonisjs/auth": "^8.0.9",
"@adonisjs/core": "^5.3.2",
"@adonisjs/drive": "^2.0.6",
"@adonisjs/lucid": "^16.0.2",
"@adonisjs/attachment-lite": "^1.0.1",
"@adonisjs/auth": "^8.0.10",
"@adonisjs/core": "^5.4.0",
"@adonisjs/drive": "^2.0.7",
"@adonisjs/lucid": "^16.2.1",
"@adonisjs/mail": "^7.2.4",
"@adonisjs/redis": "^7.0.9",
"@adonisjs/repl": "^3.1.6",
"@adonisjs/view": "^6.1.0",
"@adonisjs/repl": "^3.1.7",
"@adonisjs/view": "^6.1.1",
"cloudinary": "^1.26.3",
"luxon": "^1.28.0",
"nanoid": "^3.1.25",

View File

@ -1,10 +0,0 @@
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');

View File

@ -26,9 +26,4 @@ Route.group(() => {
* Api routes
*/
require('./api');
/**
* Serve assets
*/
require('./assets');
});

View File

@ -33,7 +33,8 @@
"@adonisjs/auth",
"@adonisjs/redis",
"@adonisjs/mail",
"@adonisjs/view"
"@adonisjs/view",
"@adonisjs/attachment-lite"
]
}
}