解决已发现问题
This commit is contained in:
@@ -116,6 +116,8 @@ class AdminUserSerializer(serializers.ModelSerializer):
|
||||
class AdminTaskSerializer(serializers.ModelSerializer):
|
||||
team_name = serializers.CharField(source="team.name", read_only=True, default=None)
|
||||
model_name = serializers.CharField(source="model_config.name", read_only=True, default=None)
|
||||
# 不改变 AITask.task_type 的调度语义;后台展示/筛选使用来源分类。
|
||||
task_category = serializers.SerializerMethodField()
|
||||
cost_anomaly = serializers.SerializerMethodField()
|
||||
# 单任务毛利(¥):actual_cost(积分)÷汇率 − base_cost。base_cost=0(成本未知)时 None,报表侧过滤
|
||||
margin_yuan = serializers.SerializerMethodField()
|
||||
@@ -125,11 +127,14 @@ class AdminTaskSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = AITask
|
||||
fields = [
|
||||
"id", "task_type", "status", "team", "team_name", "model_name",
|
||||
"id", "task_type", "task_category", "status", "team", "team_name", "model_name",
|
||||
"estimated_cost", "actual_cost", "base_cost", "margin_yuan", "cost_anomaly", "error_code", "reapable", "created_at",
|
||||
]
|
||||
read_only_fields = fields
|
||||
|
||||
def get_task_category(self, obj) -> str:
|
||||
return str(getattr(obj, "task_category", "standard") or "standard")
|
||||
|
||||
def get_cost_anomaly(self, obj) -> bool:
|
||||
return is_cost_anomaly(obj.estimated_cost, obj.actual_cost)
|
||||
|
||||
|
||||
@@ -403,9 +403,10 @@ class AdminTaskMonitorTests(TestCase):
|
||||
]
|
||||
self.assertTrue(task_selects)
|
||||
for sql in task_selects:
|
||||
self.assertNotIn("request_payload", sql)
|
||||
# 仅允许从 JSON 中提取 feature 做「全能创作」分类,不能把整份 Prompt/响应/报错读进列表页。
|
||||
self.assertNotIn("response_payload", sql)
|
||||
self.assertNotIn("error_message", sql)
|
||||
self.assertNotIn("x" * 100_000, str(response.data))
|
||||
|
||||
detail = self.ac.get(f"/api/admin/tasks/{self.t_ok.id}/")
|
||||
self.assertEqual(detail.status_code, 200)
|
||||
@@ -420,6 +421,26 @@ class AdminTaskMonitorTests(TestCase):
|
||||
self.assertIn(str(self.t_anom.id), ids)
|
||||
self.assertNotIn(str(self.t_ok.id), ids)
|
||||
|
||||
def test_omni_create_tasks_have_separate_category_and_filter(self):
|
||||
task = self.AITask.objects.create(
|
||||
team=self.team,
|
||||
model_config=self.mc,
|
||||
task_type=self.AITask.Type.FREE_VIDEO,
|
||||
status=self.AITask.Status.SUCCEEDED,
|
||||
estimated_cost="1.0",
|
||||
actual_cost="1.0",
|
||||
idempotency_key="k-omni-create",
|
||||
request_payload={"feature": "omni_create", "prompt": "完整出片指令"},
|
||||
)
|
||||
|
||||
all_rows = self.ac.get("/api/admin/tasks/").data["results"]
|
||||
row = next(item for item in all_rows if item["id"] == str(task.id))
|
||||
self.assertEqual(row["task_type"], "free_video")
|
||||
self.assertEqual(row["task_category"], "omni_create")
|
||||
|
||||
category_rows = self.ac.get("/api/admin/tasks/?category=omni_create").data["results"]
|
||||
self.assertEqual([item["id"] for item in category_rows], [str(task.id)])
|
||||
|
||||
def test_cost_anomaly_flag(self):
|
||||
self.assertTrue(self.ac.get(f"/api/admin/tasks/{self.t_anom.id}/").data["cost_anomaly"])
|
||||
self.assertFalse(self.ac.get(f"/api/admin/tasks/{self.t_ok.id}/").data["cost_anomaly"])
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import logging
|
||||
from decimal import Decimal, ROUND_HALF_UP
|
||||
|
||||
from django.db.models import Count, F, Q
|
||||
from django.db.models import Case, CharField, Count, F, Q, Value, When
|
||||
from rest_framework import status
|
||||
from rest_framework.authtoken.models import Token
|
||||
from rest_framework.decorators import api_view, permission_classes
|
||||
@@ -469,6 +469,14 @@ def admin_tasks(request):
|
||||
qs = (
|
||||
AITask.objects.select_related("team", "model_config")
|
||||
.defer("request_payload", "response_payload", "error_message")
|
||||
# task_type 仍用于调度;用请求来源区分「全能创作」和自由视频/图片,不读取整份 Prompt。
|
||||
.annotate(
|
||||
task_category=Case(
|
||||
When(request_payload__feature="omni_create", then=Value("omni_create")),
|
||||
default=Value("standard"),
|
||||
output_field=CharField(),
|
||||
)
|
||||
)
|
||||
.order_by("-created_at")
|
||||
)
|
||||
st = request.query_params.get("status")
|
||||
@@ -479,6 +487,9 @@ def admin_tasks(request):
|
||||
tt = request.query_params.get("task_type")
|
||||
if tt in dict(AITask.Type.choices):
|
||||
qs = qs.filter(task_type=tt)
|
||||
category = request.query_params.get("category")
|
||||
if category == "omni_create":
|
||||
qs = qs.filter(request_payload__feature="omni_create")
|
||||
team_id = request.query_params.get("team")
|
||||
if team_id:
|
||||
qs = qs.filter(team_id=team_id)
|
||||
|
||||
Reference in New Issue
Block a user