feat: add meta for write model

This commit is contained in:
Innei
2022-04-22 21:44:48 +08:00
parent a571facd2b
commit 20a788c1a2
13 changed files with 166 additions and 106 deletions

View File

@@ -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()
}

15
src/global/json.global.ts Normal file
View File

@@ -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
}
}
}

View File

@@ -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'

View File

@@ -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 })

View File

@@ -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 {

View File

@@ -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(

View File

@@ -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'

View File

@@ -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'

View File

@@ -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)
}
}

View File

@@ -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 }

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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<string, any>
static get protectedKeys() {
return super.protectedKeys
}
}