pipeline-opportunity/wwwroot/api/opp_references_items.dspy

87 lines
3.5 KiB
Plaintext
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.

# opp_references_items.dspy - 某软件主题的分项列表(references 可查证)
# 入参:category=<主题名>。每条分项:标题+时间+预算+地区 + 「公告原文」「来源页」按钮(新窗口)
import json as _json
uid = await get_user()
if not uid:
return {"widgettype": "Message", "options": {"title": "未登录", "message": "请先登录"}}
category = ((params_kw or {}).get("category") or "").strip()
days = int((params_kw or {}).get("days") or 30)
if not category:
return {"widgettype": "Message", "options": {"title": "缺少参数", "message": "缺少 category"}}
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", {})
rows = []
if not ok:
rows.append({"widgettype": "Text", "options": {
"text": "查询失败:" + str(res)[:200],
"color": "#dc2626", "padding": "12px", "halign": "left"}})
else:
items = res.get("items") or []
if not items:
rows.append({"widgettype": "Text", "options": {
"text": "该主题近 %d 天无分项" % days, "color": "#64748b", "padding": "12px", "halign": "left"}})
for it in items:
url = str(it.get("url") or "")
src = str(it.get("source_url") or "")
sub_btns = []
if url:
sub_btns.append({"widgettype": "Button", "options": {"label": "公告原文", "css": "small"},
"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 ""), 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],
str(it.get("region") or "—"),
(("预算 %.0f 万" % budget) if budget else "预算未公开"))
rows.append({
"widgettype": "VBox",
"options": {"width": "100%", "padding": "8px 12px", "gap": "4px",
"border": "1px solid #e2e8f0", "borderRadius": "8px",
"margin": "0 0 6px 0", "bgcolor": "#ffffff"},
"subwidgets": [
{"widgettype": "Text", "options": {
"text": str(it.get("title") or ""), "cfontsize": 0.95,
"color": "#0f172a", "halign": "left", "wrap": True}},
{"widgettype": "HBox", "options": {"width": "100%", "gap": "10px",
"alignItems": "center"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": meta,
"cfontsize": 0.75, "color": "#94a3b8", "halign": "left"}},
{"widgettype": "Filler"}
] + sub_btns}
]
})
total = res.get("count", len(rows)) if ok else 0
return {
"widgettype": "PopupWindow",
"id": "opp_refs_items_pw",
"options": {"title": "分项明细:%s(%d 条)" % (category, total),
"width": "80%", "height": "82%", "auto_open": True, "resizable": True},
"subwidgets": [{
"widgettype": "VBox",
"options": {"css": "filler", "width": "100%", "height": "100%",
"padding": "12px 16px", "gap": "0px", "overflow": "auto"},
"subwidgets": [
{"widgettype": "Text", "options": {
"text": "每条「公告原文」为招标公告原链接;来源按钮显示数据来源名称、点击直达该条采集来源页,均在新窗口打开,可逐条查证。",
"cfontsize": 0.78, "color": "#64748b", "halign": "left", "margin": "0 0 8px 0"}}
] + rows
}]
}