85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
|
|
/**
|
|||
|
|
* 路径解析工具
|
|||
|
|
* 解决开发环境下路径解析问题
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import path from 'path';
|
|||
|
|
import fs from 'fs';
|
|||
|
|
import { fileURLToPath } from 'url';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取项目根目录
|
|||
|
|
* 通过从当前文件向上查找 package.json 来确定
|
|||
|
|
*/
|
|||
|
|
export function getProjectRoot(): string {
|
|||
|
|
// 在开发环境使用 tsx 时,使用 process.cwd()
|
|||
|
|
// 在构建后的环境,使用 __dirname 的方式
|
|||
|
|
let currentDir: string;
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// ESM 模式下获取当前文件目录
|
|||
|
|
const __filename = fileURLToPath(import.meta.url);
|
|||
|
|
currentDir = path.dirname(__filename);
|
|||
|
|
} catch {
|
|||
|
|
// 回退到 process.cwd()
|
|||
|
|
currentDir = process.cwd();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Windows 路径处理(去除开头的 /)
|
|||
|
|
if (process.platform === 'win32' && currentDir.startsWith('/') && /^[a-zA-Z]:/.test(currentDir.slice(1))) {
|
|||
|
|
currentDir = currentDir.substring(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 从当前目录向上查找 package.json
|
|||
|
|
let searchDir = currentDir;
|
|||
|
|
for (let i = 0; i < 10; i++) {
|
|||
|
|
const pkgPath = path.join(searchDir, 'package.json');
|
|||
|
|
if (fs.existsSync(pkgPath)) {
|
|||
|
|
return searchDir;
|
|||
|
|
}
|
|||
|
|
searchDir = path.dirname(searchDir);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果找不到,回退到 process.cwd()
|
|||
|
|
return process.cwd();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取上传目录的绝对路径
|
|||
|
|
*/
|
|||
|
|
export function getUploadsDir(): string {
|
|||
|
|
const projectRoot = getProjectRoot();
|
|||
|
|
return path.join(projectRoot, 'uploads');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 解析图片路径
|
|||
|
|
* 将数据库中存储的路径 (/uploads/xxx.png) 解析为绝对路径
|
|||
|
|
*/
|
|||
|
|
export function resolveImagePath(imagePath: string): string {
|
|||
|
|
// 在 Windows 上,path.isAbsolute 会将 /uploads/... 认为是绝对路径
|
|||
|
|
// 但这实际上是 Unix 风格的相对路径,需要特殊处理
|
|||
|
|
const isWindowsAbsPath = process.platform === 'win32'
|
|||
|
|
? /^[a-zA-Z]:\\/.test(imagePath) // Windows 真正的绝对路径如 C:\
|
|||
|
|
: path.isAbsolute(imagePath);
|
|||
|
|
|
|||
|
|
if (isWindowsAbsPath) {
|
|||
|
|
return imagePath;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理 /uploads/ 开头的相对路径
|
|||
|
|
if (imagePath.startsWith('/uploads/')) {
|
|||
|
|
return path.join(getUploadsDir(), imagePath.replace('/uploads/', ''));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 其他相对路径,使用项目根目录
|
|||
|
|
return path.join(getProjectRoot(), imagePath);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 生成存储到数据库的路径
|
|||
|
|
*/
|
|||
|
|
export function generateDbPath(filename: string): string {
|
|||
|
|
return `/uploads/${filename}`;
|
|||
|
|
}
|