Add ops feedback reward grants

This commit is contained in:
2569718930@qq.com
2026-06-08 20:54:20 +08:00
parent 7d1bfea8da
commit 6273921005
9 changed files with 514 additions and 43 deletions
+5
View File
@@ -504,6 +504,11 @@ class GrantPointsRequest(BaseModel):
points: int = Field(..., gt=0, le=100000)
class FeedbackRewardRequest(BaseModel):
points: int = Field(..., gt=0, le=100000)
reason: str = Field(..., min_length=2, max_length=500)
def _sf(v) -> Optional[float]:
if v is None:
return None
+16 -1
View File
@@ -2,7 +2,7 @@
from fastapi import APIRouter, Request, Response
from web.core import GrantPointsRequest
from web.core import FeedbackRewardRequest, GrantPointsRequest
from web.services.ops_api import (
extend_ops_subscription,
get_ops_analytics_funnel,
@@ -28,6 +28,7 @@ from web.services.ops_api import (
list_ops_payments,
search_ops_users,
update_ops_config,
grant_ops_feedback_reward,
update_ops_sensitive_config,
update_ops_feedback_status,
get_ops_training_accuracy,
@@ -88,6 +89,20 @@ async def ops_feedback_update_status(request: Request, feedback_id: int):
return update_ops_feedback_status(request, feedback_id=feedback_id, status=status)
@router.post("/api/ops/feedback/{feedback_id}/reward")
async def ops_feedback_grant_reward(
request: Request,
feedback_id: int,
body: FeedbackRewardRequest,
):
return grant_ops_feedback_reward(
request,
feedback_id=feedback_id,
points=body.points,
reason=body.reason,
)
@router.get("/api/ops/memberships")
async def ops_memberships(request: Request, limit: int = 200):
return list_ops_memberships(request, limit=limit)
+24
View File
@@ -189,6 +189,30 @@ def update_ops_feedback_status(
return {"ok": True, "feedback": updated}
def grant_ops_feedback_reward(
request: Request,
*,
feedback_id: int,
points: int,
reason: str,
) -> Dict[str, Any]:
admin = _require_ops(request) or {}
db = DBManager()
result = db.grant_feedback_reward(
feedback_id,
points=points,
reason=reason,
)
result["operator_email"] = admin.get("email")
if not result.get("ok"):
reason_code = str(result.get("reason") or "feedback_reward_failed")
status_code = 404 if reason_code in {"feedback_not_found", "user_not_found"} else 400
if reason_code == "already_rewarded":
status_code = 409
raise HTTPException(status_code=status_code, detail=result)
return result
def _list_active_subscriptions_with_windows(
limit: int,
) -> tuple[list[dict[str, Any]], dict[str, dict[str, Any]], bool]: