2026-07-03 09:34:07 +08:00
|
|
|
from decimal import Decimal
|
|
|
|
|
|
2026-07-03 10:34:37 +08:00
|
|
|
from django.conf import settings
|
2026-07-02 22:41:37 +08:00
|
|
|
from rest_framework import serializers
|
|
|
|
|
|
2026-07-03 09:34:07 +08:00
|
|
|
from apps.billing.models import RechargeOrder
|
|
|
|
|
|
2026-07-02 22:41:37 +08:00
|
|
|
|
|
|
|
|
class GenerateTitleRequestSerializer(serializers.Serializer):
|
|
|
|
|
prompt = serializers.CharField(trim_whitespace=True, allow_blank=False)
|
|
|
|
|
model = serializers.CharField(
|
|
|
|
|
required=False,
|
|
|
|
|
allow_blank=True,
|
|
|
|
|
trim_whitespace=True,
|
|
|
|
|
max_length=64,
|
|
|
|
|
)
|
|
|
|
|
image_url = serializers.URLField(required=False, allow_blank=True)
|
|
|
|
|
image_base64 = serializers.CharField(required=False, allow_blank=True)
|
|
|
|
|
resolution = serializers.CharField(
|
|
|
|
|
required=False,
|
|
|
|
|
allow_blank=True,
|
|
|
|
|
trim_whitespace=True,
|
|
|
|
|
default="1K",
|
|
|
|
|
)
|
|
|
|
|
parameters = serializers.DictField(required=False, default=dict)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class GenerateImageRequestSerializer(serializers.Serializer):
|
|
|
|
|
prompt = serializers.CharField(trim_whitespace=True, allow_blank=False)
|
|
|
|
|
model = serializers.CharField(
|
|
|
|
|
required=False,
|
|
|
|
|
allow_blank=True,
|
|
|
|
|
trim_whitespace=True,
|
|
|
|
|
max_length=64,
|
|
|
|
|
)
|
|
|
|
|
image_url = serializers.URLField(required=False, allow_blank=True)
|
|
|
|
|
image_base64 = serializers.CharField(required=False, allow_blank=True)
|
2026-07-17 15:55:38 +08:00
|
|
|
images = serializers.ListField(required=False, write_only=True)
|
2026-07-02 22:41:37 +08:00
|
|
|
resolution = serializers.CharField(
|
|
|
|
|
required=False,
|
|
|
|
|
allow_blank=True,
|
|
|
|
|
trim_whitespace=True,
|
|
|
|
|
default="1K",
|
|
|
|
|
)
|
|
|
|
|
aspect_ratio = serializers.CharField(
|
|
|
|
|
required=False,
|
|
|
|
|
allow_blank=True,
|
|
|
|
|
trim_whitespace=True,
|
|
|
|
|
default="1:1",
|
|
|
|
|
)
|
|
|
|
|
parameters = serializers.DictField(required=False, default=dict)
|
2026-07-03 09:34:07 +08:00
|
|
|
|
2026-07-17 15:55:38 +08:00
|
|
|
def validate_images(self, value):
|
|
|
|
|
if not value:
|
|
|
|
|
raise serializers.ValidationError("images 至少需要一张图片。")
|
|
|
|
|
max_images = max(1, int(settings.IMAGE_MAX_INPUT_IMAGES))
|
|
|
|
|
if len(value) > max_images:
|
|
|
|
|
raise serializers.ValidationError(f"单次最多上传 {max_images} 张图片。")
|
2026-07-03 09:34:07 +08:00
|
|
|
|
2026-07-17 15:55:38 +08:00
|
|
|
serializer = ImageInputSerializer(data=value, many=True)
|
|
|
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
|
return serializer.validated_data
|
|
|
|
|
|
|
|
|
|
def validate(self, attrs):
|
|
|
|
|
has_legacy_image = bool(str(attrs.get("image_url") or "").strip()) or bool(
|
|
|
|
|
str(attrs.get("image_base64") or "").strip()
|
|
|
|
|
)
|
|
|
|
|
if attrs.get("images") is not None and has_legacy_image:
|
|
|
|
|
raise serializers.ValidationError(
|
|
|
|
|
"images 不能与 image_url 或 image_base64 同时提供。"
|
|
|
|
|
)
|
|
|
|
|
return attrs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ImageInputSerializer(serializers.Serializer):
|
2026-07-16 14:13:19 +08:00
|
|
|
image_url = serializers.URLField(required=False, allow_blank=True)
|
|
|
|
|
image_base64 = serializers.CharField(required=False, allow_blank=True)
|
|
|
|
|
|
|
|
|
|
def validate(self, attrs):
|
|
|
|
|
has_url = bool(str(attrs.get("image_url") or "").strip())
|
|
|
|
|
has_base64 = bool(str(attrs.get("image_base64") or "").strip())
|
|
|
|
|
if has_url == has_base64:
|
|
|
|
|
raise serializers.ValidationError(
|
|
|
|
|
"每张图片必须且只能提供 image_url 或 image_base64。"
|
|
|
|
|
)
|
|
|
|
|
return attrs
|
|
|
|
|
|
|
|
|
|
|
2026-07-17 15:55:38 +08:00
|
|
|
class VisionImageInputSerializer(ImageInputSerializer):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
2026-07-16 14:13:19 +08:00
|
|
|
class AnalyzeImagesRequestSerializer(serializers.Serializer):
|
|
|
|
|
prompt = serializers.CharField(trim_whitespace=True, allow_blank=False)
|
|
|
|
|
model = serializers.CharField(
|
|
|
|
|
required=False,
|
|
|
|
|
allow_blank=True,
|
|
|
|
|
trim_whitespace=True,
|
|
|
|
|
max_length=64,
|
|
|
|
|
)
|
|
|
|
|
images = VisionImageInputSerializer(many=True, allow_empty=False)
|
|
|
|
|
parameters = serializers.DictField(required=False, default=dict)
|
|
|
|
|
|
|
|
|
|
def validate_images(self, value):
|
|
|
|
|
max_images = max(1, int(settings.VISION_MAX_IMAGES))
|
|
|
|
|
if len(value) > max_images:
|
|
|
|
|
raise serializers.ValidationError(f"单次最多上传 {max_images} 张图片。")
|
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
|
|
2026-07-03 09:34:07 +08:00
|
|
|
class RechargeCreateRequestSerializer(serializers.Serializer):
|
|
|
|
|
amount = serializers.DecimalField(
|
|
|
|
|
max_digits=12,
|
|
|
|
|
decimal_places=2,
|
|
|
|
|
min_value=Decimal("0.01"),
|
|
|
|
|
)
|
|
|
|
|
pay_method = serializers.ChoiceField(choices=RechargeOrder.PayMethod.values)
|
|
|
|
|
|
2026-07-03 10:34:37 +08:00
|
|
|
def validate_amount(self, value):
|
|
|
|
|
max_amount = Decimal(str(settings.RECHARGE_MAX_AMOUNT_CNY))
|
|
|
|
|
if value > max_amount:
|
|
|
|
|
raise serializers.ValidationError(f"单笔充值金额不能超过 {max_amount:.2f} CNY")
|
|
|
|
|
return value
|
|
|
|
|
|
2026-07-03 09:34:07 +08:00
|
|
|
|
|
|
|
|
class RechargeStatusRequestSerializer(serializers.Serializer):
|
|
|
|
|
order_no = serializers.CharField(
|
|
|
|
|
trim_whitespace=True,
|
|
|
|
|
allow_blank=False,
|
|
|
|
|
max_length=64,
|
|
|
|
|
)
|