pansou增加关键词过滤

This commit is contained in:
mtvpls
2026-01-23 14:28:35 +08:00
parent ed23e1da6f
commit a167763324
5 changed files with 85 additions and 6 deletions

View File

@@ -336,6 +336,7 @@ interface SiteConfig {
PansouApiUrl?: string;
PansouUsername?: string;
PansouPassword?: string;
PansouKeywordBlocklist?: string;
EnableComments: boolean;
EnableRegistration?: boolean;
RegistrationRequireTurnstile?: boolean;
@@ -6679,6 +6680,7 @@ const SiteConfigComponent = ({
PansouApiUrl: '',
PansouUsername: '',
PansouPassword: '',
PansouKeywordBlocklist: '',
EnableComments: false,
EnableRegistration: false,
RegistrationRequireTurnstile: false,
@@ -6769,6 +6771,7 @@ const SiteConfigComponent = ({
PansouApiUrl: config.SiteConfig.PansouApiUrl || '',
PansouUsername: config.SiteConfig.PansouUsername || '',
PansouPassword: config.SiteConfig.PansouPassword || '',
PansouKeywordBlocklist: config.SiteConfig.PansouKeywordBlocklist || '',
EnableComments: config.SiteConfig.EnableComments || false,
});
}
@@ -7508,6 +7511,28 @@ const SiteConfigComponent = ({
Token
</p>
</div>
{/* 关键词屏蔽 */}
<div>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
</label>
<input
type='text'
placeholder='多个关键词用中文或英文逗号分隔'
value={siteSettings.PansouKeywordBlocklist}
onChange={(e) =>
setSiteSettings((prev) => ({
...prev,
PansouKeywordBlocklist: e.target.value,
}))
}
className='w-full 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 focus:ring-2 focus:ring-green-500 focus:border-transparent'
/>
<p className='mt-1 text-xs text-gray-500 dark:text-gray-400'>
</p>
</div>
</div>
{/* 评论功能配置 */}

View File

@@ -49,6 +49,7 @@ export async function POST(request: NextRequest) {
PansouApiUrl,
PansouUsername,
PansouPassword,
PansouKeywordBlocklist,
EnableComments,
CustomAdFilterCode,
CustomAdFilterVersion,
@@ -89,6 +90,7 @@ export async function POST(request: NextRequest) {
PansouApiUrl?: string;
PansouUsername?: string;
PansouPassword?: string;
PansouKeywordBlocklist?: string;
EnableComments: boolean;
CustomAdFilterCode?: string;
CustomAdFilterVersion?: number;
@@ -129,6 +131,7 @@ export async function POST(request: NextRequest) {
(TMDBReverseProxy !== undefined && typeof TMDBReverseProxy !== 'string') ||
(BannerDataSource !== undefined && typeof BannerDataSource !== 'string') ||
(RecommendationDataSource !== undefined && typeof RecommendationDataSource !== 'string') ||
(PansouKeywordBlocklist !== undefined && typeof PansouKeywordBlocklist !== 'string') ||
typeof EnableComments !== 'boolean' ||
(CustomAdFilterCode !== undefined && typeof CustomAdFilterCode !== 'string') ||
(CustomAdFilterVersion !== undefined && typeof CustomAdFilterVersion !== 'number') ||
@@ -184,6 +187,7 @@ export async function POST(request: NextRequest) {
PansouApiUrl,
PansouUsername,
PansouPassword,
PansouKeywordBlocklist,
EnableComments,
CustomAdFilterCode,
CustomAdFilterVersion,

View File

@@ -3,7 +3,7 @@
import { NextRequest, NextResponse } from 'next/server';
import { getConfig } from '@/lib/config';
import { searchPansou } from '@/lib/pansou.client';
import { PansouLink, searchPansou } from '@/lib/pansou.client';
export const runtime = 'nodejs';
@@ -44,13 +44,50 @@ export async function POST(request: NextRequest) {
password,
});
const rawBlocklist = config.SiteConfig.PansouKeywordBlocklist || '';
const normalizedBlocklist = rawBlocklist.replace(//g, ',');
const blockedKeywords = normalizedBlocklist
.split(',')
.map((item) => item.trim())
.filter(Boolean);
let filteredResults = results;
if (blockedKeywords.length > 0 && results.merged_by_type) {
const mergedByType: Record<string, PansouLink[]> = {};
let total = 0;
const shouldBlock = (link: PansouLink) => {
const content = `${link.note || ''} ${link.url || ''} ${link.source || ''}`.toLowerCase();
return blockedKeywords.some((item) =>
content.includes(item.toLowerCase())
);
};
Object.entries(results.merged_by_type).forEach(([type, links]) => {
const filteredLinks = links.filter((link) => !shouldBlock(link));
if (filteredLinks.length > 0) {
mergedByType[type] = filteredLinks;
total += filteredLinks.length;
}
});
filteredResults = {
...results,
merged_by_type: mergedByType,
total,
};
}
console.log('Pansou 搜索结果:', {
total: results.total,
hasData: !!results.merged_by_type,
types: results.merged_by_type ? Object.keys(results.merged_by_type) : [],
total: filteredResults.total,
hasData: !!filteredResults.merged_by_type,
types: filteredResults.merged_by_type
? Object.keys(filteredResults.merged_by_type)
: [],
});
return NextResponse.json(results);
return NextResponse.json(filteredResults);
} catch (error: any) {
console.error('Pansou 搜索失败:', error);
return NextResponse.json(

View File

@@ -29,6 +29,7 @@ export interface AdminConfig {
PansouApiUrl?: string;
PansouUsername?: string;
PansouPassword?: string;
PansouKeywordBlocklist?: string;
// 评论功能开关
EnableComments: boolean;
// 自定义去广告代码

View File

@@ -251,6 +251,11 @@ async function getInitConfig(configFile: string, subConfig: {
TMDBApiKey: process.env.TMDB_API_KEY || '',
TMDBProxy: process.env.TMDB_PROXY || '',
TMDBReverseProxy: process.env.TMDB_REVERSE_PROXY || '',
// Pansou配置
PansouApiUrl: '',
PansouUsername: '',
PansouPassword: '',
PansouKeywordBlocklist: '',
// 评论功能开关
EnableComments: false,
},
@@ -446,6 +451,10 @@ export function configSelfCheck(adminConfig: AdminConfig): AdminConfig {
FluidSearch: true,
DanmakuApiBase: 'http://localhost:9321',
DanmakuApiToken: '87654321',
PansouApiUrl: '',
PansouUsername: '',
PansouPassword: '',
PansouKeywordBlocklist: '',
EnableComments: false,
};
}
@@ -460,6 +469,9 @@ export function configSelfCheck(adminConfig: AdminConfig): AdminConfig {
if (adminConfig.SiteConfig.EnableComments === undefined) {
adminConfig.SiteConfig.EnableComments = false;
}
if (adminConfig.SiteConfig.PansouKeywordBlocklist === undefined) {
adminConfig.SiteConfig.PansouKeywordBlocklist = '';
}
if (!adminConfig.UserConfig) {
adminConfig.UserConfig = { Users: [] };
}
@@ -665,4 +677,4 @@ export async function setCachedConfig(config: AdminConfig) {
export async function clearConfigCache() {
cachedConfig = null as any;
configInitPromise = null;
}
}