213 lines
5.8 KiB
Python
213 lines
5.8 KiB
Python
from typing import Any, Dict, List
|
||
|
||
from fastapi import APIRouter, Depends, Query
|
||
from pydantic import BaseModel, Field
|
||
|
||
from app.controllers.keyword import KeywordController
|
||
from app.core.dependency import DependPermission
|
||
from app.schemas.keyword import (
|
||
CrawlCompleteRequest,
|
||
KeywordCreate,
|
||
KeywordUpdate,
|
||
PageProgressRequest,
|
||
)
|
||
|
||
router = APIRouter(tags=["关键词接口"])
|
||
|
||
|
||
class MarkUsedRequest(BaseModel):
|
||
source: str = Field(pattern="^(boss|qcwy|zhilian)$")
|
||
ids: List[int]
|
||
|
||
|
||
class StatsQuery(BaseModel):
|
||
source: str = Field(pattern="^(boss|qcwy|zhilian)$")
|
||
date: str | None = None
|
||
|
||
|
||
async def get_keyword_controller() -> KeywordController:
|
||
"""获取关键词控制器实例
|
||
|
||
返回:
|
||
关键词控制器实例
|
||
"""
|
||
return KeywordController()
|
||
|
||
|
||
@router.get("/available", summary="获取当天未使用的检索条件")
|
||
async def get_available(
|
||
source: str,
|
||
limit: int = 1,
|
||
reserve: bool = True,
|
||
crawler_id: str = "",
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""根据平台获取当天未使用的检索条件
|
||
|
||
优先级: partial(断点续爬) > failed(重试) > 全新关键词
|
||
"""
|
||
return await controller.get_available(source, limit, reserve, crawler_id)
|
||
|
||
|
||
@router.post("/mark-used", summary="将检索条件标记为今日已使用")
|
||
async def mark_used(
|
||
request: MarkUsedRequest,
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""将指定检索条件标记为今日已使用
|
||
|
||
参数:
|
||
request: 包含平台标识与记录ID列表的请求体
|
||
|
||
返回:
|
||
更新结果,包含成功条数与日期
|
||
"""
|
||
return await controller.mark_used(request.source, request.ids)
|
||
|
||
|
||
@router.get("/stats", summary="统计使用与未使用数量")
|
||
async def get_stats(
|
||
source: str,
|
||
date: str | None = None,
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""统计指定平台在某日期的使用与未使用数量
|
||
|
||
参数:
|
||
source: 平台标识,boss|qcwy|zhilian
|
||
date: 统计日期,格式 YYYY-MM-DD;不传则为今天
|
||
|
||
返回:
|
||
标准字典结构,包含 total/used/unused
|
||
"""
|
||
from datetime import date as _date
|
||
d = None
|
||
if date:
|
||
try:
|
||
y, m, d0 = map(int, date.split("-"))
|
||
d = _date(y, m, d0)
|
||
except Exception:
|
||
d = None
|
||
return await controller.get_stats(source, d)
|
||
|
||
|
||
@router.get("/overview", summary="获取所有平台统计概览", dependencies=[DependPermission])
|
||
async def get_overview(
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""获取所有平台统计概览
|
||
|
||
返回:
|
||
各平台统计数据
|
||
"""
|
||
return await controller.get_overview_stats()
|
||
|
||
|
||
@router.get("/list", summary="获取关键词列表", dependencies=[DependPermission])
|
||
async def list_keywords(
|
||
source: str = Query(..., pattern="^(boss|qcwy|zhilian)$"),
|
||
page: int = 1,
|
||
page_size: int = 20,
|
||
city: str | None = None,
|
||
job: str | None = None,
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""获取关键词列表
|
||
|
||
参数:
|
||
source: 平台标识
|
||
page: 页码
|
||
page_size: 每页数量
|
||
city: 城市过滤
|
||
job: 职位过滤
|
||
|
||
返回:
|
||
列表数据
|
||
"""
|
||
return await controller.list_keywords(source, page, page_size, city, job)
|
||
|
||
|
||
@router.post("/create", summary="创建关键词", dependencies=[DependPermission])
|
||
async def create_keyword(
|
||
item: KeywordCreate,
|
||
source: str = Query(..., pattern="^(boss|qcwy|zhilian)$"),
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""创建关键词
|
||
|
||
参数:
|
||
item: 关键词数据
|
||
source: 平台标识
|
||
|
||
返回:
|
||
创建结果
|
||
"""
|
||
return await controller.create_keyword(source, item)
|
||
|
||
|
||
@router.put("/update", summary="更新关键词", dependencies=[DependPermission])
|
||
async def update_keyword(
|
||
id: int,
|
||
item: KeywordUpdate,
|
||
source: str = Query(..., pattern="^(boss|qcwy|zhilian)$"),
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""更新关键词
|
||
|
||
参数:
|
||
id: 记录ID
|
||
item: 更新数据
|
||
source: 平台标识
|
||
|
||
返回:
|
||
更新结果
|
||
"""
|
||
return await controller.update_keyword(source, id, item)
|
||
|
||
|
||
@router.delete("/delete", summary="删除关键词", dependencies=[DependPermission])
|
||
async def delete_keyword(
|
||
id: int,
|
||
source: str = Query(..., pattern="^(boss|qcwy|zhilian)$"),
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""删除关键词
|
||
|
||
参数:
|
||
id: 记录ID
|
||
source: 平台标识
|
||
|
||
返回:
|
||
删除结果
|
||
"""
|
||
return await controller.delete_keyword(source, id)
|
||
|
||
|
||
@router.post("/page-progress", summary="爬虫汇报单页爬取进度")
|
||
async def report_page_progress(
|
||
request: PageProgressRequest,
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""爬虫每完成一页后调用此接口汇报进度"""
|
||
return await controller.report_page_progress(
|
||
request.source,
|
||
request.keyword_id,
|
||
request.page,
|
||
request.total_pages,
|
||
request.jobs_found,
|
||
)
|
||
|
||
|
||
@router.post("/crawl-complete", summary="爬虫汇报爬取完成或失败")
|
||
async def report_crawl_complete(
|
||
request: CrawlCompleteRequest,
|
||
controller: KeywordController = Depends(get_keyword_controller),
|
||
) -> Dict[str, Any]:
|
||
"""爬虫完成或失败后调用此接口更新状态"""
|
||
return await controller.report_crawl_complete(
|
||
request.source,
|
||
request.keyword_id,
|
||
request.status,
|
||
request.error_message,
|
||
)
|