pipeline-sdlc/wwwroot/api/workspace_open.dspy
ymq 524abb23e6 feat(workspace): 工作空间端点按会话解析项目(session_id)
- workspace_popup/tree/files/view/open/delete/upload/file + office_read/save 读 session_id 传 get_workspace_dir
- 内部 URL 链路(查看/编辑/删除/上传/文件/vi编辑/univer-office)透传 session_id
- workspace_edit.xterm 手写项目解析收敛到 get_workspace_dir(session_id)
2026-08-24 16:40:49 +08:00

115 lines
4.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# workspace_open.dspy - 打开文件:文本/源码→vi编辑,office/pdf→下载,媒体→播放
import os
import json as _json
from urllib.parse import quote
file_id = (params_kw or {}).get('id', '').strip()
uid = await get_user()
if not uid:
uid = 'user-01'
session_id = (params_kw or {}).get('session_id', '') or ''
dbname = get_module_dbname('pipeline-sdlc')
async with DBPools().sqlorContext(dbname) as sor:
ws_dir, _ = await get_workspace_dir(sor, uid, session_id)
if not file_id:
return {"widgettype": "Message", "options": {"title": "打开失败", "message": "未指定文件"}}
full_path = ws_dir + '/' + file_id if ws_dir else file_id
if not os.path.isfile(full_path):
return {"widgettype": "Message", "options": {"title": "打开失败", "message": "文件不存在: " + file_id}}
name = os.path.basename(full_path)
ext = os.path.splitext(name)[1].lower()
text_exts = ['.md', '.py', '.js', '.html', '.css', '.json', '.txt', '.xml', '.yaml', '.yml',
'.toml', '.cfg', '.sh', '.sql', '.dspy', '.ui', '.csv', '.ts', '.tsx', '.jsx',
'.java', '.c', '.cpp', '.h', '.go', '.rs', '.rb', '.php', '.vue', '.scss', '.less', '.ini']
video_exts = ['.mp4', '.m3u8', '.mpd', '.webm', '.mov', '.avi', '.mkv']
audio_exts = ['.mp3', '.wav', '.aac', '.flac', '.m4a', '.ogg']
image_exts = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.bmp', '.ico']
office_exts = ['.docx'] # 在线编辑(univer-office)。xlsx/ppt 后续接入 Univer sheet/slide 插件
file_url = entire_url("/pipeline-sdlc/api/workspace_file.dspy") + "?id=" + quote(file_id) + (("&session_id=" + session_id) if session_id else "")
# 1. 文本/源码 → Wterm + vi 编辑
if ext in text_exts:
ws_url = entire_url("/wss/pipeline-sdlc/workspace_edit.xterm") + "?id=" + quote(file_id) + (("&session_id=" + session_id) if session_id else "")
return {
"widgettype": "PopupWindow",
"options": {"title": name + " (vi 编辑)", "width": "85%", "height": "85%", "auto_open": True, "resizable": True},
"subwidgets": [{
"widgettype": "Wterm",
"options": {
"width": "100%",
"height": "100%",
"term_options": {"fontSize": 14, "cursorBlink": True},
"ws_url": ws_url
}
}]
}
# 2. 媒体 → 播放
if ext in video_exts:
return {
"widgettype": "PopupWindow",
"options": {"title": name, "width": "70%", "height": "70%", "auto_open": True, "resizable": True},
"subwidgets": [{
"widgettype": "VideoPlayer",
"options": {"url": file_url, "width": "100%", "height": "100%"}
}]
}
if ext in audio_exts:
return {
"widgettype": "PopupWindow",
"options": {"title": name, "width": "50%", "height": "30%", "auto_open": True, "resizable": True},
"subwidgets": [{
"widgettype": "AudioPlayer",
"options": {"url": file_url, "width": "100%", "height": "100%"}
}]
}
# 3. 图片 → 预览
if ext in image_exts:
return {
"widgettype": "PopupWindow",
"options": {"title": name, "width": "70%", "height": "70%", "auto_open": True, "resizable": True},
"subwidgets": [
{"widgettype": "Image",
"options": {"url": file_url, "width": "100%", "height": "100%"}}
]
}
# 4. office 文档 → iframe 嵌入 univer-office 在线编辑
if ext in office_exts:
univer_url = entire_url("/univer-office/") + "?file=" + quote(file_id) + (("&session_id=" + session_id) if session_id else "")
return {
"widgettype": "PopupWindow",
"options": {"title": name + " (在线编辑)", "width": "85%", "height": "85%", "auto_open": True, "resizable": True},
"subwidgets": [
{"widgettype": "Iframe", "options": {"url": univer_url, "width": "100%", "height": "100%"}}
]
}
# 5. pdf 等 → 下载后用本地应用打开
download_url = file_url + "&download=1"
download_script = (
"window.open(" + _json.dumps(download_url) + ",'_blank');"
)
return {
"widgettype": "PopupWindow",
"options": {"title": name, "cwidth": 34, "cheight": 12, "auto_open": True, "resizable": True},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "该文件类型需下载后用本地应用打开", "cfontsize": 1, "padding": "16px", "halign": "middle"}},
{"widgettype": "Button", "options": {"label": "下载文件", "css": "primary"},
"binds": [{"wid": "self", "event": "click", "actiontype": "script", "target": "self", "script": download_script}]}
]
}