import { randomUUID } from "node:crypto"; import { eq } from "drizzle-orm"; import { jsonFailure, jsonSuccess, readJsonBody } from "@/modules/core/server/api"; import { recordAuditLog } from "@/modules/core/server/audit"; import { requirePermission } from "@/modules/core/server/auth"; import { getDatabase } from "@/modules/core/server/db"; import { campuses, buildings, floors, rooms } from "@/modules/core/server/schema"; import { readData } from "@/modules/core/server/store"; function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function readString(source: Record, key: string): string { const value = source[key]; return typeof value === "string" ? value.trim() : ""; } function readPositiveNumber(source: Record, key: string, fallback: number): number { const value = source[key]; const numeric = typeof value === "number" ? value : Number(value); return Number.isInteger(numeric) && numeric > 0 ? numeric : fallback; } export async function GET(): Promise { const auth = await requirePermission("facility:read", { action: "room.list", targetType: "room", }); if (!auth.success) { return auth.response; } const data = await readData(); const organizationId = auth.context.organization?.id; return jsonSuccess("房间列表已加载", { rooms: organizationId ? data.rooms.filter((room) => room.organizationId === organizationId) : data.rooms, }); } export async function POST(request: Request): Promise { const auth = await requirePermission("facility:manage", { action: "room.create", targetType: "room", }); if (!auth.success) { return auth.response; } const organizationId = auth.context.organization?.id; if (!organizationId) { return jsonFailure("请选择机构后维护房间", 400); } const body = await readJsonBody(request); if (!isRecord(body)) { return jsonFailure("请求数据格式无效"); } const roomName = readString(body, "name"); const roomCode = readString(body, "code"); if (!roomName || !roomCode) { return jsonFailure("房间名称和编号不能为空"); } const database = getDatabase(); const createdRows = await database.transaction(async (transaction) => { const campusRows = await transaction.select().from(campuses).where(eq(campuses.organizationId, organizationId)).limit(1); const campus = campusRows[0] ?? ( await transaction .insert(campuses) .values({ organizationId, name: "默认院区", address: "" }) .returning() )[0]; if (!campus) { throw new Error("院区初始化失败"); } const buildingRows = await transaction.select().from(buildings).where(eq(buildings.campusId, campus.id)).limit(1); const building = buildingRows[0] ?? ( await transaction .insert(buildings) .values({ organizationId, campusId: campus.id, name: "默认楼栋" }) .returning() )[0]; if (!building) { throw new Error("楼栋初始化失败"); } const floorRows = await transaction.select().from(floors).where(eq(floors.buildingId, building.id)).limit(1); const floor = floorRows[0] ?? ( await transaction .insert(floors) .values({ organizationId, buildingId: building.id, name: "默认楼层", level: 1 }) .returning() )[0]; if (!floor) { throw new Error("楼层初始化失败"); } return await transaction .insert(rooms) .values({ id: randomUUID(), organizationId, floorId: floor.id, name: roomName, code: roomCode, capacity: readPositiveNumber(body, "capacity", 1), }) .returning(); }); const room = createdRows[0]; if (!room) { return jsonFailure("房间创建失败", 500); } await recordAuditLog({ actor: auth.context.account, organizationId, action: "room.create", targetType: "room", targetId: room.id, result: "success", reason: `新增房间:${room.name}`, }); return jsonSuccess("房间已创建", { room }, 201); }