# task_tree.dspy - 任务树(懒加载:无 id 返回根节点,id=__root__ 返回任务列表) import json uid = await get_user() if not uid: uid = 'user-01' node_id = (params_kw or {}).get('id', '').strip() dbname = get_module_dbname('pipeline-sdlc') _state_icons = { 'completed': '\u2705', 'approved': '\u2705', 'running': '\U0001f7e1', 'failed': '\u274c', 'waiting': '\u26a0\ufe0f', 'submitted': '\u2b1c', 'review': '\U0001f440', 'rejected': '\U0001f6ab', 'paused': '\u23f8\ufe0f', 'cancelled': '\U0001f6d1', } 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 '' if not pid: if not node_id: return json.dumps([{"id": "__root__", "label": "请先选择项目", "is_leaf": True}], ensure_ascii=False) return json.dumps([], ensure_ascii=False) # 项目名 pname = '' precs = await sor.sqlExe("SELECT name FROM sd_projects WHERE id=${p}$", {"p": pid}) if precs: pname = getattr(precs[0], 'name', '') or '' if not node_id: # 根节点 return json.dumps([{"id": "__root__", "label": pname or "项目", "is_leaf": False}], ensure_ascii=False) if node_id != '__root__': return json.dumps([], ensure_ascii=False) # 任务列表(子节点) tasks = await sor.sqlExe( "SELECT id, title, role, state FROM pipeline_tasks WHERE tenant_id=${p}$ ORDER BY created_at ASC", {"p": pid}) nodes = [] for t in (tasks or []): tid = getattr(t, 'id', '') title = getattr(t, 'title', '') or '' role = getattr(t, 'role', '') or '' state = getattr(t, 'state', '') or '' if not tid or not title: continue icon = _state_icons.get(state, '\u2b1c') nodes.append({ "id": tid, "label": "{} [{}] {}".format(icon, role, title), "is_leaf": True, }) return json.dumps(nodes, ensure_ascii=False)