From 5c80ad394855724cfe330b513a493c7d0075acc9 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Sat, 1 Aug 2026 10:43:43 +0800 Subject: [PATCH] feat: model config popup button in cockpit, my_bugs API, task_tree_popup --- wwwroot/api/my_bugs.dspy | 51 +++++++++++++++++++++++++++++++++++++ wwwroot/sd_cockpit/index.ui | 4 +-- wwwroot/task_tree_popup.ui | 39 ++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 wwwroot/api/my_bugs.dspy create mode 100644 wwwroot/task_tree_popup.ui diff --git a/wwwroot/api/my_bugs.dspy b/wwwroot/api/my_bugs.dspy new file mode 100644 index 0000000..a00a11c --- /dev/null +++ b/wwwroot/api/my_bugs.dspy @@ -0,0 +1,51 @@ +user_id = await get_user() +if not user_id: + return json.dumps([], ensure_ascii=False) + +try: + async with get_sor_context(request._run_ns, "pipeline") as sor: + sql = """ + SELECT b.id, b.title, b.severity, b.priority, b.status, + b.reporter_type, b.step_name, b.created_at, + i.iteration_name + FROM sd_bugs b + LEFT JOIN sd_iterations i ON b.iteration_id = i.id + WHERE b.reporter_id = ${uid}$ OR b.assignee_id = ${uid}$ + ORDER BY + CASE b.status + WHEN 'open' THEN 1 + WHEN 'confirmed' THEN 2 + WHEN 'in_progress' THEN 3 + WHEN 'resolved' THEN 4 + WHEN 'closed' THEN 5 + ELSE 6 + END, + b.created_at DESC + LIMIT 100 + """ + recs = await sor.sqlExe(sql, {"uid": user_id}) + rows = [] + status_labels = { + "open": "待处理", "confirmed": "已确认", + "in_progress": "处理中", "resolved": "已解决", "closed": "已关闭", + } + severity_labels = { + "critical": "致命", "major": "严重", + "minor": "一般", "trivial": "轻微", + } + for r in recs: + rows.append({ + "id": r.id, + "title": r.title or "", + "severity": severity_labels.get(r.severity, r.severity or ""), + "priority": r.priority or "", + "status": status_labels.get(r.status, r.status or ""), + "status_raw": r.status or "", + "reporter_type": "agent" if r.reporter_type == "agent" else "human", + "step_name": r.step_name or "", + "iteration_name": r.iteration_name or "", + "created_at": str(r.created_at)[:16] if r.created_at else "", + }) + return json.dumps(rows, ensure_ascii=False) +except Exception as e: + return json.dumps([], ensure_ascii=False) diff --git a/wwwroot/sd_cockpit/index.ui b/wwwroot/sd_cockpit/index.ui index e59517f..b219b9a 100644 --- a/wwwroot/sd_cockpit/index.ui +++ b/wwwroot/sd_cockpit/index.ui @@ -21,10 +21,10 @@ { "widgettype": "Filler" }, { "widgettype": "Button", - "options": { "name": "refresh", "label": "\u5237\u65b0", "css": "small" }, + "options": { "name": "model_config", "label": "\u6a21\u578b\u914d\u7f6e", "css": "small" }, "binds": [{ "wid": "self", "event": "click", "actiontype": "script", "target": "self", - "script": "location.reload();" + "script": "var pw=new bricks.PopupWindow({title:'\u6a21\u578b\u914d\u7f6e',auto_open:true});bricks.widgetBuild({widgettype:'urlwidget',options:{url:'/pipeline_core/llm/index.ui',method:'GET'}},pw.content_w).then(function(w){if(w)pw.content_w.add_widget(w);});" }] } ] diff --git a/wwwroot/task_tree_popup.ui b/wwwroot/task_tree_popup.ui new file mode 100644 index 0000000..19a9327 --- /dev/null +++ b/wwwroot/task_tree_popup.ui @@ -0,0 +1,39 @@ +{% set task_id = params_kw.get('task_id', '') %} +{% set task_title = params_kw.get('title', '') or 'Task' %} +{ + "widgettype": "VBox", + "options": {"width": "100%", "padding": "8px"}, + "subwidgets": [ + { + "widgettype": "HBox", + "options": {"width": "100%", "marginBottom": "8px", "alignItems": "center", "gap": "8px"}, + "subwidgets": [ + {"widgettype": "Text", "options": {"text": "📋 {{task_title}}", "cfontsize": 15}}, + {"widgettype": "Filler"}, + { + "widgettype": "Button", + "options": {"label": "查看完整详情", "css": "text"}, + "binds": [{ + "wid": "self", "event": "click", "actiontype": "urlwidget", + "target": "app.main_content", + "mode": "replace", + "options": {"url": "{{entire_url('/pipeline_task/task_detail.ui')}}?task_id={{task_id}}"} + }] + } + ] + }, + { + "widgettype": "Tree", + "id": "step_tree", + "options": { + "title": "步骤树", + "parentField": "parent_step", + "idField": "id", + "textField": "label", + "dataurl": "{{entire_url('/pipeline_task/api/task_tree.dspy')}}?task_id={{task_id}}", + "css": "card" + } + }, + {"widgettype": "Filler"} + ] +}