fix:linux上路径问题

This commit is contained in:
Jerry 2025-09-23 15:27:35 +08:00
parent 8d62d0a979
commit 2bb0bcf5ea
11 changed files with 86 additions and 69 deletions

0
LICENSE Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

0
nest-cli.json Normal file → Executable file
View File

0
package.json Normal file → Executable file
View File

0
pnpm-lock.yaml generated Normal file → Executable file
View File

View File

@ -53,42 +53,72 @@ export class FilesService {
remoteApiPath: string, remoteApiPath: string,
replacPath: string, replacPath: string,
) { ) {
const remoteBasePath = this.configService.get(`OPENLIST_API_BASE_PATH`); const remoteBasePath = this.configService.get(`OPENLIST_API_BASE_PATH`) as
| string
| undefined;
const normalizedLocalFiles = localFiles.map((f) => const normalizedLocalFiles = localFiles.map((f) =>
path.normalize(f).replace(/\\/g, '/'), path.normalize(f).replace(/\\/g, '/'),
); );
const remoteApiNorm = (remoteApiPath || '')
.replace(/\\/g, '/')
.replace(/\/+$/, '');
const remoteBaseNorm = (remoteBasePath || '')
.replace(/\\/g, '/')
.replace(/\/+$/, '');
let replacPathNorm = (replacPath || '').replace(/\\/g, '/');
if (replacPathNorm && !replacPathNorm.startsWith('/'))
replacPathNorm = '/' + replacPathNorm;
replacPathNorm = replacPathNorm.replace(/\/+$/, '');
for (const remoteFile of remoteFiles) { for (const remoteFile of remoteFiles) {
let relativePath = path.relative(remoteApiPath, remoteFile.path); const rawRemotePath = String(remoteFile.path || '').replace(/\\/g, '/');
//this.logger.debug(`relativePath: ${relativePath}`);
//this.logger.debug(remoteBasePath); let remoteRelativePath = '';
if (remoteBasePath) {
let remoteRelativePath = relativePath.replace(remoteBasePath, ''); //服务器下载用目录 if (remoteBaseNorm && rawRemotePath.startsWith(remoteBaseNorm)) {
//this.logger.debug(`remoteRelativePath: ${remoteRelativePath}`); //√\ remoteRelativePath = rawRemotePath.slice(remoteBaseNorm.length);
remoteRelativePath = path } else if (remoteApiNorm && rawRemotePath.includes(remoteApiNorm)) {
.normalize(remoteRelativePath) remoteRelativePath = rawRemotePath.slice(
.replace(/\\/g, '/'); rawRemotePath.indexOf(remoteApiNorm),
replacPath = path.normalize(replacPath).replace(/\\/g, '/'); );
relativePath = remoteRelativePath.replace(replacPath, ''); //本地储存用 } else {
this.logger.debug(`replacPath: ${relativePath}`); const rel = path.posix.relative(remoteApiNorm || '/', rawRemotePath);
relativePath = path.normalize(relativePath).replace(/\\/g, '/'); remoteRelativePath = rel ? '/' + rel.replace(/\/+/g, '/') : '/';
this.logger.debug(`relativePathEd: ${relativePath}`); }
const localFilePath = path
.normalize(path.join(localPath, relativePath)) remoteRelativePath = remoteRelativePath.replace(/\/+/g, '/');
.replace(/\\/g, '/'); if (!remoteRelativePath.startsWith('/'))
//this.logger.debug(`localFilePath: ${localFilePath}`); remoteRelativePath = '/' + remoteRelativePath;
let localRelative = remoteRelativePath;
if (replacPathNorm && localRelative.startsWith(replacPathNorm)) {
localRelative = localRelative.slice(replacPathNorm.length);
} else if (replacPathNorm && localRelative.includes(replacPathNorm)) {
localRelative = localRelative.replace(replacPathNorm, '');
}
localRelative = localRelative.replace(/\/+/g, '/').replace(/^\/+/, '');
const localFilePathRaw = path.join(localPath, localRelative);
const localFilePath = path.normalize(localFilePathRaw);
const localFilePathForCompare = localFilePath.replace(/\\/g, '/');
this.logger.debug(`replacPath: ${replacPath}`);
this.logger.debug(`remoteBaseNorm: ${remoteBaseNorm}`);
this.logger.debug(`rawRemotePath: ${rawRemotePath}`);
this.logger.debug(`remoteRelativePath: ${remoteRelativePath}`);
this.logger.debug(`localRelative: ${localRelative}`);
this.logger.debug(`localFilePath: ${localFilePathForCompare}`);
if (remoteFile.is_dir) { if (remoteFile.is_dir) {
try { try {
//const localDirPath = path.dirname(localFilePath); const subRemote =
//await fs.mkdir(localDirPath, { recursive: true });
//this.logger.log(`文件夹已创建: ${localDirPath}`);
//相关逻辑已在oplist工具中处理
const subRemoteFiles =
await this.openListService.listFiles(remoteRelativePath); await this.openListService.listFiles(remoteRelativePath);
if (subRemoteFiles.code === 200 && subRemoteFiles.data.content) { if (subRemote.code === 200 && subRemote.data?.content) {
await this.compareAndDownloadFiles( await this.compareAndDownloadFiles(
localPath, localPath,
normalizedLocalFiles, normalizedLocalFiles,
subRemoteFiles.data.content, subRemote.data.content,
remoteApiPath, remoteApiPath,
replacPath, replacPath,
); );
@ -97,25 +127,16 @@ export class FilesService {
this.logger.error(`递归处理文件夹失败: ${localFilePath}`, error); this.logger.error(`递归处理文件夹失败: ${localFilePath}`, error);
} }
} else { } else {
const normalizedLocalFiles = localFiles.map((f) => if (!normalizedLocalFiles.includes(localFilePathForCompare)) {
path.normalize(f).replace(/\\/g, '/'),
);
//this.logger.debug(
//`normalizedLocalFiles: ${JSON.stringify(normalizedLocalFiles)}`,
//);
if (!normalizedLocalFiles.includes(localFilePath)) {
this.logger.log(`文件缺失: ${localFilePath}, 开始下载..`); this.logger.log(`文件缺失: ${localFilePath}, 开始下载..`);
try { try {
await fs.mkdir(path.dirname(localFilePath), { recursive: true });
await this.openListService.downloadFile( await this.openListService.downloadFile(
remoteRelativePath, remoteRelativePath,
localFilePath, localFilePath,
); );
this.logger.log(`文件下载成功: ${localFilePath}`); this.logger.log(`文件下载成功: ${localFilePath}`);
normalizedLocalFiles.push(localFilePath); normalizedLocalFiles.push(localFilePathForCompare);
this.logger.debug(
`localFilePath: ${JSON.stringify(normalizedLocalFiles)}`,
);
} catch (error) { } catch (error) {
this.logger.error(`下载文件失败: ${localFilePath}`, error); this.logger.error(`下载文件失败: ${localFilePath}`, error);
} }
@ -123,9 +144,6 @@ export class FilesService {
this.logger.log('本地文件已是最新..'); this.logger.log('本地文件已是最新..');
} }
} }
} else {
this.logger.error(`未配置远程根路径..`);
}
} }
} }

View File

@ -33,7 +33,6 @@ async function bootstrap() {
{ path: 'public/(.*)', method: RequestMethod.ALL }, { path: 'public/(.*)', method: RequestMethod.ALL },
], ],
}); });
app.useGlobalInterceptors(new ResponseInterceptor()); app.useGlobalInterceptors(new ResponseInterceptor());
app.useGlobalFilters(new AllExceptionsFilter()); app.useGlobalFilters(new AllExceptionsFilter());
const systemService = app.get(SystemService); const systemService = app.get(SystemService);

