feat: add meta for write model
This commit is contained in:
@@ -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
15
src/global/json.global.ts
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
21
src/shared/model/base-comment.model.ts
Normal file
21
src/shared/model/base-comment.model.ts
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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 }
|
||||
|
||||
13
src/shared/model/count.model.ts
Normal file
13
src/shared/model/count.model.ts
Normal 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
|
||||
}
|
||||
39
src/shared/model/image.model.ts
Normal file
39
src/shared/model/image.model.ts
Normal 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
|
||||
}
|
||||
57
src/shared/model/write-base.model.ts
Normal file
57
src/shared/model/write-base.model.ts
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user