portfolio.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. from fastapi import APIRouter, Depends, HTTPException, Form, UploadFile, File
  2. import db
  3. import schemas
  4. import auth_utils
  5. import config
  6. import os
  7. import uuid
  8. import shutil
  9. router = APIRouter(tags=["portfolio"])
  10. @router.get("/portfolio")
  11. async def get_public_portfolio():
  12. query = """
  13. SELECT p.id, p.file_path, o.material_name, o.id as order_id
  14. FROM order_photos p
  15. JOIN orders o ON p.order_id = o.id
  16. WHERE p.is_public = TRUE AND o.allow_portfolio = TRUE
  17. ORDER BY p.created_at DESC
  18. """
  19. return db.execute_query(query)
  20. @router.post("/admin/orders/{order_id}/photos")
  21. async def admin_upload_order_photo(
  22. order_id: int,
  23. is_public: bool = Form(False),
  24. file: UploadFile = File(...),
  25. token: str = Depends(auth_utils.oauth2_scheme)
  26. ):
  27. payload = auth_utils.decode_token(token)
  28. if not payload or payload.get("role") != 'admin':
  29. raise HTTPException(status_code=403, detail="Admin role required")
  30. order = db.execute_query("SELECT allow_portfolio FROM orders WHERE id = %s", (order_id,))
  31. if not order: raise HTTPException(status_code=404, detail="Order not found")
  32. if is_public and not order[0]['allow_portfolio']:
  33. raise HTTPException(status_code=400, detail="Cannot make public: User did not consent to portfolio usage")
  34. if not file.filename: raise HTTPException(status_code=400, detail="Invalid file")
  35. unique_filename = f"{uuid.uuid4()}{os.path.splitext(file.filename)[1]}"
  36. file_path = os.path.join(config.UPLOAD_DIR, unique_filename).replace("\\", "/")
  37. with open(file_path, "wb") as buffer:
  38. shutil.copyfileobj(file.file, buffer)
  39. query = "INSERT INTO order_photos (order_id, file_path, is_public) VALUES (%s, %s, %s)"
  40. photo_id = db.execute_commit(query, (order_id, file_path, is_public))
  41. return {"id": photo_id, "file_path": file_path, "is_public": is_public}
  42. @router.patch("/admin/photos/{photo_id}")
  43. async def admin_update_photo_status(photo_id: int, data: schemas.PhotoUpdate, token: str = Depends(auth_utils.oauth2_scheme)):
  44. payload = auth_utils.decode_token(token)
  45. if not payload or payload.get("role") != 'admin':
  46. raise HTTPException(status_code=403, detail="Admin role required")
  47. query = "SELECT p.*, o.allow_portfolio FROM order_photos p JOIN orders o ON p.order_id = o.id WHERE p.id = %s"
  48. photo_data = db.execute_query(query, (photo_id,))
  49. if not photo_data: raise HTTPException(status_code=404, detail="Photo not found")
  50. if data.is_public and not photo_data[0]['allow_portfolio']:
  51. raise HTTPException(status_code=400, detail="Cannot make public: User did not consent to portfolio usage")
  52. db.execute_commit("UPDATE order_photos SET is_public = %s WHERE id = %s", (data.is_public, photo_id))
  53. return {"id": photo_id, "is_public": data.is_public}