pipeline-opportunity/wwwroot/api/opp_demand_items.dspy

90 lines
3.7 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_demand_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, record_type="demand")
await sor.sqlExe("COMMIT", {})
SRC_NAME = {"zbj": "猪八戒", "epwk": "一品威客"}
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
plat = SRC_NAME.get(str(it.get("source") or ""), str(it.get("source") or "众包平台"))
meta = "%s | %s | %s" % (
str(it.get("publish_time") or "")[:10],
plat,
(("预算 %.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_demand_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
}]
}