pipeline-sdlc/wwwroot/api/cockpit_cards.dspy

61 lines
2.9 KiB
Plaintext

# cockpit_cards.dspy — Returns 4 dynamic dashboard cards with popups
uid = await get_user()
org_id = await get_userorgid() or '0'
async with DBPools().sqlorContext(get_module_dbname('pipeline-sdlc')) as sor:
# Counts
projs = await sor.sqlExe("SELECT COUNT(*) as cnt FROM sd_projects WHERE status='active' AND org_id=${oid}$", {"oid": org_id})
iters = await sor.sqlExe("SELECT COUNT(*) as cnt FROM sd_iterations WHERE status='active'", {})
bugs = await sor.sqlExe("SELECT COUNT(*) as cnt FROM sd_bugs WHERE status IN ('open','confirmed')", {})
approvs = await sor.sqlExe("SELECT COUNT(*) as cnt FROM pipeline_task_steps WHERE state='waiting' AND step_type IN ('human_task','approval_gate')", {})
pc = projs[0].cnt if projs else 0
ic = iters[0].cnt if iters else 0
bc = bugs[0].cnt if bugs else 0
ac = approvs[0].cnt if approvs else 0
cards = [
{"title": "活跃项目", "count": pc, "color": "#3b82f6", "icon": "📁",
"popup_url": "/pipeline-sdlc/sd_projects/index.ui", "popup_title": "项目管理"},
{"title": "进行中迭代", "count": ic, "color": "#10b981", "icon": "🔄",
"popup_url": "/pipeline-sdlc/sd_iterations/index.ui", "popup_title": "迭代管理"},
{"title": "待处理Bug", "count": bc, "color": "#ef4444", "icon": "🐛",
"popup_url": "/pipeline-sdlc/sd_bugs/index.ui", "popup_title": "Bug管理"},
{"title": "待审批", "count": ac, "color": "#f59e0b", "icon": "✅",
"popup_url": "/pipeline-sdlc/sd_iterations/index.ui", "popup_title": "待审批任务"},
]
card_widgets = []
for c in cards:
url = c["popup_url"]
title = c["popup_title"]
card_widgets.append({
"widgettype": "VBox",
"options": {
"css": "card",
"width": "25%",
"bgcolor": c["color"] + "08",
"border": f"1px solid {c['color']}33",
"borderRadius": "10px",
"padding": "14px 16px",
"alignItems": "center",
"gap": "6px",
"hover_border": f"1px solid {c['color']}99",
},
"binds": [{
"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": f"var pw=new bricks.PopupWindow({{title:'{title}',cwidth:44,cheight:32,auto_open:true}});bricks.widgetBuild({{widgettype:'urlwidget',options:{{url:'{url}',method:'GET'}}}},pw.content_w).then(function(w){{if(w)pw.content_w.add_widget(w);}});"
}],
"subwidgets": [
{"widgettype": "Text", "options": {"text": c["icon"], "cfontsize": 1.8}},
{"widgettype": "Text", "options": {"text": str(c["count"]), "cfontsize": 1.6, "color": c["color"], "fontWeight": "bold"}},
{"widgettype": "Text", "options": {"text": c["title"], "cfontsize": 0.8, "color": "#475569"}},
]
})
return {
"widgettype": "HBox",
"options": {"width": "100%", "gap": "12px"},
"subwidgets": card_widgets
}