From 20a788c1a2ac51779e92d19df153e9e21e9feaf3 Mon Sep 17 00:00:00 2001 From: Innei Date: Fri, 22 Apr 2022 21:44:48 +0800 Subject: [PATCH] feat: add meta for write model --- src/global/index.global.ts | 5 + src/global/json.global.ts | 15 +++ src/modules/comment/comment.service.ts | 2 +- src/modules/note/note.model.ts | 7 +- src/modules/page/page.model.ts | 2 +- src/modules/post/post.controller.ts | 3 +- src/modules/post/post.model.ts | 3 +- src/processors/helper/helper.image.service.ts | 3 +- src/shared/model/base-comment.model.ts | 21 ++++ src/shared/model/base.model.ts | 102 +----------------- src/shared/model/count.model.ts | 13 +++ src/shared/model/image.model.ts | 39 +++++++ src/shared/model/write-base.model.ts | 57 ++++++++++ 13 files changed, 166 insertions(+), 106 deletions(-) create mode 100644 src/global/json.global.ts create mode 100644 src/shared/model/base-comment.model.ts create mode 100644 src/shared/model/count.model.ts create mode 100644 src/shared/model/image.model.ts create mode 100644 src/shared/model/write-base.model.ts diff --git a/src/global/index.global.ts b/src/global/index.global.ts index d5394930..79a7abe9 100644 --- a/src/global/index.global.ts +++ b/src/global/index.global.ts @@ -1,6 +1,7 @@ /* eslint-disable import/order */ import cluster from 'cluster' import { mkdirSync } from 'fs' + import 'zx-cjs/globals' import { Logger } from '@nestjs/common' @@ -14,8 +15,11 @@ import { } from '~/constants/path.constant' import { consola, registerStdLogger } from './consola.global' + import './dayjs.global' + import { cwd, isDev } from './env.global' +import { registerJSONGlobal } from './json.global' // 建立目录 function mkdirs() { @@ -49,4 +53,5 @@ export function register() { registerStdLogger() mkdirs() registerGlobal() + registerJSONGlobal() } diff --git a/src/global/json.global.ts b/src/global/json.global.ts new file mode 100644 index 00000000..a0f55a1b --- /dev/null +++ b/src/global/json.global.ts @@ -0,0 +1,15 @@ +declare global { + interface JSON { + safeParse: typeof JSON.parse + } +} + +export const registerJSONGlobal = () => { + JSON.safeParse = (...rest) => { + try { + return JSON.parse(...rest) + } catch (error) { + return null + } + } +} diff --git a/src/modules/comment/comment.service.ts b/src/modules/comment/comment.service.ts index 10b0142f..c1a55bc4 100644 --- a/src/modules/comment/comment.service.ts +++ b/src/modules/comment/comment.service.ts @@ -12,7 +12,7 @@ import { EmailService, ReplyMailType, } from '~/processors/helper/helper.email.service' -import { WriteBaseModel } from '~/shared/model/base.model' +import { WriteBaseModel } from '~/shared/model/write-base.model' import { InjectModel } from '~/transformers/model.transformer' import { hasChinese } from '~/utils' diff --git a/src/modules/note/note.model.ts b/src/modules/note/note.model.ts index 2c5924fa..ac835528 100644 --- a/src/modules/note/note.model.ts +++ b/src/modules/note/note.model.ts @@ -14,7 +14,8 @@ import { AutoIncrementID } from '@typegoose/auto-increment' import { index, modelOptions, plugin, prop } from '@typegoose/typegoose' import { Paginator } from '~/shared/interface/paginator.interface' -import { CountMixed, WriteBaseModel } from '~/shared/model/base.model' +import { CountModel } from '~/shared/model/count.model' +import { WriteBaseModel } from '~/shared/model/write-base.model' @modelOptions({ schemaOptions: { id: false, _id: false } }) export class Coordinate { @@ -111,8 +112,8 @@ export class NoteModel extends WriteBaseModel { @IsOptional() location?: string - @prop({ type: CountMixed, default: { read: 0, like: 0 }, _id: false }) - count?: CountMixed + @prop({ type: CountModel, default: { read: 0, like: 0 }, _id: false }) + count?: CountModel @prop({ type: [NoteMusic] }) @ValidateNested({ each: true }) diff --git a/src/modules/page/page.model.ts b/src/modules/page/page.model.ts index 33842419..27ed89fc 100644 --- a/src/modules/page/page.model.ts +++ b/src/modules/page/page.model.ts @@ -11,7 +11,7 @@ import { import { PartialType } from '@nestjs/mapped-types' import { modelOptions, prop } from '@typegoose/typegoose' -import { WriteBaseModel } from '~/shared/model/base.model' +import { WriteBaseModel } from '~/shared/model/write-base.model' import { IsNilOrString } from '~/utils/validator/isNilOrString' export enum PageType { diff --git a/src/modules/post/post.controller.ts b/src/modules/post/post.controller.ts index 623d7bed..9930ba10 100644 --- a/src/modules/post/post.controller.ts +++ b/src/modules/post/post.controller.ts @@ -20,7 +20,6 @@ import { Auth } from '~/common/decorator/auth.decorator' import { Paginator } from '~/common/decorator/http.decorator' import { IpLocation, IpRecord } from '~/common/decorator/ip.decorator' import { ApiName } from '~/common/decorator/openapi.decorator' -import { IsMaster } from '~/common/decorator/role.decorator' import { VisitDocument } from '~/common/decorator/update-count.decorator' import { CannotFindException } from '~/common/exceptions/cant-find.exception' import { CountingService } from '~/processors/helper/helper.counting.service' @@ -41,7 +40,7 @@ export class PostController { @Get('/') @Paginator - async getPaginate(@Query() query: PostQueryDto, @IsMaster() master: boolean) { + async getPaginate(@Query() query: PostQueryDto) { const { size, select, page, year, sortBy, sortOrder } = query return await this.postService.findWithPaginator( diff --git a/src/modules/post/post.model.ts b/src/modules/post/post.model.ts index b109c11d..b5b7d682 100644 --- a/src/modules/post/post.model.ts +++ b/src/modules/post/post.model.ts @@ -22,7 +22,8 @@ import { import { BeAnObject } from '@typegoose/typegoose/lib/types' import { Paginator } from '~/shared/interface/paginator.interface' -import { CountMixed as Count, WriteBaseModel } from '~/shared/model/base.model' +import { CountModel as Count } from '~/shared/model/count.model' +import { WriteBaseModel } from '~/shared/model/write-base.model' import { CategoryModel as Category } from '../category/category.model' diff --git a/src/processors/helper/helper.image.service.ts b/src/processors/helper/helper.image.service.ts index 51c620fa..1843dc7e 100644 --- a/src/processors/helper/helper.image.service.ts +++ b/src/processors/helper/helper.image.service.ts @@ -8,7 +8,8 @@ import { import { ReturnModelType } from '@typegoose/typegoose' import { ConfigsService } from '~/modules/configs/configs.service' -import { TextImageRecordType, WriteBaseModel } from '~/shared/model/base.model' +import { TextImageRecordType } from '~/shared/model/base.model' +import { WriteBaseModel } from '~/shared/model/write-base.model' import { getAverageRGB, pickImagesFromMarkdown } from '~/utils/pic.util' import { HttpService } from './helper.http.service' diff --git a/src/shared/model/base-comment.model.ts b/src/shared/model/base-comment.model.ts new file mode 100644 index 00000000..297d8f52 --- /dev/null +++ b/src/shared/model/base-comment.model.ts @@ -0,0 +1,21 @@ +import { IsBoolean, IsOptional } from 'class-validator' + +import { ApiHideProperty } from '@nestjs/swagger' +import { prop } from '@typegoose/typegoose' + +import { BaseModel } from './base.model' + +export abstract class BaseCommentIndexModel extends BaseModel { + @prop({ default: 0 }) + @ApiHideProperty() + commentsIndex?: number + + @prop({ default: true }) + @IsBoolean() + @IsOptional() + allowComment: boolean + + static get protectedKeys() { + return ['commentsIndex'].concat(super.protectedKeys) + } +} diff --git a/src/shared/model/base.model.ts b/src/shared/model/base.model.ts index 339838b1..96a32596 100644 --- a/src/shared/model/base.model.ts +++ b/src/shared/model/base.model.ts @@ -1,28 +1,19 @@ -import { Type } from 'class-transformer' -import { - IsBoolean, - IsHexColor, - IsNotEmpty, - IsNumber, - IsOptional, - IsString, - IsUrl, - ValidateNested, -} from 'class-validator' import LeanId from 'mongoose-lean-id' import { default as mongooseLeanVirtuals } from 'mongoose-lean-virtuals' import Paginate from 'mongoose-paginate-v2' import { ApiHideProperty } from '@nestjs/swagger' -import { index, modelOptions, plugin, prop } from '@typegoose/typegoose' +import { index, modelOptions, plugin } from '@typegoose/typegoose' + +import { ImageModel } from './image.model' @plugin(mongooseLeanVirtuals) @plugin(Paginate) @plugin(LeanId) @modelOptions({ schemaOptions: { - toJSON: { virtuals: true }, - toObject: { virtuals: true }, + toJSON: { virtuals: true, getters: true }, + toObject: { virtuals: true, getters: true }, timestamps: { createdAt: 'created', updatedAt: false, @@ -44,87 +35,4 @@ export class BaseModel { } } -@modelOptions({ - schemaOptions: { _id: false }, -}) -abstract class ImageModel { - @prop() - @IsOptional() - @IsNumber() - width?: number - - @prop() - @IsOptional() - @IsNumber() - height?: number - - @prop() - @IsOptional() - @IsHexColor() - accent?: string - - @prop() - @IsString() - @IsOptional() - type?: string - - @prop() - @IsOptional() - @IsUrl() - src?: string -} - -export abstract class BaseCommentIndexModel extends BaseModel { - @prop({ default: 0 }) - @ApiHideProperty() - commentsIndex?: number - - @prop({ default: true }) - @IsBoolean() - @IsOptional() - allowComment: boolean - - static get protectedKeys() { - return ['commentsIndex'].concat(super.protectedKeys) - } -} - -export class WriteBaseModel extends BaseCommentIndexModel { - @prop({ trim: true, index: true, required: true }) - @IsString() - @IsNotEmpty() - title: string - - @prop({ trim: true }) - @IsString() - text: string - - @prop({ type: ImageModel }) - @ApiHideProperty() - @IsOptional() - @ValidateNested() - @Type(() => ImageModel) - images?: ImageModel[] - - @prop({ default: null, type: Date }) - @ApiHideProperty() - modified: Date | null - - static get protectedKeys() { - return super.protectedKeys - } -} - -@modelOptions({ - schemaOptions: { id: false, _id: false }, - options: { customName: 'count' }, -}) -export class CountMixed { - @prop({ default: 0 }) - read?: number - - @prop({ default: 0 }) - like?: number -} - export type { ImageModel as TextImageRecordType } diff --git a/src/shared/model/count.model.ts b/src/shared/model/count.model.ts new file mode 100644 index 00000000..dc794926 --- /dev/null +++ b/src/shared/model/count.model.ts @@ -0,0 +1,13 @@ +import { modelOptions, prop } from '@typegoose/typegoose' + +@modelOptions({ + schemaOptions: { id: false, _id: false }, + options: { customName: 'count' }, +}) +export class CountModel { + @prop({ default: 0 }) + read?: number + + @prop({ default: 0 }) + like?: number +} diff --git a/src/shared/model/image.model.ts b/src/shared/model/image.model.ts new file mode 100644 index 00000000..84830051 --- /dev/null +++ b/src/shared/model/image.model.ts @@ -0,0 +1,39 @@ +import { + IsHexColor, + IsNumber, + IsOptional, + IsString, + IsUrl, +} from 'class-validator' + +import { modelOptions, prop } from '@typegoose/typegoose' + +@modelOptions({ + schemaOptions: { _id: false }, +}) +export abstract class ImageModel { + @prop() + @IsOptional() + @IsNumber() + width?: number + + @prop() + @IsOptional() + @IsNumber() + height?: number + + @prop() + @IsOptional() + @IsHexColor() + accent?: string + + @prop() + @IsString() + @IsOptional() + type?: string + + @prop() + @IsOptional() + @IsUrl() + src?: string +} diff --git a/src/shared/model/write-base.model.ts b/src/shared/model/write-base.model.ts new file mode 100644 index 00000000..de1c125f --- /dev/null +++ b/src/shared/model/write-base.model.ts @@ -0,0 +1,57 @@ +import { Type } from 'class-transformer' +import { + IsNotEmpty, + IsObject, + IsOptional, + IsString, + ValidateNested, +} from 'class-validator' + +import { ApiHideProperty } from '@nestjs/swagger' +import { PropType, prop } from '@typegoose/typegoose' + +import { BaseCommentIndexModel } from './base-comment.model' +import { ImageModel } from './image.model' + +export class WriteBaseModel extends BaseCommentIndexModel { + @prop({ trim: true, index: true, required: true }) + @IsString() + @IsNotEmpty() + title: string + + @prop({ trim: true }) + @IsString() + text: string + + @prop({ type: ImageModel }) + @ApiHideProperty() + @IsOptional() + @ValidateNested() + @Type(() => ImageModel) + images?: ImageModel[] + + @prop({ default: null, type: Date }) + @ApiHideProperty() + modified: Date | null + + @prop( + { + type: String, + + get(jsonString) { + return JSON.safeParse(jsonString) + }, + set(val) { + return JSON.stringify(val) + }, + }, + PropType.NONE, + ) + @IsOptional() + @IsObject() + meta?: Record + + static get protectedKeys() { + return super.protectedKeys + } +}