瀏覽代碼

Merge branch 'test' of http://192.168.136.99:3000/servers/ASJServer into locky

locky 1 年之前
父節點
當前提交
c95c277fd6
共有 4 個文件被更改,包括 537 次插入20 次删除
  1. 18 18
      AdminController/DeviceManagementController.py
  2. 2 0
      Ansjer/urls.py
  3. 513 0
      Controller/CampaignController/CampaignController.py
  4. 4 2
      Model/models.py

+ 18 - 18
AdminController/DeviceManagementController.py

@@ -167,7 +167,7 @@ class DeviceManagement(View):
                         if device_type_qs.exists():
                             device_info_list["datas"][k]['fields']['Type'] = device_type_qs[0]['name']
                         uid_set_qs = UidSetModel.objects.filter(
-                            uid=device_info_list["datas"][k]['fields']['UID']).\
+                            uid=device_info_list["datas"][k]['fields']['UID']). \
                             values('detect_status', 'is_alexa', 'ip', 'version', 'is_ai', 'is_human', 'cloud_vod',
                                    'ucode', 'device_type')
                         if uid_set_qs.exists():
@@ -184,10 +184,8 @@ class DeviceManagement(View):
                                 cloud_vod = '不支持'
                             if uid_set_qs[0]['is_ai'] == 2:
                                 isAI = '不支持'
-                            elif uid_set_qs[0]['is_ai'] == 1:
-                                isAI = '开启'
                             else:
-                                isAI = '关闭'
+                                isAI = '支持'
                             device_info_list["datas"][k]['fields']['isHuman'] = isHuman
                             device_info_list["datas"][k]['fields']['isAI'] = isAI
                             device_info_list["datas"][k]['fields']['isAlexa'] = isAlexa
@@ -208,6 +206,16 @@ class DeviceManagement(View):
                                 device_info_list["datas"][k]['fields']['status'] = 0
                         else:
                             device_info_list["datas"][k]['fields']['status'] = 0
+                        # AI开关状态
+                        ai_service = AiService.objects.filter(uid=device_info_list["datas"][k]['fields']['UID']).values(
+                            'detect_status')
+                        if ai_service.exists():
+                            if ai_service[0]['detect_status']:
+                                device_info_list["datas"][k]['fields']['ai_status'] = 1
+                            else:
+                                device_info_list["datas"][k]['fields']['ai_status'] = 0
+                        else:
+                            device_info_list["datas"][k]['fields']['ai_status'] = 0
             return response.json(0, {'list': device_info_list, 'total': total})
         except Exception as e:
             print(e)
@@ -538,7 +546,7 @@ class DeviceManagement(View):
     @staticmethod
     def batch_edit_app_device_type(request_dict, request, response):
         # app_device_type表数据
-        app_device_type_id = request_dict.get('app_device_type__id',None)
+        app_device_type_id = request_dict.get('app_device_type__id', None)
         model = request_dict.get('model', None)
         type = request_dict.get('type', None)
         icon = request.FILES.get('icon', None)
@@ -546,10 +554,10 @@ class DeviceManagement(View):
         device_name_language_id = request_dict.get('app_device_type__devicenamelanguage__id', None)
         sort = request_dict.get('sort', None)
         version_number = request_dict.get('version_number', None)
-        if not all([app_device_type_id,device_name_language_id, model, type, sort,version_number]):
-             return response.json(444)
+        if not all([app_device_type_id, device_name_language_id, model, type, sort, version_number]):
+            return response.json(444)
 
-        #强制类型转换
+        # 强制类型转换
         list_app_device_type_id = [int(item) for item in eval(app_device_type_id)]
         list_device_name_language_id = [int(item) for item in eval(device_name_language_id)]
 
@@ -597,7 +605,7 @@ class DeviceManagement(View):
             with transaction.atomic():
                 if icon:
                     icon_path = 'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/{}'.format(icon)
