mat/backend/apps/statistics/views.py

164 lines
5.4 KiB
Python

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from django.db.models import Count, Q
from apps.material.models import Material
from apps.factory.models import Factory
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def overview_statistics(request):
"""
数据总览统计
"""
# 只有管理员可以访问
if request.user.role != 'admin':
return Response({"detail": "无权访问"}, status=403)
# 材料总数
total_materials = Material.objects.count()
# 材料种类(材料子类数量)
total_material_categories = Material.objects.values('material_subcategory').distinct().count()
# 品牌数(工厂数)
total_brands = Factory.objects.count()
# 按专业类别的材料数量分布
major_category_stats = Material.objects.values('major_category').annotate(
count=Count('id')
).order_by('-count')
# 按材料子类的材料数量分布
material_subcategory_stats = Material.objects.values('material_subcategory').annotate(
count=Count('id')
).order_by('-count')[:10] # 取前10个
# 按所属品牌的材料数量分布
brand_stats = Material.objects.values('factory__factory_name').annotate(
count=Count('id')
).order_by('-count')
# 按地区的工厂数量分布
region_stats = Factory.objects.values('province', 'city').annotate(
count=Count('id')
).order_by('-count')
# 应用案例列表(有案例描述的材料)
cases_list = Material.objects.filter(
status='approved',
cases__isnull=False,
cases__gt=''
).values('id', 'name', 'cases', 'factory__factory_name')[:10]
return Response({
'total_materials': total_materials,
'total_material_categories': total_material_categories,
'total_brands': total_brands,
'major_category_stats': list(major_category_stats),
'material_subcategory_stats': list(material_subcategory_stats),
'brand_stats': list(brand_stats),
'region_stats': list(region_stats),
'cases_list': list(cases_list),
})
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def material_statistics(request):
"""
材料库统计
"""
# 只有管理员可以访问
if request.user.role != 'admin':
return Response({"detail": "无权访问"}, status=403)
# 获取筛选条件
material_subcategory = request.query_params.get('material_subcategory')
# 基础查询
queryset = Material.objects.filter(status='approved')
# 按材料子类筛选
if material_subcategory:
queryset = queryset.filter(material_subcategory=material_subcategory)
# 材料星级对比(按材料子类)
star_stats = {}
for subcategory in queryset.values_list('material_subcategory', flat=True).distinct():
materials = queryset.filter(material_subcategory=subcategory)
star_stats[subcategory] = {
'quality_level': list(materials.values('quality_level').annotate(count=Count('id'))),
'durability_level': list(materials.values('durability_level').annotate(count=Count('id'))),
'eco_level': list(materials.values('eco_level').annotate(count=Count('id'))),
'carbon_level': list(materials.values('carbon_level').annotate(count=Count('id'))),
'score_level': list(materials.values('score_level').annotate(count=Count('id'))),
}
# 竞争优势与替代材料对比
advantage_replace_stats = list(queryset.values('advantage', 'replace_type').annotate(
count=Count('id')
))
# 应用场景对比
application_scene_stats = list(queryset.values('application_scene').annotate(
count=Count('id')
))
# 材料列表
materials_list = list(queryset.values(
'id', 'name', 'material_category', 'material_subcategory',
'factory__factory_name', 'brochure'
)[:20])
return Response({
'star_stats': star_stats,
'advantage_replace_stats': advantage_replace_stats,
'application_scene_stats': application_scene_stats,
'materials_list': materials_list,
})
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def factory_statistics(request):
"""
工厂库统计
"""
# 只有管理员可以访问
if request.user.role != 'admin':
return Response({"detail": "无权访问"}, status=403)
# 工厂地区分布
region_stats = list(Factory.objects.values('province', 'city').annotate(
count=Count('id')
).order_by('-count'))
# 工厂材料分类分布
factory_category_stats = []
for factory in Factory.objects.all():
material_categories = Material.objects.filter(factory=factory).values(
'material_category'
).annotate(
count=Count('id')
)
factory_category_stats.append({
'factory_id': factory.id,
'factory_name': factory.factory_name,
'categories': list(material_categories),
'total_materials': factory.materials.count()
})
# 工厂列表
factories_list = list(Factory.objects.values(
'id', 'factory_name', 'factory_short_name', 'province', 'city', 'website'
))
return Response({
'region_stats': region_stats,
'factory_category_stats': factory_category_stats,
'factories_list': factories_list,
})