reallife_asset/wwwroot/api/submit_list_assets.dspy
yumoqing 6491182249 feat: add view_assets page — browse media by group with bricks widgets
- init.py: add rl_list_assets_client() — validates org ownership, syncs
  from vendor, returns asset list with status/url/type
- view_assets.ui: dropdown to select vendor_group_id, submit triggers
  asset list display
- submit_list_assets.dspy: returns responsive card grid with Image/
  VideoPlayer/AudioPlayer widgets, per-asset refresh status + download
- index.ui: add '查看素材' card for customers
- load_path.py: register view_assets.ui under logined RBAC
2026-05-30 10:31:08 +08:00

147 lines
4.7 KiB
Plaintext

vendor_group_id = params_kw.get('vendor_group_id', '')
if not vendor_group_id:
return json.dumps({
"widgettype": "Error",
"options": {"title": "错误", "message": "请选择认证组合"}
})
org_id = (await get_userorgid()) or '0'
result = await rl_list_assets_client(org_id, vendor_group_id)
if not result.get('success'):
return json.dumps({
"widgettype": "Error",
"options": {"title": "查询失败", "message": result.get('message', '未知错误')}
})
assets = result.get('assets', [])
if not assets:
return json.dumps({
"widgettype": "VBox",
"id": "rl_asset_results",
"options": {"padding": "16px", "gap": "12px"},
"subwidgets": [
{
"widgettype": "Text",
"options": {"text": "该认证组合下暂无素材,请先上传素材。"}
}
]
})
# Build asset cards
cards = []
for a in assets:
status = a.get('status', '')
name = a.get('name', '')
url = a.get('url', '')
atype = a.get('asset_type', '')
create_time = str(a.get('create_time', ''))[:16]
asset_id = a.get('id', '')
vendor_asset_id = a.get('vendor_asset_id', '')
# Status icon
s_lower = status.lower() if status else ''
if s_lower in ('active', 'available', 'ready'):
status_icon = "✅"
elif s_lower in ('processing', 'pending', 'submitted'):
status_icon = "⏳"
elif s_lower in ('failed', 'error'):
status_icon = "❌"
else:
status_icon = "📋"
# Build card subwidgets
card_subs = [
{
"widgettype": "HBox",
"options": {"gap": "8px", "alignItems": "center", "marginBottom": "4px"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": name or "未命名", "fontWeight": "bold"}},
{"widgettype": "Text", "options": {"text": f"{status_icon} {status}", "cfontsize": 0.9}}
]
},
{
"widgettype": "Text",
"options": {"text": f"类型: {atype} 创建: {create_time}", "cfontsize": 0.9}
}
]
# Media preview
if url:
if atype == 'Image':
card_subs.append({
"widgettype": "Image",
"options": {"url": url, "cwidth": 15, "cheight": 10, "objectFit": "cover", "borderRadius": "4px", "marginTop": "8px"}
})
elif atype == 'Video':
card_subs.append({
"widgettype": "VideoPlayer",
"options": {"url": url, "cwidth": 20, "cheight": 12, "marginTop": "8px"}
})
elif atype == 'Audio':
card_subs.append({
"widgettype": "AudioPlayer",
"options": {"url": url, "marginTop": "8px"}
})
# Refresh status button (always show for processing assets, optional for others)
check_url = request.path.rsplit('/', 1)[0] + '/submit_query_status.dspy'
btn_subs = [
{
"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}});" \
"})()"
}]
}
]
if url:
btn_subs.append({
"widgettype": "Button",
"options": {"label": "下载"},
"binds": [{
"wid": "self", "event": "click",
"actiontype": "script", "target": "self",
"script": "window.open('" + url + "', '_blank')"
}]
})
card_subs.append({
"widgettype": "HBox",
"options": {"gap": "8px", "marginTop": "8px"},
"subwidgets": btn_subs
})
cards.append({
"widgettype": "VBox",
"options": {"css": "card", "padding": "12px", "borderRadius": "8px"},
"subwidgets": card_subs
})
# Wrap cards in ResponsableBox for responsive grid
result_widget = {
"widgettype": "VBox",
"id": "rl_asset_results",
"options": {"padding": "16px", "gap": "12px"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": f"共 {len(assets)} 个素材", "fontWeight": "bold"}},
{
"widgettype": "ResponsableBox",
"options": {"gap": "12px", "minWidth": "300px"},
"subwidgets": cards
}
]
}
return json.dumps(result_widget, ensure_ascii=False)