"""admin 反馈工单 schemas。""" from __future__ import annotations from datetime import datetime from pydantic import BaseModel, ConfigDict, Field from app.core.rewards import FEEDBACK_REWARD_MAX_COINS class FeedbackOut(BaseModel): model_config = ConfigDict(from_attributes=True) id: int user_id: int content: str contact: str # 反馈来源入口:profile(「我的」页)/ comparison(比价结果页)——admin 展示/筛选「反馈类型」 source: str = "profile" # 比价反馈的问题场景(找错商品/优惠不对…);普通反馈为 None scene: str | None = None images: list[str] | None = None status: str reject_reason: str | None = None reward_coins: int | None = None review_note: str | None = None # 运营给用户的回复留言(用户端可见,采纳/未采纳都可填) admin_reply: str | None = None reviewed_by_admin_id: int | None = None reviewed_at: datetime | None = None created_at: datetime # 提交端环境快照(feedback 表列):提交版本号 / 机型OS版本;改版前的历史反馈为 None app_version: str | None = None device_model: str | None = None rom_name: str | None = None android_version: str | None = None # 联表瞬态字段(queries._attach_user_info 挂):列表展示完整手机号,点手机号查该用户全部反馈 phone: str | None = None nickname: str | None = None class FeedbackApproveRequest(BaseModel): reward_coins: int = Field( ge=1, le=FEEDBACK_REWARD_MAX_COINS, description="采纳后发放金币数", ) note: str | None = Field(default=None, max_length=256, description="采纳要点/审核备注(内部)") reply: str | None = Field(default=None, max_length=256, description="给用户的回复留言,用户端可见") class FeedbackRejectRequest(BaseModel): reason: str = Field(min_length=1, max_length=256, description="未采纳原因,用户端可见") note: str | None = Field(default=None, max_length=256, description="运营内部审核备注") reply: str | None = Field(default=None, max_length=256, description="给用户的回复留言,用户端可见") class FeedbackSummary(BaseModel): """审核台顶部各状态计数(pending 含历史 new 态)。""" pending: int adopted: int rejected: int total: int