feat(knowledge): Phase D 统一搜索 + 种子知识冷启动
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- search/recommend API 返回 UnifiedSearchResult (文档+结构化双通道) - POST /api/v1/knowledge/seed 种子知识冷启动 (幂等, admin权限) - seed_knowledge service: 按标题+行业查重, source=distillation - SearchRequest 扩展: search_structured/search_documents/industry_id
This commit is contained in:
@@ -374,21 +374,17 @@ pub async fn rollback_version(
|
||||
|
||||
// === 检索 ===
|
||||
|
||||
/// POST /api/v1/knowledge/search — 语义搜索
|
||||
/// POST /api/v1/knowledge/search — 统一搜索(双通道:文档 + 结构化)
|
||||
pub async fn search(
|
||||
State(state): State<AppState>,
|
||||
Extension(ctx): Extension<AuthContext>,
|
||||
Json(req): Json<SearchRequest>,
|
||||
) -> SaasResult<Json<Vec<SearchResult>>> {
|
||||
) -> SaasResult<Json<UnifiedSearchResult>> {
|
||||
check_permission(&ctx, "knowledge:search")?;
|
||||
let limit = req.limit.unwrap_or(5).min(10);
|
||||
let min_score = req.min_score.unwrap_or(0.5);
|
||||
let results = service::search(
|
||||
let results = service::unified_search(
|
||||
&state.db,
|
||||
&req.query,
|
||||
req.category_id.as_deref(),
|
||||
limit,
|
||||
min_score,
|
||||
&req,
|
||||
Some(&ctx.account_id),
|
||||
).await?;
|
||||
Ok(Json(results))
|
||||
}
|
||||
@@ -398,15 +394,15 @@ pub async fn recommend(
|
||||
State(state): State<AppState>,
|
||||
Extension(ctx): Extension<AuthContext>,
|
||||
Json(req): Json<SearchRequest>,
|
||||
) -> SaasResult<Json<Vec<SearchResult>>> {
|
||||
) -> SaasResult<Json<UnifiedSearchResult>> {
|
||||
check_permission(&ctx, "knowledge:search")?;
|
||||
let limit = req.limit.unwrap_or(5).min(10);
|
||||
let results = service::search(
|
||||
let mut req = req;
|
||||
req.min_score = Some(0.3);
|
||||
req.search_structured = req.search_structured.or(Some(true));
|
||||
let results = service::unified_search(
|
||||
&state.db,
|
||||
&req.query,
|
||||
req.category_id.as_deref(),
|
||||
limit,
|
||||
0.3,
|
||||
&req,
|
||||
Some(&ctx.account_id),
|
||||
).await?;
|
||||
Ok(Json(results))
|
||||
}
|
||||
@@ -885,3 +881,34 @@ async fn handle_structured_upload(
|
||||
_ => Err(SaasError::InvalidInput("意外的处理结果".into())),
|
||||
}
|
||||
}
|
||||
|
||||
// === 种子知识冷启动 ===
|
||||
|
||||
/// POST /api/v1/knowledge/seed — 触发种子知识冷启动
|
||||
///
|
||||
/// 需要 admin 权限,幂等(按标题+行业查重)
|
||||
pub async fn seed_knowledge(
|
||||
State(state): State<AppState>,
|
||||
Extension(ctx): Extension<AuthContext>,
|
||||
Json(req): Json<SeedKnowledgeRequest>,
|
||||
) -> SaasResult<Json<serde_json::Value>> {
|
||||
check_permission(&ctx, "knowledge:admin")?;
|
||||
|
||||
if req.items.len() > 100 {
|
||||
return Err(SaasError::InvalidInput("单次种子不能超过 100 条".into()));
|
||||
}
|
||||
|
||||
let created = service::seed_knowledge(
|
||||
&state.db,
|
||||
&req.industry_id,
|
||||
req.category_id.as_deref().unwrap_or("seed"),
|
||||
&req.items.iter().map(|i| (i.title.clone(), i.content.clone(), i.keywords.clone().unwrap_or_default())).collect::<Vec<_>>(),
|
||||
&ctx.account_id,
|
||||
).await?;
|
||||
|
||||
Ok(Json(serde_json::json!({
|
||||
"industry_id": req.industry_id,
|
||||
"created_count": created,
|
||||
"total_submitted": req.items.len(),
|
||||
})))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user