feat: url builder
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
52
src/processors/helper/helper.url-builder.service.ts
Normal file
52
src/processors/helper/helper.url-builder.service.ts
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user