Merge origin/main into feat/feedback-qr-and-admin-ops

解决冲突(均为两边各自新增、按并集保留):
- ad_feed_reward 模型/schema/repo/api:本侧 feed_scene 点位场景 + main 侧 app_env/our_code_id/aborted 全部保留;
  feed_scene 一并补进 main 新增的 closed_early / too_short 分支,保证全路径落库。
- core/media.py:保留本侧泛化 _delete_managed(subdir) + 并入 main 的 save_cps_image / to_abs_media_url,
  去掉 main 重复的旧 delete_avatar(本侧已有薄封装)。
- admin/schemas/user.py:本侧 UserRewardStats / UserCoinRecord 与 main 的 _strip_reason 并存。
- admin/routers/withdraw.py:列表接口用 3 元组(带 total)解包 + 保留本侧手机号/昵称/累计富化,total 一并返回。
- alembic:新增 merge 迁移 ceb286289426 合并 add_feed_scene 与 launch_confirm_sample_table 双 head。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
zzhyyyyy
2026-06-20 23:53:54 +08:00
184 changed files with 9944 additions and 530 deletions
+5 -6
View File
@@ -1,7 +1,7 @@
"""帮助与反馈 endpoint。
路由前缀 `/api/v1/feedback`,需 Bearer 鉴权(反馈绑到登录用户,便于回访)。
POST / 提交反馈(multipart:content / contact 必填,images 可选 ≤4 张)
POST / 提交反馈(multipart:content 必填;contact 可选(原型改版后客户端已不再采集);images 可选 ≤6 张)
截图复用 [app.core.media] 落盘到 /media/feedback/。
"""
@@ -21,8 +21,8 @@ logger = logging.getLogger("shagua.feedback")
router = APIRouter(prefix="/api/v1/feedback", tags=["feedback"])
_MAX_IMAGES = 4
_CONTENT_MAX = 2000
_MAX_IMAGES = 6
_CONTENT_MAX = 200
_CONTACT_MAX = 128
@@ -31,7 +31,8 @@ async def submit_feedback(
user: CurrentUser,
db: DbSession,
content: str = Form(...),
contact: str = Form(...),
# 原型改版后客户端不再采集联系方式;保留字段以兼容旧端 + 后续可能复用,默认空串。
contact: str = Form(default=""),
images: list[UploadFile] = File(default=[]),
) -> FeedbackOut:
content = content.strip()
@@ -40,8 +41,6 @@ async def submit_feedback(
raise HTTPException(status_code=400, detail="反馈内容不能为空")
if len(content) > _CONTENT_MAX:
raise HTTPException(status_code=400, detail="反馈内容过长")
if not contact:
raise HTTPException(status_code=400, detail="联系方式不能为空")
if len(contact) > _CONTACT_MAX:
raise HTTPException(status_code=400, detail="联系方式过长")