feat: add status query flow after upload (frontend专用 dspy)
- submit_upload.dspy: frontend form handler returning bricks Message widget with asset_id, status, and '查询处理状态' button - submit_query_status.dspy: frontend status query returning Message widget with current status, retry button when still processing - upload_asset.ui: use submit_upload.dspy + submited bind (was missing) - External APIs (rl_upload.dspy, rl_status.dspy) unchanged for downstream systems
This commit is contained in:
parent
2f1974ae8f
commit
daf82107fb
68
wwwroot/api/submit_query_status.dspy
Normal file
68
wwwroot/api/submit_query_status.dspy
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
asset_id = params_kw.get('asset_id', '')
|
||||||
|
|
||||||
|
if not asset_id:
|
||||||
|
return json.dumps({
|
||||||
|
"widgettype": "Error",
|
||||||
|
"options": {"title": "错误", "message": "缺少素材ID"}
|
||||||
|
})
|
||||||
|
|
||||||
|
org_id = (await get_userorgid()) or '0'
|
||||||
|
user_id = (await get_user()) or ''
|
||||||
|
|
||||||
|
result = await rl_sync_asset_status_user(org_id, asset_id, user_id)
|
||||||
|
|
||||||
|
if result.get('success'):
|
||||||
|
status = result.get('status', '')
|
||||||
|
url = result.get('url', '')
|
||||||
|
msg = f"素材状态:{status}"
|
||||||
|
if url:
|
||||||
|
msg += f"\n下载地址:{url}"
|
||||||
|
|
||||||
|
subwidgets = [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {"text": msg}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# If still processing, show a retry button
|
||||||
|
if status and status.lower() in ('processing', 'pending', 'submitted'):
|
||||||
|
base_path = request.path.rsplit('/', 1)[0]
|
||||||
|
check_url = base_path + '/submit_query_status.dspy'
|
||||||
|
subwidgets.append({
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {"label": "再次查询"},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "click",
|
||||||
|
"actiontype": "script",
|
||||||
|
"target": "self",
|
||||||
|
"script": "(async function(){"
|
||||||
|
"var url='" + check_url + "?_webbricks_=1&asset_id=" + asset_id + "';"
|
||||||
|
"var r=await fetch(url);"
|
||||||
|
"var j=await r.json();"
|
||||||
|
"await bricks.show_resp_message_or_error({json:async function(){return j}});"
|
||||||
|
"})()"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"widgettype": "Message",
|
||||||
|
"id": "status_result_popup",
|
||||||
|
"options": {"title": "素材状态", "message": ""},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {"padding": "8px", "gap": "12px"},
|
||||||
|
"subwidgets": subwidgets
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
return json.dumps({
|
||||||
|
"widgettype": "Error",
|
||||||
|
"options": {"title": "查询失败", "message": result.get('message', '未知错误')}
|
||||||
|
})
|
||||||
96
wwwroot/api/submit_upload.dspy
Normal file
96
wwwroot/api/submit_upload.dspy
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
vendor_group_id = params_kw.get('vendor_group_id', '')
|
||||||
|
source_url = params_kw.get('source_url', '')
|
||||||
|
asset_type = params_kw.get('asset_type', '')
|
||||||
|
name = params_kw.get('name', '')
|
||||||
|
|
||||||
|
if not vendor_group_id or not source_url:
|
||||||
|
return json.dumps({
|
||||||
|
"widgettype": "Error",
|
||||||
|
"options": {"title": "错误", "message": "请选择认证组合并上传素材文件"}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Validate media file type from path extension
|
||||||
|
ext = os.path.splitext(source_url.split('?')[0])[1].lower() if source_url else ''
|
||||||
|
media_map = {
|
||||||
|
'.jpg': 'Image', '.jpeg': 'Image', '.png': 'Image', '.gif': 'Image', '.bmp': 'Image', '.webp': 'Image', '.svg': 'Image',
|
||||||
|
'.mp4': 'Video', '.avi': 'Video', '.mov': 'Video', '.wmv': 'Video', '.flv': 'Video', '.mkv': 'Video', '.webm': 'Video',
|
||||||
|
'.mp3': 'Audio', '.wav': 'Audio', '.aac': 'Audio', '.flac': 'Audio', '.ogg': 'Audio', '.wma': 'Audio', '.m4a': 'Audio',
|
||||||
|
}
|
||||||
|
detected_type = media_map.get(ext, '')
|
||||||
|
if ext and not detected_type:
|
||||||
|
return json.dumps({
|
||||||
|
"widgettype": "Error",
|
||||||
|
"options": {"title": "错误", "message": f"不支持的文件类型: {ext},请上传图片、音频或视频文件"}
|
||||||
|
})
|
||||||
|
if not asset_type and detected_type:
|
||||||
|
asset_type = detected_type
|
||||||
|
if not asset_type:
|
||||||
|
asset_type = 'Image'
|
||||||
|
|
||||||
|
# Convert base64 / local path to public URL
|
||||||
|
if source_url.startswith('data:') or (not source_url.startswith('http') and len(source_url) < 8000):
|
||||||
|
source_url = await b64media2url(request, source_url)
|
||||||
|
if not source_url:
|
||||||
|
return json.dumps({
|
||||||
|
"widgettype": "Error",
|
||||||
|
"options": {"title": "错误", "message": "素材文件转换失败"}
|
||||||
|
})
|
||||||
|
|
||||||
|
org_id = (await get_userorgid()) or '0'
|
||||||
|
user_id = (await get_user()) or ''
|
||||||
|
|
||||||
|
result = await rl_upload_user(org_id, vendor_group_id, source_url, asset_type, name, user_id)
|
||||||
|
|
||||||
|
if result.get('success'):
|
||||||
|
asset_id = result.get('id', '')
|
||||||
|
vendor_asset_id = result.get('vendor_asset_id', '')
|
||||||
|
status_text = result.get('status', 'Processing')
|
||||||
|
msg = f"素材已提交,当前状态:{status_text}\n素材ID:{asset_id}\n供应商资产ID:{vendor_asset_id}"
|
||||||
|
|
||||||
|
# Build check-status URL from current request path
|
||||||
|
base_path = request.path.rsplit('/', 1)[0]
|
||||||
|
check_url = base_path + '/submit_query_status.dspy'
|
||||||
|
|
||||||
|
return json.dumps({
|
||||||
|
"widgettype": "Message",
|
||||||
|
"id": "upload_result_popup",
|
||||||
|
"options": {"title": "上传成功", "message": ""},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {"padding": "8px", "gap": "12px"},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {"text": msg}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Button",
|
||||||
|
"options": {"label": "查询处理状态"},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "click",
|
||||||
|
"actiontype": "script",
|
||||||
|
"target": "self",
|
||||||
|
"script": "(async function(){"
|
||||||
|
"var url='" + check_url + "?_webbricks_=1&asset_id=" + asset_id + "';"
|
||||||
|
"var r=await fetch(url);"
|
||||||
|
"var j=await r.json();"
|
||||||
|
"await bricks.show_resp_message_or_error({json:async function(){return j}});"
|
||||||
|
"})()"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
return json.dumps({
|
||||||
|
"widgettype": "Error",
|
||||||
|
"options": {"title": "上传失败", "message": result.get('message', '未知错误')}
|
||||||
|
})
|
||||||
@ -30,7 +30,7 @@
|
|||||||
"widgettype": "Form",
|
"widgettype": "Form",
|
||||||
"id": "upload_form",
|
"id": "upload_form",
|
||||||
"options": {
|
"options": {
|
||||||
"submit_url": "{{entire_url('api/rl_upload.dspy')}}",
|
"submit_url": "{{entire_url('api/submit_upload.dspy')}}",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"uitype": "code",
|
"uitype": "code",
|
||||||
@ -72,7 +72,15 @@
|
|||||||
"placeholder": "可选,默认使用URL最后一部分"
|
"placeholder": "可选,默认使用URL最后一部分"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "submited",
|
||||||
|
"actiontype": "script",
|
||||||
|
"script": "await bricks.show_resp_message_or_error(event.params)"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user