# 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 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');"}]}) 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');"}]}) 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 }] }