mirror of
https://github.com/crystelf/crystelf-core.git
synced 2025-12-05 18:41:56 +00:00
添加部分服务
This commit is contained in:
parent
120bf912f1
commit
ccda3ec271
@ -24,7 +24,7 @@
|
|||||||
"@nestjs/platform-ws": "^11.1.6",
|
"@nestjs/platform-ws": "^11.1.6",
|
||||||
"@nestjs/swagger": "^11.2.0",
|
"@nestjs/swagger": "^11.2.0",
|
||||||
"@nestjs/websockets": "^11.1.6",
|
"@nestjs/websockets": "^11.1.6",
|
||||||
"axios": "^1.10.0",
|
"axios": "1.11.0",
|
||||||
"ioredis": "^5.6.1",
|
"ioredis": "^5.6.1",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
|
|||||||
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
@ -10,7 +10,7 @@ importers:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/axios':
|
'@nestjs/axios':
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
version: 4.0.1(@nestjs/common@11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.10.0)(rxjs@7.8.2)
|
version: 4.0.1(@nestjs/common@11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.11.0)(rxjs@7.8.2)
|
||||||
'@nestjs/common':
|
'@nestjs/common':
|
||||||
specifier: ^11.0.1
|
specifier: ^11.0.1
|
||||||
version: 11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
version: 11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
@ -36,8 +36,8 @@ importers:
|
|||||||
specifier: ^11.1.6
|
specifier: ^11.1.6
|
||||||
version: 11.1.6(@nestjs/common@11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.5)(@nestjs/platform-socket.io@11.1.6)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
version: 11.1.6(@nestjs/common@11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.5)(@nestjs/platform-socket.io@11.1.6)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
axios:
|
axios:
|
||||||
specifier: ^1.10.0
|
specifier: 1.11.0
|
||||||
version: 1.10.0
|
version: 1.11.0
|
||||||
ioredis:
|
ioredis:
|
||||||
specifier: ^5.6.1
|
specifier: ^5.6.1
|
||||||
version: 5.6.1
|
version: 5.6.1
|
||||||
@ -1437,8 +1437,8 @@ packages:
|
|||||||
asynckit@0.4.0:
|
asynckit@0.4.0:
|
||||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||||
|
|
||||||
axios@1.10.0:
|
axios@1.11.0:
|
||||||
resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==}
|
resolution: {integrity: sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==}
|
||||||
|
|
||||||
b4a@1.6.7:
|
b4a@1.6.7:
|
||||||
resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==}
|
resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==}
|
||||||
@ -4432,10 +4432,10 @@ snapshots:
|
|||||||
'@napi-rs/nice-win32-x64-msvc': 1.0.4
|
'@napi-rs/nice-win32-x64-msvc': 1.0.4
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@nestjs/axios@4.0.1(@nestjs/common@11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.10.0)(rxjs@7.8.2)':
|
'@nestjs/axios@4.0.1(@nestjs/common@11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.11.0)(rxjs@7.8.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nestjs/common': 11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
'@nestjs/common': 11.1.5(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||||
axios: 1.10.0
|
axios: 1.11.0
|
||||||
rxjs: 7.8.2
|
rxjs: 7.8.2
|
||||||
|
|
||||||
'@nestjs/cli@11.0.7(@swc/cli@0.6.0(@swc/core@1.13.1)(chokidar@4.0.3))(@swc/core@1.13.1)(@types/node@22.16.5)':
|
'@nestjs/cli@11.0.7(@swc/cli@0.6.0(@swc/core@1.13.1)(chokidar@4.0.3))(@swc/core@1.13.1)(@types/node@22.16.5)':
|
||||||
@ -5191,7 +5191,7 @@ snapshots:
|
|||||||
|
|
||||||
asynckit@0.4.0: {}
|
asynckit@0.4.0: {}
|
||||||
|
|
||||||
axios@1.10.0:
|
axios@1.11.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects: 1.15.9
|
follow-redirects: 1.15.9
|
||||||
form-data: 4.0.4
|
form-data: 4.0.4
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export class ResponseInterceptor<T>
|
|||||||
map((data) => ({
|
map((data) => ({
|
||||||
success: true,
|
success: true,
|
||||||
data,
|
data,
|
||||||
message: '操作成功',
|
message: '欢迎使用晶灵核心 | Welcome to use crystelf-core',
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export class AppConfigService implements OnModuleInit {
|
|||||||
* @param key 键值
|
* @param key 键值
|
||||||
* @param defaultValue 默认
|
* @param defaultValue 默认
|
||||||
*/
|
*/
|
||||||
get<T = string>(key: string, defaultValue?: T): T | undefined {
|
public get<T = string>(key: string, defaultValue?: T): T | undefined {
|
||||||
const value = this.nestConfigService.get<T>(key);
|
const value = this.nestConfigService.get<T>(key);
|
||||||
if (value === undefined || value === null) {
|
if (value === undefined || value === null) {
|
||||||
if (defaultValue !== undefined) {
|
if (defaultValue !== undefined) {
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { Inject, Injectable, Logger } from '@nestjs/common';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { PathService } from '../path/path.service';
|
import { PathService } from '../path/path.service';
|
||||||
import { AutoUpdateModule } from '../auto-update/auto-update.module';
|
|
||||||
import { AutoUpdateService } from '../auto-update/auto-update.service';
|
import { AutoUpdateService } from '../auto-update/auto-update.service';
|
||||||
import * as process from 'node:process';
|
import * as process from 'node:process';
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ToolsService } from './tools.service';
|
import { ToolsService } from './tools.service';
|
||||||
|
import { AppConfigModule } from '../../config/config.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [AppConfigModule],
|
||||||
providers: [ToolsService],
|
providers: [ToolsService],
|
||||||
exports: [ToolsService],
|
exports: [ToolsService],
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,10 +1,19 @@
|
|||||||
import { Injectable, Logger } from '@nestjs/common';
|
import {
|
||||||
|
Inject,
|
||||||
|
Injectable,
|
||||||
|
Logger,
|
||||||
|
UnauthorizedException,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { RetryOptions } from './retry-options.interface';
|
import { RetryOptions } from './retry-options.interface';
|
||||||
|
import { AppConfigService } from '../../config/config.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ToolsService {
|
export class ToolsService {
|
||||||
private readonly logger = new Logger(ToolsService.name);
|
private readonly logger = new Logger(ToolsService.name);
|
||||||
|
constructor(
|
||||||
|
@Inject(AppConfigService)
|
||||||
|
private readonly config: AppConfigService,
|
||||||
|
) {}
|
||||||
/**
|
/**
|
||||||
* 异步重试
|
* 异步重试
|
||||||
* @param operation
|
* @param operation
|
||||||
@ -48,4 +57,26 @@ export class ToolsService {
|
|||||||
getRandomDelay(min: number, max: number): number {
|
getRandomDelay(min: number, max: number): number {
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查 token 是否有效
|
||||||
|
* @param token 待验证的 token
|
||||||
|
*/
|
||||||
|
checkToken(token: string): boolean {
|
||||||
|
const expected = this.config.get<string>('TOKEN');
|
||||||
|
if (!expected) {
|
||||||
|
this.logger.error('环境变量 TOKEN 未配置,无法进行验证!');
|
||||||
|
throw new UnauthorizedException('系统配置错误,缺少 TOKEN');
|
||||||
|
}
|
||||||
|
return token === expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token 验证失败时的逻辑
|
||||||
|
* @param token 无效的 token
|
||||||
|
*/
|
||||||
|
tokenCheckFailed(token: string): never {
|
||||||
|
this.logger.warn(`有个小可爱使用了错误的 token: ${JSON.stringify(token)}`);
|
||||||
|
throw new UnauthorizedException('token 验证失败..');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { AuthenticatedSocket } from '../../../types/ws/ws.interface';
|
import { AuthenticatedSocket } from '../../../types/ws/ws.interface';
|
||||||
import { IMessageHandler } from '../../../types/ws/ws.handlers.interface';
|
import { IMessageHandler } from '../../../types/ws/ws.handlers.interface';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PongHandler implements IMessageHandler {
|
export class PongHandler implements IMessageHandler {
|
||||||
type = 'pong';
|
type = 'pong';
|
||||||
private readonly logger = new Logger(PongHandler.name);
|
|
||||||
|
|
||||||
async handle(socket: AuthenticatedSocket, msg: any) {
|
async handle(socket: AuthenticatedSocket, msg: any) {
|
||||||
//this.logger.debug(`收到 pong 消息: ${JSON.stringify(msg)}`);
|
//this.logger.debug(`收到 pong 消息: ${JSON.stringify(msg)}`);
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { WsTools } from './ws.tools';
|
|||||||
import { WsClientManager } from './ws-client.manager';
|
import { WsClientManager } from './ws-client.manager';
|
||||||
import { IMessageHandler } from '../../types/ws/ws.handlers.interface';
|
import { IMessageHandler } from '../../types/ws/ws.handlers.interface';
|
||||||
import { AuthenticatedSocket } from '../../types/ws/ws.interface';
|
import { AuthenticatedSocket } from '../../types/ws/ws.interface';
|
||||||
import { TestHandler } from './handlers/test.handler';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WsMessageHandler {
|
export class WsMessageHandler {
|
||||||
|
|||||||
58
src/modules/system/system.controller.ts
Normal file
58
src/modules/system/system.controller.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Post,
|
||||||
|
Body,
|
||||||
|
UnauthorizedException,
|
||||||
|
Inject,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { ApiTags, ApiOperation, ApiBody } from '@nestjs/swagger';
|
||||||
|
import { SystemWebService } from './system.service';
|
||||||
|
import { ToolsService } from '../../core/tools/tools.service';
|
||||||
|
|
||||||
|
class TokenDto {
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiTags('System')
|
||||||
|
@Controller('system')
|
||||||
|
export class SystemController {
|
||||||
|
constructor(
|
||||||
|
@Inject(SystemWebService)
|
||||||
|
private readonly systemService: SystemWebService,
|
||||||
|
@Inject(ToolsService)
|
||||||
|
private readonly toolService: ToolsService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重启系统
|
||||||
|
*/
|
||||||
|
@Post('restart')
|
||||||
|
@ApiOperation({
|
||||||
|
summary: '系统重启',
|
||||||
|
description: '传入正确的 token 后,核心将执行重启。',
|
||||||
|
})
|
||||||
|
@ApiBody({ type: TokenDto })
|
||||||
|
async systemRestart(@Body() body: TokenDto): Promise<string> {
|
||||||
|
if (!this.toolService.checkToken(body.token)) {
|
||||||
|
throw new UnauthorizedException('Token 无效');
|
||||||
|
}
|
||||||
|
await this.systemService.systemRestart();
|
||||||
|
return '核心正在重启..';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取系统重启耗时
|
||||||
|
*/
|
||||||
|
@Post('getRestartTime')
|
||||||
|
@ApiOperation({
|
||||||
|
summary: '获取重启所需时间',
|
||||||
|
description: '传入正确的 token,返回上次核心重启的耗时',
|
||||||
|
})
|
||||||
|
@ApiBody({ type: TokenDto })
|
||||||
|
async getRestartTime(@Body() body: TokenDto): Promise<string> {
|
||||||
|
if (!this.toolService.checkToken(body.token)) {
|
||||||
|
throw new UnauthorizedException('Token 无效');
|
||||||
|
}
|
||||||
|
return await this.systemService.getRestartTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/modules/system/system.module.ts
Normal file
12
src/modules/system/system.module.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { SystemController } from './system.controller';
|
||||||
|
import { SystemWebService } from './system.service';
|
||||||
|
import { ToolsModule } from '../../core/tools/tools.module';
|
||||||
|
import { PathModule } from '../../core/path/path.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [ToolsModule, SystemModule, PathModule],
|
||||||
|
controllers: [SystemController],
|
||||||
|
providers: [SystemWebService],
|
||||||
|
})
|
||||||
|
export class SystemModule {}
|
||||||
34
src/modules/system/system.service.ts
Normal file
34
src/modules/system/system.service.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import path from 'path';
|
||||||
|
import { PathService } from '../../core/path/path.service';
|
||||||
|
import { SystemService } from 'src/core/system/system.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SystemWebService {
|
||||||
|
private readonly logger = new Logger(SystemWebService.name);
|
||||||
|
@Inject(SystemService)
|
||||||
|
private readonly system: SystemService;
|
||||||
|
@Inject(PathService)
|
||||||
|
private readonly pathService: PathService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重启系统
|
||||||
|
*/
|
||||||
|
async systemRestart(): Promise<void> {
|
||||||
|
this.logger.debug(`有个小可爱正在请求重启核心..`);
|
||||||
|
await this.system.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上次重启所耗时间
|
||||||
|
*/
|
||||||
|
async getRestartTime(): Promise<string> {
|
||||||
|
this.logger.debug(`有个小可爱想知道核心重启花了多久..`);
|
||||||
|
const restartTimePath = path.join(
|
||||||
|
this.pathService.get('temp'),
|
||||||
|
'restart_time',
|
||||||
|
);
|
||||||
|
return await fs.readFile(restartTimePath, 'utf8');
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user