This commit is contained in:
jeremygan2021
2026-02-02 14:07:47 +08:00
parent 5ada8c16e8
commit 6af90017d5
12 changed files with 388 additions and 46 deletions

View File

@@ -1,7 +1,7 @@
from django.contrib import admin
from django.utils.html import format_html
from django.db.models import Sum
from .models import ESP32Config, Order, Salesperson, WeChatPayConfig, Service, ARService
from .models import ESP32Config, Order, Salesperson, WeChatPayConfig, Service, ARService, ProductFeature
import qrcode
from io import BytesIO
import base64
@@ -11,6 +11,11 @@ admin.site.site_header = "量迹AI硬件销售管理后台"
admin.site.site_title = "量迹AI后台"
admin.site.index_title = "欢迎使用量迹AI管理系统"
class ProductFeatureInline(admin.TabularInline):
model = ProductFeature
extra = 1
fields = ('title', 'description', 'icon_name', 'icon_image', 'icon_url', 'order')
@admin.register(WeChatPayConfig)
class WeChatPayConfigAdmin(admin.ModelAdmin):
list_display = ('app_id', 'mch_id', 'is_active', 'notify_url')
@@ -33,6 +38,7 @@ class ESP32ConfigAdmin(admin.ModelAdmin):
list_display = ('name', 'chip_type', 'price', 'has_camera', 'has_microphone')
list_filter = ('chip_type', 'has_camera')
search_fields = ('name', 'description')
inlines = [ProductFeatureInline]
fieldsets = (
('基本信息', {
'fields': ('name', 'price', 'description')

View File

@@ -0,0 +1,32 @@
# Generated by Django 6.0.1 on 2026-02-02 06:04
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0006_arservice_esp32config_detail_image_and_more'),
]
operations = [
migrations.CreateModel(
name='ProductFeature',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=50, verbose_name='特性标题')),
('description', models.TextField(verbose_name='特性描述')),
('icon_name', models.CharField(blank=True, help_text='例如: SafetyCertificate, Eye, Thunderbolt', max_length=50, null=True, verbose_name='Antd图标名称')),
('icon_image', models.ImageField(blank=True, null=True, upload_to='products/features/', verbose_name='特性图标 (上传)')),
('icon_url', models.URLField(blank=True, null=True, verbose_name='特性图标 (URL)')),
('order', models.IntegerField(default=0, help_text='数字越小越靠前', verbose_name='排序权重')),
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='features', to='shop.esp32config', verbose_name='所属产品')),
],
options={
'verbose_name': '产品特性',
'verbose_name_plural': '产品特性',
'ordering': ['order'],
},
),
]

View File

@@ -28,6 +28,27 @@ class ESP32Config(models.Model):
verbose_name_plural = "硬件配置 (小智参数)"
class ProductFeature(models.Model):
"""
产品特性模型 (关联到具体硬件配置)
"""
product = models.ForeignKey(ESP32Config, on_delete=models.CASCADE, related_name='features', verbose_name="所属产品")
title = models.CharField(max_length=50, verbose_name="特性标题")
description = models.TextField(verbose_name="特性描述")
icon_name = models.CharField(max_length=50, blank=True, null=True, verbose_name="Antd图标名称", help_text="例如: SafetyCertificate, Eye, Thunderbolt")
icon_image = models.ImageField(upload_to='products/features/', blank=True, null=True, verbose_name="特性图标 (上传)")
icon_url = models.URLField(blank=True, null=True, verbose_name="特性图标 (URL)")
order = models.IntegerField(default=0, verbose_name="排序权重", help_text="数字越小越靠前")
def __str__(self):
return f"{self.product.name} - {self.title}"
class Meta:
verbose_name = "产品特性"
verbose_name_plural = "产品特性"
ordering = ['order']
class Salesperson(models.Model):
"""
销售人员模型

View File

@@ -1,5 +1,22 @@
from rest_framework import serializers
from .models import ESP32Config, Order, Salesperson, Service, ARService
from .models import ESP32Config, Order, Salesperson, Service, ARService, ProductFeature
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):
"""
@@ -54,6 +71,7 @@ class ESP32ConfigSerializer(serializers.ModelSerializer):
ESP32配置序列化器
"""
display_detail_image = serializers.SerializerMethodField()
features = ProductFeatureSerializer(many=True, read_only=True)
class Meta:
model = ESP32Config