feat(admin): Phase 4 质量词 Admin(平台单层) — QualityWord + 生成侧读配置(无配置回落) + 质量词页
后端:apps/ai QualityWord(stage/slot/text/sort/enabled)+ migration;services.py quality_words/quality_suffix, 4 个 builder 接入(person/model_tryon/storyboard/video)无配置回落原写死值零回归;adminpanel CRUD + 审计。 前端:adminApi quality 系列;Admin 质量词页(按 stage 分组卡 + 编辑模式开关 + 行内增改删 chip)。 测试:adminpanel 23 + accounts 22 = 45 单测过(CRUD/权限/生成读配置+回落/停用词不取); 无头 e2e _admin-p4.mjs 4 断言过 + 0 console error + live 库零残留;tsc+build 绿。 注:apps.ai 3 个 image_edit 路由测试失败为进场前既有(已 stash 比对 HEAD 同样失败),非本 Phase 引入。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6560633959
commit
01d4f235ed
@@ -10,9 +10,15 @@ from apps.accounts.audit import log_admin_action
|
||||
from apps.accounts.models import Invitation, Team, User
|
||||
from apps.accounts.permissions import IsPlatformAdmin
|
||||
from apps.accounts.serializers import InvitationSerializer
|
||||
from apps.ai.models import QualityWord
|
||||
from apps.common.pagination import DefaultPagination
|
||||
|
||||
from .serializers import AdminTeamMemberSerializer, AdminTeamSerializer, AdminUserSerializer
|
||||
from .serializers import (
|
||||
AdminTeamMemberSerializer,
|
||||
AdminTeamSerializer,
|
||||
AdminUserSerializer,
|
||||
QualityWordSerializer,
|
||||
)
|
||||
|
||||
|
||||
def _team_qs():
|
||||
@@ -199,3 +205,60 @@ def admin_user_reset_password(request, user_id):
|
||||
target_name=user.username,
|
||||
)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
# ─────────────────────────── 质量词(平台单层)───────────────────────────
|
||||
|
||||
|
||||
@api_view(["GET", "POST"])
|
||||
@permission_classes([IsPlatformAdmin])
|
||||
def admin_quality_words(request):
|
||||
"""GET 列全部质量词(配置量小,不分页,前端按 stage 分组);POST 新增一条。"""
|
||||
if request.method == "GET":
|
||||
qs = QualityWord.objects.all().order_by("stage", "sort", "created_at")
|
||||
return Response(QualityWordSerializer(qs, many=True).data)
|
||||
serializer = QualityWordSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
obj = serializer.save()
|
||||
log_admin_action(
|
||||
request,
|
||||
"quality_word.create",
|
||||
target_type="quality_word",
|
||||
target_id=obj.id,
|
||||
target_name=f"{obj.stage}:{obj.text}",
|
||||
after={"stage": obj.stage, "text": obj.text},
|
||||
)
|
||||
return Response(QualityWordSerializer(obj).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
|
||||
@api_view(["PATCH", "DELETE"])
|
||||
@permission_classes([IsPlatformAdmin])
|
||||
def admin_quality_word_detail(request, word_id):
|
||||
obj = QualityWord.objects.filter(id=word_id).first()
|
||||
if obj is None:
|
||||
return Response({"detail": "not found"}, status=status.HTTP_404_NOT_FOUND)
|
||||
if request.method == "DELETE":
|
||||
log_admin_action(
|
||||
request,
|
||||
"quality_word.delete",
|
||||
target_type="quality_word",
|
||||
target_id=obj.id,
|
||||
target_name=f"{obj.stage}:{obj.text}",
|
||||
before={"stage": obj.stage, "text": obj.text},
|
||||
)
|
||||
obj.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
before_text = obj.text
|
||||
serializer = QualityWordSerializer(obj, data=request.data, partial=True)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
log_admin_action(
|
||||
request,
|
||||
"quality_word.update",
|
||||
target_type="quality_word",
|
||||
target_id=obj.id,
|
||||
target_name=f"{obj.stage}:{obj.text}",
|
||||
before={"text": before_text},
|
||||
after={"text": obj.text},
|
||||
)
|
||||
return Response(QualityWordSerializer(obj).data)
|
||||
|
||||
Reference in New Issue
Block a user