feat(orders): 订单页改双栏——左队列/右详情,含分层预览与整体预览、单订单/全部导出
This commit is contained in:
@@ -999,6 +999,88 @@ def get_order(request: Request, order_no: str) -> dict:
|
||||
return o
|
||||
|
||||
|
||||
@app.get("/api/orders/{order_no}/design")
|
||||
def order_design(request: Request, order_no: str) -> dict:
|
||||
"""订单设计详情:画布 + 各层元素(含素材 URL),供前端做分层/整体预览。"""
|
||||
_require_orders_auth(request)
|
||||
path = Path(_order_dir(order_no)) / "order.json"
|
||||
if not path.exists():
|
||||
raise HTTPException(status_code=404, detail="order not found")
|
||||
o = json.loads(path.read_text(encoding="utf-8"))
|
||||
tid = o.get("template_id")
|
||||
tjson = _design_template_dir(tid) / "template.json" if tid else None
|
||||
if not tjson or not tjson.exists():
|
||||
raise HTTPException(status_code=404, detail="订单设计不存在")
|
||||
data = json.loads(tjson.read_text(encoding="utf-8"))
|
||||
doc = data.get("document") or {}
|
||||
|
||||
elements = []
|
||||
for e in doc.get("elements") or []:
|
||||
if not isinstance(e, dict):
|
||||
continue
|
||||
item = dict(e)
|
||||
asset_id = e.get("assetId")
|
||||
if asset_id:
|
||||
meta = _read_asset_meta(_asset_dir(str(asset_id))) or {}
|
||||
item["assetUrl"] = meta.get("file_url") or f"/api/assets/{asset_id}/download"
|
||||
item["assetName"] = meta.get("name") or str(asset_id)
|
||||
else:
|
||||
item["assetUrl"] = ""
|
||||
elements.append(item)
|
||||
|
||||
try:
|
||||
status = manager.get_status(str(o.get("job_id") or "")).status
|
||||
except Exception:
|
||||
status = o.get("status", "unknown")
|
||||
|
||||
return {
|
||||
"order_no": order_no,
|
||||
"status": status,
|
||||
"job_id": o.get("job_id"),
|
||||
"template_id": tid,
|
||||
"design": {
|
||||
"width": doc.get("width"),
|
||||
"height": doc.get("height"),
|
||||
"background": doc.get("background", "#ffffff"),
|
||||
"layers": doc.get("layers") or [],
|
||||
"elements": elements,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@app.get("/api/orders/{order_no}/export")
|
||||
async def export_order(request: Request, order_no: str) -> StreamingResponse:
|
||||
"""单订单导出多层 ZIP。"""
|
||||
_require_orders_auth(request)
|
||||
path = Path(_order_dir(order_no)) / "order.json"
|
||||
if not path.exists():
|
||||
raise HTTPException(status_code=404, detail="order not found")
|
||||
o = json.loads(path.read_text(encoding="utf-8"))
|
||||
buf = io.BytesIO()
|
||||
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||
folder = f"orders/{order_no}/"
|
||||
zf.writestr(folder + "order.json", json.dumps(o, ensure_ascii=False, indent=2))
|
||||
tid = o.get("template_id")
|
||||
job_id = o.get("job_id")
|
||||
if tid:
|
||||
tjson = _design_template_dir(tid) / "template.json"
|
||||
if tjson.exists():
|
||||
zf.write(str(tjson), folder + "design/template.json")
|
||||
if job_id:
|
||||
try:
|
||||
st = manager.get_status(str(job_id))
|
||||
png = manager.resolve_artifact_path(st, "png")
|
||||
zf.write(str(png), folder + "result/result.png")
|
||||
except Exception:
|
||||
pass
|
||||
buf.seek(0)
|
||||
return StreamingResponse(
|
||||
buf,
|
||||
media_type="application/zip",
|
||||
headers={"Content-Disposition": f'attachment; filename="order-{order_no}.zip"'},
|
||||
)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# 4. 模板接口
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user