mirror of
https://github.com/sergeyyarkov/educt-server.git
synced 2026-10-11 10:19:20 +03:00
feat: upd deps & image attaching to course
This commit is contained in:
parent
98a67f1744
commit
987fafd440
@ -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
1
.gitignore
vendored
@ -5,3 +5,4 @@ coverage
|
||||
.DS_STORE
|
||||
.env
|
||||
tmp
|
||||
uploads
|
||||
|
||||
@ -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);
|
||||
@ -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',
|
||||
})
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
@ -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'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@ -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) => {
|
||||
/**
|
||||
|
||||
@ -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
545
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -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",
|
||||
|
||||
@ -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');
|
||||
@ -26,9 +26,4 @@ Route.group(() => {
|
||||
* Api routes
|
||||
*/
|
||||
require('./api');
|
||||
|
||||
/**
|
||||
* Serve assets
|
||||
*/
|
||||
require('./assets');
|
||||
});
|
||||
|
||||
@ -33,7 +33,8 @@
|
||||
"@adonisjs/auth",
|
||||
"@adonisjs/redis",
|
||||
"@adonisjs/mail",
|
||||
"@adonisjs/view"
|
||||
"@adonisjs/view",
|
||||
"@adonisjs/attachment-lite"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user