Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aggregate): aggregate data module #396

Merged
merged 4 commits into from
Oct 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions apps/core/src/app.controller.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import PKG from "../../../package.json";
import PKG from '../../../package.json';
import { ApiOperation } from '@nestjs/swagger';

@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}

@Get(["/", "/info"])
@ApiOperation({ summary: "获取服务端版本等信息" })
@Get(['/', '/info'])
@ApiOperation({ summary: '获取服务端版本等信息' })
async appInfo() {
return {
name: PKG.name,
author: PKG.author,
// @ts-ignore
version: isDev ? "dev" : PKG.version,
version: isDev ? 'dev' : PKG.version,
homepage: PKG.homepage,
issues: PKG.issues,
};
}

@Get(["/ping"])
@ApiOperation({ summary: "测试接口是否存活" })
ping(): "pong" {
return "pong";
@Get(['/ping'])
@ApiOperation({ summary: '测试接口是否存活' })
ping(): 'pong' {
return 'pong';
}
}
2 changes: 2 additions & 0 deletions apps/core/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { JSONSerializeInterceptor } from '~/shared/common/interceptors/json-seri
import { ResponseInterceptor } from '~/shared/common/interceptors/response.interceptor';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AggregateModule } from './modules/aggregate/aggregate.module';
import { CategoryModule } from './modules/category/category.module';
import { PageModule } from './modules/page/page.module';
import { PostModule } from './modules/post/post.module';
Expand All @@ -26,6 +27,7 @@ import { UserModule } from './modules/user/user.module';
PostModule,
PageModule,
CategoryModule,
AggregateModule,
],
controllers: [AppController],
providers: [
Expand Down
14 changes: 5 additions & 9 deletions apps/core/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @author: Wibus
* @Date: 2022-09-03 14:19:53
* @LastEditors: Wibus
* @LastEditTime: 2022-09-25 15:33:26
* @LastEditTime: 2022-10-01 20:02:53
* Coding With IU
*/

Expand Down Expand Up @@ -43,21 +43,18 @@ export async function bootstrap() {
whitelist: true, // 允许所有参数
errorHttpStatusCode: 422, // 返回422错误
forbidUnknownValues: true, // 禁止未知参数
// @ts-ignore

enableDebugMessages: isDev, // 开启调试模式
stopAtFirstError: true, // 在第一个错误后立即停止
}),
);

// @ts-ignore
!isDev && app.setGlobalPrefix(`api`);

// @ts-ignore
if (isDev) {
app.useGlobalInterceptors(new LoggingInterceptor());
}

// @ts-ignore
if (isDev) {
const { DocumentBuilder, SwaggerModule } = await import('@nestjs/swagger');
const options = new DocumentBuilder()
Expand All @@ -79,18 +76,17 @@ export async function bootstrap() {
Logger.error(err);
process.exit(1);
}
// @ts-ignore

consola.info('ENV:', process.env.NODE_ENV);
const url = await app.getUrl();
const pid = process.pid;

const prefix = 'P';
// @ts-ignore

if (isDev || argv.dev_online == 'true') {
// @ts-ignore
consola.debug(`[${prefix + pid}] OpenApi: ${url}/api-docs`);
}
// @ts-ignore

consola.success(`[${prefix + pid}] 服务器正在监听: ${url}`);
Logger.log(
`NxServer 已启动. ${chalk.yellow(`+${performance.now() | 0}ms`)}`,
Expand Down
92 changes: 92 additions & 0 deletions apps/core/src/modules/aggregate/aggregate.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* @FilePath: /mog-core/apps/core/src/modules/aggregate/aggregate.controller.ts
* @author: Wibus
* @Date: 2022-10-01 20:52:08
* @LastEditors: Wibus
* @LastEditTime: 2022-10-01 20:54:01
* Coding With IU
*/

import { CacheKey, CacheTTL, Controller, Get, Query } from '@nestjs/common';
import { ApiOperation } from '@nestjs/swagger';
import { ConfigService } from '~/libs/config/src';
import { Auth } from '~/shared/common/decorator/auth.decorator';
import { ApiName } from '~/shared/common/decorator/openapi.decorator';
import { IsMaster } from '~/shared/common/decorator/role.decorator';
import { CacheKeys } from '~/shared/constants/cache.constant';
import { TopQueryDto } from './aggregate.dto';
import { AggregateService } from './aggregate.service';

@Controller('aggregate')
@ApiName
export class AggregateController {
constructor(
private readonly aggregateService: AggregateService,
private readonly configService: ConfigService,
) {}

@Get('/')
@ApiOperation({ summary: '获取概要' })
@CacheKey(CacheKeys.AggregateCatch)
@CacheTTL(300)
async aggregate() {
const tasks = await Promise.allSettled([
// this.configService.getMaster(),
this.aggregateService.getAllCategory(),
this.aggregateService.getAllPages(),
// this.configService.get("urls"),
// this.configService.get("site"),
]);
const [categories, pageMeta] = tasks.map((t) => {
if (t.status === 'fulfilled') {
return t.value;
} else {
return null;
}
});
return {
categories,
pageMeta,
};
}

@Get('/top')
@ApiOperation({ summary: '获取网站统计信息' })
async top(@Query() query: TopQueryDto, @IsMaster() isMaster: boolean) {
const { size } = query;
return await this.aggregateService.topActivity(size, isMaster);
}

@Get('/sitemap')
@ApiOperation({ summary: '获取网站sitemap' })
@CacheKey(CacheKeys.SiteMapCatch)
@CacheTTL(3600)
async getSiteMapContent() {
return { data: await this.aggregateService.getSiteMapContent() };
}

@Get('/feed')
@ApiOperation({ summary: '获取网站RSS' })
@CacheKey(CacheKeys.RSS)
@CacheTTL(3600)
async getRSSFeed() {
return await this.aggregateService.buildRssStructure();
}

@Get('/stat')
@ApiOperation({ summary: '获取网站统计信息' })
@Auth()
async stat() {
const [count] = await Promise.all([this.aggregateService.getCounts()]);
return {
...count,
};
}

@Get('/clear')
@ApiOperation({ summary: '清除缓存' })
@Auth()
async clearCache() {
return await this.aggregateService.clearAggregateCache();
}
}
10 changes: 10 additions & 0 deletions apps/core/src/modules/aggregate/aggregate.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Transform } from 'class-transformer';
import { Min, Max, IsOptional } from 'class-validator';

export class TopQueryDto {
@Transform(({ value: val }) => parseInt(val))
@Min(1)
@Max(10)
@IsOptional()
size?: number;
}
13 changes: 13 additions & 0 deletions apps/core/src/modules/aggregate/aggregate.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface RSSProps {
title: string;
// url: string;
// author: string;
data: {
created: Date | null;
modified: Date | null;
// link: string;
title: string;
text: string;
id: string;
}[];
}
21 changes: 21 additions & 0 deletions apps/core/src/modules/aggregate/aggregate.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* @FilePath: /mog-core/apps/core/src/modules/aggregate/aggregate.module.ts
* @author: Wibus
* @Date: 2022-10-01 19:50:35
* @LastEditors: Wibus
* @LastEditTime: 2022-10-01 20:54:25
* Coding With IU
*/

import { Module } from '@nestjs/common';
import { PageServiceModule } from '~/apps/page-service/src/page-service.module';
import { AggregateController } from './aggregate.controller';
import { AggregateService } from './aggregate.service';

@Module({
imports: [PageServiceModule],
controllers: [AggregateController],
providers: [AggregateService],
exports: [AggregateService],
})
export class AggregateModule {}
Loading