From 6a10e807949572f4292fc2cc08e31d7260b08d07 Mon Sep 17 00:00:00 2001 From: ymq Date: Fri, 11 Sep 2026 18:29:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(sdlc):=20=E5=BD=93=E5=89=8D=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E8=BF=87=E6=BB=A4=E4=BC=9A=E8=AF=9D=E7=BA=A7=E5=8C=96?= =?UTF-8?q?=E2=80=94=E2=80=94task=5Ftree=E6=94=B9get=5Fsession=5Fproject?= =?UTF-8?q?=5Fid(session=E4=BC=98=E5=85=88=E2=86=92=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=85=9C=E5=BA=95+=E4=BA=A7=E7=BA=BF=E9=9A=94=E7=A6=BB),?= =?UTF-8?q?=E5=88=A0=E5=8F=AA=E8=AF=BB=E5=85=A8=E5=B1=80=E7=9A=84=E6=97=A7?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0;workspace=5Fpopup=E6=97=A0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E5=8D=87=E7=BA=A7'=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=88=96=E6=96=B0=E5=BB=BA'=E5=B8=A6=E7=9B=B4=E8=BE=BE?= =?UTF-8?q?=E6=8C=89=E9=92=AE(=E6=96=B0=E5=BB=BA=E9=A1=B9=E7=9B=AE/?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E9=A1=B9=E7=9B=AE,=E8=B0=83agent=5Fproject?= =?UTF-8?q?=5Fpopup);=E6=A0=B9=E8=8A=82=E7=82=B9=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E6=96=87=E6=A1=88=E7=BB=9F=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wwwroot/api/task_tree.dspy | 21 +++++++++++++++------ wwwroot/api/workspace_popup.dspy | 32 +++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/wwwroot/api/task_tree.dspy b/wwwroot/api/task_tree.dspy index 9caa3e8..0fc64d3 100644 --- a/wwwroot/api/task_tree.dspy +++ b/wwwroot/api/task_tree.dspy @@ -64,15 +64,24 @@ def _iter_of(task): async with DBPools().sqlorContext(dbname) as sor: - # 当前项目 - recs = await sor.sqlExe( - "SELECT current_project_id FROM pipeline_agent_settings WHERE user_id=${u}$", - {"u": uid}) - pid = getattr(recs[0], 'current_project_id', '') if recs else '' + # 当前项目(2026-09-11 升级:会话级解析——session 优先→全局兜底, + # 含悬空自愈+产线隔离;旧实现只读全局 pipeline_agent_settings,多 tab 串项目) + _sid = (params_kw or {}).get('session_id', '') or '' + pid = '' + try: + from pipeline_service.workspace import get_session_project_id + pid = await get_session_project_id(sor, uid, _sid, 'sdlc_general') or '' + except Exception: + pid = '' + if not pid: + recs = await sor.sqlExe( + "SELECT current_project_id FROM pipeline_agent_settings WHERE user_id=${u}$", + {"u": uid}) + pid = getattr(recs[0], 'current_project_id', '') if recs else '' if not pid: if not node_id: - return json.dumps([{"id": "__root__", "label": "请先选择项目", "is_leaf": True}], ensure_ascii=False) + return json.dumps([{"id": "__root__", "label": "请先选择或新建项目", "is_leaf": True}], ensure_ascii=False) return json.dumps([], ensure_ascii=False) # 项目名 diff --git a/wwwroot/api/workspace_popup.dspy b/wwwroot/api/workspace_popup.dspy index 39220fc..232c9e1 100644 --- a/wwwroot/api/workspace_popup.dspy +++ b/wwwroot/api/workspace_popup.dspy @@ -36,12 +36,38 @@ async with DBPools().sqlorContext(dbname) as sor: pname = os.path.basename(project_dir) if project_dir else '' if not project_dir: + # 2026-09-11 用户要求:没当前项目 → 提示选择或新建项目(给直达按钮,不给死胡同) + _proj_base = entire_url("/pipeline_core/api/agent_project_popup.dspy") + _proj_q = [] + if session_id: + _proj_q.append("session_id=" + session_id) + if pipeline_id: + _proj_q.append("pipeline_id=" + pipeline_id) + + def _pbtn(label, css, op): + _js = ("var r=await fetch(" + _json.dumps(_proj_base + "?op=" + op + + (("&" + "&".join(_proj_q)) if _proj_q else "")) + ");" + "var d=await r.json();if(d){bricks.widgetBuild(d,bricks.app);}") + return {"widgettype": "Button", "options": {"label": label, "css": css}, + "binds": [{"wid": "self", "event": "click", "actiontype": "script", + "target": "self", "script": _js}]} + resp = { "widgettype": "PopupWindow", - "options": {"title": "提示", "cwidth": 30, "cheight": 8, "auto_open": True}, + "id": "ws_no_project_pw", + "options": {"title": "提示", "cwidth": 38, "cheight": 10, "auto_open": True}, "subwidgets": [{ - "widgettype": "Text", - "options": {"text": "请先在会话中切换项目", "cfontsize": 1, "color": "#64748b", "padding": "20px"} + "widgettype": "VBox", + "options": {"width": "100%", "gap": "12px", "padding": "18px 22px"}, + "subwidgets": [ + {"widgettype": "Text", + "options": {"text": "当前会话还没有项目,请先选择或新建项目", + "cfontsize": 1, "color": "#64748b"}}, + {"widgettype": "HBox", + "options": {"width": "100%", "gap": "10px"}, + "subwidgets": [_pbtn("✨ 新建项目", "primary", "new"), + _pbtn("🔀 切换项目", "small", "switch")]} + ] }] } else: