feat:oplist工具模块框架

This commit is contained in:
Jerry 2025-09-15 16:58:03 +08:00
parent 97d536766e
commit cbea0c2b33
6 changed files with 196 additions and 0 deletions

View File

@ -2,3 +2,6 @@ RD_PORT=6379
RD_ADD=127.0.0.1
WS_SECRET=114514
TOKEN=54188
OPENLIST_API_BASE_URL=http://127.0.0.1:5244
OPENLIST_API_BASE_USERNAME=USER
OPENLIST_API_BASE_PASSWORD=123456

View File

@ -13,6 +13,7 @@ import { BotModule } from './modules/bot/bot.module';
import { CdnModule } from './modules/cdn/cdn.module';
import { WordsModule } from './modules/words/words.module';
import { MemeModule } from './modules/meme/meme.module';
import { OpenListModule } from './core/openlist/openlist.module';
@Module({
imports: [
@ -30,6 +31,7 @@ import { MemeModule } from './modules/meme/meme.module';
CdnModule,
WordsModule,
MemeModule,
OpenListModule,
],
})
export class AppModule {}

View File

@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { OpenListService } from './openlist.service';
import { AppConfigModule } from '../../config/config.module';
@Module({
imports: [AppConfigModule],
providers: [OpenListService],
exports: [OpenListService],
})
export class OpenListModule {}

View File

@ -0,0 +1,16 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { AppConfigService } from '../../config/config.service';
import { DirectoryList, FileInfo, UserInfo } from './openlist.types';
import { OpenListUtils } from './openlist.utils';
@Injectable()
export class OpenListService {
private readonly logger = new Logger(OpenListService.name);
constructor(
@Inject(AppConfigService)
private readonly configService: AppConfigService,
) {
OpenListUtils.init(configService);
}
}

View File

@ -0,0 +1,25 @@
export interface UserInfo {
id: number;
username: string;
email: string;
role: string;
created_at: string;
updated_at: string;
}
export interface DirectoryList {
path: string;
name: string;
is_directory: boolean;
size: number;
modified_at: string;
}
export interface FileInfo {
path: string;
size: number;
mime_type: string;
created_at: string;
modified_at: string;
is_directory: boolean;
}

View File

@ -0,0 +1,140 @@
import axios from 'axios';
import { AppConfigService } from '../../config/config.service';
import { Inject, Logger } from '@nestjs/common';
import * as crypto from 'crypto';
export class OpenListUtils {
private static readonly logger = new Logger(OpenListUtils.name);
private static apiBaseUrl: string | undefined;
static init(@Inject(AppConfigService) configService: AppConfigService) {
this.apiBaseUrl = configService.get('OPENLIST_API_BASE_URL');
}
/**
* JWT Token
* @param username
* @param password
* @returns token
*/
static async getToken(username: string, password: string): Promise<string> {
const url = `${this.apiBaseUrl}/auth/token`;
const hashedPassword = this.hashPassword(password);
try {
const response = await axios.post(url, {
username,
password: hashedPassword,
});
const token = response.data.token;
this.logger.log(`获取 Token 成功: ${token}`);
return token;
} catch (error) {
this.logger.error('获取 Token 失败', error);
throw new Error('获取 Token 失败');
}
}
/**
*
* @param token Token
* @returns
*/
static async getUserInfo(token: string): Promise<any> {
const url = `${this.apiBaseUrl}/auth/userinfo`;
try {
const response = await axios.get(url, {
headers: { Authorization: `Bearer ${token}` },
});
this.logger.log('获取用户信息成功');
return response.data;
} catch (error) {
this.logger.error('获取用户信息失败', error);
throw new Error('获取用户信息失败');
}
}
/**
*
* @param token Token
* @param path
* @returns
*/
static async listDirectory(token: string, path: string): Promise<any> {
const url = `${this.apiBaseUrl}/fs/list`;
try {
const response = await axios.get(url, {
params: { path },
headers: { Authorization: `Bearer ${token}` },
});
this.logger.log('列出目录成功');
return response.data;
} catch (error) {
this.logger.error('列出目录失败', error);
throw new Error('列出目录失败');
}
}
/**
*
* @param token Token
* @param filePath
* @returns
*/
static async getFileInfo(token: string, filePath: string): Promise<any> {
const url = `${this.apiBaseUrl}/fs/info`;
try {
const response = await axios.get(url, {
params: { path: filePath },
headers: { Authorization: `Bearer ${token}` },
});
this.logger.log('获取文件信息成功');
return response.data;
} catch (error) {
this.logger.error('获取文件信息失败', error);
throw new Error('获取文件信息失败');
}
}
/**
*
* @param token Token
* @param oldPath
* @param newPath
* @returns
*/
static async renameFile(
token: string,
oldPath: string,
newPath: string,
): Promise<any> {
const url = `${this.apiBaseUrl}/fs/rename`;
try {
const response = await axios.post(
url,
{ oldPath, newPath },
{
headers: { Authorization: `Bearer ${token}` },
},
);
this.logger.log(`文件重命名成功: ${oldPath} => ${newPath}`);
return response.data;
} catch (error) {
this.logger.error('文件重命名失败', error);
throw new Error('文件重命名失败');
}
}
/**
* sha256 hash
* @param password
* @returns hashed
*/
private static hashPassword(password: string): string {
return crypto.createHash('sha256').update(password).digest('hex');
}
}