feat: 机构远程空间配置页(sd_org_remote)+ 权限注册

This commit is contained in:
p 2026-08-14 13:33:07 +08:00
parent 534591e5d5
commit 8f9ae04028
2 changed files with 122 additions and 0 deletions

View File

@ -111,6 +111,9 @@ PATHS_LOGINED = [
# 工作环境 / 部署账号(普通用户可用)
f"/{MOD}/api/work_env.dspy",
f"/{MOD}/api/deploy_account.dspy",
# 机构远程空间配置(页面 loginedorg 级设置由 API 层校验 superuser
f"/{MOD}/sd_org_remote/index.ui",
f"/{MOD}/sd_org_remote",
]

View File

@ -0,0 +1,119 @@
{
"widgettype": "VBox",
"options": {"width": "100%", "height": "100%", "padding": "24px", "gap": "16px"},
"subwidgets": [
{
"widgettype": "Html",
"options": {
"html": "<script>setTimeout(function(){fetch('/pipeline-sdlc/api/work_env.dspy?action=get').then(function(r){return r.json()}).then(function(d){if(d.ok&&d.env){var f=bricks.getWidgetById('remote_form',bricks.app);if(f){f.setValue(d.env);}}})},300);</script>",
"height": "0",
"width": "0"
}
},
{
"widgettype": "Title3",
"options": {"text": "机构远程空间配置"}
},
{
"widgettype": "Text",
"options": {
"text": "设置机构的远程工作空间。远程模式下,机构所有用户的工作目录与沙箱命令都在远程主机执行(远程主机需部署 bwrap。",
"cfontsize": 0.9,
"color": "#64748b"
}
},
{
"widgettype": "VBox",
"options": {"bgcolor": "#fff", "border": "1px solid #e2e8f0", "borderRadius": "12px", "padding": "20px", "gap": "12px"},
"subwidgets": [
{
"widgettype": "Form",
"id": "remote_form",
"options": {
"name": "remote_form",
"cols": 2,
"fields": [
{
"name": "mode",
"uitype": "code",
"label": "工作模式",
"cwidth": 12,
"data": [
{"value": "local", "text": "本地bwrap 沙箱)"},
{"value": "remote", "text": "远程SSH + bwrap 沙箱)"}
],
"valueField": "value",
"textField": "text"
},
{
"name": "remote_host",
"uitype": "str",
"label": "远程主机",
"cwidth": 24,
"placeholder": "例如 192.168.1.10 或 remote.example.com"
},
{
"name": "remote_port",
"uitype": "str",
"label": "远程端口",
"cwidth": 8,
"value": "22"
},
{
"name": "remote_user",
"uitype": "str",
"label": "远程用户",
"cwidth": 12
},
{
"name": "remote_dir",
"uitype": "str",
"label": "远程目录",
"cwidth": 24,
"placeholder": "绝对路径,例如 /data/pipeline/ws"
}
]
}
},
{
"widgettype": "HBox",
"options": {"gap": "12px"},
"subwidgets": [
{
"widgettype": "Button",
"id": "save_btn",
"options": {"label": "保存配置"},
"binds": [{
"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": "var f=bricks.getWidgetById('remote_form',bricks.app);var v=f?f.getValue():{};var body=new URLSearchParams();body.append('action','set');body.append('owner_type','org');body.append('mode',v.mode||'local');body.append('remote_host',v.remote_host||'');body.append('remote_port',v.remote_port||'22');body.append('remote_user',v.remote_user||'');body.append('remote_dir',v.remote_dir||'');fetch('/pipeline-sdlc/api/work_env.dspy',{method:'POST',body:body}).then(function(r){return r.json()}).then(function(d){var m=new bricks.Message({title:d.ok?'成功':'失败',message:d.ok?'远程空间配置已保存':(d.error||'未知错误')});m.open();});"
}]
},
{
"widgettype": "Button",
"id": "test_btn",
"options": {"label": "测试远程连接"},
"binds": [{
"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": "var f=bricks.getWidgetById('remote_form',bricks.app);var v=f?f.getValue():{};var body=new URLSearchParams();body.append('action','ensure_remote_bwrap');body.append('remote_host',v.remote_host||'');body.append('remote_port',v.remote_port||'22');body.append('remote_user',v.remote_user||'');fetch('/pipeline-sdlc/api/work_env.dspy',{method:'POST',body:body}).then(function(r){return r.json()}).then(function(d){var m=new bricks.Message({title:d.ok?'连接成功':'连接失败',message:d.ok?('远程 bwrap 位置: '+(d.location||'unknown')):(d.error||'未知错误')});m.open();});"
}]
},
{
"widgettype": "Button",
"id": "pubkey_btn",
"options": {"label": "获取机构公钥"},
"binds": [{
"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": "fetch('/pipeline-sdlc/api/work_env.dspy?action=get_org_pubkey').then(function(r){return r.json()}).then(function(d){if(d.ok){var t=bricks.getWidgetById('pubkey_text',bricks.app);if(t)t.set_text('机构公钥(复制到远程主机 ~/.ssh/authorized_keys\\n'+d.pubkey);}else{var m=new bricks.Message({title:'失败',message:d.error||'未知错误'});m.open();}});"
}]
}
]
},
{
"widgettype": "Text",
"id": "pubkey_text",
"options": {"text": "", "whiteSpace": "pre-wrap", "cfontsize": 0.85, "color": "#334155"}
}
]
}
]
}