"""API - 小程序端售后评价接口""" from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app.core.database import get_db from app.core.auth import get_current_user from app.core.response import success_response, error_response from app.crud.product_review import product_review from app.crud.product_review_media import product_review_media from app.schemas.product_review import ( ProductReviewCreate, ProductReviewUpdate, ProductReviewListResponse ) from app.schemas.product_review_media import ProductReviewMediaCreate router = APIRouter(prefix="/mini/reviews", tags=["小程序评价接口"]) def require_client_or_supplier(current_user: dict = Depends(get_current_user)): """验证客户或供应商权限""" role = current_user.get("role") if role not in ["client", "supplier", "admin"]: raise HTTPException(status_code=403, detail="需要客户或供应商权限") return current_user @router.get("/product/{product_id}", response_model=dict) def list_product_reviews( product_id: str, page: int = Query(1, ge=1, description="页码"), pageSize: int = Query(10, ge=1, le=100, description="每页条数"), hasMedia: Optional[int] = Query(None, description="是否有媒体:1-有图/视频"), db: Session = Depends(get_db), current_user: dict = Depends(get_current_user) ): """获取商品的评价列表(仅显示已审核通过的评价)""" items, total = product_review.get_by_product( db, product_id=product_id, skip=(page - 1) * pageSize, limit=pageSize, status="approved", has_media=hasMedia ) # 获取每个评价的媒体列表 result_list = [] for item in items: media_list = product_review_media.get_by_review(db, item.id) result_list.append({ "id": item.id, "productId": item.product_id, "userId": item.user_id, "userName": "匿名用户" if item.is_anonymous else item.user_name, "rating": item.rating, "ratingTags": item.rating_tags, "content": item.content, "isAnonymous": item.is_anonymous, "replyContent": item.reply_content, "replyTime": str(item.reply_time) if item.reply_time else None, "likeCount": item.like_count, "createAt": str(item.create_at) if item.create_at else None, "mediaList": [{ "id": m.id, "mediaType": m.media_type, "fileUrl": m.file_url, "thumbnailUrl": m.thumbnail_url } for m in media_list] }) return success_response({ "list": result_list, "total": total, "page": page, "pageSize": pageSize }) @router.post("", response_model=dict) def create_review( review_data: dict, db: Session = Depends(get_db), current_user: dict = Depends(require_client_or_supplier) ): """提交评价""" user_id = current_user.get("user_id") user_name = current_user.get("real_name") # 检查是否已评价 if product_review.user_can_review(db, user_id, review_data.get("product_id"), review_data.get("order_id")): return error_response(400, "您已评价过该商品") creator = {"user_id": user_id, "real_name": user_name} # 创建评价 review = product_review.create(db, { "product_id": review_data.get("product_id"), "order_id": review_data.get("order_id"), "order_item_id": review_data.get("order_item_id"), "user_id": user_id, "user_name": user_name, "rating": review_data.get("rating", 5), "rating_tags": review_data.get("rating_tags"), "content": review_data.get("content"), "is_anonymous": review_data.get("is_anonymous", 0), "status": "pending" # 默认待审核 }, creator) # 保存媒体 media_items = review_data.get("media", []) if media_items: product_review_media.create_batch(db, review.id, media_items, creator) return success_response({ "id": review.id, "message": "评价提交成功,等待审核" }) @router.post("/{review_id}/like", response_model=dict) def like_review( review_id: str, db: Session = Depends(get_db), current_user: dict = Depends(get_current_user) ): """点赞评价""" review = product_review.like(db, review_id) if not review: return error_response(404, "评价不存在或未通过审核") return success_response({ "likeCount": review.like_count }) @router.get("/statistics/{product_id}", response_model=dict) def get_product_review_stats( product_id: str, db: Session = Depends(get_db), current_user: dict = Depends(get_current_user) ): """获取商品评价统计""" stats = product_review.get_statistics(db, product_id) return success_response(stats)