feat: url builder

This commit is contained in:
Innei
2022-06-17 22:00:48 +08:00
parent 675a932218
commit 07f9c6bbf8
8 changed files with 94 additions and 10 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<any>[] = [
AssetService,
@@ -33,6 +34,7 @@ const providers: Provider<any>[] = [
HttpService,
JWTService,
ImageService,
UrlBuilderService,
TaskQueueService,
TextMacroService,
UploadService,

View File

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

View File

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