View File

@ -10,7 +10,7 @@ import { FilesService } from '../../core/files/files.service';
export class CdnService { export class CdnService {
private readonly logger = new Logger(CdnService.name); private readonly logger = new Logger(CdnService.name);
private filePath: string; private filePath: string;
private readonly updateMs = 15 * 60 * 1000; // 15min private readonly updateMs = 2 * 60 * 100; // 15min
@Inject(PathService) @Inject(PathService)
private readonly paths: PathService; private readonly paths: PathService;
constructor( constructor(
@ -24,7 +24,7 @@ export class CdnService {
private readonly filesService: FilesService, private readonly filesService: FilesService,
) { ) {
this.startAutoUpdate(); this.startAutoUpdate();
this.logger.log(`晶灵云数据中心初始化.. 数据存储在: ${this.filePath}`); this.logger.log(`晶灵云数据中心初始化.. 数据存储在: ${this.filePath}`);
} }
private startAutoUpdate() { private startAutoUpdate() {
@ -55,7 +55,7 @@ export class CdnService {
this.logger.error(`晶灵cdn检查更新失败: ${error}`); this.logger.error(`晶灵cdn检查更新失败: ${error}`);
} }
} else { } else {
this.logger.warn('未配置远程表情包地址..'); this.logger.warn('未配置远程cdn地址..');
} }
}, this.updateMs); }, this.updateMs);
} }

0
start.sh Normal file → Executable file
View File

0
tsconfig.build.json Normal file → Executable file
View File

0
tsconfig.json Normal file → Executable file
View File