191 lines
6.8 KiB
Python
191 lines
6.8 KiB
Python
from rest_framework import serializers
|
||
from .models import ESP32Config, Order, Salesperson, Service, ARService, ProductFeature, ServiceOrder, WeChatUser, Distributor, Withdrawal
|
||
|
||
class WeChatUserSerializer(serializers.ModelSerializer):
|
||
class Meta:
|
||
model = WeChatUser
|
||
fields = ['id', 'nickname', 'avatar_url', 'gender', 'country', 'province', 'city']
|
||
read_only_fields = ['id']
|
||
|
||
class DistributorSerializer(serializers.ModelSerializer):
|
||
user_info = WeChatUserSerializer(source='user', read_only=True)
|
||
|
||
class Meta:
|
||
model = Distributor
|
||
fields = ['id', 'user_info', 'level', 'commission_rate', 'total_earnings', 'withdrawable_balance', 'status', 'invite_code', 'qr_code_url']
|
||
read_only_fields = ['level', 'commission_rate', 'total_earnings', 'withdrawable_balance', 'status', 'invite_code', 'qr_code_url']
|
||
|
||
class WithdrawalSerializer(serializers.ModelSerializer):
|
||
class Meta:
|
||
model = Withdrawal
|
||
fields = ['id', 'amount', 'status', 'remark', 'created_at']
|
||
read_only_fields = ['status', 'created_at', 'remark']
|
||
|
||
class ProductFeatureSerializer(serializers.ModelSerializer):
|
||
"""
|
||
产品特性序列化器
|
||
"""
|
||
display_icon = serializers.SerializerMethodField()
|
||
|
||
class Meta:
|
||
model = ProductFeature
|
||
fields = ['title', 'description', 'icon_name', 'display_icon', 'order']
|
||
|
||
def get_display_icon(self, obj):
|
||
if obj.icon_url:
|
||
return obj.icon_url
|
||
if obj.icon_image:
|
||
return obj.icon_image.url
|
||
return None
|
||
|
||
class ServiceSerializer(serializers.ModelSerializer):
|
||
"""
|
||
AI服务序列化器
|
||
"""
|
||
features_list = serializers.SerializerMethodField()
|
||
display_icon = serializers.SerializerMethodField()
|
||
display_detail_image = serializers.SerializerMethodField()
|
||
|
||
class Meta:
|
||
model = Service
|
||
fields = '__all__'
|
||
|
||
def get_features_list(self, obj):
|
||
if obj.features:
|
||
return [line.strip() for line in obj.features.split('\n') if line.strip()]
|
||
return []
|
||
|
||
def get_display_icon(self, obj):
|
||
if obj.icon_url:
|
||
return obj.icon_url
|
||
if obj.icon:
|
||
return obj.icon.url
|
||
return None
|
||
|
||
def get_display_detail_image(self, obj):
|
||
if obj.detail_image_url:
|
||
return obj.detail_image_url
|
||
if obj.detail_image:
|
||
return obj.detail_image.url
|
||
return None
|
||
|
||
class ServiceOrderSerializer(serializers.ModelSerializer):
|
||
"""
|
||
AI服务订单序列化器
|
||
"""
|
||
service_name = serializers.CharField(source='service.title', read_only=True)
|
||
# 接收前端传来的 ref_code
|
||
ref_code = serializers.CharField(write_only=True, required=False, allow_blank=True)
|
||
|
||
class Meta:
|
||
model = ServiceOrder
|
||
fields = ['id', 'service', 'service_name', 'customer_name', 'company_name',
|
||
'phone_number', 'email', 'requirements', 'total_price', 'status', 'created_at', 'ref_code']
|
||
read_only_fields = ['total_price', 'status', 'created_at']
|
||
|
||
def create(self, validated_data):
|
||
ref_code = validated_data.pop('ref_code', None)
|
||
service = validated_data.get('service')
|
||
|
||
# 默认设置预估总价为服务起步价
|
||
if service:
|
||
validated_data['total_price'] = service.price
|
||
|
||
# 尝试关联销售员
|
||
if ref_code:
|
||
try:
|
||
salesperson = Salesperson.objects.get(code=ref_code)
|
||
validated_data['salesperson'] = salesperson
|
||
except Salesperson.DoesNotExist:
|
||
pass
|
||
|
||
return super().create(validated_data)
|
||
|
||
class ARServiceSerializer(serializers.ModelSerializer):
|
||
"""
|
||
AR服务序列化器
|
||
"""
|
||
display_cover_image = serializers.SerializerMethodField()
|
||
|
||
class Meta:
|
||
model = ARService
|
||
fields = '__all__'
|
||
|
||
def get_display_cover_image(self, obj):
|
||
if obj.cover_image_url:
|
||
return obj.cover_image_url
|
||
if obj.cover_image:
|
||
return obj.cover_image.url
|
||
return None
|
||
|
||
class ESP32ConfigSerializer(serializers.ModelSerializer):
|
||
"""
|
||
ESP32配置序列化器
|
||
"""
|
||
display_detail_image = serializers.SerializerMethodField()
|
||
features = ProductFeatureSerializer(many=True, read_only=True)
|
||
|
||
class Meta:
|
||
model = ESP32Config
|
||
fields = '__all__'
|
||
|
||
def get_display_detail_image(self, obj):
|
||
if obj.detail_image_url:
|
||
return obj.detail_image_url
|
||
if obj.detail_image:
|
||
return obj.detail_image.url
|
||
return None
|
||
|
||
|
||
class OrderSerializer(serializers.ModelSerializer):
|
||
"""
|
||
订单序列化器
|
||
"""
|
||
config_name = serializers.CharField(source='config.name', read_only=True)
|
||
config_image = serializers.SerializerMethodField()
|
||
salesperson_name = serializers.CharField(source='salesperson.name', read_only=True)
|
||
salesperson_code = serializers.CharField(source='salesperson.code', read_only=True)
|
||
# 接收前端传来的 ref_code,用于查找 Salesperson
|
||
ref_code = serializers.CharField(write_only=True, required=False, allow_blank=True)
|
||
|
||
class Meta:
|
||
model = Order
|
||
fields = ['id', 'config', 'config_name', 'config_image', 'quantity', 'total_price', 'status', 'created_at', 'updated_at', 'wechat_trade_no',
|
||
'customer_name', 'phone_number', 'shipping_address', 'ref_code', 'salesperson_name', 'salesperson_code', 'courier_name', 'tracking_number']
|
||
read_only_fields = ['total_price', 'status', 'wechat_trade_no', 'created_at', 'updated_at']
|
||
extra_kwargs = {
|
||
'customer_name': {'required': True},
|
||
'phone_number': {'required': True},
|
||
'shipping_address': {'required': True},
|
||
}
|
||
|
||
def get_config_image(self, obj):
|
||
if obj.config.static_image_url:
|
||
return obj.config.static_image_url
|
||
if obj.config.detail_image_url:
|
||
return obj.config.detail_image_url
|
||
if obj.config.detail_image:
|
||
return obj.config.detail_image.url
|
||
return None
|
||
|
||
def create(self, validated_data):
|
||
"""
|
||
重写创建方法,自动计算总价并关联销售员
|
||
"""
|
||
config = validated_data.get('config')
|
||
quantity = validated_data.get('quantity', 1)
|
||
ref_code = validated_data.pop('ref_code', None)
|
||
|
||
validated_data['total_price'] = config.price * quantity
|
||
|
||
# 尝试关联销售员
|
||
if ref_code:
|
||
try:
|
||
salesperson = Salesperson.objects.get(code=ref_code)
|
||
validated_data['salesperson'] = salesperson
|
||
except Salesperson.DoesNotExist:
|
||
# 如果找不到对应的销售员,忽略该推广码,仍继续创建订单(算作自然流量)
|
||
pass
|
||
|
||
return super().create(validated_data)
|