From 07f9c6bbf894e4b30595d06622fd838b5328b60e Mon Sep 17 00:00:00 2001 From: Innei Date: Fri, 17 Jun 2022 22:00:48 +0800 Subject: [PATCH] feat: url builder --- src/modules/aggregate/aggregate.service.ts | 14 ++--- src/modules/recently/recently.model.ts | 20 ++++++- src/modules/recently/recently.service.ts | 12 ++++- src/processors/database/database.service.ts | 2 +- src/processors/helper/helper.module.ts | 2 + .../helper/helper.url-builder.service.ts | 52 +++++++++++++++++++ src/utils/{demo.util.ts => biz.util.ts} | 0 src/utils/index.ts | 2 +- 8 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 src/processors/helper/helper.url-builder.service.ts rename src/utils/{demo.util.ts => biz.util.ts} (100%) diff --git a/src/modules/aggregate/aggregate.service.ts b/src/modules/aggregate/aggregate.service.ts index c8b93260..0ce36d26 100644 --- a/src/modules/aggregate/aggregate.service.ts +++ b/src/modules/aggregate/aggregate.service.ts @@ -12,6 +12,7 @@ import { CacheKeys, RedisKeys } from '~/constants/cache.constant' import { EventBusEvents } from '~/constants/event-bus.constant' import { CacheService } from '~/processors/cache/cache.service' import { WebEventsGateway } from '~/processors/gateway/web/events.gateway' +import { UrlBuilderService } from '~/processors/helper/helper.url-builder.service' import { addYearCondition } from '~/transformers/db-query.transformer' import { getRedisKey } from '~/utils/redis.util' import { getShortDate } from '~/utils/time.util' @@ -56,6 +57,8 @@ export class AggregateService { @Inject(forwardRef(() => RecentlyService)) private readonly recentlyService: RecentlyService, + private readonly urlService: UrlBuilderService, + private readonly configs: ConfigsService, private readonly gateway: WebEventsGateway, private readonly cacheService: CacheService, @@ -263,9 +266,11 @@ export class AggregateService { } async getRSSFeedContent() { const { - url: { webUrl: baseURL }, + url: { webUrl }, } = await this.configs.waitForConfigReady() + const baseURL = webUrl.replace(/\/$/, '') + const [posts, notes] = await Promise.all([ this.postService.model .find({ hide: false }) @@ -293,10 +298,7 @@ export class AggregateService { text: post.text, created: post.created!, modified: post.modified, - link: new URL( - '/posts' + `/${(post.category as CategoryModel).slug}/${post.slug}`, - baseURL, - ).toString(), + link: baseURL + this.urlService.build(post), } }) const notesRss: RSSProps['data'] = notes.map((note) => { @@ -309,7 +311,7 @@ export class AggregateService { text: isSecret ? '这篇文章暂时没有公开呢' : note.text, created: note.created!, modified: note.modified, - link: new URL(`/notes/${note.nid}`, baseURL).toString(), + link: baseURL + this.urlService.build(note), } }) return postsRss diff --git a/src/modules/recently/recently.model.ts b/src/modules/recently/recently.model.ts index e8f3fe32..260daf59 100644 --- a/src/modules/recently/recently.model.ts +++ b/src/modules/recently/recently.model.ts @@ -1,9 +1,14 @@ -import { IsOptional, IsString } from 'class-validator' +import { IsMongoId, IsOptional, IsString } from 'class-validator' import { modelOptions, prop } from '@typegoose/typegoose' import { BaseModel } from '~/shared/model/base.model' +export type RefType = { + title: string + url: string +} + @modelOptions({ options: { customName: 'Recently', @@ -15,8 +20,21 @@ export class RecentlyModel extends BaseModel { content: string @prop() @IsOptional() + @IsMongoId() + refId?: string + + ref?: RefType + + /** + * @deprecated + */ + @prop() + @IsOptional() @IsString() project?: string + /** + * @deprecated + */ @prop() @IsString() @IsOptional() diff --git a/src/modules/recently/recently.service.ts b/src/modules/recently/recently.service.ts index e0cb7f21..0a161abc 100644 --- a/src/modules/recently/recently.service.ts +++ b/src/modules/recently/recently.service.ts @@ -1,6 +1,7 @@ -import { Injectable } from '@nestjs/common' +import { BadRequestException, Injectable } from '@nestjs/common' import { BusinessEvents, EventScope } from '~/constants/business-event.constant' +import { DatabaseService } from '~/processors/database/database.service' import { EventManagerService } from '~/processors/helper/helper.event.service' import { InjectModel } from '~/transformers/model.transformer' @@ -12,6 +13,7 @@ export class RecentlyService { @InjectModel(RecentlyModel) private readonly recentlyModel: MongooseModel, private readonly eventManager: EventManagerService, + private readonly databaseService: DatabaseService, ) {} public get model() { @@ -54,10 +56,18 @@ export class RecentlyService { } async create(model: RecentlyModel) { + if (model.refId) { + const existModel = await this.databaseService.findGlobalById(model.refId) + if (!existModel.type) { + throw new BadRequestException('ref model not found') + } + } + const res = await this.model.create({ content: model.content, language: model.language, project: model.project, + refId: model.refId, }) process.nextTick(async () => { await this.eventManager.broadcast(BusinessEvents.RECENTLY_CREATE, res, { diff --git a/src/processors/database/database.service.ts b/src/processors/database/database.service.ts index 40c64001..df72b80e 100644 --- a/src/processors/database/database.service.ts +++ b/src/processors/database/database.service.ts @@ -55,7 +55,7 @@ export class DatabaseService { const document = doc[index] return { document, - type: ['Post', 'Note', 'Page'][index], + type: (['Post', 'Note', 'Page'] as const)[index], } } diff --git a/src/processors/helper/helper.module.ts b/src/processors/helper/helper.module.ts index 57dbba03..b96bc6b8 100644 --- a/src/processors/helper/helper.module.ts +++ b/src/processors/helper/helper.module.ts @@ -22,6 +22,7 @@ import { JWTService } from './helper.jwt.service' import { TextMacroService } from './helper.macro.service' import { TaskQueueService } from './helper.tq.service' import { UploadService } from './helper.upload.service' +import { UrlBuilderService } from './helper.url-builder.service' const providers: Provider[] = [ AssetService, @@ -33,6 +34,7 @@ const providers: Provider[] = [ HttpService, JWTService, ImageService, + UrlBuilderService, TaskQueueService, TextMacroService, UploadService, diff --git a/src/processors/helper/helper.url-builder.service.ts b/src/processors/helper/helper.url-builder.service.ts new file mode 100644 index 00000000..3db48360 --- /dev/null +++ b/src/processors/helper/helper.url-builder.service.ts @@ -0,0 +1,52 @@ +import { isDefined } from 'class-validator' +import { URL } from 'url' + +import { Injectable } from '@nestjs/common' + +import { CategoryModel } from '~/modules/category/category.model' +import { ConfigsService } from '~/modules/configs/configs.service' +import { NoteModel } from '~/modules/note/note.model' +import { PageModel } from '~/modules/page/page.model' +import { PostModel } from '~/modules/post/post.model' + +@Injectable() +export class UrlBuilderService { + constructor(private readonly configsService: ConfigsService) {} + isPostModel(model: any): model is PostModel { + return ( + isDefined(model.title) && isDefined(model.slug) && !isDefined(model.order) + ) + } + + isPageModel(model: any): model is PageModel { + return ( + isDefined(model.title) && isDefined(model.slug) && isDefined(model.order) + ) + } + + isNoteModel(model: any): model is NoteModel { + return isDefined(model.title) && isDefined(model.nid) + } + + build(model: PostModel | NoteModel | PageModel) { + if (this.isPostModel(model)) { + return `/posts/${ + (model.category as CategoryModel).slug + }/${encodeURIComponent(model.slug)}` + } else if (this.isPageModel(model)) { + return `/${model.slug}` + } else if (this.isNoteModel(model)) { + return `/notes/${model.nid}` + } + + return '/' + } + + async buildWithBaseUrl(model: PostModel | NoteModel | PageModel) { + const { + url: { webUrl: baseURL }, + } = await this.configsService.waitForConfigReady() + + return new URL(this.build(model), baseURL).href + } +} diff --git a/src/utils/demo.util.ts b/src/utils/biz.util.ts similarity index 100% rename from src/utils/demo.util.ts rename to src/utils/biz.util.ts diff --git a/src/utils/index.ts b/src/utils/index.ts index fb2970d6..4eece8dd 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -6,4 +6,4 @@ export * from './redis.util' export * from './system.util' export * from './time.util' export * from './tool.util' -export * from './demo.util' +export * from './biz.util'