crystelf-core/modules/public/file.controller.ts
2025-07-07 21:48:42 +08:00

113 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import express from 'express';
import FileService from './file.service';
import logger from '../../core/utils/system/logger';
import response from '../../core/utils/system/response';
import paths from '../../core/utils/system/path';
import multer from 'multer';
import tools from '../../core/utils/modules/tools';
const uploadDir = paths.get('uploads');
const upload = multer({
dest: uploadDir,
});
class FileController {
private readonly router: express.Router;
private readonly FileService: FileService;
constructor() {
this.router = express.Router();
this.FileService = new FileService();
this.initializeRoutes();
}
public getRouter(): express.Router {
return this.router;
}
private initializeRoutes(): void {
this.router.get('*', this.handleGetFile);
this.router.post('/upload', upload.single('file'), this.handleUploadFile);
}
/**
* get文件
* @param req
* @param res
*/
private handleGetFile = async (req: express.Request, res: express.Response): Promise<void> => {
try {
const fullPath = req.params[0];
logger.debug(`有个小可爱正在请求${fullPath}噢..`);
const filePath = await this.FileService.getFile(fullPath);
if (!filePath) {
logger.warn(`${fullPath}:文件不存在..`);
await response.error(res, '文件不存在啦!', 404);
return;
}
res.sendFile(filePath);
logger.info(`成功投递文件: ${filePath}`);
} catch (error) {
await response.error(res, '晶灵服务处理文件请求时出错..', 500);
logger.error('晶灵数据请求处理失败:', error);
}
};
/**
* 处理文件上传请求
* 客户端应以 `multipart/form-data` 格式上传文件,字段名为 `file`
* @example 示例请求(使用 axios 和 form-data
* ```js
* const form = new FormData();
* const fileStream = fs.createReadStream(filePath);
* form.append('file', fileStream);
* const uploadUrl = `http://localhost:4000/upload?dir=example&expire=600`;
* const response = await axios.post(uploadUrl, form, {
* headers: {
* ...form.getHeaders(),
* },
* maxContentLength: Infinity,
* maxBodyLength: Infinity,
* });
* ```
*
* @queryParam dir 上传到的相对目录,默认根目录
* @queryParam expire 文件保留时间,默认 600 秒
* @param req
* @param res
*/
private handleUploadFile = async (req: express.Request, res: express.Response): Promise<void> => {
try {
const token = req.body.token;
if (tools.checkToken(token.toString())) {
if (!req.file) {
await response.error(res, `未检测到上传文件`, 400);
return;
}
logger.debug(`检测到上传文件..`);
const uploadDir = req.query.dir?.toString() || '';
const deleteAfter = parseInt(req.query.expire as string) || 10 * 60;
const { fullPath, relativePath } = await this.FileService.saveUploadedFile(
req.file,
uploadDir
);
await this.FileService.scheduleDelete(fullPath, deleteAfter * 1000);
await response.success(res, {
message: '文件上传成功..',
filePath: fullPath,
url: relativePath,
});
} else {
await tools.tokenCheckFailed(res, token);
}
} catch (e) {
await response.error(res, `文件上传失败..`, 500);
logger.error(e);
}
};
}
export default new FileController();