counts_views.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. from django.core.paginator import Paginator
  2. import time
  3. import datetime
  4. from operator import itemgetter
  5. from django.db.models import Q, Sum, Count
  6. from django.conf import settings
  7. from rest_framework.views import APIView
  8. from rest_framework.response import Response
  9. from smartfarming.models.ascend import MongoBase, MongoLandInfo, MongoPlantInfo, MongoAreaJob, LandPlanInfo, CountryModel, PlanWeekend
  10. from smartfarming.models.user import DeviceUser
  11. from smartfarming.models.device import MongoDevice
  12. from smartfarming.models.worm_forecast import MongoCBDphoto
  13. from smartfarming.serializers.ascend_serializers import LandPlanInfoSerializers
  14. from smartfarming.utils import get_recent_month
  15. from smartfarming.api.views.forecast.all_dict import insect_dict
  16. class LandPlanInfoAPIView(APIView):
  17. def post(self, request):
  18. # 种植采收列表及统计信息
  19. request_data = request.data
  20. plan = request_data.get("plan")
  21. year = request_data.get("year")
  22. page_num = int(request_data.get("pagenum")) if request_data.get("pagenum") else 1
  23. page_size = int(request_data.get("pagesize")) if request_data.get("pagesize") else 10
  24. start_timestamp, end_timestatmp = 0, 0
  25. if year:
  26. start_timestamp = datetime.datetime(int(year), 1,1,0,0).timestamp()
  27. end_timestatmp = datetime.datetime(int(year), 12,31,23,59).timestamp()
  28. plan_ids_head = []
  29. if plan :
  30. plan_ids_head = MongoPlantInfo.objects.filter(plantname__icontains=plan).values_list("id", flat=True)
  31. if plan_ids_head and year:
  32. queryset = LandPlanInfo.objects.filter(Q(plan_id__in = plan_ids_head) & Q(addtime__gte=start_timestamp, addtime__lte=end_timestatmp)).exclude(recovery_time=0).filter(is_delete=1).order_by("-addtime")
  33. elif year:
  34. queryset = LandPlanInfo.objects.filter(addtime__gte=start_timestamp, addtime__lte=end_timestatmp).filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
  35. elif plan_ids_head:
  36. queryset = LandPlanInfo.objects.filter(plan_id__in = plan_ids_head).filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
  37. else:
  38. queryset = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).order_by("-addtime")
  39. total_obj = queryset.count()
  40. paginator = Paginator(queryset, page_size)
  41. page_obj = paginator.get_page(page_num)
  42. serializers = LandPlanInfoSerializers(page_obj, many=True)
  43. # 折线图
  44. year_value = LandPlanInfo.objects.all().exclude(recovery_time=0).values_list("addtime", flat=True).order_by("-addtime")
  45. years = []
  46. for year in year_value:
  47. y = datetime.datetime.fromtimestamp(year).year
  48. if y not in years:
  49. years.append(y)
  50. years.reverse()
  51. # 获取最近5年的作物ID
  52. end = datetime.datetime(int(years[-1]) -5, 12,31,23,59).timestamp()
  53. start = datetime.datetime(int(years[-1]), 12,31,23,59).timestamp()
  54. plan_ids = LandPlanInfo.objects.filter(addtime__gte=end, addtime__lte=start).exclude(recovery_time=0).distinct().values_list("plan_id", flat=True).order_by("plan_id")
  55. counts = []
  56. # 组织具体数据
  57. for i in years:
  58. start_timestamp = datetime.datetime(i, 1,1,0,0).timestamp()
  59. end_timestatmp = datetime.datetime(i, 12,31,23,59).timestamp()
  60. plan_totals = LandPlanInfo.objects.filter(
  61. addtime__gte=start_timestamp,
  62. addtime__lte=end_timestatmp).exclude(recovery_time=0).values("plan_id").annotate(total=Sum("recovery_kg")).order_by("plan_id").values_list("plan_id", "total")
  63. inners = {}
  64. for k in plan_totals:
  65. inners[str(k[0])] = k[1]
  66. pid =[]
  67. for j in plan_ids:
  68. pid.append(inners.get(str(j), 0))
  69. counts.append(pid)
  70. transpose_matrix = [[row[i] for row in counts] for i in range(len(counts[0]))]
  71. plannames = []
  72. # 组织农作物
  73. for p in plan_ids:
  74. plan_obj = MongoPlantInfo.objects.filter(id=p)
  75. if plan_obj:
  76. planname = plan_obj.first().plantname +"-"+ plan_obj.first().planttype
  77. else:
  78. planname = ""
  79. plannames.append(planname)
  80. return Response({
  81. "code": 0,
  82. "msg": "success",
  83. "data": serializers.data,
  84. "count": total_obj,
  85. "charts": {
  86. "years": years,
  87. "data": transpose_matrix,
  88. "plan": plannames
  89. }
  90. })
  91. class PlanNameAPIView(APIView):
  92. def post(self, request):
  93. try:
  94. # 作物名字
  95. plan_ids = LandPlanInfo.objects.filter(is_delete=1).exclude(recovery_time=0).values_list("plan_id", flat=True).order_by("-addtime")
  96. plans = MongoPlantInfo.objects.filter(is_delete=1, id__in=plan_ids).values_list("plantname", flat=True).distinct()
  97. return Response({"code": 0, "msg": "success", "data": plans})
  98. except Exception as e:
  99. return Response({"code": 0, "msg": "success", "data": []})
  100. class PlanAreaAPIView(APIView):
  101. def post(self, request):
  102. # 种植面积与作物个数统计
  103. land_plan_ids = LandPlanInfo.objects.filter(status="采收").filter(recovery_kg=0).values("land_id", "plan_id")
  104. plan_land = []
  105. plans = []
  106. plan_area = 0
  107. for i in land_plan_ids:
  108. landarea = MongoLandInfo.objects.get(id=i.get("land_id")).landarea
  109. plant = MongoPlantInfo.objects.get(id=i.get("plan_id"))
  110. plantname = f"{plant.plantname}({plant.planttype})"
  111. plan_land.append(
  112. {
  113. "name": plantname,
  114. "value": round(float(landarea), 2)
  115. }
  116. )
  117. plans.append(plantname) if plantname not in plans else None
  118. plan_area += round(float(landarea), 2)
  119. return Response({"code": 0, "msg": "success", "data": {"lands_area": round(plan_area, 2), "plans_count": len(plans), "p_list": plan_land}})
  120. class DeviceCountAPIView(APIView):
  121. def post(self, request):
  122. # 统计设备在线或离线统计
  123. device_status = MongoDevice.objects.values("device_status").annotate(total=Count("id"))
  124. online = 0
  125. offline = 0
  126. for k in device_status:
  127. if k.get("device_status") == 1:
  128. online = k.get("total")
  129. if k.get("device_status") == 0:
  130. offline = k.get("total")
  131. # 设备分类
  132. device_type = MongoDevice.objects.values("device_type_id").annotate(total=Count("id"))
  133. config_dict = settings.CONFIG.get("device_type_zh")
  134. device_type = {config_dict.get(str(result["device_type_id"])): result["total"] for result in device_type}
  135. return Response({
  136. "code": 0,
  137. "msg": "success",
  138. "data": {
  139. "device_status": {"online": online, "offline": offline},
  140. "device_category": device_type
  141. }
  142. })
  143. class RecentPestCountAPIView(APIView):
  144. def post(self, request):
  145. # 统计最近一个月的害虫排名
  146. start = get_recent_month(1)
  147. data = MongoCBDphoto.objects.filter(uptime__gte=start).values_list("indentify_result", flat=True)
  148. try:
  149. pest_count = {}
  150. for i in data:
  151. tp_lst = i.split("#")
  152. for k in tp_lst:
  153. pest = k.split(",")
  154. p_0 = pest[0]
  155. p_1 = pest[1]
  156. p_name = insect_dict.get(p_0)
  157. if p_name not in pest_count.keys():
  158. pest_count[p_name] = int(p_1)
  159. else:
  160. pest_count[p_name] += int(p_1)
  161. result = sorted(pest_count.items(), key=itemgetter(1), reverse=False)
  162. result = {m[0]:m[1] for m in result[-10:]}
  163. return Response({"code": 0, "msg": "success", "data": result})
  164. except Exception as e:
  165. return Response({"code": 2, "msg": "数据有误,请核查"})