feat: add admin db query
This commit is contained in:
@@ -119,6 +119,7 @@
|
||||
"passport": "0.5.2",
|
||||
"passport-jwt": "4.0.0",
|
||||
"pluralize": "*",
|
||||
"qs": "6.10.3",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rxjs": "7.5.4",
|
||||
"snakecase-keys": "5.1.2",
|
||||
@@ -148,12 +149,14 @@
|
||||
"@types/node": "16.11.26",
|
||||
"@types/nodemailer": "6.4.4",
|
||||
"@types/passport-jwt": "3.0.6",
|
||||
"@types/qs": "6.9.7",
|
||||
"@types/ua-parser-js": "0.7.36",
|
||||
"@vercel/ncc": "0.33.3",
|
||||
"cron": "*",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint": "*",
|
||||
"husky": "7.0.4",
|
||||
"i": "0.3.7",
|
||||
"ioredis": "4.28.5",
|
||||
"jest": "27.5.1",
|
||||
"lint-staged": "12.3.5",
|
||||
|
||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -44,6 +44,7 @@ specifiers:
|
||||
'@types/node': 16.11.26
|
||||
'@types/nodemailer': 6.4.4
|
||||
'@types/passport-jwt': 3.0.6
|
||||
'@types/qs': 6.9.7
|
||||
'@types/ua-parser-js': 0.7.36
|
||||
'@vercel/ncc': 0.33.3
|
||||
algoliasearch: 4.12.2
|
||||
@@ -68,6 +69,7 @@ specifiers:
|
||||
get-image-colors: 4.0.1
|
||||
html-minifier: 4.0.0
|
||||
husky: 7.0.4
|
||||
i: 0.3.7
|
||||
image-size: 1.0.1
|
||||
inquirer: '*'
|
||||
ioredis: 4.28.5
|
||||
@@ -94,6 +96,7 @@ specifiers:
|
||||
passport-jwt: 4.0.0
|
||||
pluralize: '*'
|
||||
prettier: 2.5.1
|
||||
qs: 6.10.3
|
||||
redis-memory-server: 0.5.0
|
||||
reflect-metadata: 0.1.13
|
||||
rimraf: 3.0.2
|
||||
@@ -169,6 +172,7 @@ dependencies:
|
||||
passport: 0.5.2
|
||||
passport-jwt: 4.0.0
|
||||
pluralize: 8.0.0
|
||||
qs: 6.10.3
|
||||
reflect-metadata: 0.1.13
|
||||
rxjs: 7.5.4
|
||||
snakecase-keys: 5.1.2
|
||||
@@ -202,12 +206,14 @@ devDependencies:
|
||||
'@types/node': 16.11.26
|
||||
'@types/nodemailer': 6.4.4
|
||||
'@types/passport-jwt': 3.0.6
|
||||
'@types/qs': 6.9.7
|
||||
'@types/ua-parser-js': 0.7.36
|
||||
'@vercel/ncc': 0.33.3
|
||||
cron: 1.7.2
|
||||
cross-env: 7.0.3
|
||||
eslint: 8.10.0
|
||||
husky: 7.0.4
|
||||
i: 0.3.7
|
||||
ioredis: 4.28.5
|
||||
jest: 27.5.1_ts-node@10.6.0
|
||||
lint-staged: 12.3.5
|
||||
@@ -4701,6 +4707,11 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/i/0.3.7:
|
||||
resolution: {integrity: sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==}
|
||||
engines: {node: '>=0.4'}
|
||||
dev: true
|
||||
|
||||
/iconv-lite/0.4.24:
|
||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -6985,6 +6996,13 @@ packages:
|
||||
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
/qs/6.10.3:
|
||||
resolution: {integrity: sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==}
|
||||
engines: {node: '>=0.6'}
|
||||
dependencies:
|
||||
side-channel: 1.0.4
|
||||
dev: false
|
||||
|
||||
/qs/6.5.2:
|
||||
resolution: {integrity: sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { AnalyzeInterceptor } from './common/interceptors/analyze.interceptor'
|
||||
import { HttpCacheInterceptor } from './common/interceptors/cache.interceptor'
|
||||
import { CountingInterceptor } from './common/interceptors/counting.interceptor'
|
||||
import { JSONSerializeInterceptor } from './common/interceptors/json-serialize.interceptor'
|
||||
import { QueryInterceptor } from './common/interceptors/query.interceptor'
|
||||
import { ResponseInterceptor } from './common/interceptors/response.interceptor'
|
||||
import { AttachHeaderTokenMiddleware } from './common/middlewares/attach-auth.middleware'
|
||||
import { AggregateModule } from './modules/aggregate/aggregate.module'
|
||||
@@ -85,7 +86,12 @@ import { LoggerModule } from './processors/logger/logger.module'
|
||||
providers: [
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: HttpCacheInterceptor,
|
||||
useClass: QueryInterceptor,
|
||||
},
|
||||
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: HttpCacheInterceptor, // 4
|
||||
},
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
@@ -93,15 +99,15 @@ import { LoggerModule } from './processors/logger/logger.module'
|
||||
},
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: CountingInterceptor,
|
||||
useClass: CountingInterceptor, // 3
|
||||
},
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: JSONSerializeInterceptor,
|
||||
useClass: JSONSerializeInterceptor, // 2
|
||||
},
|
||||
{
|
||||
provide: APP_INTERCEPTOR,
|
||||
useClass: ResponseInterceptor,
|
||||
useClass: ResponseInterceptor, // 1
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
NestInterceptor,
|
||||
} from '@nestjs/common'
|
||||
import { ReturnModelType } from '@typegoose/typegoose'
|
||||
import { FastifyRequest } from 'fastify'
|
||||
import isbot from 'isbot'
|
||||
import { InjectModel } from 'nestjs-typegoose'
|
||||
import { Observable } from 'rxjs'
|
||||
@@ -21,6 +20,7 @@ import { RedisKeys } from '~/constants/cache.constant'
|
||||
import { AnalyzeModel } from '~/modules/analyze/analyze.model'
|
||||
import { OptionModel } from '~/modules/configs/configs.model'
|
||||
import { CacheService } from '~/processors/cache/cache.service'
|
||||
import { getNestExecutionContextRequest } from '~/utils'
|
||||
import { getIp } from '~/utils/ip.util'
|
||||
import { getRedisKey } from '~/utils/redis.util'
|
||||
|
||||
@@ -47,7 +47,7 @@ export class AnalyzeInterceptor implements NestInterceptor {
|
||||
next: CallHandler<any>,
|
||||
): Promise<Observable<any>> {
|
||||
const call$ = next.handle()
|
||||
const request = this.getRequest(context)
|
||||
const request = getNestExecutionContextRequest(context)
|
||||
if (!request) {
|
||||
return call$
|
||||
}
|
||||
@@ -130,12 +130,4 @@ export class AnalyzeInterceptor implements NestInterceptor {
|
||||
|
||||
return call$
|
||||
}
|
||||
|
||||
getRequest(context: ExecutionContext) {
|
||||
const req = context.switchToHttp().getRequest<KV>()
|
||||
if (req) {
|
||||
return req as FastifyRequest & { user?: any }
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
35
src/common/interceptors/query.interceptor.ts
Normal file
35
src/common/interceptors/query.interceptor.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import {
|
||||
CallHandler,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
NestInterceptor,
|
||||
} from '@nestjs/common'
|
||||
import qs from 'qs'
|
||||
import { Observable } from 'rxjs'
|
||||
import { getNestExecutionContextRequest } from '~/utils'
|
||||
/** 此拦截器用于转换 req.query.query -> js object,用于直接数据库查询,需要鉴权 */
|
||||
@Injectable()
|
||||
export class QueryInterceptor implements NestInterceptor {
|
||||
intercept(
|
||||
context: ExecutionContext,
|
||||
next: CallHandler<any>,
|
||||
): Observable<any> | Promise<Observable<any>> {
|
||||
const request = getNestExecutionContextRequest(context)
|
||||
const query = request.query as any
|
||||
|
||||
if (!query) {
|
||||
return next.handle()
|
||||
}
|
||||
|
||||
const queryObj = query.db_query
|
||||
|
||||
if (request.user) {
|
||||
;(request.query as any).db_query =
|
||||
typeof queryObj === 'string' ? qs.parse(queryObj) : queryObj
|
||||
} else {
|
||||
delete (request.query as any).db_query
|
||||
}
|
||||
|
||||
return next.handle()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Body, Controller, Post, Query } from '@nestjs/common'
|
||||
import { Body, Controller, Get, Post, Query } from '@nestjs/common'
|
||||
import { AdminEventsGateway } from '~/processors/gateway/admin/events.gateway'
|
||||
import { EventTypes } from '~/processors/gateway/events.types'
|
||||
import { WebEventsGateway } from '~/processors/gateway/web/events.gateway'
|
||||
import { PagerDto } from '~/shared/dto/pager.dto'
|
||||
|
||||
@Controller('debug')
|
||||
export class DebugController {
|
||||
@@ -9,6 +10,10 @@ export class DebugController {
|
||||
private readonly webEvent: WebEventsGateway,
|
||||
private readonly adminEvent: AdminEventsGateway,
|
||||
) {}
|
||||
@Get('qs')
|
||||
async qs(@Query() query: PagerDto) {
|
||||
return query
|
||||
}
|
||||
|
||||
@Post('/events')
|
||||
async sendEvent(
|
||||
|
||||
@@ -61,12 +61,12 @@ export class NoteController {
|
||||
@Paginator
|
||||
@ApiOperation({ summary: '获取记录带分页器' })
|
||||
async getNotes(@IsMaster() isMaster: boolean, @Query() query: NoteQueryDto) {
|
||||
const { size, select, page, sortBy, sortOrder, year } = query
|
||||
const { size, select, page, sortBy, sortOrder, year, db_query } = query
|
||||
const condition = {
|
||||
...addHidePasswordAndHideCondition(isMaster),
|
||||
...addYearCondition(year),
|
||||
}
|
||||
return await this.noteService.model.paginate(condition, {
|
||||
return await this.noteService.model.paginate(db_query ?? condition, {
|
||||
limit: size,
|
||||
page,
|
||||
select: isMaster
|
||||
|
||||
@@ -11,7 +11,11 @@ import {
|
||||
ValidateIf,
|
||||
} from 'class-validator'
|
||||
|
||||
export class PagerDto {
|
||||
class DbQueryDto {
|
||||
@IsOptional()
|
||||
db_query?: any
|
||||
}
|
||||
export class PagerDto extends DbQueryDto {
|
||||
@Min(1)
|
||||
@Max(50)
|
||||
@IsInt()
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { ExecutionContext } from '@nestjs/common'
|
||||
import type { FastifyRequest } from 'fastify'
|
||||
import type { UserModel } from '~/modules/user/user.model'
|
||||
export function getNestExecutionContextRequest(
|
||||
context: ExecutionContext,
|
||||
): FastifyRequest & KV {
|
||||
): FastifyRequest & { user?: UserModel } & KV {
|
||||
return context.switchToHttp().getRequest<FastifyRequest>()
|
||||
// if (req) {
|
||||
// return req
|
||||
|
||||
Reference in New Issue
Block a user