增加视频特殊源配置功能

This commit is contained in:
mtvpls
2026-06-09 15:25:22 +08:00
parent 3f9206e754
commit 65d89be93a
18 changed files with 454 additions and 26 deletions
+44
View File
@@ -19,6 +19,8 @@ type Action =
| 'batch_enable'
| 'batch_delete'
| 'toggle_proxy_mode'
| 'toggle_special_source'
| 'set_special_sources'
| 'update_weight'
| 'batch_update_weights';
@@ -58,6 +60,8 @@ export async function POST(request: NextRequest) {
'batch_enable',
'batch_delete',
'toggle_proxy_mode',
'toggle_special_source',
'set_special_sources',
'update_weight',
'batch_update_weights',
];
@@ -146,6 +150,9 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ error: '该源不可删除' }, { status: 400 });
}
adminConfig.SourceConfig.splice(idx, 1);
adminConfig.SpecialSourceApis = (adminConfig.SpecialSourceApis || []).filter(
(api) => api !== key
);
// 检查并清理用户组和用户的权限数组
// 清理用户组权限
@@ -226,6 +233,10 @@ export async function POST(request: NextRequest) {
}
});
adminConfig.SpecialSourceApis = (adminConfig.SpecialSourceApis || []).filter(
(api) => !keysToDelete.includes(api)
);
// 检查并清理用户组和用户的权限数组
if (keysToDelete.length > 0) {
// 清理用户组权限
@@ -290,6 +301,39 @@ export async function POST(request: NextRequest) {
entry.proxyMode = !entry.proxyMode;
break;
}
case 'toggle_special_source': {
const { key } = body as { key?: string };
if (!key)
return NextResponse.json({ error: '缺少 key 参数' }, { status: 400 });
const entry = adminConfig.SourceConfig.find((s) => s.key === key);
if (!entry)
return NextResponse.json({ error: '源不存在' }, { status: 404 });
const specialApis = new Set(adminConfig.SpecialSourceApis || []);
if (specialApis.has(key)) {
specialApis.delete(key);
} else {
specialApis.add(key);
}
adminConfig.SpecialSourceApis = Array.from(specialApis).filter((api) =>
adminConfig.SourceConfig.some((source) => source.key === api)
);
break;
}
case 'set_special_sources': {
const { keys } = body as { keys?: string[] };
if (!Array.isArray(keys)) {
return NextResponse.json({ error: 'keys 参数格式错误' }, { status: 400 });
}
const sourceKeySet = new Set(adminConfig.SourceConfig.map((source) => source.key));
adminConfig.SpecialSourceApis = Array.from(new Set(keys)).filter((key) =>
sourceKeySet.has(key)
);
break;
}
case 'batch_update_weights': {
const { weights, order } = body as {
weights?: Array<{ key?: string; weight?: number }>;
+2 -1
View File
@@ -21,6 +21,7 @@ export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const id = searchParams.get('id');
const sourceCode = searchParams.get('source');
const includeSpecialSources = searchParams.get('special') === '1';
if (!id || !sourceCode) {
return NextResponse.json({ error: '缺少必要参数' }, { status: 400 });
@@ -233,7 +234,7 @@ export async function GET(request: NextRequest) {
}
try {
const apiSites = await getAvailableApiSites(authInfo.username);
const apiSites = await getAvailableApiSites(authInfo.username, includeSpecialSources);
const apiSite = apiSites.find((site) => site.key === sourceCode);
if (!apiSite) {
+2 -1
View File
@@ -25,6 +25,7 @@ export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const query = searchParams.get('q');
const includeSpecialSources = searchParams.get('special') === '1';
if (!query) {
const cacheTime = await getCacheTime();
@@ -42,7 +43,7 @@ export async function GET(request: NextRequest) {
}
const config = await getConfig();
const apiSites = await getAvailableApiSites(authInfo.username);
const apiSites = await getAvailableApiSites(authInfo.username, includeSpecialSources);
const [canAccessOpenList, canAccessEmby] = await Promise.all([
hasFeaturePermission(authInfo.username, 'private_library'),
hasFeaturePermission(authInfo.username, 'emby'),
+2 -1
View File
@@ -25,6 +25,7 @@ export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const query = searchParams.get('q');
const includeSpecialSources = searchParams.get('special') === '1';
if (!query) {
return new Response(
@@ -39,7 +40,7 @@ export async function GET(request: NextRequest) {
}
const config = await getConfig();
const apiSites = await getAvailableApiSites(authInfo.username);
const apiSites = await getAvailableApiSites(authInfo.username, includeSpecialSources);
const [canAccessOpenList, canAccessEmby] = await Promise.all([
hasFeaturePermission(authInfo.username, 'private_library'),
hasFeaturePermission(authInfo.username, 'emby'),
+2 -1
View File
@@ -111,6 +111,7 @@ export async function GET(request: NextRequest) {
const sourceCode = normalizeNetdiskSource(searchParams.get('source'));
const fileName = searchParams.get('fileName'); // 小雅源:用户点击的文件名
const title = searchParams.get('title');
const includeSpecialSources = searchParams.get('special') === '1';
if (!id || !sourceCode) {
return NextResponse.json({ error: '缺少必要参数' }, { status: 400 });
@@ -1201,7 +1202,7 @@ export async function GET(request: NextRequest) {
// 对于其他采集源,直接按 id 获取详情。
try {
const apiSites = await getAvailableApiSites(authInfo.username);
const apiSites = await getAvailableApiSites(authInfo.username, includeSpecialSources);
const apiSite = apiSites.find((site) => site.key === sourceCode);
if (!apiSite) {
@@ -24,6 +24,7 @@ export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const sourceKey = searchParams.get('source');
const includeSpecialSources = searchParams.get('special') === '1';
if (!sourceKey) {
return NextResponse.json(
@@ -34,7 +35,7 @@ export async function GET(request: NextRequest) {
try {
const config = await getConfig();
const apiSites = await getAvailableApiSites(authInfo.username);
const apiSites = await getAvailableApiSites(authInfo.username, includeSpecialSources);
const targetSite = apiSites.find((site) => site.key === sourceKey);
if (!targetSite) {
+2 -1
View File
@@ -52,7 +52,8 @@ export async function GET(request: NextRequest) {
}
try {
const apiSites = await getAvailableApiSites(authInfo.username);
const includeSpecialSources = request.nextUrl.searchParams.get('special') === '1';
const apiSites = await getAvailableApiSites(authInfo.username, includeSpecialSources);
const targetSite = apiSites.find((site) => site.key === sourceKey);
if (!targetSite) {
+2 -1
View File
@@ -12,7 +12,8 @@ export async function GET(request: NextRequest) {
}
try {
const apiSites = await getAvailableApiSites(authInfo.username);
const includeSpecialSources = request.nextUrl.searchParams.get('special') === '1';
const apiSites = await getAvailableApiSites(authInfo.username, includeSpecialSources);
return NextResponse.json({
sources: apiSites.map((site) => ({
+2 -1
View File
@@ -52,7 +52,8 @@ export async function GET(request: NextRequest) {
}
try {
const apiSites = await getAvailableApiSites(authInfo.username);
const includeSpecialSources = request.nextUrl.searchParams.get('special') === '1';
const apiSites = await getAvailableApiSites(authInfo.username, includeSpecialSources);
const targetSite = apiSites.find((site) => site.key === sourceKey);
if (!targetSite) {