feat(project): init
This commit is contained in:
53
app/api/images/[id]/route.ts
Normal file
53
app/api/images/[id]/route.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { NextResponse, type NextRequest } from "next/server";
|
||||
import { requireApiUser } from "@/lib/api-auth";
|
||||
import { getStoredImageAssetForViewer } from "@/lib/db";
|
||||
import { jsonError, normalizeError } from "@/lib/http";
|
||||
import { readStoredImageFile } from "@/lib/image-storage";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> },
|
||||
) {
|
||||
try {
|
||||
const viewer = requireApiUser(request);
|
||||
const { id } = await params;
|
||||
const asset = getStoredImageAssetForViewer({
|
||||
viewerId: viewer.id,
|
||||
viewerRole: viewer.role,
|
||||
imageId: id,
|
||||
});
|
||||
|
||||
if (!asset) {
|
||||
return jsonError("图片不存在。", 404);
|
||||
}
|
||||
|
||||
const fileBuffer = await readStoredImageFile(asset.storageKey);
|
||||
const shouldDownload = request.nextUrl.searchParams.get("download") === "1";
|
||||
const dispositionType = shouldDownload ? "attachment" : "inline";
|
||||
|
||||
return new NextResponse(new Uint8Array(fileBuffer), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": asset.mimeType,
|
||||
"Content-Length": String(fileBuffer.byteLength),
|
||||
"Cache-Control": "private, max-age=86400",
|
||||
"Content-Disposition": `${dispositionType}; filename*=UTF-8''${encodeURIComponent(asset.fileName)}`,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
const normalizedError = normalizeError(error, "读取图片失败。");
|
||||
|
||||
if (
|
||||
error &&
|
||||
typeof error === "object" &&
|
||||
"code" in error &&
|
||||
error.code === "ENOENT"
|
||||
) {
|
||||
return jsonError("图片不存在。", 404);
|
||||
}
|
||||
|
||||
return jsonError(normalizedError.message, normalizedError.statusCode);
|
||||
}
|
||||
}
|
||||
24
app/api/images/route.ts
Normal file
24
app/api/images/route.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { NextResponse, type NextRequest } from "next/server";
|
||||
import { requireApiUser } from "@/lib/api-auth";
|
||||
import { listImageHistoryForViewer } from "@/lib/db";
|
||||
import { jsonError, normalizeError } from "@/lib/http";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const viewer = requireApiUser(request);
|
||||
const items = listImageHistoryForViewer({
|
||||
viewerId: viewer.id,
|
||||
viewerRole: viewer.role,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
ok: true,
|
||||
items,
|
||||
});
|
||||
} catch (error) {
|
||||
const normalizedError = normalizeError(error, "读取图片历史失败。");
|
||||
return jsonError(normalizedError.message, normalizedError.statusCode);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user