47 lines
1.3 KiB
TypeScript
47 lines
1.3 KiB
TypeScript
import { createReadStream, existsSync, statSync } from 'node:fs';
|
|
import { basename } from 'pathe';
|
|
|
|
import {
|
|
getRouterParam,
|
|
sendStream,
|
|
setResponseHeader,
|
|
setResponseStatus,
|
|
} from 'h3';
|
|
|
|
import { getMediaMessageById } from '~/utils/media-repository';
|
|
import { useResponseError } from '~/utils/response';
|
|
|
|
export default defineEventHandler((event) => {
|
|
const idParam = getRouterParam(event, 'id');
|
|
const id = idParam ? Number.parseInt(idParam, 10) : NaN;
|
|
|
|
if (!Number.isInteger(id)) {
|
|
setResponseStatus(event, 400);
|
|
return useResponseError('媒体ID不合法', -1);
|
|
}
|
|
|
|
const media = getMediaMessageById(id);
|
|
if (!media) {
|
|
setResponseStatus(event, 404);
|
|
return useResponseError('未找到对应的媒体记录', -1);
|
|
}
|
|
|
|
if (!media.filePath || !existsSync(media.filePath)) {
|
|
setResponseStatus(event, 404);
|
|
return useResponseError('媒体文件不存在或已被移除', -1);
|
|
}
|
|
|
|
const fileStats = statSync(media.filePath);
|
|
|
|
setResponseHeader(event, 'Content-Type', media.mimeType ?? 'application/octet-stream');
|
|
setResponseHeader(
|
|
event,
|
|
'Content-Disposition',
|
|
`attachment; filename="${encodeURIComponent(media.fileName ?? basename(media.filePath))}"`,
|
|
);
|
|
setResponseHeader(event, 'Content-Length', `${fileStats.size}`);
|
|
|
|
return sendStream(event, createReadStream(media.filePath));
|
|
});
|
|
|