feat: 添加 is_adult 字段以支持成人内容标记,更新相关逻辑处理
This commit is contained in:
+28
-3
@@ -70,6 +70,7 @@ interface DataSource {
|
|||||||
detail?: string;
|
detail?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
from: 'config' | 'custom';
|
from: 'config' | 'custom';
|
||||||
|
is_adult?: boolean; // 添加成人内容标记字段
|
||||||
}
|
}
|
||||||
|
|
||||||
// 可折叠标签组件
|
// 可折叠标签组件
|
||||||
@@ -643,6 +644,7 @@ const VideoSourceConfig = ({
|
|||||||
detail: '',
|
detail: '',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
from: 'config',
|
from: 'config',
|
||||||
|
is_adult: false, // 默认不是成人内容
|
||||||
});
|
});
|
||||||
|
|
||||||
// dnd-kit 传感器
|
// dnd-kit 传感器
|
||||||
@@ -721,6 +723,7 @@ const VideoSourceConfig = ({
|
|||||||
name: newSource.name,
|
name: newSource.name,
|
||||||
api: newSource.api,
|
api: newSource.api,
|
||||||
detail: newSource.detail,
|
detail: newSource.detail,
|
||||||
|
is_adult: newSource.is_adult, // 传递成人内容标记
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setNewSource({
|
setNewSource({
|
||||||
@@ -730,6 +733,7 @@ const VideoSourceConfig = ({
|
|||||||
detail: '',
|
detail: '',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
from: 'custom',
|
from: 'custom',
|
||||||
|
is_adult: false, // 重置为默认值
|
||||||
});
|
});
|
||||||
setShowAddForm(false);
|
setShowAddForm(false);
|
||||||
})
|
})
|
||||||
@@ -866,7 +870,8 @@ const VideoSourceConfig = ({
|
|||||||
exportConfig.api_site[source.key] = {
|
exportConfig.api_site[source.key] = {
|
||||||
api: source.api,
|
api: source.api,
|
||||||
name: source.name,
|
name: source.name,
|
||||||
...(source.detail && { detail: source.detail })
|
...(source.detail && { detail: source.detail }),
|
||||||
|
...(source.is_adult !== undefined && { is_adult: source.is_adult }) // 确保导出 is_adult 字段
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -939,7 +944,7 @@ const VideoSourceConfig = ({
|
|||||||
throw new Error(`${key}: 无效的配置对象`);
|
throw new Error(`${key}: 无效的配置对象`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sourceObj = source as { api?: string; name?: string; detail?: string };
|
const sourceObj = source as { api?: string; name?: string; detail?: string; is_adult?: boolean };
|
||||||
|
|
||||||
if (!sourceObj.api || !sourceObj.name) {
|
if (!sourceObj.api || !sourceObj.name) {
|
||||||
throw new Error(`${key}: 缺少必要字段 api 或 name`);
|
throw new Error(`${key}: 缺少必要字段 api 或 name`);
|
||||||
@@ -950,7 +955,8 @@ const VideoSourceConfig = ({
|
|||||||
key: key,
|
key: key,
|
||||||
name: sourceObj.name,
|
name: sourceObj.name,
|
||||||
api: sourceObj.api,
|
api: sourceObj.api,
|
||||||
detail: sourceObj.detail || ''
|
detail: sourceObj.detail || '',
|
||||||
|
is_adult: sourceObj.is_adult || false // 确保处理 is_adult 字段
|
||||||
});
|
});
|
||||||
successCount++;
|
successCount++;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1246,6 +1252,25 @@ const VideoSourceConfig = ({
|
|||||||
}
|
}
|
||||||
className='px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100'
|
className='px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* 成人内容标记复选框 */}
|
||||||
|
<div className='flex items-center space-x-2'>
|
||||||
|
<input
|
||||||
|
type='checkbox'
|
||||||
|
id='is_adult'
|
||||||
|
checked={newSource.is_adult || false}
|
||||||
|
onChange={(e) =>
|
||||||
|
setNewSource((prev) => ({ ...prev, is_adult: e.target.checked }))
|
||||||
|
}
|
||||||
|
className='w-4 h-4 text-red-600 bg-gray-100 border-gray-300 rounded focus:ring-red-500 dark:bg-gray-700 dark:border-gray-600'
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
htmlFor='is_adult'
|
||||||
|
className='text-sm font-medium text-gray-900 dark:text-gray-300'
|
||||||
|
>
|
||||||
|
🔞 成人内容资源站
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex justify-end'>
|
<div className='flex justify-end'>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -59,11 +59,12 @@ export async function POST(request: NextRequest) {
|
|||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'add': {
|
case 'add': {
|
||||||
const { key, name, api, detail } = body as {
|
const { key, name, api, detail, is_adult } = body as {
|
||||||
key?: string;
|
key?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
api?: string;
|
api?: string;
|
||||||
detail?: string;
|
detail?: string;
|
||||||
|
is_adult?: boolean;
|
||||||
};
|
};
|
||||||
if (!key || !name || !api) {
|
if (!key || !name || !api) {
|
||||||
return NextResponse.json({ error: '缺少必要参数' }, { status: 400 });
|
return NextResponse.json({ error: '缺少必要参数' }, { status: 400 });
|
||||||
@@ -78,6 +79,7 @@ export async function POST(request: NextRequest) {
|
|||||||
detail,
|
detail,
|
||||||
from: 'custom',
|
from: 'custom',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
is_adult: is_adult || false, // 确保处理 is_adult 字段
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-2
@@ -262,6 +262,7 @@ export async function getConfig(): Promise<AdminConfig> {
|
|||||||
detail: site.detail,
|
detail: site.detail,
|
||||||
from: 'config',
|
from: 'config',
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
is_adult: (site as any).is_adult || false, // 确保处理 is_adult 字段
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -271,6 +272,12 @@ export async function getConfig(): Promise<AdminConfig> {
|
|||||||
adminConfig.SourceConfig.forEach((source) => {
|
adminConfig.SourceConfig.forEach((source) => {
|
||||||
if (!apiSiteKeys.has(source.key)) {
|
if (!apiSiteKeys.has(source.key)) {
|
||||||
source.from = 'custom';
|
source.from = 'custom';
|
||||||
|
} else {
|
||||||
|
// 更新现有源的 is_adult 字段
|
||||||
|
const siteConfig = fileConfig.api_site[source.key];
|
||||||
|
if (siteConfig) {
|
||||||
|
source.is_adult = (siteConfig as any).is_adult || false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -388,7 +395,20 @@ export async function getCacheTime(): Promise<number> {
|
|||||||
|
|
||||||
export async function getAvailableApiSites(filterAdult = false): Promise<ApiSite[]> {
|
export async function getAvailableApiSites(filterAdult = false): Promise<ApiSite[]> {
|
||||||
const config = await getConfig();
|
const config = await getConfig();
|
||||||
let sites = config.SourceConfig.filter((s) => !s.disabled);
|
|
||||||
|
// 防御性检查:确保 SourceConfig 存在且为数组
|
||||||
|
if (!config.SourceConfig || !Array.isArray(config.SourceConfig)) {
|
||||||
|
console.warn('SourceConfig is missing or not an array, returning empty array');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防御性处理:为每个源确保 is_adult 字段存在
|
||||||
|
let sites = config.SourceConfig
|
||||||
|
.filter((s) => !s.disabled)
|
||||||
|
.map((s) => ({
|
||||||
|
...s,
|
||||||
|
is_adult: s.is_adult === true // 严格检查,只有明确为 true 的才是成人内容
|
||||||
|
}));
|
||||||
|
|
||||||
// 如果需要过滤成人内容,则排除标记为成人内容的资源站
|
// 如果需要过滤成人内容,则排除标记为成人内容的资源站
|
||||||
if (filterAdult) {
|
if (filterAdult) {
|
||||||
@@ -406,8 +426,16 @@ export async function getAvailableApiSites(filterAdult = false): Promise<ApiSite
|
|||||||
// 获取成人内容资源站
|
// 获取成人内容资源站
|
||||||
export async function getAdultApiSites(): Promise<ApiSite[]> {
|
export async function getAdultApiSites(): Promise<ApiSite[]> {
|
||||||
const config = await getConfig();
|
const config = await getConfig();
|
||||||
|
|
||||||
|
// 防御性检查:确保 SourceConfig 存在且为数组
|
||||||
|
if (!config.SourceConfig || !Array.isArray(config.SourceConfig)) {
|
||||||
|
console.warn('SourceConfig is missing or not an array, returning empty array');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防御性处理:严格检查成人内容标记
|
||||||
const adultSites = config.SourceConfig
|
const adultSites = config.SourceConfig
|
||||||
.filter((s) => !s.disabled && s.is_adult);
|
.filter((s) => !s.disabled && s.is_adult === true); // 只有明确为 true 的才被认为是成人内容
|
||||||
|
|
||||||
return adultSites.map((s) => ({
|
return adultSites.map((s) => ({
|
||||||
key: s.key,
|
key: s.key,
|
||||||
|
|||||||
Reference in New Issue
Block a user