feat(opp): detail popups show source as name button jumping to source url - SOURCE_REGISTRY in opp_common aligned with crawler sites.yaml (source_url preferred, homepage fallback)
This commit is contained in:
parent
d607d8d940
commit
8c032d7be0
@ -23,6 +23,58 @@ logger = logging.getLogger("pipeline.opportunity")
|
||||
# 爬虫平台默认接入点(内网网卡地址,公网不可达);可被 params 表覆盖
|
||||
DEFAULT_API_BASE = "http://192.168.16.2:9085"
|
||||
|
||||
# ── 数据来源登记表(code → 显示名称/来源主页)──
|
||||
# 名称与主页对齐爬虫平台数据源注册表 tender_opp_build/sites.yaml(事实源),
|
||||
# 众包/海外平台补齐。明细弹窗用名称展示、点击直跳来源 url(记录级 source_url
|
||||
# 优先,缺失回退来源主页)。新增采集源时在此登记。
|
||||
SOURCE_REGISTRY = {
|
||||
"ccgp": ("中国政府采购网", "http://www.ccgp.gov.cn/"),
|
||||
"ggzy": ("全国公共资源交易平台", "https://www.ggzy.gov.cn/"),
|
||||
"cebpub": ("中国招标投标公共服务平台", "https://www.cebpubservice.com/"),
|
||||
"zycg": ("中央国家机关政府采购中心", "https://www.zycg.gov.cn/"),
|
||||
"weain": ("军队采购网", "http://www.weain.mil.cn/"),
|
||||
"chinabidding": ("中国招标网", "https://www.chinabidding.com.cn/"),
|
||||
"qianlima": ("千里马招标网", "https://www.qianlima.com/"),
|
||||
"bidcenter": ("中国采购与招标网", "http://www.bidcenter.com.cn/"),
|
||||
"jianyu360": ("剑鱼标讯", "https://www.jianyu360.cn/"),
|
||||
"zbj": ("猪八戒", "https://www.zbj.com/"),
|
||||
"epwk": ("一品威客", "https://www.epwk.com/"),
|
||||
"freelancer": ("Freelancer.com", "https://www.freelancer.com/"),
|
||||
"pph": ("PeoplePerHour", "https://www.peopleperhour.com/"),
|
||||
}
|
||||
|
||||
|
||||
def source_display(code):
|
||||
"""来源 code → (显示名称, 来源主页 url)。未登记来源原样回显 code。"""
|
||||
code = (code or "").strip()
|
||||
if code in SOURCE_REGISTRY:
|
||||
return SOURCE_REGISTRY[code]
|
||||
return (code or "", "")
|
||||
|
||||
|
||||
def source_button_widget(code, source_url=""):
|
||||
"""来源名称按钮:显示来源名称,点击新窗口直跳来源 url。
|
||||
|
||||
跳转目标优先记录级 source_url(采集来源页,最精确),缺失回退来源主页;
|
||||
两者皆无返回 None(不渲染按钮)。code 缺失但有 source_url 时名称显示
|
||||
「采集来源页」。
|
||||
"""
|
||||
code = (code or "").strip()
|
||||
name, home = source_display(code)
|
||||
target = (source_url or "").strip() or home
|
||||
if not target:
|
||||
return None
|
||||
if not name:
|
||||
name = "采集来源页"
|
||||
return {
|
||||
"widgettype": "Button",
|
||||
"options": {"label": name, "css": "small"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "window.open(%s,'_blank','noopener');"
|
||||
% json.dumps(target)}],
|
||||
}
|
||||
|
||||
# ── 报告状态 ──
|
||||
RP_DRAFT = "draft" # 草稿(agent 编写中/待审阅)
|
||||
RP_CONFIRMED = "confirmed" # 人工确认通过(门禁)
|
||||
|
||||
@ -16,6 +16,7 @@ dbname = get_module_dbname('pipeline-opportunity')
|
||||
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
from pipeline_opportunity.opp_data_capability import category_references
|
||||
from pipeline_opportunity.opp_common import source_button_widget
|
||||
ok, res = await category_references(sor, category, days=days, limit=500, record_type="demand")
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
|
||||
@ -40,11 +41,10 @@ else:
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "window.open(" + _json.dumps(url) + ",'_blank','noopener');"}]})
|
||||
if src and src != url:
|
||||
sub_btns.append({"widgettype": "Button", "options": {"label": "来源页", "css": "small"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "window.open(" + _json.dumps(src) + ",'_blank','noopener');"}]})
|
||||
# 来源:显示来源名称,点击直跳来源 url(2026-09-08 用户定夺)
|
||||
_sb = source_button_widget(str(it.get("source") or ""), src)
|
||||
if _sb:
|
||||
sub_btns.append(_sb)
|
||||
budget = it.get("budget_wan") or 0
|
||||
plat = SRC_NAME.get(str(it.get("source") or ""), str(it.get("source") or "众包平台"))
|
||||
meta = "%s | %s | %s" % (
|
||||
@ -82,7 +82,7 @@ return {
|
||||
"padding": "12px 16px", "gap": "0px", "overflow": "auto"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {
|
||||
"text": "每条「需求详情」为众包平台(猪八戒/一品威客)原始需求页,「来源页」为采集来源页,均在新窗口打开,可逐条查证。",
|
||||
"text": "每条「需求详情」为众包平台原始需求页;来源按钮显示平台名称、点击直达该条采集来源页,均在新窗口打开,可逐条查证。",
|
||||
"cfontsize": 0.78, "color": "#64748b", "halign": "left", "margin": "0 0 8px 0"}}
|
||||
] + rows
|
||||
}]
|
||||
|
||||
@ -16,6 +16,7 @@ dbname = get_module_dbname('pipeline-opportunity')
|
||||
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
from pipeline_opportunity.opp_data_capability import overseas_references
|
||||
from pipeline_opportunity.opp_common import source_button_widget
|
||||
ok, res = await overseas_references(sor, category, days=days, limit=500)
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
|
||||
@ -40,6 +41,10 @@ else:
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "window.open(" + _json.dumps(url) + ",'_blank','noopener');"}]})
|
||||
# 来源:显示来源名称,点击直跳来源 url(2026-09-08 用户定夺)
|
||||
_sb = source_button_widget(str(it.get("source") or ""), str(it.get("source_url") or ""))
|
||||
if _sb:
|
||||
sub_btns.append(_sb)
|
||||
budget = it.get("budget_wan") or 0
|
||||
meta = "%s | %s | %s" % (
|
||||
str(it.get("publish_time") or "")[:10],
|
||||
@ -76,7 +81,7 @@ return {
|
||||
"padding": "12px 16px", "gap": "0px", "overflow": "auto"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {
|
||||
"text": "每条「需求详情」为海外众包平台(Freelancer.com / PeoplePerHour)原始需求页,在新窗口打开,可逐条查证。",
|
||||
"text": "每条「需求详情」为海外众包平台原始需求页;来源按钮显示平台名称、点击直达平台主页,在新窗口打开,可逐条查证。",
|
||||
"cfontsize": 0.78, "color": "#64748b", "halign": "left", "margin": "0 0 8px 0"}}
|
||||
] + rows
|
||||
}]
|
||||
|
||||
@ -16,6 +16,7 @@ dbname = get_module_dbname('pipeline-opportunity')
|
||||
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
from pipeline_opportunity.opp_data_capability import category_references
|
||||
from pipeline_opportunity.opp_common import source_button_widget
|
||||
ok, res = await category_references(sor, category, days=days, limit=500)
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
|
||||
@ -38,11 +39,10 @@ else:
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "window.open(" + _json.dumps(url) + ",'_blank','noopener');"}]})
|
||||
if src and src != url:
|
||||
sub_btns.append({"widgettype": "Button", "options": {"label": "来源页", "css": "small"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "script",
|
||||
"target": "self",
|
||||
"script": "window.open(" + _json.dumps(src) + ",'_blank','noopener');"}]})
|
||||
# 来源:显示来源名称,点击直跳来源 url(2026-09-08 用户定夺)
|
||||
_sb = source_button_widget(str(it.get("source") or ""), src)
|
||||
if _sb:
|
||||
sub_btns.append(_sb)
|
||||
budget = it.get("budget_wan") or 0
|
||||
meta = "%s | %s | %s" % (
|
||||
str(it.get("publish_time") or "")[:10],
|
||||
@ -79,7 +79,7 @@ return {
|
||||
"padding": "12px 16px", "gap": "0px", "overflow": "auto"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {
|
||||
"text": "每条「公告原文」为招标公告原链接、「来源页」为采集来源页,均在新窗口打开,可逐条查证。",
|
||||
"text": "每条「公告原文」为招标公告原链接;来源按钮显示数据来源名称、点击直达该条采集来源页,均在新窗口打开,可逐条查证。",
|
||||
"cfontsize": 0.78, "color": "#64748b", "halign": "left", "margin": "0 0 8px 0"}}
|
||||
] + rows
|
||||
}]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user