feat: 添加成人内容过滤功能

- 新增用户设置系统支持内容过滤开关
- 扩展类型定义支持成人内容标记
- 实现用户设置API端点(GET/PATCH/PUT)
- 增强搜索API支持内容分组和过滤
- 创建AdultContentFilter UI组件
- 添加用户设置页面和认证检查
- 更新配置示例和README文档
- 实现LocalStorage和Redis存储后端
- 默认启用过滤确保安全性
This commit is contained in:
katelya
2025-09-04 21:11:02 +08:00
parent c9429efba6
commit 86ebbb2cf6
12 changed files with 658 additions and 17 deletions
+128
View File
@@ -0,0 +1,128 @@
import { headers } from 'next/headers';
import { NextRequest, NextResponse } from 'next/server';
import { getStorage } from '@/lib/db';
import { UserSettings } from '@/lib/types';
// 获取用户设置
export async function GET(_request: NextRequest) {
try {
const headersList = headers();
const authorization = headersList.get('Authorization');
if (!authorization) {
return NextResponse.json({ error: '未授权访问' }, { status: 401 });
}
const userName = authorization.split(' ')[1]; // 假设格式为 "Bearer username"
if (!userName) {
return NextResponse.json({ error: '用户名不能为空' }, { status: 400 });
}
const storage = getStorage();
const settings = await storage.getUserSettings(userName);
return NextResponse.json({
settings: settings || {
filter_adult_content: true, // 默认开启成人内容过滤
theme: 'auto',
language: 'zh-CN',
auto_play: true,
video_quality: 'auto'
}
});
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error getting user settings:', error);
return NextResponse.json({ error: '获取用户设置失败' }, { status: 500 });
}
}
// 更新用户设置
export async function PATCH(request: NextRequest) {
try {
const headersList = headers();
const authorization = headersList.get('Authorization');
if (!authorization) {
return NextResponse.json({ error: '未授权访问' }, { status: 401 });
}
const userName = authorization.split(' ')[1];
if (!userName) {
return NextResponse.json({ error: '用户名不能为空' }, { status: 400 });
}
const body = await request.json();
const { settings } = body as { settings: Partial<UserSettings> };
if (!settings) {
return NextResponse.json({ error: '设置数据不能为空' }, { status: 400 });
}
const storage = getStorage();
// 验证用户存在
const userExists = await storage.checkUserExist(userName);
if (!userExists) {
return NextResponse.json({ error: '用户不存在' }, { status: 404 });
}
await storage.updateUserSettings(userName, settings);
return NextResponse.json({
success: true,
message: '设置更新成功'
});
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error updating user settings:', error);
return NextResponse.json({ error: '更新用户设置失败' }, { status: 500 });
}
}
// 重置用户设置
export async function PUT(request: NextRequest) {
try {
const headersList = headers();
const authorization = headersList.get('Authorization');
if (!authorization) {
return NextResponse.json({ error: '未授权访问' }, { status: 401 });
}
const userName = authorization.split(' ')[1];
if (!userName) {
return NextResponse.json({ error: '用户名不能为空' }, { status: 400 });
}
const body = await request.json();
const { settings } = body as { settings: UserSettings };
if (!settings) {
return NextResponse.json({ error: '设置数据不能为空' }, { status: 400 });
}
const storage = getStorage();
// 验证用户存在
const userExists = await storage.checkUserExist(userName);
if (!userExists) {
return NextResponse.json({ error: '用户不存在' }, { status: 404 });
}
await storage.setUserSettings(userName, settings);
return NextResponse.json({
success: true,
message: '设置已重置'
});
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error resetting user settings:', error);
return NextResponse.json({ error: '重置用户设置失败' }, { status: 500 });
}
}