-                    AppDeviceType.objects.filter(id=app_device_type_id)\
+                    AppDeviceType.objects.filter(id=app_device_type_id) \
                         .update(model=model, type=type, icon=icon_path, app_version_number_id=version_number)
                     bucket_name = 'ansjerfilemanager'
                     file_key = 'app/device_type_images/{}'.format(icon)
@@ -609,7 +617,7 @@ class DeviceManagement(View):
                         icon,
                         {'ContentType': icon.content_type, 'ACL': 'public-read'})
                 else:
-                    AppDeviceType.objects.filter(id=app_device_type_id)\
+                    AppDeviceType.objects.filter(id=app_device_type_id) \
                         .update(model=model, type=type, app_version_number_id=version_number)
                 DeviceNameLanguage.objects.filter(id=device_name_language_id).update(lang=lang, name=name, sort=sort)
             return response.json(0)
@@ -841,11 +849,3 @@ class DeviceManagement(View):
         except Exception as e:
             print(e)
             return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-
-
-
-
-
-
-
-

+ 2 - 0
Ansjer/urls.py

@@ -30,6 +30,7 @@ from Controller.MessagePush import EquipmentMessagePush
 from Controller.SensorGateway import SensorGatewayController, EquipmentFamilyController
 from Controller.Surveys import CloudStorageController
 from Controller.UserDevice import UserDeviceShareController
