109 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""商机产线数据能力:从数据爬取平台拉取招标数据(只读)。
所有函数签名统一 (sor, **params),返回 (ok, payload|错误信息)。
薄封装:查询条件透传给爬虫平台,本层不做二次加工(热点排序由爬虫平台算)。
"""
from .opp_common import crawler_get
async def search_tenders(sor, keyword="", days=7, source="", only_it=True, limit=50):
"""关键词检索招标信息。"""
params = {"days": days, "limit": limit}
if keyword:
params["keyword"] = keyword
if source:
params["source"] = source
params["only_it"] = "1" if only_it else "0"
return await crawler_get(sor, "/api/tenders", params)
async def tender_detail(sor, tender_id):
"""单条招标详情(含公告全文、来源 url)。"""
return await crawler_get(sor, "/api/tenders/%s" % tender_id)
async def daily_ai_tenders(sor, target_date=""):
"""每日 AI/Agent 软件类招标展示数据。"""
params = {}
if target_date:
params["date"] = target_date
return await crawler_get(sor, "/api/ai_tenders", params)
async def hot_software(sor, days=30, top=10):
"""热点软件主题排名(数量+预算+热点地区+样例)。"""
return await crawler_get(sor, "/api/hot_software",
{"days": days, "top": top})
async def category_references(sor, category, days=30, limit=500, record_type="tender"):
"""某软件主题的全部分项(references 可查证)。
每条带公告原文/详情页 url + 采集来源 source_url,供界面逐条查证。
record_type: tender=招标(默认) / demand=众包需求发布(猪八戒/一品威客)。
"""
return await crawler_get(sor, "/api/category_references",
{"category": category, "days": days, "limit": limit,
"record_type": record_type})
async def crawler_stats(sor):
"""爬虫平台采集健康度。"""
return await crawler_get(sor, "/api/stats")
async def demands(sor, keyword="", days=30, source="", limit=50):
"""众包平台软件需求发布列表(国内:猪八戒/一品威客;海外:Freelancer/PeoplePerHour)。
区别于招标:这些是甲方在众包平台直接发布的开发需求,
反映市场真实需求热度与预算分布。每条带详情页 url(可查证)。
"""
params = {"days": days, "limit": limit}
if keyword:
params["keyword"] = keyword
if source:
params["source"] = source
return await crawler_get(sor, "/api/demands", params)
async def hot_demands(sor, days=30, top=10):
"""众包需求热点主题排名(需求侧热度)。"""
return await crawler_get(sor, "/api/hot_demands",
{"days": days, "top": top})
async def hot_overseas(sor, days=30, top=10):
"""海外众包软件需求热点主题排名(Freelancer/PeoplePerHour,英文主题)。"""
return await crawler_get(sor, "/api/hot_overseas",
{"days": days, "top": top})
async def overseas_references(sor, category, days=30, limit=500):
"""某海外需求主题的全部分项(references 可查证)。
每条带海外平台详情页 url,供界面逐条查证。
"""
return await crawler_get(sor, "/api/overseas_references",
{"category": category, "days": days, "limit": limit})
async def query_tenders(sor, keyword="", region="", buyer="", notice_type="",
source="", min_budget="", max_budget="", min_ai="",
days=90, group_by="", limit=50, only_it=True):
"""条件检索 + 汇总(用户口述条件 → LLM 映射为参数)。
过滤:keyword(标题多词AND)/region/buyer 模糊,notice_type/source 精确,
min_budget/max_budget(万元)区间,min_ai 评分下限,days 回溯窗口,only_it。
汇总:group_by=region|notice_type|category|source|month → 分组统计+样例。
"""
params: dict = {"days": days, "limit": limit}
for k, v in (("keyword", keyword), ("region", region), ("buyer", buyer),
("notice_type", notice_type), ("source", source),
("min_budget", min_budget), ("max_budget", max_budget),
("min_ai", min_ai), ("group_by", group_by)):
if v not in (None, ""):
params[k] = v
params["only_it"] = "1" if only_it else "0"
return await crawler_get(sor, "/api/tenders_query", params)