feat(admin): Phase 8 模型供应商管理 — provider/model CRUD + 启停 + 定价 + 设默认
后端:ModelConfig.is_default + migration;get_default_model 优先 is_default 否则回落最早 active(零回归); adminpanel providers CRUD(api_key write-only 不回传)+ models CRUD(?provider/capability 筛)+ set-default(同 capability 清旧); IsPlatformAdmin + 审计。 前端:adminApi providers/models/setDefault;Admin 模型供应商页(供应商表+模型表+启停+定价+设默认+供应商/模型弹窗)。 测试:adminpanel 51 单测过(api_key 隐藏+入库/CRUD/set-default 改 get_default_model); apps.ai 仍仅 3 个进场前既有失败(零回归);无头 e2e _admin-p8.mjs 5 断言过 + 0 console error (用一次性禁用 provider+model capability=export,无副作用,跑完删);tsc+build 绿。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
39b4467258
commit
4ce7e957d2
@@ -3,7 +3,7 @@ from decimal import Decimal
|
||||
from rest_framework import serializers
|
||||
|
||||
from apps.accounts.models import Team, TeamMember, User
|
||||
from apps.ai.models import AITask, QualityWord
|
||||
from apps.ai.models import AITask, ModelConfig, ModelProvider, QualityWord
|
||||
from apps.assets.models import Asset
|
||||
from apps.billing.models import CreditLedger, QuotaPolicy
|
||||
|
||||
@@ -133,3 +133,35 @@ class AdminQuotaPolicySerializer(serializers.ModelSerializer):
|
||||
"monthly_limit", "project_limit", "per_task_limit", "is_active", "created_at",
|
||||
]
|
||||
read_only_fields = ["id", "team_name", "created_at"]
|
||||
|
||||
|
||||
class AdminModelProviderSerializer(serializers.ModelSerializer):
|
||||
has_api_key = serializers.SerializerMethodField()
|
||||
model_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = ModelProvider
|
||||
fields = ["id", "name", "display_name", "status", "base_url", "api_key", "metadata", "has_api_key", "model_count", "created_at"]
|
||||
# api_key 只写不读(密钥不回传前端)
|
||||
extra_kwargs = {"api_key": {"write_only": True, "required": False}}
|
||||
read_only_fields = ["id", "has_api_key", "model_count", "created_at"]
|
||||
|
||||
def get_has_api_key(self, obj) -> bool:
|
||||
return bool(obj.api_key)
|
||||
|
||||
def get_model_count(self, obj) -> int:
|
||||
anno = getattr(obj, "model_count_anno", None)
|
||||
return anno if anno is not None else obj.models.count()
|
||||
|
||||
|
||||
class AdminModelConfigSerializer(serializers.ModelSerializer):
|
||||
provider_name = serializers.CharField(source="provider.name", read_only=True, default=None)
|
||||
|
||||
class Meta:
|
||||
model = ModelConfig
|
||||
fields = [
|
||||
"id", "provider", "provider_name", "name", "display_name", "capability",
|
||||
"endpoint", "unit_price", "status", "is_default", "rate_limit_per_minute", "metadata", "created_at",
|
||||
]
|
||||
# is_default 只经 set-default 端点改,不在普通编辑里直接写
|
||||
read_only_fields = ["id", "provider_name", "is_default", "created_at"]
|
||||
|
||||
Reference in New Issue
Block a user