mirror of
https://github.com/sergeyyarkov/educt-server.git
synced 2026-10-11 10:19:20 +03:00
feat: added colors to category model & added some helper funcs
This commit is contained in:
parent
aae79b582b
commit
10f72f3090
10
app/Helpers/ColorHelper.ts
Normal file
10
app/Helpers/ColorHelper.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import Color from 'App/Models/Color';
|
||||||
|
import * as utils from 'App/Utils';
|
||||||
|
|
||||||
|
export default class ColorHelper {
|
||||||
|
public static async generateRandomColor(): Promise<Color | null> {
|
||||||
|
const colors = await Color.query();
|
||||||
|
if (colors.length === 0) return null;
|
||||||
|
return colors[utils.generateRandomInt({ min: 0, max: colors.length - 1 })];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,9 @@
|
|||||||
/* eslint-disable import/no-cycle */
|
/* eslint-disable import/no-cycle */
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import { BaseModel, beforeCreate, column } from '@ioc:Adonis/Lucid/Orm';
|
import { BaseModel, beforeCreate, belongsTo, BelongsTo, column } from '@ioc:Adonis/Lucid/Orm';
|
||||||
|
import ColorHelper from 'App/Helpers/ColorHelper';
|
||||||
|
import Color from './Color';
|
||||||
|
|
||||||
export default class Category extends BaseModel {
|
export default class Category extends BaseModel {
|
||||||
@column({ isPrimary: true })
|
@column({ isPrimary: true })
|
||||||
@ -14,6 +16,14 @@ export default class Category extends BaseModel {
|
|||||||
@column()
|
@column()
|
||||||
public description: string;
|
public description: string;
|
||||||
|
|
||||||
|
@column({ serializeAs: null })
|
||||||
|
public color_id: number | null;
|
||||||
|
|
||||||
|
@belongsTo(() => Color, {
|
||||||
|
foreignKey: 'color_id',
|
||||||
|
})
|
||||||
|
public color: BelongsTo<typeof Color>;
|
||||||
|
|
||||||
@column.dateTime({ autoCreate: true, serializeAs: null })
|
@column.dateTime({ autoCreate: true, serializeAs: null })
|
||||||
public createdAt: DateTime;
|
public createdAt: DateTime;
|
||||||
|
|
||||||
@ -28,4 +38,13 @@ export default class Category extends BaseModel {
|
|||||||
public static assignCategoryId(category: Category) {
|
public static assignCategoryId(category: Category) {
|
||||||
category.id = nanoid();
|
category.id = nanoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@beforeCreate()
|
||||||
|
public static async assignRandomColor(category: Category) {
|
||||||
|
const color = await ColorHelper.generateRandomColor();
|
||||||
|
|
||||||
|
if (color) {
|
||||||
|
category.color_id = color.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,10 +14,12 @@ import {
|
|||||||
manyToMany,
|
manyToMany,
|
||||||
} from '@ioc:Adonis/Lucid/Orm';
|
} from '@ioc:Adonis/Lucid/Orm';
|
||||||
import { attachment, AttachmentContract } from '@ioc:Adonis/Addons/AttachmentLite';
|
import { attachment, AttachmentContract } from '@ioc:Adonis/Addons/AttachmentLite';
|
||||||
|
import ColorHelper from 'App/Helpers/ColorHelper';
|
||||||
import Category from 'App/Models/Category';
|
import Category from 'App/Models/Category';
|
||||||
import Lesson from 'App/Models/Lesson';
|
import Lesson from 'App/Models/Lesson';
|
||||||
import User from 'App/Models/User';
|
import User from 'App/Models/User';
|
||||||
import CourseStatusEnum from 'App/Datatypes/Enums/CourseStatusEnum';
|
import CourseStatusEnum from 'App/Datatypes/Enums/CourseStatusEnum';
|
||||||
|
import Color from './Color';
|
||||||
|
|
||||||
export default class Course extends BaseModel {
|
export default class Course extends BaseModel {
|
||||||
@column({ isPrimary: true })
|
@column({ isPrimary: true })
|
||||||
@ -38,6 +40,14 @@ export default class Course extends BaseModel {
|
|||||||
@column({ serializeAs: null })
|
@column({ serializeAs: null })
|
||||||
public category_id: string;
|
public category_id: string;
|
||||||
|
|
||||||
|
@column({ serializeAs: null })
|
||||||
|
public color_id: number | null;
|
||||||
|
|
||||||
|
@belongsTo(() => Color, {
|
||||||
|
foreignKey: 'color_id',
|
||||||
|
})
|
||||||
|
public color: BelongsTo<typeof Color>;
|
||||||
|
|
||||||
@column()
|
@column()
|
||||||
public status: CourseStatusEnum;
|
public status: CourseStatusEnum;
|
||||||
|
|
||||||
@ -86,6 +96,15 @@ export default class Course extends BaseModel {
|
|||||||
course.id = nanoid();
|
course.id = nanoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@beforeCreate()
|
||||||
|
public static async assignRandomColor(course: Course) {
|
||||||
|
const color = await ColorHelper.generateRandomColor();
|
||||||
|
|
||||||
|
if (color) {
|
||||||
|
course.color_id = color.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize the `$extras` object
|
* Serialize the `$extras` object
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export default class Lesson extends BaseModel {
|
|||||||
public course: BelongsTo<typeof Course>;
|
public course: BelongsTo<typeof Course>;
|
||||||
|
|
||||||
@column({ serializeAs: null })
|
@column({ serializeAs: null })
|
||||||
public color_id: number;
|
public color_id: number | null;
|
||||||
|
|
||||||
@belongsTo(() => Color, {
|
@belongsTo(() => Color, {
|
||||||
foreignKey: 'color_id',
|
foreignKey: 'color_id',
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export default class CategoryRepository {
|
|||||||
* @returns Array of categories
|
* @returns Array of categories
|
||||||
*/
|
*/
|
||||||
public async getAll(): Promise<Category[]> {
|
public async getAll(): Promise<Category[]> {
|
||||||
const categories = await this.Category.query();
|
const categories = await this.Category.query().preload('color');
|
||||||
return categories;
|
return categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ export default class CategoryRepository {
|
|||||||
* @returns Category or null
|
* @returns Category or null
|
||||||
*/
|
*/
|
||||||
public async getById(id: string | number): Promise<Category | null> {
|
public async getById(id: string | number): Promise<Category | null> {
|
||||||
const category = await this.Category.query().where('id', id).first();
|
const category = await this.Category.query().preload('color').where('id', id).first();
|
||||||
return category;
|
return category;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,12 @@ export default class CourseRepository {
|
|||||||
query.andWhere('status', status);
|
query.andWhere('status', status);
|
||||||
}
|
}
|
||||||
|
|
||||||
const courses = await query.preload('category').withCount('students').withCount('likes').withCount('lessons');
|
const courses = await query
|
||||||
|
.preload('color')
|
||||||
|
.preload('category')
|
||||||
|
.withCount('students')
|
||||||
|
.withCount('likes')
|
||||||
|
.withCount('lessons');
|
||||||
|
|
||||||
return courses;
|
return courses;
|
||||||
}
|
}
|
||||||
@ -75,6 +80,7 @@ export default class CourseRepository {
|
|||||||
public async getById(id: string | number): Promise<Course | null> {
|
public async getById(id: string | number): Promise<Course | null> {
|
||||||
const course = await this.Course.query()
|
const course = await this.Course.query()
|
||||||
.preload('teacher')
|
.preload('teacher')
|
||||||
|
.preload('color')
|
||||||
.preload('category')
|
.preload('category')
|
||||||
.preload('lessons', q => q.preload('color'))
|
.preload('lessons', q => q.preload('color'))
|
||||||
.preload('students')
|
.preload('students')
|
||||||
@ -192,6 +198,9 @@ export default class CourseRepository {
|
|||||||
course.teacher_id = data.teacher_id;
|
course.teacher_id = data.teacher_id;
|
||||||
course.category_id = data.category_id;
|
course.category_id = data.category_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach image
|
||||||
|
*/
|
||||||
if (data.image) {
|
if (data.image) {
|
||||||
course.image = Attachment.fromFile(data.image);
|
course.image = Attachment.fromFile(data.image);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ export default class MeService {
|
|||||||
*/
|
*/
|
||||||
if (RoleHelper.userHasRoles(user.roles, [RoleEnum.STUDENT])) {
|
if (RoleHelper.userHasRoles(user.roles, [RoleEnum.STUDENT])) {
|
||||||
await user.load('courses', q => {
|
await user.load('courses', q => {
|
||||||
q.preload('category');
|
q.preload('category', loader => loader.preload('color'));
|
||||||
q.withCount('students');
|
q.withCount('students');
|
||||||
q.withCount('likes');
|
q.withCount('likes');
|
||||||
q.withCount('lessons');
|
q.withCount('lessons');
|
||||||
|
|||||||
4
app/Utils/index.ts
Normal file
4
app/Utils/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export const generateRandomInt = ({ min, max }: { min: number; max: number }): number => {
|
||||||
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||||
|
};
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import Factory from '@ioc:Adonis/Lucid/Factory';
|
import Factory from '@ioc:Adonis/Lucid/Factory';
|
||||||
|
import { string } from '@ioc:Adonis/Core/Helpers';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Datatypes
|
* Datatypes
|
||||||
@ -21,7 +22,7 @@ const makeFakeUser = (faker: Faker.FakerStatic, loginPrefix?: string) => {
|
|||||||
return {
|
return {
|
||||||
first_name: faker.name.firstName(),
|
first_name: faker.name.firstName(),
|
||||||
last_name: faker.name.lastName(),
|
last_name: faker.name.lastName(),
|
||||||
login: `${loginPrefix || 'user'}${faker.datatype.number(10000)}`,
|
login: `${loginPrefix || 'user'}-${string.generateRandom(5)}`,
|
||||||
email: faker.internet.exampleEmail(),
|
email: faker.internet.exampleEmail(),
|
||||||
password: '123456',
|
password: '123456',
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export default class Colors extends BaseSchema {
|
|||||||
.enu('name', Object.keys(ColorEnum), {
|
.enu('name', Object.keys(ColorEnum), {
|
||||||
useNative: true,
|
useNative: true,
|
||||||
enumName: 'color_name_enum',
|
enumName: 'color_name_enum',
|
||||||
existingType: false,
|
existingType: true,
|
||||||
schemaName: 'public',
|
schemaName: 'public',
|
||||||
})
|
})
|
||||||
.notNullable();
|
.notNullable();
|
||||||
|
|||||||
@ -8,6 +8,7 @@ export default class Categories extends BaseSchema {
|
|||||||
table.string('id', 21).primary();
|
table.string('id', 21).primary();
|
||||||
table.string('title').notNullable();
|
table.string('title').notNullable();
|
||||||
table.string('description');
|
table.string('description');
|
||||||
|
table.integer('color_id').unsigned().references('colors.id');
|
||||||
table.timestamp('created_at', { useTz: true });
|
table.timestamp('created_at', { useTz: true });
|
||||||
table.timestamp('updated_at', { useTz: true });
|
table.timestamp('updated_at', { useTz: true });
|
||||||
});
|
});
|
||||||
|
|||||||
@ -16,11 +16,12 @@ export default class Courses extends BaseSchema {
|
|||||||
table.string('description').notNullable();
|
table.string('description').notNullable();
|
||||||
table.string('teacher_id', 21).unsigned().references('users.id').notNullable().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.string('category_id', 21).unsigned().references('categories.id').notNullable().onDelete('CASCADE');
|
||||||
|
table.integer('color_id').unsigned().references('colors.id');
|
||||||
table
|
table
|
||||||
.enu('status', Object.values(CourseStatusEnum), {
|
.enu('status', Object.values(CourseStatusEnum), {
|
||||||
useNative: true,
|
useNative: true,
|
||||||
enumName: 'course_status_enum',
|
enumName: 'course_status_enum',
|
||||||
existingType: false,
|
existingType: true,
|
||||||
schemaName: 'public',
|
schemaName: 'public',
|
||||||
})
|
})
|
||||||
.notNullable();
|
.notNullable();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user