WuYongJie e4dcb6260a
Some checks failed
CI Check / check (push) Has been cancelled
feat: Admin页面重构 & UI三层架构系统
- 创建统一UI三层架构系统(基础层、颜色层、组合层)
- 拆分Admin页面为独立Tab组件(MonitorTab、UsersTab、DepartmentsTab等)
- 提取公共逻辑到Hooks(useToast、useDataFetch、useUserOperations等)
- 提取工具函数(validators、formatters、api等)
- 创建统一弹窗组件(Modal)和useModal Hook
- 添加错误边界和统一状态组件
- 完善类型定义和可访问性支持
- 更新文档(优化记录、优化计划、更新日志)
2025-11-22 15:17:10 +08:00

145 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
const baseSelect = {
id: true,
name: true,
description: true,
status: true,
version: true,
fieldGroups: true,
displayConfig: true,
createdAt: true,
updatedAt: true,
fields: {
orderBy: { orderIndex: 'asc' },
select: {
id: true,
key: true,
label: true,
type: true,
required: true,
orderIndex: true,
layoutWidth: true,
validations: true,
optionsSource: true,
optionsStatic: true,
allowedExtensions: true,
visibleOnHomeFilter: true,
isSearchable: true,
isReadOnly: true,
conditions: true,
createdAt: true,
updatedAt: true,
},
},
} as const
export async function GET() {
try {
const session = await getServerSession(authOptions)
if (!session || (session.user as any)?.role !== 'ADMIN') {
return NextResponse.json({ error: '无权限' }, { status: 403 })
}
const templates = await prisma.uploadTemplate.findMany({
orderBy: { updatedAt: 'desc' },
select: baseSelect,
})
return NextResponse.json(templates)
} catch (error) {
console.error('List upload templates error:', error)
return NextResponse.json({ error: '获取上传模板失败' }, { status: 500 })
}
}
export async function POST(req: NextRequest) {
let body: any = null
try {
const session = await getServerSession(authOptions)
if (!session || (session.user as any)?.role !== 'ADMIN') {
return NextResponse.json({ error: '无权限' }, { status: 403 })
}
body = await req.json()
const {
name,
description,
status = 'draft',
fieldGroups,
displayConfig,
fields = [],
} = body || {}
if (!name) {
return NextResponse.json({ error: '模板名称不能为空' }, { status: 400 })
}
const formattedFields = Array.isArray(fields)
? fields.map((field: any, index: number) => ({
key: String(field.key || '').trim(),
label: String(field.label || '').trim() || `字段${index + 1}`,
type: String(field.type || 'text'),
required: !!field.required,
orderIndex: field.orderIndex ?? index,
layoutWidth: field.layoutWidth || 'full',
validations: field.validations ?? null,
optionsSource: field.optionsSource ?? null,
// optionsStatic 需要是字符串或 null,如果是数组则转换为 JSON 字符串
optionsStatic: field.optionsStatic !== null && field.optionsStatic !== undefined
? (Array.isArray(field.optionsStatic) ? JSON.stringify(field.optionsStatic) : String(field.optionsStatic))
: null,
allowedExtensions: field.allowedExtensions ?? null,
visibleOnHomeFilter: !!field.visibleOnHomeFilter,
isSearchable: !!field.isSearchable,
isReadOnly: !!field.isReadOnly,
conditions: field.conditions ?? null,
}))
: []
const template = await prisma.uploadTemplate.create({
data: {
name,
description: description ?? null,
status,
fieldGroups: fieldGroups ?? null,
displayConfig: displayConfig ?? null,
fields: formattedFields.length
? { createMany: { data: formattedFields } }
: undefined,
},
select: baseSelect,
})
return NextResponse.json(template, { status: 201 })
} catch (error: any) {
console.error('Create upload template error:', error)
console.error('Error details:', {
message: error?.message,
code: error?.code,
meta: error?.meta,
stack: error?.stack,
body: body,
})
// 如果是 Prisma 错误,返回更详细的错误信息
if (error?.code) {
if (error.code === 'P2002') {
return NextResponse.json({ error: '模板名称已存在,请使用其他名称' }, { status: 400 })
}
if (error.code === 'P2003') {
return NextResponse.json({ error: '关联数据不存在' }, { status: 400 })
}
}
// 返回更详细的错误信息
const errorMessage = error?.message || '创建上传模板失败'
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
}