90 lines
3.6 KiB
TypeScript
90 lines
3.6 KiB
TypeScript
import { jsonError, jsonOk, readJsonBody } from "@/lib/server/api";
|
|
import { requireAdminSession } from "@/lib/server/auth/current-user";
|
|
import {
|
|
AccountStoreError,
|
|
createPlatformOrganization,
|
|
deletePlatformOrganization,
|
|
listPlatformOrganizations,
|
|
updatePlatformOrganization
|
|
} from "@/lib/server/account-store";
|
|
import { hasSuperAdminAccess } from "@/lib/auth/permissions";
|
|
import type { AuthUser } from "@/lib/auth/session";
|
|
|
|
export const runtime = "nodejs";
|
|
export const dynamic = "force-dynamic";
|
|
|
|
export async function GET() {
|
|
try {
|
|
const session = await requireAdminSession();
|
|
const organizations = await listPlatformOrganizations({ includeDisabled: hasSuperAdminAccess(session.user) });
|
|
return jsonOk({ organizations: organizations
|
|
.filter((organization) => hasSuperAdminAccess(session.user) || organization.id === session.user.organizationId)
|
|
.map((organization) => ({ id: organization.id, name: organization.name, status: organization.status })) });
|
|
} catch (error) {
|
|
return jsonError(error, 500, { source: "api.admin.organizations" });
|
|
}
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const session = await requireAdminSession();
|
|
requireSuperAdmin(session.user);
|
|
const body = await readJsonBody<Record<string, unknown>>(request);
|
|
const organization = await createPlatformOrganization(requiredString(body.name, "组织名称"));
|
|
return jsonOk({ ok: true, organization: publicOrganization(organization) }, { status: 201 });
|
|
} catch (error) {
|
|
return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true });
|
|
}
|
|
}
|
|
|
|
export async function PATCH(request: Request) {
|
|
try {
|
|
const session = await requireAdminSession();
|
|
requireSuperAdmin(session.user);
|
|
const body = await readJsonBody<Record<string, unknown>>(request);
|
|
const organization = await updatePlatformOrganization(requiredString(body.organizationId, "组织 ID"), {
|
|
name: optionalString(body.name),
|
|
status: parseStatus(body.status)
|
|
});
|
|
return jsonOk({ ok: true, organization: publicOrganization(organization) });
|
|
} catch (error) {
|
|
return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true });
|
|
}
|
|
}
|
|
|
|
export async function DELETE(request: Request) {
|
|
try {
|
|
const session = await requireAdminSession();
|
|
requireSuperAdmin(session.user);
|
|
const body = await readJsonBody<Record<string, unknown>>(request);
|
|
await deletePlatformOrganization(requiredString(body.organizationId, "组织 ID"));
|
|
return jsonOk({ ok: true });
|
|
} catch (error) {
|
|
return jsonError(error, 500, { request, source: "api.admin.organizations", logClientErrors: true });
|
|
}
|
|
}
|
|
|
|
function requireSuperAdmin(user: AuthUser) {
|
|
if (!hasSuperAdminAccess(user)) throw new AccountStoreError("需要超级管理员权限。", 403);
|
|
}
|
|
|
|
function publicOrganization(organization: { id: string; name: string; status: string }) {
|
|
return { id: organization.id, name: organization.name, status: organization.status };
|
|
}
|
|
|
|
function requiredString(value: unknown, label: string): string {
|
|
const normalized = optionalString(value);
|
|
if (!normalized) throw new AccountStoreError(`${label}不能为空。`, 400);
|
|
return normalized;
|
|
}
|
|
|
|
function optionalString(value: unknown): string | undefined {
|
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
}
|
|
|
|
function parseStatus(value: unknown): "active" | "disabled" | undefined {
|
|
if (value === undefined || value === null || value === "") return undefined;
|
|
if (value === "active" || value === "disabled") return value;
|
|
throw new AccountStoreError("组织状态不正确。", 400);
|
|
}
|