diff --git a/apps/api/src/crawler/crawler.service.ts b/apps/api/src/crawler/crawler.service.ts index 67ff925..8b35bf0 100644 --- a/apps/api/src/crawler/crawler.service.ts +++ b/apps/api/src/crawler/crawler.service.ts @@ -5,6 +5,7 @@ import { execSync } from 'child_process' import * as path from 'path' import * as fs from 'fs' import { PrismaService } from '../prisma/prisma.service' +import { inferCategory } from '../lead/lead.service' const SCRIPTS_DIR = path.resolve(__dirname, '../../../../../scripts') const TENDER_FETCHER_DIR = path.join(SCRIPTS_DIR, 'tender-fetcher') @@ -130,6 +131,7 @@ export class CrawlerService implements OnModuleInit { deadline: r.deadline, detailUrl: r.detailUrl, publishTime: r.publishTime || null, + category: inferCategory(r.title), ...(r.amount ? { amount: r.amount } : {}), ...(r.region ? { region: r.region } : {}), ...(r.regionDetail ? { regionDetail: r.regionDetail } : {}), @@ -146,7 +148,7 @@ export class CrawlerService implements OnModuleInit { amount: r.amount || '待确认', status: '待复核', level: 'C', - category: '', + category: inferCategory(r.title), region: r.region || '', regionDetail: r.regionDetail || '', summary: `来源: ${r.source}\n公告ID: ${r.noticeId}\n链接: ${r.detailUrl}`, diff --git a/apps/api/src/lead/lead.service.ts b/apps/api/src/lead/lead.service.ts index 938eae4..2b91f40 100644 --- a/apps/api/src/lead/lead.service.ts +++ b/apps/api/src/lead/lead.service.ts @@ -2,8 +2,8 @@ import { Injectable, NotFoundException, Logger, ServiceUnavailableException } fr import { PrismaService } from '../prisma/prisma.service' import { IntegrationService } from '../integration/integration.service' -// 品类 → 标题关键词映射(筛选时按标题模糊匹配,不走 category 字段) -const CATEGORY_KEYWORDS: Record = { +// 品类 → 标题关键词映射(筛选 + 入库均使用) +export const CATEGORY_KEYWORDS: Record = { '防火门': ['防火门', '防火卷帘', '防火窗', '钢质防火', '木质防火'], '配电箱': ['配电箱', '配电柜', '配电盘', '照明配电箱', '动力配电箱', '电表箱'], '电线电缆': ['电线', '电缆', '导线', '电力线', '控制电缆', '光缆', '架空线'], @@ -21,6 +21,17 @@ const CATEGORY_KEYWORDS: Record = { '电机': ['电机', '电动机', '减速机', '减速器', '变频电机'], } +/** 根据标题推断品类,未匹配返回空字符串 */ +export function inferCategory(title: string): string { + if (!title) return '' + for (const [cat, keywords] of Object.entries(CATEGORY_KEYWORDS)) { + for (const kw of keywords) { + if (title.includes(kw)) return cat + } + } + return '' +} + @Injectable() export class LeadService { private readonly logger = new Logger(LeadService.name) diff --git a/apps/web/src/lib/apiBase.ts b/apps/web/src/lib/apiBase.ts index 5a1d4f2..d8d5055 100644 --- a/apps/web/src/lib/apiBase.ts +++ b/apps/web/src/lib/apiBase.ts @@ -1 +1 @@ -export const API_BASE: string = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000' +export const API_BASE: string = process.env.NEXT_PUBLIC_API_URL ?? 'http://localhost:4000'