36 lines
1.4 KiB
Plaintext
36 lines
1.4 KiB
Plaintext
# opp_report_ppt.dspy - 下载报告 PPT(附件)
|
||
# 入参:report_id。路径只从库读(不接受用户传路径),防路径穿越。
|
||
|
||
import os
|
||
from urllib.parse import quote
|
||
from aiohttp.web_fileresponse import FileResponse
|
||
|
||
uid = await get_user()
|
||
if not uid:
|
||
return {"widgettype": "Message", "options": {"title": "未登录", "message": "请先登录"}}
|
||
|
||
report_id = ((params_kw or {}).get('report_id') or '').strip()
|
||
if not report_id:
|
||
return {"widgettype": "Message", "options": {"title": "缺少参数", "message": "缺少 report_id"}}
|
||
|
||
dbname = get_module_dbname('pipeline-opportunity')
|
||
async with DBPools().sqlorContext(dbname) as sor:
|
||
recs = await sor.sqlExe(
|
||
"SELECT title, ppt_path FROM opp_reports WHERE id=${i}$", {"i": report_id})
|
||
await sor.sqlExe("COMMIT", {})
|
||
|
||
if not recs:
|
||
return {"widgettype": "Message", "options": {"title": "不存在", "message": "报告不存在"}}
|
||
|
||
ppt_path = (getattr(recs[0], 'ppt_path', '') or '').strip()
|
||
title = getattr(recs[0], 'title', '') or '研发报告'
|
||
if not ppt_path or not os.path.isfile(ppt_path):
|
||
return {"widgettype": "Message", "options": {
|
||
"title": "无 PPT", "message": "该报告尚未生成 PPT(提交人工确认时自动生成)"}}
|
||
|
||
filename = os.path.basename(ppt_path)
|
||
safe_name = quote(filename)
|
||
headers = {'Content-Disposition':
|
||
'attachment; filename="%s"; filename*=UTF-8\'\'%s' % (filename, safe_name)}
|
||
return FileResponse(ppt_path, headers=headers)
|