Sfoglia il codice sorgente

优化代理商绑定上架云存套餐

zhangdongming 2 mesi fa
parent
commit
c5495fa977
1 ha cambiato i file con 93 aggiunte e 15 eliminazioni
  1. 93 15
      AdminController/CloudServiceManage/AgentCustomerController.py

+ 93 - 15
AdminController/CloudServiceManage/AgentCustomerController.py

@@ -11,15 +11,16 @@ import time
 import json
 from decimal import Decimal
 
-from django.db.models import Sum
+from django.db.models import Sum, F, Q
 from django.http import QueryDict
 from django.views import View
 from django.core.paginator import Paginator
 from datetime import datetime, timedelta
+from Ansjer.config import CONFIG_CN, LOGGER, CONFIG_INFO
 
 from AgentModel.models import AgentCustomerInfo, AgentCustomerCard, AgentCustomerPackage, AgentCloudServicePackage, \
     AgentDeviceOrder, AgentAccountWithdraw, AgentDevice, AgentAccount, ApplyAgent, AgentDeviceOrderInstallment
-from Model.models import UnicomCombo, Store_Meal, Device_User
+from Model.models import UnicomCombo, Store_Meal, Device_User, CouponCombo
 
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -55,7 +56,7 @@ class AgentCustomerView(View):
         language = request_dict.get('language', 'en')
         response = ResponseObject(language, 'pc')
         if operation == 'getUnicomAndIcloud':
-            return self.get_unicom_and_icloud(response)
+            return self.get_unicom_and_icloud(request_dict, response)
         elif operation == 'applyAgent':
             return self.apply_agent(request_dict, response)
         else:
@@ -109,31 +110,108 @@ class AgentCustomerView(View):
             else:
                 return response.json(444, 'operation')
 
-    def get_unicom_and_icloud(self, response):
+    @classmethod
+    def get_unicom_and_icloud(cls, request_dict, response):
         """
         查询云存储套餐和物联网卡套餐列表
         @param response: 响应对象
-        @return:
+        @return: 包含套餐信息的响应
         """
         try:
-            # 云存储套餐查询,只包括is_show=0的记录
-            store_meals = Store_Meal.objects.filter(is_show=0).values('id', 'bucket__bucket').distinct()
+            lang = request_dict.get('lang', 'cn')
+
+            # 1. 优化查询 - 云存储套餐
+            store_meals_qs = Store_Meal.objects.filter(
+                ~Q(pay_type__in=[10, 11]),
+                lang__lang=lang,
+                is_show=0
+            ).exclude(app_type=2)
+
+            # 根据配置区分国内外套餐
+            if CONFIG_INFO == CONFIG_CN:
+                store_meals_qs = store_meals_qs.filter(is_ai=0, bucket__mold=0)
+            else:
+                store_meals_qs = store_meals_qs.filter(bucket__mold=1)
+
+            # 一次性获取所有需要的字段和关联数据
+            store_meals = store_meals_qs.annotate(
+                title=F('lang__title'),
+                content=F('lang__content'),
+                new_title=F('lang__new_title'),
+                discount_content=F('lang__discount_content'),
+                store_day=F('bucket__storeDay'),
+                bucket_name=F('bucket__bucket'),
+                bucket_area=F('bucket__area')
+            ).order_by('-pixel_level', '-is_ai').values(
+                "id", "title", "content", "price", "day", "currency", "store_day",
+                "new_title", "bucket_name", "bucket_area", "commodity_code", "commodity_type",
+                "is_discounts", "virtual_price", "expire", "discount_price",
+                "discount_content", "symbol", "cycle_config_id",
+                'pixel_level', 'is_ai', 'app_type'
+            )
 
-            # 联通套餐查询,只包括is_show=1且未被删除的记录
-            unicom_combos = UnicomCombo.objects.filter(is_show=1, is_del=False).values('id', 'combo_name').distinct()
+            # 2. 批量处理优惠券信息 - 避免N+1查询
+            ios_meal_ids = [meal['id'] for meal in store_meals if meal.get('app_type') == 1]
+            coupon_map = {}
+            if ios_meal_ids:
+                coupon_combos = CouponCombo.objects.filter(
+                    combo_id__in=ios_meal_ids
+                ).values_list('combo_id', flat=True).distinct()
+                coupon_map = {combo_id: True for combo_id in coupon_combos}
+
+            # 3. 使用列表推导式构建套餐列表
+            store_meal_list = []
+            for meal in store_meals:
+                # 构建基础名称
+                name_parts = [meal['title'],
+                              f'{meal.get("symbol")}{meal["price"]}',
+                              f"({str(meal['expire'])}month+",
+                              '≥4K' if meal.get('pixel_level') == 1 else '<4K']
+
+                # 添加AI标识
+                if meal.get('is_ai') == 1:
+                    name_parts.append('+AI')
+
+                # 处理iOS套餐
+                if meal.get('app_type') == 1:
+                    name_parts.append('+ios')
+                    # 检查优惠券 - 使用预处理的映射
+                    if meal['id'] in coupon_map:
+                        name_parts.append('+discount')
+
+                # 添加周期订阅标识
+                if meal.get('cycle_config_id', 0) == 1:
+                    name_parts.append('+cycle')
+
+                # 关闭括号并连接字符串
+                name_parts.append(')')
+
+                full_name = ''.join(name_parts)
+
+                store_meal_list.append({
+                    'id': meal['id'],
+                    'name': full_name
+                })
 
-            # 将查询结果转换为列表
-            store_meal_list = [{'id': meal['id'], 'name': meal['bucket__bucket']} for meal in store_meals]
-            unicom_combo_list = [{'id': combo['id'], 'name': combo['combo_name']} for combo in unicom_combos]
+            # 4. 物联网卡套餐查询
+            unicom_combo_list = list(
+                UnicomCombo.objects.filter(
+                    is_show=1,
+                    is_del=False
+                ).distinct().values('id', 'combo_name')
+            )
+            # 统一字段名
+            for combo in unicom_combo_list:
+                combo['name'] = combo.pop('combo_name')
 
-            # 合并结果并返回
             return response.json(0, {
                 'storeMeals': store_meal_list,
                 'unicomCombos': unicom_combo_list,
             })
+
         except Exception as e:
-            print(e)
-            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            LOGGER.error(f"get_unicom_and_icloud error: {str(e)}", exc_info=True)
+            return response.json(500, 'Server error')
 
     def get_agent_info(self, userID, response):
         """