fix: 滚动条主题适配 + 套餐 API 输入校验补全
- 滚动条默认浅色,data-theme="dark" 下切换深色 - admin layout / PayPageLayout 根 div 加 data-theme 属性 - 套餐 POST/PUT: name 类型、空值、长度(100)校验 + trim - 套餐 PUT: 补全 sort_order 非负整数校验
This commit is contained in:
@@ -35,7 +35,7 @@ function AdminLayoutInner({ children }: { children: React.ReactNode }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={['min-h-screen', isDark ? 'bg-slate-950' : 'bg-slate-100'].join(' ')}>
|
||||
<div data-theme={theme} className={['min-h-screen', isDark ? 'bg-slate-950' : 'bg-slate-100'].join(' ')}>
|
||||
<div className="px-2 pt-2 sm:px-3 sm:pt-3">
|
||||
<nav
|
||||
className={[
|
||||
|
||||
@@ -61,10 +61,19 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
|
||||
if (body.validity_days !== undefined && (!Number.isInteger(body.validity_days) || body.validity_days <= 0)) {
|
||||
return NextResponse.json({ error: 'validity_days 必须是正整数' }, { status: 400 });
|
||||
}
|
||||
if (body.name !== undefined && (typeof body.name !== 'string' || body.name.trim() === '')) {
|
||||
return NextResponse.json({ error: 'name 不能为空' }, { status: 400 });
|
||||
}
|
||||
if (body.name !== undefined && body.name.length > 100) {
|
||||
return NextResponse.json({ error: 'name 不能超过 100 个字符' }, { status: 400 });
|
||||
}
|
||||
if (body.sort_order !== undefined && (!Number.isInteger(body.sort_order) || body.sort_order < 0)) {
|
||||
return NextResponse.json({ error: 'sort_order 必须是非负整数' }, { status: 400 });
|
||||
}
|
||||
|
||||
const data: Record<string, unknown> = {};
|
||||
if (body.group_id !== undefined) data.groupId = Number(body.group_id);
|
||||
if (body.name !== undefined) data.name = body.name;
|
||||
if (body.name !== undefined) data.name = body.name.trim();
|
||||
if (body.description !== undefined) data.description = body.description;
|
||||
if (body.price !== undefined) data.price = body.price;
|
||||
if (body.original_price !== undefined) data.originalPrice = body.original_price;
|
||||
|
||||
@@ -93,8 +93,14 @@ export async function POST(request: NextRequest) {
|
||||
product_name,
|
||||
} = body;
|
||||
|
||||
if (!group_id || !name || price === undefined) {
|
||||
return NextResponse.json({ error: '缺少必填字段: group_id, name, price' }, { status: 400 });
|
||||
if (!group_id || price === undefined) {
|
||||
return NextResponse.json({ error: '缺少必填字段: group_id, price' }, { status: 400 });
|
||||
}
|
||||
if (typeof name !== 'string' || name.trim() === '') {
|
||||
return NextResponse.json({ error: 'name 不能为空' }, { status: 400 });
|
||||
}
|
||||
if (name.length > 100) {
|
||||
return NextResponse.json({ error: 'name 不能超过 100 个字符' }, { status: 400 });
|
||||
}
|
||||
|
||||
if (typeof price !== 'number' || price <= 0 || price > 99999999.99) {
|
||||
@@ -126,7 +132,7 @@ export async function POST(request: NextRequest) {
|
||||
const plan = await prisma.subscriptionPlan.create({
|
||||
data: {
|
||||
groupId: Number(group_id),
|
||||
name,
|
||||
name: name.trim(),
|
||||
description: description ?? null,
|
||||
price,
|
||||
originalPrice: original_price ?? null,
|
||||
|
||||
@@ -17,10 +17,10 @@ body {
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
/* Scrollbar - Dark theme */
|
||||
/* Scrollbar - Light theme (default) */
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #475569 #1e293b;
|
||||
scrollbar-color: #cbd5e1 #f1f5f9;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
@@ -29,18 +29,40 @@ body {
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: #1e293b;
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background: #475569;
|
||||
background: #cbd5e1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb:hover {
|
||||
background: #64748b;
|
||||
background: #94a3b8;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-corner {
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
/* Scrollbar - Dark theme */
|
||||
[data-theme='dark'],
|
||||
[data-theme='dark'] * {
|
||||
scrollbar-color: #475569 #1e293b;
|
||||
}
|
||||
|
||||
[data-theme='dark'] *::-webkit-scrollbar-track {
|
||||
background: #1e293b;
|
||||
}
|
||||
|
||||
[data-theme='dark'] *::-webkit-scrollbar-thumb {
|
||||
background: #475569;
|
||||
}
|
||||
|
||||
[data-theme='dark'] *::-webkit-scrollbar-thumb:hover {
|
||||
background: #64748b;
|
||||
}
|
||||
|
||||
[data-theme='dark'] *::-webkit-scrollbar-corner {
|
||||
background: #1e293b;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ export default function PayPageLayout({
|
||||
|
||||
return (
|
||||
<div
|
||||
data-theme={isDark ? 'dark' : 'light'}
|
||||
className={[
|
||||
'relative w-full overflow-hidden',
|
||||
isEmbedded ? 'min-h-screen p-2' : 'min-h-screen p-3 sm:p-4',
|
||||
|
||||
Reference in New Issue
Block a user