from rest_framework import serializers from .models import IAMUser, VolcAccount, GlobalConfig, AlertRecord, SpendingRecord, QuotaAllocation class VolcAccountSerializer(serializers.ModelSerializer): class Meta: model = VolcAccount fields = ['id', 'name', 'access_key_hint', 'is_active', 'created_at', 'updated_at'] read_only_fields = ['access_key_hint', 'created_at', 'updated_at'] class VolcAccountCreateSerializer(serializers.Serializer): name = serializers.CharField(max_length=100, default='默认主账号') access_key = serializers.CharField(write_only=True) secret_key = serializers.CharField(write_only=True) class IAMUserSerializer(serializers.ModelSerializer): remaining_quota = serializers.DecimalField(max_digits=12, decimal_places=2, read_only=True) usage_percent = serializers.FloatField(read_only=True) effective_alert_thresholds = serializers.SerializerMethodField() class Meta: model = IAMUser fields = [ 'id', 'username', 'display_name', 'user_id', 'email', 'phone', 'project_name', 'status', 'access_key_ids', 'allocated_quota', 'consumed_total', 'remaining_quota', 'usage_percent', 'spending_updated_at', 'monitor_enabled', 'auto_disable_enabled', 'alert_thresholds', 'triggered_alerts', 'effective_alert_thresholds', 'remark', 'created_at', 'updated_at', ] read_only_fields = ['user_id', 'access_key_ids', 'status', 'consumed_total', 'spending_updated_at', 'triggered_alerts', 'created_at', 'updated_at'] def get_effective_alert_thresholds(self, obj): return obj.get_alert_thresholds() class IAMUserCreateSerializer(serializers.Serializer): username = serializers.CharField(max_length=200) display_name = serializers.CharField(max_length=200, required=False, default='') email = serializers.EmailField(required=False, default='') phone = serializers.CharField(max_length=20, required=False, default='') password = serializers.CharField(write_only=True, required=False, default='') project_name = serializers.CharField(max_length=200, required=False, default='') class IAMUserImportSerializer(serializers.Serializer): username = serializers.CharField(max_length=200, help_text='已存在的 IAM 用户名') class IAMUserConfigSerializer(serializers.Serializer): """子账号配置更新""" project_name = serializers.CharField(max_length=200, required=False, allow_blank=True) alert_thresholds = serializers.ListField( child=serializers.IntegerField(min_value=1, max_value=99), required=False, ) monitor_enabled = serializers.BooleanField(required=False) auto_disable_enabled = serializers.BooleanField(required=False) class QuotaAllocateSerializer(serializers.Serializer): """额度变更:正数=追加,负数=扣减""" amount = serializers.DecimalField(max_digits=12, decimal_places=2) note = serializers.CharField(max_length=500, required=False, default='') def validate_amount(self, value): from decimal import Decimal if value == Decimal('0'): raise serializers.ValidationError('变更金额不能为 0') return value class QuotaAllocationSerializer(serializers.ModelSerializer): class Meta: model = QuotaAllocation fields = ['id', 'amount', 'total_after', 'note', 'created_by', 'created_at'] class GlobalConfigSerializer(serializers.ModelSerializer): class Meta: model = GlobalConfig fields = [ 'default_alert_thresholds', 'monitor_interval_seconds', 'feishu_webhook_url', 'feishu_alert_mobiles', 'updated_at', ] read_only_fields = ['updated_at'] class AlertRecordSerializer(serializers.ModelSerializer): iam_username = serializers.CharField(source='iam_user.username', default='') class Meta: model = AlertRecord fields = [ 'id', 'iam_user', 'iam_username', 'alert_type', 'title', 'content', 'spending_amount', 'threshold_amount', 'notified', 'created_at', ] class SpendingRecordSerializer(serializers.ModelSerializer): iam_username = serializers.CharField(source='iam_user.username') class Meta: model = SpendingRecord fields = ['id', 'iam_user', 'iam_username', 'bill_period', 'amount', 'updated_at'] class DashboardSerializer(serializers.Serializer): total_users = serializers.IntegerField() active_users = serializers.IntegerField() disabled_users = serializers.IntegerField() monitored_users = serializers.IntegerField() total_spending = serializers.DecimalField(max_digits=12, decimal_places=2) recent_alerts = AlertRecordSerializer(many=True)