route.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { NextRequest, NextResponse } from "next/server";
  2. import { writeFile } from "node:fs/promises";
  3. import {
  4. addMessage,
  5. clearMessages,
  6. createStorageKey,
  7. formatUploadedFileMeta,
  8. getOnlineUsers,
  9. listMessages,
  10. resolveUploadPath,
  11. touchPresence
  12. } from "@/lib/chat-store";
  13. export async function GET(request: NextRequest) {
  14. const user = request.nextUrl.searchParams.get("user") || undefined;
  15. touchPresence(user);
  16. return NextResponse.json({
  17. messages: listMessages(),
  18. onlineUsers: getOnlineUsers()
  19. });
  20. }
  21. export async function POST(request: NextRequest) {
  22. const contentType = request.headers.get("content-type") || "";
  23. let user = "局域网设备";
  24. let content = "";
  25. let fileRecord:
  26. | {
  27. name: string;
  28. meta: string;
  29. kind: "image" | "file";
  30. storageKey: string;
  31. }
  32. | undefined;
  33. if (contentType.includes("multipart/form-data")) {
  34. const formData = await request.formData();
  35. user = String(formData.get("user") || "局域网设备").trim() || "局域网设备";
  36. content = String(formData.get("content") || "").trim();
  37. const file = formData.get("file");
  38. if (file instanceof File && file.size > 0) {
  39. const storageKey = createStorageKey(file.name);
  40. const buffer = Buffer.from(await file.arrayBuffer());
  41. await writeFile(resolveUploadPath(storageKey), buffer);
  42. fileRecord = {
  43. name: file.name,
  44. meta: formatUploadedFileMeta(file.name, file.type, file.size),
  45. kind: file.type.startsWith("image/") ? "image" : "file",
  46. storageKey
  47. };
  48. }
  49. } else {
  50. const payload = (await request.json()) as {
  51. user?: string;
  52. content?: string;
  53. };
  54. user = payload.user?.trim() || "局域网设备";
  55. content = payload.content?.trim() || "";
  56. }
  57. if (!content && !fileRecord) {
  58. return NextResponse.json({ error: "消息不能为空" }, { status: 400 });
  59. }
  60. touchPresence(user);
  61. const message = addMessage({
  62. user,
  63. content,
  64. file: fileRecord
  65. });
  66. return NextResponse.json({
  67. message,
  68. onlineUsers: getOnlineUsers()
  69. });
  70. }
  71. export async function DELETE(request: NextRequest) {
  72. const payload = (await request.json().catch(() => ({}))) as {
  73. user?: string;
  74. };
  75. const user = payload.user?.trim() || "局域网设备";
  76. touchPresence(user);
  77. await clearMessages(user);
  78. return NextResponse.json({
  79. messages: listMessages(),
  80. onlineUsers: getOnlineUsers()
  81. });
  82. }