From 6408406cd91d6417fbea675fd01fc0d2ce7a436a Mon Sep 17 00:00:00 2001 From: p Date: Wed, 12 Aug 2026 15:13:25 +0800 Subject: [PATCH] workspace: relative path ids, is_leaf, workspace_files uses ws_dir --- wwwroot/api/workspace_files.dspy | 35 +++++++++++++++++++++++++++----- wwwroot/api/workspace_tree.dspy | 32 +++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/wwwroot/api/workspace_files.dspy b/wwwroot/api/workspace_files.dspy index f594bdf..71144c1 100644 --- a/wwwroot/api/workspace_files.dspy +++ b/wwwroot/api/workspace_files.dspy @@ -1,4 +1,5 @@ # workspace_files.dspy - 返回目录下文件列表(Bricks widget 格式) +# id 是相对路径,需拼接 workspace_dir import os @@ -7,18 +8,42 @@ folder_id = (params_kw or {}).get('id', '').strip() if not folder_id or folder_id == '__root__': return {"widgettype": "Text", "options": {"text": "请从左侧选择目录", "cfontsize": 0.9}} -if not os.path.isdir(folder_id): - return {"widgettype": "Text", "options": {"text": "目录不可用"}} +uid = await get_user() +if not uid: + uid = 'user-01' + +dbname = get_module_dbname('pipeline-sdlc') +workspace_base = '/d/pipeline/workspaces' + +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 '' + ws_dir = '' + if pid: + proj = await sor.sqlExe("SELECT name, org_id, workspace_dir FROM sd_projects WHERE id=${p}$", {"p": pid}) + if proj: + ws = getattr(proj[0], 'workspace_dir', '') or '' + if ws.startswith('/'): + ws_dir = ws + else: + pname = getattr(proj[0], 'name', '') + org_id = getattr(proj[0], 'org_id', '0') or '0' + ws_dir = workspace_base + '/' + org_id + '/' + pname + +full_dir = ws_dir + '/' + folder_id if ws_dir else folder_id + +if not os.path.isdir(full_dir): + return {"widgettype": "Text", "options": {"text": "目录不可用: " + folder_id}} -# 文件列表 files = [] try: - entries = sorted(os.listdir(folder_id)) + entries = sorted(os.listdir(full_dir)) except Exception as e: return {"widgettype": "Text", "options": {"text": "读取错误: " + str(e)}} for name in entries: - full = os.path.join(folder_id, name) + full = os.path.join(full_dir, name) if name.startswith('.'): continue if os.path.isfile(full): diff --git a/wwwroot/api/workspace_tree.dspy b/wwwroot/api/workspace_tree.dspy index 1ba5bd7..340543d 100644 --- a/wwwroot/api/workspace_tree.dspy +++ b/wwwroot/api/workspace_tree.dspy @@ -1,4 +1,4 @@ -# workspace_tree.dspy - 返回 Tree widget 需要的 {id, parentid, label} 格式 +# workspace_tree.dspy - 返回 Tree widget 需要的 {id, parentid, label, path} 格式 uid = await get_user() if not uid: @@ -26,12 +26,12 @@ async with DBPools().sqlorContext(dbname) as sor: ws_dir = ws if ws.startswith('/') else workspace_base + '/' + org_id + '/' + pname if not ws_dir or not os.path.isdir(ws_dir): - return [{"id": "__root__", "parentid": "", "label": "📁 工作空间(不可用)"}] + return [{"id": "__root__", "parentid": "", "label": "📁 工作空间(不可用)", "path": ""}] -# 递归扫描目录,生成 {id, parentid, label} -items = [{"id": "__root__", "parentid": "", "label": "📁 " + os.path.basename(ws_dir)}] +# 递归扫描目录,id 只含相对路径,full path 存 path 字段 +items = [{"id": "__root__", "parentid": "", "label": "📁 " + os.path.basename(ws_dir), "path": ws_dir, "is_leaf": False}] -def scan_dir(path, parent_id): +def scan_dir(path, parent_id, rel_prefix): try: entries = sorted(os.listdir(path)) except Exception: @@ -40,10 +40,24 @@ def scan_dir(path, parent_id): full = os.path.join(path, name) if name.startswith('.') or name == '__pycache__': continue + rel_path = rel_prefix + '/' + name if rel_prefix else name if os.path.isdir(full): - dir_id = full # 用全路径做 id - items.append({"id": dir_id, "parentid": parent_id, "label": "📁 " + name}) - scan_dir(full, dir_id) + items.append({ + "id": rel_path, + "parentid": parent_id, + "label": "📁 " + name, + "path": full, + "is_leaf": False + }) + scan_dir(full, rel_path, rel_path) + else: + items.append({ + "id": rel_path, + "parentid": parent_id, + "label": "📄 " + name, + "path": full, + "is_leaf": True + }) -scan_dir(ws_dir, "__root__") +scan_dir(ws_dir, "__root__", "") return items