+from Controller.CampaignController import CampaignController
 from Model import views  # 定时任务,不要删除该行代码
 
 urlpatterns = [
@@ -270,6 +271,7 @@ urlpatterns = [
     re_path(r'^weather/(?P<operation>.*)$', WeatherControl.WeatherView.as_view()),
     re_path(r'^alexaApi/', include("Ansjer.server_urls.alexa_url")),
     re_path('appCampaign/(?P<operation>.*)', AppCampaignController.AppCampaignView.as_view()),
+    re_path('campaign/(?P<operation>.*)', CampaignController.CampaignView.as_view()),
 
     # 后台界面接口 -------------------------------------------------------------------------------------------------------
     # 登录,用户信息,权限

+ 513 - 0
Controller/CampaignController/CampaignController.py

@@ -0,0 +1,513 @@
+import time
+import json
+
+from Model.models import AppAdvertiseCampaign, DeviceTypeModel, CountryModel, OpenScreenCampaign
+from Ansjer.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, SERVER_TYPE, LOGGER
+
+from django.core.paginator import Paginator
+from django.views import View
+from django.db.models import Prefetch
+from django.db.models import Q, F
+
+from Object.AWS.AmazonS3Util import AmazonS3Util
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+
+
+class CampaignView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.GET
+        return self.validation(request_dict, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.POST
+        return self.validation(request_dict, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language, 'pc')
+        if operation == 'getCountryList':
+            return self.get_country_list(response)
+        else:
+            tko = TokenObject(
+                request.META.get('HTTP_AUTHORIZATION'),
+                returntpye='pc')
+            if tko.code != 0:
+                return response.json(tko.code)
+            response.lang = tko.lang
+            if operation == 'getCampaignList':  # 获取广告活动列表
+                return self.get_campaign_list(request_dict, response)
+            elif operation == 'addCampaign':  # 添加广告活动
+                return self.add_campaign(request, request_dict, response)
+            elif operation == 'updateCampaign':  # 更新广告活动
+                return self.update_campaign(request, request_dict, response)
+            elif operation == 'deleteCampaign':  # 删除广告活动
+                return self.delete_campaign(request_dict, response)
+            elif operation == 'switchCampaign':  # 广告活动开关
+                return self.switch_campaign(request_dict, response)
+            elif operation == 'getUserBehaviorLog':  # 获取用户行为日志
+                return self.get_user_behavior_log(request_dict, response)
+            else:
+                return response.json(414)
+
+    def get_campaign_list(self, request_dict, response):
+        """
+        查询广告活动列表
+        @param request_dict: 请求参数
+        @param response: 响应对象
+        @return: 响应对象包含广告活动列表
+        """
+        campaign_name = request_dict.get('campaign_name', None)
+        campaign_country = request_dict.get('campaign_country', None)
+        status = request_dict.get('status', None)
+        pageNo = request_dict.get('pageNo', 1)
+        pageSize = request_dict.get('pageSize', 20)
+        unknown_country = 0
+
+        try:
+            # 连接并获取国家和设备类型
+            country_prefetch = Prefetch('country', queryset=CountryModel.objects.only('country_name'),
+                                        to_attr='country_list')
+            device_type_prefetch = Prefetch('device_type', queryset=DeviceTypeModel.objects.only('name'),
+                                            to_attr='device_type_list')
+            app_advertise_campaign_qs = AppAdvertiseCampaign.objects.prefetch_related(country_prefetch,
+                                                                                      device_type_prefetch)
+
+            # 过滤
+            if campaign_name:
+                app_advertise_campaign_qs = app_advertise_campaign_qs.filter(campaign_name=campaign_name)
+            if status:
+                app_advertise_campaign_qs = app_advertise_campaign_qs.filter(status=status)
+            if campaign_country:
+                campaign_country_list = campaign_country.split(',')
+                if "未知地区" in campaign_country_list:
+                    unknown_country = 1
+                app_advertise_campaign_qs = app_advertise_campaign_qs.filter(
+                    Q(country__country_name__in=campaign_country_list) | Q(unknown_country=unknown_country)).distinct()
+            app_advertise_campaign_qs = app_advertise_campaign_qs.filter(~Q(status=2))
+            # 分页
+            paginator = Paginator(app_advertise_campaign_qs.order_by('id'), pageSize)
+            campaigns = paginator.page(pageNo)
+
+            # 添加设备名和地区返回
+            campaign_list = []
+            for campaign in campaigns.object_list:
+                if campaign.unknown_country == 0:
+                    countries = ",".join([country.country_name for country in campaign.country_list])
+                else:
+                    country_list = campaign.country_list
+                    country_names = []
+                    for country in country_list:
+                        country_names.append(country.country_name)
+                    country_names.append("未知地区")
+                    countries = ",".join(country_names)
+
+                s3_url, _, _ = self.s3_server()
+
+                banner_campaign = campaign.banner_campaign
+                for sort in banner_campaign:
+                    banner_campaign[sort]["image"] = s3_url + banner_campaign[sort]["image"]
+                campaign_data = {
+                    'id': campaign.id,
+                    'image_url': s3_url + campaign.image_url,
+                    'banner_campaign': banner_campaign,
+                    'campaign_name': campaign.campaign_name,
+                    'campaign_url': campaign.campaign_url,
+                    'campaign_type': campaign.campaign_type,
+                    'status': campaign.status,
+                    'campaign_start_date': campaign.campaign_start_date,
+                    'campaign_end_date': campaign.campaign_end_date,
+                    'campaign_show_stime': campaign.campaign_show_stime,
+                    'campaign_show_etime': campaign.campaign_show_etime,
+                    'app_bundle_type': campaign.app_bundle_type,
+                    'countries': countries,
+                    'device_types': ",".join([device.name for device in campaign.device_type_list]),
+                }
+                campaign_list.append(campaign_data)
+
+            data = {
+                'list': campaign_list,
+                'total': paginator.count,
+            }
+
+            return response.json(0, data)
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    def add_campaign(self, request, request_dict, response):
+        """
+        添加新的广告活动
+        @param request: 包含文件信息
+        @param request_dict: 包含所有请求参数的字典
+        @param response: 响应对象
+        @return: 响应对象
+        """
+        try:
+            campaign_name = request_dict.get('campaign_name', None)
+            campaign_url = request_dict.get('campaign_url', None)
+            status = request_dict.get('status', 2)
+            campaign_start_time = request_dict.get('campaign_start_time', None)
+            campaign_end_time = request_dict.get('campaign_end_time', None)
+            campaign_show_stime = request_dict.get('campaign_show_stime', 0)
+            campaign_show_etime = request_dict.get('campaign_show_etime', 86399)
+            app_bundle_type = request_dict.get('app_bundle_type', None)
+            poster_file = request.FILES.get('posterFile', None)
+            banner_files = request.FILES.getlist('bannerFiles', None)
+            banner_campaign_urls = json.loads(request_dict.get('banner_campaign_url', "[]"))
+            device_type_names = json.loads(request_dict.get('device_type_list', "[]"))  # 设备类型名称列表
+            country_name_list = json.loads(request_dict.get('country_name_list', "[]"))  # 地区列表
+
+            required_fields = [campaign_name, campaign_url, campaign_start_time, campaign_end_time,
+                               app_bundle_type]
+            list_fields = [device_type_names, country_name_list, banner_campaign_urls]
+
+            # 检查基本字段是否为None
+            if any(field is None for field in required_fields):
+                return response.json(444)
+
+            # 检查列表类型的字段是否为空
+            if any(not field for field in list_fields):
+                return response.json(444)
+
+            # 确保至少提供了一个文件
+            if not poster_file and not banner_files:
+                return response.json(444)
+
+            # 针对特殊地区的处理,表没设计好用这个处理挽救一下
+            unknown_country = 0
+            if "未知地区" in country_name_list:
+                unknown_country = 1
+                country_name_list.remove("未知地区")
+
+            # 上传文件到S3
+
+            banner_image_urls = self.upload_files_to_s3(banner_files,
+                                                        "BannerAdvertise") if banner_files is not None else []
+            poster_image_url = self.upload_files_to_s3(poster_file,
+                                                       "OpenScreenAdvertise")[0] if poster_file is not None else ""
+            campaign_type = []
+            if banner_image_urls is not []:
+                campaign_type.append(1)
+                banner_campaign = {
+                    str(index): {"image": image_url, "url": campaign_url}
+                    for index, (image_url, campaign_url) in
+                    enumerate(zip(banner_image_urls, banner_campaign_urls), start=1)
+                }
+            else:
+                banner_campaign = {}
+
+            if poster_image_url != "":
+                campaign_type.append(2)
+            create_time = int(time.time())
+            update_time = int(time.time())
+            # 创建 AppAdvertiseCampaign 实例
+            new_campaign = AppAdvertiseCampaign.objects.create(
+                image_url=poster_image_url,
+                campaign_name=campaign_name,
+                campaign_url=campaign_url,
+                banner_campaign=banner_campaign,
+                campaign_type=campaign_type,
+                status=status,
+                unknown_country=unknown_country,
+                app_bundle_type=app_bundle_type,
+                campaign_start_date=campaign_start_time,
+                campaign_end_date=campaign_end_time,
+                campaign_show_stime=campaign_show_stime,
+                campaign_show_etime=campaign_show_etime,
+                create_time=create_time,
+                update_time=update_time,
+            )
+
+            # 根据名称查找 DeviceTypeModel 的实例并建立关系
+            device_type_instances = DeviceTypeModel.objects.filter(name__in=device_type_names)
+            for device_type_instance in device_type_instances:
+                new_campaign.device_type.add(device_type_instance)
+
+            # 根据 ID 关联 CountryModel 实例
+            country_instances = CountryModel.objects.filter(country_name__in=country_name_list)
+            for country_instance in country_instances:
+                new_campaign.country.add(country_instance)
+
+            return response.json(0)
+
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    def update_campaign(self, request, request_dict, response):
+        """
+        更新广告活动
+        @param request: 包含文件信息
+        @param request_dict: 包含所有请求参数的字典
+        @param response: 响应对象
+        @return: 响应对象
+        """
+        try:
+            campaign_id = request_dict.get('id', None)
+            campaign_name = request_dict.get('campaign_name', None)
+            campaign_url = request_dict.get('campaign_url', None)
+            campaign_start_time = request_dict.get('campaign_start_time', None)
+            campaign_end_time = request_dict.get('campaign_end_time', None)
+            campaign_show_stime = request_dict.get('campaign_show_stime', None)
+            campaign_show_etime = request_dict.get('campaign_show_etime', None)
+            app_bundle_type = request_dict.get('app_bundle_type', None)
+            campaign_type = json.loads(request_dict.get('campaign_type', "[]"))  # 广告类型列表
+            device_type_names = json.loads(request_dict.get('device_type_list', "[]"))  # 设备类型名称列表
+            country_name_list = json.loads(request_dict.get('country_name_list', "[]"))  # 地区列表
+            poster_file = request.FILES.get('posterFile', None)
+
+            # 更改轮播图广告图片
+            sort_files = json.loads(request_dict.get('sort_files', "[]"))
+            banner_files = request.FILES.getlist('bannerFiles', None)
+
+            # 更改轮播图链接
+            sort_urls = json.loads(request_dict.get('sort_url', "[]"))
+            banner_urls = json.loads(request_dict.get('banner_urls', "[]"))
+
+            if not campaign_id:
+                return response.json(444)
+
+            update_time = int(time.time())
+            campaign = AppAdvertiseCampaign.objects.filter(pk=campaign_id).first()
+
+            # 未知地区特殊处理
+            if country_name_list is not None:
+                if "未知地区" in country_name_list:
+                    campaign.unknown_country = 1
+                    country_name_list.remove("未知地区")
+                else:
+                    campaign.unknown_country = 0
+
+            # 开屏广告图片
+            if poster_file is not None:
+                self.del_file_to_s3(campaign.image_url)
+                poster_image_url = self.upload_files_to_s3(poster_file,
+                                                           "OpenScreenAdvertise")[0]
+                campaign.image_url = poster_image_url
+
+            # 更改轮播广告图片
+            if banner_files is not None:
+                image_num = 0
+                banner_image_urls = self.upload_files_to_s3(banner_files, "BannerAdvertise")
+                for sort in sort_files:
+                    old_image = campaign.banner_campaign[str(sort)]["image"]
+                    self.del_file_to_s3(old_image)
+                    campaign.banner_campaign[str(sort)]["image"] = banner_image_urls[image_num]
+                    image_num = image_num + 1
+
+            # 更改轮播广告链接
+            if banner_urls:
+                url_num = 0
+                for sort in sort_urls:
+                    campaign.banner_campaign[str(sort)]["url"] = banner_urls[url_num]
+                    url_num = url_num + 1
+
+            # 常规字段
+            if campaign_name is not None:
+                campaign.campaign_name = campaign_name
+            if campaign_url is not None:
+                campaign.campaign_url = campaign_url
+            if campaign_type is not None:
+                campaign.campaign_type = campaign_type
+            if app_bundle_type is not None:
+                campaign.app_bundle_type = app_bundle_type
+            if campaign_start_time is not None:
+                campaign.campaign_start_date = campaign_start_time
+            if campaign_end_time is not None:
+                campaign.campaign_end_date = campaign_end_time
+            if campaign_show_stime is not None:
+                campaign.campaign_show_stime = campaign_show_stime
+            if campaign_show_etime is not None:
+                campaign.campaign_show_etime = campaign_show_etime
+
+            # 更新多对多字段 - 设备类型
+            if device_type_names:
+                device_types = DeviceTypeModel.objects.filter(name__in=device_type_names)
+                campaign.device_type.set(device_types)
+
+            # 更新多对多字段 - 国家/地区
+            if country_name_list:
+                countries = CountryModel.objects.filter(country_name__in=country_name_list)
+                campaign.country.set(countries)
+
+            campaign.update_time = update_time
+
+            # 保存更新
+            campaign.save()
+
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    def delete_campaign(self, request_dict, response):
+        """
+        删除广告活动
+        @param request_dict: 包含所有请求参数的字典
+        @param response: 响应对象
+        @return: 响应对象
+        """
+        campaign_id = request_dict.get('id')
+        if not campaign_id:
+            return response.json(444)
+        try:
+            campaign = AppAdvertiseCampaign.objects.get(pk=campaign_id)
+            if campaign.image_url != "":
+                self.del_file_to_s3(campaign.image_url)
+            if campaign.banner_campaign is not {}:
+                banner_campaign = []
+                for sort in campaign.banner_campaign:
+                    banner = campaign.banner_campaign[sort]
+                    banner_campaign.append(banner)
+                self.del_file_to_s3(banner_campaign)
+            # 清除多对多关系
+            campaign.device_type.clear()
+            campaign.country.clear()
+            # 保留在广告表中
+            campaign.status = 2
+            campaign.update_time = int(time.time())
+            campaign.save()
+            return response.json(0)
+
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    def switch_campaign(self, request_dict, response):
+        """
+        广告活动 开启/关闭
+        @param request_dict: 包含所有请求参数的字典
+        @param response: 响应对象
+        @return: 响应对象
+        """
+        campaign_id = request_dict.get('id')
+        status = request_dict.get('status')
+        if not all([campaign_id, status]):
+            return response.json(444)
+        try:
+            AppAdvertiseCampaign.objects.filter(pk=campaign_id).update(status=status, update_time=int(time.time()))
+            return response.json(0)
+
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    def get_user_behavior_log(self, request_dict, response):
+        campaign_ids = request_dict.get('campaign_ids', None)
+        start_time = request_dict.get('start_time', None)
+        end_time = request_dict.get('end_time', None)
+        if not all([start_time, end_time]):
+            return response.json(444)
+        try:
+            open_screen_campaign_qs = OpenScreenCampaign.objects.filter(
+                update_time__range=[int(start_time), int(end_time)])
+
+            if campaign_ids is not None:
+                open_screen_campaign_qs = open_screen_campaign_qs.filter(
+                    Q(campaign_id_id__isnull=True) | Q(campaign_id_id__in=json.loads(campaign_ids)))
+
+            open_screen_campaign_qs = open_screen_campaign_qs.select_related('campaign_id').annotate(
+                campaign_name=F('campaign_id__campaign_name'),
+                campaign_type=F('campaign_id__campaign_type'),
+                campaign_status=F('campaign_id__status'),
+                start_date=F('campaign_id__campaign_start_date'),
+                end_date=F('campaign_id__campaign_end_date'),
+                start_time=F('campaign_id__campaign_show_stime'),
+                end_time=F('campaign_id__campaign_show_etime')
+            ).values('id', 'user_id', 'status', 'update_time', 'create_time', 'campaign_id', 'campaign_name',
+                     'campaign_type', 'campaign_status', 'start_date', 'end_date', 'start_time', 'end_time')
+            if not open_screen_campaign_qs.exists():
+                return response.json(0, {'list': []})
+            campaigns_list = list(open_screen_campaign_qs)
+            return response.json(0, {'list': campaigns_list})
+
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    def get_country_list(self, response):
+        try:
+            if SERVER_TYPE == 'Ansjer.us_config.formal_settings':
+                region_api = 'https://www.dvema.com/'
+            elif SERVER_TYPE == 'Ansjer.eur_config.formal_settings':
+                region_api = 'https://api.zositeche.com/'
+            elif SERVER_TYPE == 'Ansjer.cn_config.formal_settings':
+                region_api = 'https://www.zositechc.cn/'
+            else:
+                region_api = 'https://test.zositechc.cn/'
+            country_qs = CountryModel.objects.filter(region__api=region_api).values('country_name')
+            if not country_qs.exists():
+                return response.json(173)
+
+            country_list = []
+            for country in country_qs:
+                country_list.append(country['country_name'])
+            return response.json(0, {'list': country_list})
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def upload_files_to_s3(files, path_prefix):
+        """
+        广告图片文件上传到S3存储桶
+        @param files: 文件 request.FILES获取
+        @param path_prefix: 存储路径
+        @return image_urls: 列表
+        """
+        try:
+            _, regin, AWS_SES_ACCESS_REGION = CampaignView.s3_server()
+
+            # 确保files是一个列表,统一处理单个文件和多个文件
+            if not isinstance(files, list):
+                files = [files]
+
+            image_urls = []
+            bucket_name = "ansjerfilemanager"
+            s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[regin], AWS_SECRET_ACCESS_KEY[regin], AWS_SES_ACCESS_REGION)
+            for file in files:
+                timestamp = int(time.time())
+                file_key = f'app/campaign/{path_prefix}/{timestamp}_{file.name}'
+                s3.upload_file_obj(bucket_name, file_key, file,
+                                   {'ContentType': file.content_type, 'ACL': 'public-read'})
+                image_urls.append(f"{path_prefix}/{timestamp}_{file.name}")
+
+            return image_urls
+        except Exception as e:
+            LOGGER.info('存储桶添加异常:error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return None
+
+    @staticmethod
+    def del_file_to_s3(path_list):
+        """
+        S3存储桶 删除文件
+        @param path_list: 单一字符串或者列表
+        @return
+        """
+        try:
+            _, regin, AWS_SES_ACCESS_REGION = CampaignView.s3_server()
+            if not isinstance(path_list, list):
+                path_list = [path_list]
+
+            for path in path_list:
+                # 删除存储桶原来的图片
+                s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[regin], AWS_SECRET_ACCESS_KEY[regin], AWS_SES_ACCESS_REGION)
+                bucket_name = 'ansjerfilemanager'
+                s3.delete_obj(bucket_name, f"app/campaign/{path}")
+        except Exception as e:
+            LOGGER.info('存储桶删除异常:error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def s3_server():
+        if SERVER_TYPE == 'Ansjer.cn_config.formal_settings' or SERVER_TYPE == 'Ansjer.cn_config.test_settings':
+            s3_url = "https://ansjerfilemanager.s3.cn-northwest-1.amazonaws.com.cn/app/campaign/"
+            regin = 0
+            AWS_SES_ACCESS_REGION = "cn-northwest-1"
+        else:
+            s3_url = "https://ansjerfilemanager.s3.amazonaws.com/app/campaign/"
+            regin = 1
+            AWS_SES_ACCESS_REGION = 'us-east-1'
+        return s3_url, regin, AWS_SES_ACCESS_REGION

+ 4 - 2
Model/models.py

@@ -4232,14 +4232,16 @@ class DailyReconciliation(models.Model):
 
 class AppAdvertiseCampaign(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
-    image_url = models.CharField(default='', max_length=256, verbose_name='广告图片url')
+    image_url = models.CharField(default='', max_length=256, verbose_name='开屏广告图片url')
+    banner_campaign = models.JSONField(default=dict, verbose_name='轮播广告')
     campaign_url = models.CharField(default='', max_length=256, verbose_name='活动链接')
     campaign_name = models.CharField(default='', max_length=32, verbose_name='广告名称')
-    campaign_type = models.SmallIntegerField(default=1, verbose_name='广告类型')  # 1:开屏广告
+    campaign_type = models.JSONField(default=list, verbose_name='广告类型')  # 1:开屏广告 # 2:轮播广告
     device_type = models.ManyToManyField(to="DeviceTypeModel", verbose_name='设备类型')
     status = models.SmallIntegerField(default=0, verbose_name='广告状态')  # 0:关闭 1:开启 2:删除
     country = models.ManyToManyField(to="CountryModel", verbose_name='广告地区')
     unknown_country = models.SmallIntegerField(default=0, verbose_name='未知地区')  # 0表示不包括 1表示包括
+    app_bundle_type = models.SmallIntegerField(default=0, verbose_name='上架APP')  # 0表示周视 1表示Zosismart
     campaign_start_date = models.IntegerField(default=0, verbose_name='广告开始日期')
     campaign_end_date = models.IntegerField(default=0, verbose_name='广告结束日期')
     campaign_show_stime = models.IntegerField(default=0, verbose_name='当天广告起始时间')