mini_review.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. """API - 小程序端售后评价接口"""
  2. from typing import Optional
  3. from fastapi import APIRouter, Depends, HTTPException, Query
  4. from sqlalchemy.orm import Session
  5. from app.core.database import get_db
  6. from app.core.auth import get_current_user
  7. from app.core.response import success_response, error_response
  8. from app.crud.product_review import product_review
  9. from app.crud.product_review_media import product_review_media
  10. from app.schemas.product_review import (
  11. ProductReviewCreate,
  12. ProductReviewUpdate,
  13. ProductReviewListResponse
  14. )
  15. from app.schemas.product_review_media import ProductReviewMediaCreate
  16. router = APIRouter(prefix="/mini/reviews", tags=["小程序评价接口"])
  17. def require_client_or_supplier(current_user: dict = Depends(get_current_user)):
  18. """验证客户或供应商权限"""
  19. role = current_user.get("role")
  20. if role not in ["client", "supplier", "admin"]:
  21. raise HTTPException(status_code=403, detail="需要客户或供应商权限")
  22. return current_user
  23. @router.get("/product/{product_id}", response_model=dict)
  24. def list_product_reviews(
  25. product_id: str,
  26. page: int = Query(1, ge=1, description="页码"),
  27. pageSize: int = Query(10, ge=1, le=100, description="每页条数"),
  28. hasMedia: Optional[int] = Query(None, description="是否有媒体:1-有图/视频"),
  29. db: Session = Depends(get_db),
  30. current_user: dict = Depends(get_current_user)
  31. ):
  32. """获取商品的评价列表(仅显示已审核通过的评价)"""
  33. items, total = product_review.get_by_product(
  34. db,
  35. product_id=product_id,
  36. skip=(page - 1) * pageSize,
  37. limit=pageSize,
  38. status="approved",
  39. has_media=hasMedia
  40. )
  41. # 获取每个评价的媒体列表
  42. result_list = []
  43. for item in items:
  44. media_list = product_review_media.get_by_review(db, item.id)
  45. result_list.append({
  46. "id": item.id,
  47. "productId": item.product_id,
  48. "userId": item.user_id,
  49. "userName": "匿名用户" if item.is_anonymous else item.user_name,
  50. "rating": item.rating,
  51. "ratingTags": item.rating_tags,
  52. "content": item.content,
  53. "isAnonymous": item.is_anonymous,
  54. "replyContent": item.reply_content,
  55. "replyTime": str(item.reply_time) if item.reply_time else None,
  56. "likeCount": item.like_count,
  57. "createAt": str(item.create_at) if item.create_at else None,
  58. "mediaList": [{
  59. "id": m.id,
  60. "mediaType": m.media_type,
  61. "fileUrl": m.file_url,
  62. "thumbnailUrl": m.thumbnail_url
  63. } for m in media_list]
  64. })
  65. return success_response({
  66. "list": result_list,
  67. "total": total,
  68. "page": page,
  69. "pageSize": pageSize
  70. })
  71. @router.post("", response_model=dict)
  72. def create_review(
  73. review_data: dict,
  74. db: Session = Depends(get_db),
  75. current_user: dict = Depends(require_client_or_supplier)
  76. ):
  77. """提交评价"""
  78. user_id = current_user.get("user_id")
  79. user_name = current_user.get("real_name")
  80. # 检查是否已评价
  81. if product_review.user_can_review(db, user_id, review_data.get("product_id"), review_data.get("order_id")):
  82. return error_response(400, "您已评价过该商品")
  83. creator = {"user_id": user_id, "real_name": user_name}
  84. # 创建评价
  85. review = product_review.create(db, {
  86. "product_id": review_data.get("product_id"),
  87. "order_id": review_data.get("order_id"),
  88. "order_item_id": review_data.get("order_item_id"),
  89. "user_id": user_id,
  90. "user_name": user_name,
  91. "rating": review_data.get("rating", 5),
  92. "rating_tags": review_data.get("rating_tags"),
  93. "content": review_data.get("content"),
  94. "is_anonymous": review_data.get("is_anonymous", 0),
  95. "status": "pending" # 默认待审核
  96. }, creator)
  97. # 保存媒体
  98. media_items = review_data.get("media", [])
  99. if media_items:
  100. product_review_media.create_batch(db, review.id, media_items, creator)
  101. return success_response({
  102. "id": review.id,
  103. "message": "评价提交成功,等待审核"
  104. })
  105. @router.post("/{review_id}/like", response_model=dict)
  106. def like_review(
  107. review_id: str,
  108. db: Session = Depends(get_db),
  109. current_user: dict = Depends(get_current_user)
  110. ):
  111. """点赞评价"""
  112. review = product_review.like(db, review_id)
  113. if not review:
  114. return error_response(404, "评价不存在或未通过审核")
  115. return success_response({
  116. "likeCount": review.like_count
  117. })
  118. @router.get("/statistics/{product_id}", response_model=dict)
  119. def get_product_review_stats(
  120. product_id: str,
  121. db: Session = Depends(get_db),
  122. current_user: dict = Depends(get_current_user)
  123. ):
  124. """获取商品评价统计"""
  125. stats = product_review.get_statistics(db, product_id)
  126. return success_response(stats)