diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 97bdff2..5b76950 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -7676,6 +7676,9 @@ const AIConfigComponent = ({ const [enableVideoCardEntry, setEnableVideoCardEntry] = useState(true); const [enablePlayPageEntry, setEnablePlayPageEntry] = useState(true); + // 权限控制 + const [allowRegularUsers, setAllowRegularUsers] = useState(true); + // 高级设置 const [temperature, setTemperature] = useState(0.7); const [maxTokens, setMaxTokens] = useState(1000); @@ -7697,6 +7700,7 @@ const AIConfigComponent = ({ setEnableHomepageEntry(config.AIConfig.EnableHomepageEntry !== false); setEnableVideoCardEntry(config.AIConfig.EnableVideoCardEntry !== false); setEnablePlayPageEntry(config.AIConfig.EnablePlayPageEntry !== false); + setAllowRegularUsers(config.AIConfig.AllowRegularUsers !== false); setTemperature(config.AIConfig.Temperature ?? 0.7); setMaxTokens(config.AIConfig.MaxTokens ?? 1000); setSystemPrompt(config.AIConfig.SystemPrompt || ''); @@ -7726,6 +7730,7 @@ const AIConfigComponent = ({ EnableHomepageEntry: enableHomepageEntry, EnableVideoCardEntry: enableVideoCardEntry, EnablePlayPageEntry: enablePlayPageEntry, + AllowRegularUsers: allowRegularUsers, Temperature: temperature, MaxTokens: maxTokens, SystemPrompt: systemPrompt, @@ -8014,6 +8019,33 @@ const AIConfigComponent = ({ ))} + {/* 权限控制 */} +
+

+ 权限控制 +

+ +
+
+
+ 允许普通用户使用 +
+
+ 关闭后仅站长和管理员可使用AI问片功能 +
+
+ +
+
+ {/* 高级设置 */}
diff --git a/src/app/api/admin/ai/route.ts b/src/app/api/admin/ai/route.ts index 19cf836..5ab6383 100644 --- a/src/app/api/admin/ai/route.ts +++ b/src/app/api/admin/ai/route.ts @@ -57,6 +57,7 @@ export async function POST(request: NextRequest) { EnableHomepageEntry, EnableVideoCardEntry, EnablePlayPageEntry, + AllowRegularUsers, Temperature, MaxTokens, SystemPrompt, @@ -89,6 +90,7 @@ export async function POST(request: NextRequest) { EnableHomepageEntry: boolean; EnableVideoCardEntry: boolean; EnablePlayPageEntry: boolean; + AllowRegularUsers: boolean; Temperature?: number; MaxTokens?: number; SystemPrompt?: string; @@ -124,6 +126,7 @@ export async function POST(request: NextRequest) { typeof EnableHomepageEntry !== 'boolean' || typeof EnableVideoCardEntry !== 'boolean' || typeof EnablePlayPageEntry !== 'boolean' || + typeof AllowRegularUsers !== 'boolean' || (Temperature !== undefined && typeof Temperature !== 'number') || (MaxTokens !== undefined && typeof MaxTokens !== 'number') || (SystemPrompt !== undefined && typeof SystemPrompt !== 'string') @@ -171,6 +174,7 @@ export async function POST(request: NextRequest) { EnableHomepageEntry, EnableVideoCardEntry, EnablePlayPageEntry, + AllowRegularUsers, Temperature, MaxTokens, SystemPrompt, diff --git a/src/app/api/ai/chat/route.ts b/src/app/api/ai/chat/route.ts index c5dd804..3007818 100644 --- a/src/app/api/ai/chat/route.ts +++ b/src/app/api/ai/chat/route.ts @@ -8,6 +8,7 @@ import { VideoContext, } from '@/lib/ai-orchestrator'; import { getConfig } from '@/lib/config'; +import { db } from '@/lib/db'; export const runtime = 'nodejs'; @@ -72,9 +73,6 @@ async function streamClaudeChat( maxTokens: number; } ): Promise { - // Claude API格式: 移除system消息,单独传递 - const userMessages = messages.filter((m) => m.role !== 'system'); - const response = await fetch('https://api.anthropic.com/v1/messages', { method: 'POST', headers: { @@ -87,7 +85,7 @@ async function streamClaudeChat( max_tokens: config.maxTokens, temperature: config.temperature, system: systemPrompt, - messages: userMessages, + messages: messages, stream: true, }), }); @@ -187,7 +185,23 @@ export async function POST(request: NextRequest) { ); } - // 3. 解析请求参数 + // 3. 权限检查:如果不允许普通用户使用,检查用户角色 + if (!aiConfig.AllowRegularUsers) { + const username = authInfo.username; + // 站长始终有权限 + if (username !== process.env.USERNAME) { + // 检查是否为管理员 + const userInfo = await db.getUserInfoV2(username); + if (!userInfo || (userInfo.role !== 'admin' && userInfo.role !== 'owner') || userInfo.banned) { + return NextResponse.json( + { error: '该功能仅限站长和管理员使用' }, + { status: 403 } + ); + } + } + } + + // 4. 解析请求参数 const body = (await request.json()) as ChatRequest; const { message, context, history = [] } = body; @@ -214,11 +228,11 @@ export async function POST(request: NextRequest) { tavilyApiKey: aiConfig.TavilyApiKey, serperApiKey: aiConfig.SerperApiKey, serpApiKey: aiConfig.SerpApiKey, - // 决策模型配置(固定使用自定义provider) + // 决策模型配置(固定使用自定义provider,复用主模型的API配置) enableDecisionModel: aiConfig.EnableDecisionModel, decisionProvider: 'custom', - decisionApiKey: aiConfig.DecisionCustomApiKey, - decisionBaseURL: aiConfig.DecisionCustomBaseURL, + decisionApiKey: aiConfig.CustomApiKey, + decisionBaseURL: aiConfig.CustomBaseURL, decisionModel: aiConfig.DecisionCustomModel, } ); diff --git a/src/app/api/openlist/correct/route.ts b/src/app/api/openlist/correct/route.ts index 9852de4..1520c7b 100644 --- a/src/app/api/openlist/correct/route.ts +++ b/src/app/api/openlist/correct/route.ts @@ -114,7 +114,6 @@ export async function POST(request: NextRequest) { metaInfo.folders[key] = { folderName: folderName, tmdb_id: tmdbId || null, - douban_id: doubanId || null, title: title, poster_path: posterPath, release_date: releaseDate || '', diff --git a/src/app/api/openlist/list/route.ts b/src/app/api/openlist/list/route.ts index 847c80a..ad1297e 100644 --- a/src/app/api/openlist/list/route.ts +++ b/src/app/api/openlist/list/route.ts @@ -130,7 +130,6 @@ export async function GET(request: NextRequest) { id: key, folder: info.folderName, tmdbId: info.tmdb_id, - doubanId: info.douban_id, title: info.title, poster: getTMDBImageUrl(info.poster_path), releaseDate: info.release_date, diff --git a/src/app/play/page.tsx b/src/app/play/page.tsx index 69a7a79..0d5f7f5 100644 --- a/src/app/play/page.tsx +++ b/src/app/play/page.tsx @@ -5641,8 +5641,6 @@ function PlayPageClient() { title: detail.title, year: detail.year, douban_id: videoDoubanId !== 0 ? videoDoubanId : undefined, - tmdb_id: detail.tmdb_id, - type: detail.type === 'movie' ? 'movie' : 'tv', currentEpisode: currentEpisodeIndex + 1, }} welcomeMessage={`想了解《${detail.title}》的更多信息吗?我可以帮你查询剧情、演员、评价等。`} diff --git a/src/lib/admin.types.ts b/src/lib/admin.types.ts index 9c939e3..d2c855d 100644 --- a/src/lib/admin.types.ts +++ b/src/lib/admin.types.ts @@ -147,6 +147,8 @@ export interface AdminConfig { EnableHomepageEntry: boolean; // 首页入口开关 EnableVideoCardEntry: boolean; // VideoCard入口开关 EnablePlayPageEntry: boolean; // 播放页入口开关 + // 权限控制 + AllowRegularUsers: boolean; // 是否允许普通用户使用AI问片(关闭后仅站长和管理员可用) // 高级设置 Temperature?: number; // AI温度参数(0-2),默认0.7 MaxTokens?: number; // 最大回复token数,默认1000