增加可视化视频源权重设置
This commit is contained in:
@@ -9,7 +9,18 @@ import { db } from '@/lib/db';
|
||||
export const runtime = 'nodejs';
|
||||
|
||||
// 支持的操作类型
|
||||
type Action = 'add' | 'disable' | 'enable' | 'delete' | 'sort' | 'batch_disable' | 'batch_enable' | 'batch_delete' | 'toggle_proxy_mode' | 'update_weight';
|
||||
type Action =
|
||||
| 'add'
|
||||
| 'disable'
|
||||
| 'enable'
|
||||
| 'delete'
|
||||
| 'sort'
|
||||
| 'batch_disable'
|
||||
| 'batch_enable'
|
||||
| 'batch_delete'
|
||||
| 'toggle_proxy_mode'
|
||||
| 'update_weight'
|
||||
| 'batch_update_weights';
|
||||
|
||||
interface BaseBody {
|
||||
action?: Action;
|
||||
@@ -37,7 +48,19 @@ export async function POST(request: NextRequest) {
|
||||
const username = authInfo.username;
|
||||
|
||||
// 基础校验
|
||||
const ACTIONS: Action[] = ['add', 'disable', 'enable', 'delete', 'sort', 'batch_disable', 'batch_enable', 'batch_delete', 'toggle_proxy_mode', 'update_weight'];
|
||||
const ACTIONS: Action[] = [
|
||||
'add',
|
||||
'disable',
|
||||
'enable',
|
||||
'delete',
|
||||
'sort',
|
||||
'batch_disable',
|
||||
'batch_enable',
|
||||
'batch_delete',
|
||||
'toggle_proxy_mode',
|
||||
'update_weight',
|
||||
'batch_update_weights',
|
||||
];
|
||||
if (!username || !action || !ACTIONS.includes(action)) {
|
||||
return NextResponse.json({ error: '参数格式错误' }, { status: 400 });
|
||||
}
|
||||
@@ -127,17 +150,17 @@ export async function POST(request: NextRequest) {
|
||||
// 检查并清理用户组和用户的权限数组
|
||||
// 清理用户组权限
|
||||
if (adminConfig.UserConfig.Tags) {
|
||||
adminConfig.UserConfig.Tags.forEach(tag => {
|
||||
adminConfig.UserConfig.Tags.forEach((tag) => {
|
||||
if (tag.enabledApis) {
|
||||
tag.enabledApis = tag.enabledApis.filter(api => api !== key);
|
||||
tag.enabledApis = tag.enabledApis.filter((api) => api !== key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 清理用户权限
|
||||
adminConfig.UserConfig.Users.forEach(user => {
|
||||
adminConfig.UserConfig.Users.forEach((user) => {
|
||||
if (user.enabledApis) {
|
||||
user.enabledApis = user.enabledApis.filter(api => api !== key);
|
||||
user.enabledApis = user.enabledApis.filter((api) => api !== key);
|
||||
}
|
||||
});
|
||||
break;
|
||||
@@ -145,9 +168,12 @@ export async function POST(request: NextRequest) {
|
||||
case 'batch_disable': {
|
||||
const { keys } = body as { keys?: string[] };
|
||||
if (!Array.isArray(keys) || keys.length === 0) {
|
||||
return NextResponse.json({ error: '缺少 keys 参数或为空' }, { status: 400 });
|
||||
return NextResponse.json(
|
||||
{ error: '缺少 keys 参数或为空' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
keys.forEach(key => {
|
||||
keys.forEach((key) => {
|
||||
const entry = adminConfig.SourceConfig.find((s) => s.key === key);
|
||||
if (entry) {
|
||||
entry.disabled = true;
|
||||
@@ -158,9 +184,12 @@ export async function POST(request: NextRequest) {
|
||||
case 'batch_enable': {
|
||||
const { keys } = body as { keys?: string[] };
|
||||
if (!Array.isArray(keys) || keys.length === 0) {
|
||||
return NextResponse.json({ error: '缺少 keys 参数或为空' }, { status: 400 });
|
||||
return NextResponse.json(
|
||||
{ error: '缺少 keys 参数或为空' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
keys.forEach(key => {
|
||||
keys.forEach((key) => {
|
||||
const entry = adminConfig.SourceConfig.find((s) => s.key === key);
|
||||
if (entry) {
|
||||
entry.disabled = false;
|
||||
@@ -171,13 +200,16 @@ export async function POST(request: NextRequest) {
|
||||
case 'batch_delete': {
|
||||
const { keys } = body as { keys?: string[] };
|
||||
if (!Array.isArray(keys) || keys.length === 0) {
|
||||
return NextResponse.json({ error: '缺少 keys 参数或为空' }, { status: 400 });
|
||||
return NextResponse.json(
|
||||
{ error: '缺少 keys 参数或为空' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
// 过滤掉 from=config 的源,记录跳过的数量
|
||||
const keysToDelete: string[] = [];
|
||||
const skippedKeys: string[] = [];
|
||||
|
||||
keys.forEach(key => {
|
||||
keys.forEach((key) => {
|
||||
const entry = adminConfig.SourceConfig.find((s) => s.key === key);
|
||||
if (entry && entry.from === 'config') {
|
||||
skippedKeys.push(key);
|
||||
@@ -187,7 +219,7 @@ export async function POST(request: NextRequest) {
|
||||
});
|
||||
|
||||
// 批量删除
|
||||
keysToDelete.forEach(key => {
|
||||
keysToDelete.forEach((key) => {
|
||||
const idx = adminConfig.SourceConfig.findIndex((s) => s.key === key);
|
||||
if (idx !== -1) {
|
||||
adminConfig.SourceConfig.splice(idx, 1);
|
||||
@@ -198,17 +230,21 @@ export async function POST(request: NextRequest) {
|
||||
if (keysToDelete.length > 0) {
|
||||
// 清理用户组权限
|
||||
if (adminConfig.UserConfig.Tags) {
|
||||
adminConfig.UserConfig.Tags.forEach(tag => {
|
||||
adminConfig.UserConfig.Tags.forEach((tag) => {
|
||||
if (tag.enabledApis) {
|
||||
tag.enabledApis = tag.enabledApis.filter(api => !keysToDelete.includes(api));
|
||||
tag.enabledApis = tag.enabledApis.filter(
|
||||
(api) => !keysToDelete.includes(api)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 清理用户权限
|
||||
adminConfig.UserConfig.Users.forEach(user => {
|
||||
adminConfig.UserConfig.Users.forEach((user) => {
|
||||
if (user.enabledApis) {
|
||||
user.enabledApis = user.enabledApis.filter(api => !keysToDelete.includes(api));
|
||||
user.enabledApis = user.enabledApis.filter(
|
||||
(api) => !keysToDelete.includes(api)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -254,14 +290,80 @@ export async function POST(request: NextRequest) {
|
||||
entry.proxyMode = !entry.proxyMode;
|
||||
break;
|
||||
}
|
||||
case 'batch_update_weights': {
|
||||
const { weights, order } = body as {
|
||||
weights?: Array<{ key?: string; weight?: number }>;
|
||||
order?: string[];
|
||||
};
|
||||
if (!Array.isArray(weights) || weights.length === 0) {
|
||||
return NextResponse.json(
|
||||
{ error: '缺少 weights 参数或为空' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
for (const item of weights) {
|
||||
if (!item?.key) {
|
||||
return NextResponse.json(
|
||||
{ error: 'weights 中存在无效 key' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
if (
|
||||
typeof item.weight !== 'number' ||
|
||||
item.weight < 0 ||
|
||||
item.weight > 100
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: '权重必须是 0-100 之间的数字' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
const entry = adminConfig.SourceConfig.find(
|
||||
(source) => source.key === item.key
|
||||
);
|
||||
if (!entry) {
|
||||
return NextResponse.json(
|
||||
{ error: `源不存在: ${item.key}` },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
entry.weight = item.weight;
|
||||
}
|
||||
|
||||
if (Array.isArray(order)) {
|
||||
const map = new Map(
|
||||
adminConfig.SourceConfig.map((source) => [source.key, source])
|
||||
);
|
||||
const newList: typeof adminConfig.SourceConfig = [];
|
||||
order.forEach((key) => {
|
||||
const item = map.get(key);
|
||||
if (item) {
|
||||
newList.push(item);
|
||||
map.delete(key);
|
||||
}
|
||||
});
|
||||
adminConfig.SourceConfig.forEach((item) => {
|
||||
if (map.has(item.key)) newList.push(item);
|
||||
});
|
||||
adminConfig.SourceConfig = newList;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'update_weight': {
|
||||
const { key, weight } = body as { key?: string; weight?: number };
|
||||
if (!key)
|
||||
return NextResponse.json({ error: '缺少 key 参数' }, { status: 400 });
|
||||
if (weight === undefined || weight === null)
|
||||
return NextResponse.json({ error: '缺少 weight 参数' }, { status: 400 });
|
||||
return NextResponse.json(
|
||||
{ error: '缺少 weight 参数' },
|
||||
{ status: 400 }
|
||||
);
|
||||
if (typeof weight !== 'number' || weight < 0 || weight > 100)
|
||||
return NextResponse.json({ error: '权重必须是 0-100 之间的数字' }, { status: 400 });
|
||||
return NextResponse.json(
|
||||
{ error: '权重必须是 0-100 之间的数字' },
|
||||
{ status: 400 }
|
||||
);
|
||||
const entry = adminConfig.SourceConfig.find((s) => s.key === key);
|
||||
if (!entry)
|
||||
return NextResponse.json({ error: '源不存在' }, { status: 404 });
|
||||
@@ -293,14 +395,11 @@ export async function POST(request: NextRequest) {
|
||||
responseData.skipped = (body as any)._batchDeleteResult.skipped;
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
responseData,
|
||||
{
|
||||
headers: {
|
||||
'Cache-Control': 'no-store',
|
||||
},
|
||||
}
|
||||
);
|
||||
return NextResponse.json(responseData, {
|
||||
headers: {
|
||||
'Cache-Control': 'no-store',
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('视频源管理操作失败:', error);
|
||||
return NextResponse.json(
|
||||
|
||||
Reference in New Issue
Block a user