Browse Source

APP业务API-广告接口

linhaohong 1 year ago
parent
commit
5075509c9f

+ 0 - 0
Controller/CampaignController/CampaignController.py → AdminController/CampaignController.py


+ 3 - 3
Ansjer/urls.py

@@ -4,7 +4,7 @@ from django.urls import re_path
 
 from AdminController import UserManageController, RoleController, MenuController, TestServeController, \
     ServeManagementController, LogManagementController, DeviceManagementController, VersionManagementController, \
-    AiServeController, SurveysManageController, SerialManageController, IcloudManagementController
+    AiServeController, SurveysManageController, SerialManageController, IcloudManagementController, CampaignController
 from AdminController.CloudServiceManage import AgentDeviceController, AgentCustomerController, AgentOrderController
 from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppInfo, \
     Test, MealManage, DeviceManage, EquipmentStatus, SysManage, DeviceLog, LogAccess, \
@@ -24,13 +24,13 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     RegionController, VPGController, LanguageController, TestController, DeviceConfirmRegion, S3GetStsController, \
     DetectControllerV2, PcInfo, PctestController, DeviceDebug, PaymentCycle, \
     DeviceLogController, CouponController, AiController, ShadowController, AppAccountManagement, InitController, \
-    WeatherControl, AppCampaignController
+    WeatherControl
 from Controller.Cron import CronTaskController
 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 Controller.CampaignController import AppCampaignController
 from Model import views  # 定时任务,不要删除该行代码
 
 urlpatterns = [

+ 0 - 558
Controller/AppCampaignController.py

@@ -1,558 +0,0 @@
-import time
-import pytz
-import json
-from datetime import datetime
-from datetime import time as Time
-
-from Model.models import AppAdvertiseCampaign, DeviceTypeModel, CountryModel, Device_User, OpenScreenCampaign
-from Ansjer.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, SERVER_TYPE
-
-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 AppCampaignView(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 == 'getCampaignList':  # 获取广告活动列表
-            return self.get_campaign_list(request_dict, response)
-        elif operation == 'getCountryList':  # 查询国家列表
-            return self.get_country_list(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 == 'appGetCampaigns':
-            return self.app_get_campaigns(request_dict)
-        elif operation == 'recordUserBehavior':
-            return self.record_user_behavior(request_dict)
-        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
-
-        # 连接并获取国家和设备类型
-        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)
-
-        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/"
-        else:
-            s3_url = "https://ansjerfilemanager.s3.amazonaws.com/app/campaign/"
-
-        # 添加设备名和地区返回
-        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)
-            campaign_data = {
-                'id': campaign.id,
-                'image_url': s3_url + campaign.image_url,
-                '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,
-                '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)
-
-    def add_campaign(self, request, request_dict, response):
-        """
-        添加新的广告活动
-        @param request_dict: 包含所有请求参数的字典
-        @param response: 响应对象
-        @return: 响应对象
-        """
-        file = request.FILES.get('posterFile', None)
-        campaign_name = request_dict.get('campaign_name', None)
-        campaign_url = request_dict.get('campaign_url', None)
-        campaign_type = request_dict.get('campaign_type', None)
-        status = request_dict.get('status', None)
-        device_type_names = json.loads(request_dict.get('device_type_list', None))  # 设备类型名称列表
-        country_name_list = json.loads(request_dict.get('country_name_list', 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', 0)
-        campaign_show_etime = request_dict.get('campaign_show_etime', 86399)
-
-        if not all([campaign_name, campaign_type, device_type_names, campaign_url,
-                    country_name_list, campaign_start_time, campaign_end_time, file]):
-            return response.json(444)
-
-        # 针对特殊地区的处理,表没设计好用这个处理挽救一下
-        unknown_country = 0
-        if "未知地区" in country_name_list:
-            unknown_country = 1
-            country_name_list.remove("未知地区")
-        if SERVER_TYPE == 'Ansjer.cn_config.formal_settings' or SERVER_TYPE == 'Ansjer.cn_config.test_settings':
-            regin = 0
-            AWS_SES_ACCESS_REGION = "cn-northwest-1"
-        else:
-            regin = 1
-            AWS_SES_ACCESS_REGION = 'us-east-1'
-        fileName = file.name
-        try:
-            create_time = int(time.time())
-            update_time = int(time.time())
-            # 保存图片到存储桶
-            bucket_name = 'ansjerfilemanager'
-            file_key = f'app/campaign/OpenScreenAdvertise/{update_time}_{fileName}'
-            s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[regin], AWS_SECRET_ACCESS_KEY[regin], AWS_SES_ACCESS_REGION)
-            # 地址:https://ansjerfilemanager.s3.amazonaws.com/app/campaign/OpenScreenAdvertise/XXX.jpg
-            s3.upload_file_obj(
-                bucket_name,
-                file_key,
-                file,
-                {'ContentType': file.content_type, 'ACL': 'public-read'})
-            # 创建 AppAdvertiseCampaign 实例
-            new_campaign = AppAdvertiseCampaign.objects.create(
-                image_url=f"OpenScreenAdvertise/{update_time}_{fileName}",
-                campaign_name=campaign_name,
-                campaign_url=campaign_url,
-                campaign_type=campaign_type,
-                status=status,
-                unknown_country=unknown_country,
-                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)
-
-        except Exception as e:
-            return response.json(178)
-
-        return response.json(0)
-
-    def update_campaign(self, request, request_dict, response):
-        campaign_id = request_dict.get('id', None)
-        campaign_name = request_dict.get('campaign_name', None)
-        campaign_url = request_dict.get('campaign_url', None)
-        campaign_type = request_dict.get('campaign_type', None)
-        device_type_names = json.loads(request_dict.get('device_type_list', '[]'))  # 设备类型名称列表
-        country_name_list = json.loads(request_dict.get('country_name_list', '[]'))  # 地区列表
-        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)
-        file = request.FILES.get('posterFile', None)
-        if not campaign_id:
-            return response.json(444)
-
-        if SERVER_TYPE == 'Ansjer.cn_config.formal_settings' or SERVER_TYPE == 'Ansjer.cn_config.test_settings':
-            regin = 0
-            AWS_SES_ACCESS_REGION = "cn-northwest-1"
-        else:
-            regin = 1
-            AWS_SES_ACCESS_REGION = 'us-east-1'
-
-        try:
-            update_time = int(time.time())
-            campaign = AppAdvertiseCampaign.objects.get(id=campaign_id)
-            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 file is not None:
-                # 删除存储桶原来的图片
-                s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[regin], AWS_SECRET_ACCESS_KEY[regin], AWS_SES_ACCESS_REGION)
-                bucket_name = 'ansjerfilemanager'
-                if campaign.image_url:
-                    s3.delete_obj(bucket_name, f"app/campaign/{campaign.image_url}")
-                # 添加新的图片
-                file_key = f'app/campaign/OpenScreenAdvertise/{update_time}_{file.name}'
-                s3.upload_file_obj(
-                    bucket_name,
-                    file_key,
-                    file,
-                    {'ContentType': file.content_type, 'ACL': 'public-read'}
-                )
-                campaign.image_url = f'OpenScreenAdvertise/{update_time}_{file.name}'
-            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 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()
-        except Exception as e:
-            return response.json(177)
-
-        return response.json(0)
-
-    def switch_campaign(self, request_dict, response):
-        campaign_id = request_dict.get('id')
-        status = request_dict.get('status')
-        if not campaign_id:
-            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:
-            return response.json(444)
-
-    def delete_campaign(self, request_dict, response):
-        campaign_id = request_dict.get('id')
-        if SERVER_TYPE == 'Ansjer.cn_config.formal_settings' or SERVER_TYPE == 'Ansjer.cn_config.test_settings':
-            regin = 0
-            AWS_SES_ACCESS_REGION = "cn-northwest-1"
-        else:
-            regin = 1
-            AWS_SES_ACCESS_REGION = 'us-east-1'
-        if not campaign_id:
-            return response.json(444)
-        try:
-            campaign = AppAdvertiseCampaign.objects.get(pk=campaign_id)
-            s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[regin], AWS_SECRET_ACCESS_KEY[regin], AWS_SES_ACCESS_REGION)
-            bucket_name = 'ansjerfilemanager'
-            if campaign.image_url:
-                s3.delete_obj(bucket_name, f"app/campaign/{campaign.image_url}")
-            # 清除多对多关系
-            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:
-            return response.json(176)
-
-    def get_timezone_offset(self, tz):
-        """
-        将 "+8:00" 格式的时区字符串转换为包含分钟偏移的时区。
-        """
-        sign = tz[0]  # " " 或 "-"
-        hours, minutes = map(int, tz[1:].split('.'))  # 分离小时和分钟
-
-        # 计算总分钟数
-        total_minutes = hours * 60 + minutes
-        if sign == '-':
-            total_minutes = -total_minutes
-
-        # 使用 pytz.FixedOffset 创建时区
-        return pytz.FixedOffset(total_minutes)
-
-    def app_get_campaigns(cls, request_dict):
-        """
-        APP获取广告活动列表
-        @param request_dict: 请求参数
-        @param response: 响应对象
-        @return: 响应对象
-        """
-        language = request_dict.get('language', 'en')
-        tz = request_dict.get('tz', '+0:00')
-        token = request_dict.get('token', None)
-        response = ResponseObject(language)
-        if not token:
-            return response.json(444)
-        token = TokenObject(token)
-        if token.code != 0:
-            return response.json(token.code)
-        user_id = token.userID
-
-        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/"
-        else:
-            s3_url = "https://ansjerfilemanager.s3.amazonaws.com/app/campaign/"
-
-        # 当日时间戳区间获取
-        timezone = cls.get_timezone_offset(tz)
-        current_date = datetime.now().date()
-        start_of_day = datetime.combine(current_date, Time.min)
-        end_of_day = datetime.combine(current_date, Time.max)
-        start_timestamp = int(start_of_day.timestamp())
-        end_timestamp = int(end_of_day.timestamp())
-
-        open_screen_campaign_qs = OpenScreenCampaign.objects.filter(
-            user_id=user_id,
-            create_time__gt=start_timestamp,
-            create_time__lt=end_timestamp
-        )
-        if not open_screen_campaign_qs.exists():
-            OpenScreenCampaign.objects.create(user_id=user_id,
-                                              update_time=int(time.time()),
-                                              create_time=int(time.time()))
-        try:
-            country_prefetch = Prefetch('country', queryset=CountryModel.objects.only('id'), to_attr='country_list')
-            device_type_prefetch = Prefetch('device_type', queryset=DeviceTypeModel.objects.only('type'),
-                                            to_attr='device_type_list')
-            app_advertise_campaign_qs = AppAdvertiseCampaign.objects.prefetch_related(country_prefetch,
-                                                                                      device_type_prefetch)
-
-            device_info_qs = Device_User.objects.filter(userID=user_id).values("region_country").first()
-            country_id = device_info_qs.get('region_country')
-            if country_id != 0:
-                app_advertise_campaign_qs = app_advertise_campaign_qs.filter(country__id=country_id, status=1)
-            else:
-                app_advertise_campaign_qs = app_advertise_campaign_qs.filter(status=1, unknown_country=1)
-
-            # 返回 广告名称、广告类型、开始时间、结束时间、广告图片、活动链接
-            campaigns_list = []
-
-            for campaign in app_advertise_campaign_qs:
-                # campaign_end_date = (datetime.utcfromtimestamp(campaign.campaign_end_date) # 日期版本
-                #                      .replace(tzinfo=pytz.utc).astimezone(timezone).strftime('%Y-%m-%d'))
-
-                # 日期范围
-                campaigns_start_date = datetime.fromtimestamp(campaign.campaign_start_date, pytz.utc).astimezone(
-                    timezone).replace(hour=0, minute=0, second=0, microsecond=0).timestamp()  # 时间戳版本
-                campaign_end_date = datetime.fromtimestamp(campaign.campaign_end_date, pytz.utc).astimezone(
-                    timezone).replace(hour=0, minute=0, second=0, microsecond=0).timestamp()  # 时间戳版本
-
-                # 时间范围
-                campaign_start_firstday = sum(int(x) * 60 ** i for i, x in enumerate(reversed(
-                    datetime.utcfromtimestamp(campaign.campaign_start_date + campaign.campaign_show_stime).replace(
-                        tzinfo=pytz.utc).astimezone(timezone).strftime('%H:%M').split(':')))) * 60  # 秒数版本
-                campaign_end_firstday = sum(int(x) * 60 ** i for i, x in enumerate(reversed(
-                    datetime.utcfromtimestamp(campaign.campaign_start_date + campaign.campaign_show_etime).replace(
-                        tzinfo=pytz.utc).astimezone(timezone).strftime('%H:%M').split(':')))) * 60  # 秒数版本
-
-                # campaign_end_firstday = (
-                #     datetime.utcfromtimestamp(campaign.campaign_start_date + campaign.campaign_show_etime)
-                #     .replace(tzinfo=pytz.utc).astimezone(timezone).strftime('%H:%M')) # 时间版本
-
-                campaigns_list.append({
-                    'campaign_id': campaign.id,
-                    'image_url': s3_url + campaign.image_url,
-                    'campaign_url': campaign.campaign_url,
-                    'campaign_name': campaign.campaign_name,
-                    'campaign_type': campaign.campaign_type,
-                    'start_date': campaigns_start_date,
-                    'end_date': campaign_end_date,
-                    'start_time': campaign_start_firstday,
-                    'end_time': campaign_end_firstday,
-                    'device_types': [device.type for device in campaign.device_type_list],
-                })
-            return response.json(0, {
-                'interval_time': 86400,
-                'campaigns': campaigns_list
-            })
-        except Exception as e:
-            return response.json(173)
-
-    def record_user_behavior(cls, request_dict):
-        """
-        记录用户行为
-        @param request_dict: 请求参数
-        @param response: 响应对象
-        @return: 响应对象
-        """
-        language = request_dict.get('language', 'en')
-        status = request_dict.get('status', None)  # 1.未跳过 2.已跳过 3.点击广告
-        campaign_id = request_dict.get('campaign_id', None)
-        token = request_dict.get('token', None)
-        response = ResponseObject(language)
-        if not token:
-            return response.json(444)
-        token = TokenObject(token)
-        if token.code != 0:
-            return response.json(token.code)
-        user_id = token.userID
-
-        if not all([status, campaign_id]):
-            return response.json(444)
-
-        # 当日时间戳区间获取
-        current_date = datetime.now().date()
-        start_of_day = datetime.combine(current_date, Time.min)
-        end_of_day = datetime.combine(current_date, Time.max)
-        start_timestamp = int(start_of_day.timestamp())
-        end_timestamp = int(end_of_day.timestamp())
-
-        try:
-            # 筛选符合条件的记录
-            open_screen_campaigns = OpenScreenCampaign.objects.filter(
-                user_id=user_id,
-                create_time__gt=start_timestamp,
-                create_time__lt=end_timestamp,
-                status=0,
-            )
-
-            # 检查是否存在记录
-            if not open_screen_campaigns.exists():
-                # 如果不存在,则创建新记录
-                OpenScreenCampaign.objects.create(
-                    user_id=user_id,
-                    status=status,
-                    campaign_id_id=campaign_id,
-                    create_time=int(time.time()),
-                    update_time=int(time.time())
-                )
-
-            else:
-                # 如果存在,则更新最新的记录
-                latest_campaign = open_screen_campaigns.latest("create_time")
-                latest_campaign.status = status
-                latest_campaign.campaign_id_id = campaign_id
-                latest_campaign.update_time = int(time.time())
-                latest_campaign.save()
-
-        except Exception as e:
-            return response.json(177, {'error': '更新错误'})
-
-        return response.json(0)
-
-    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(173)
-
-    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)))
-

+ 204 - 0
Controller/CampaignController/AppCampaignController.py

@@ -0,0 +1,204 @@
+import time
+import pytz
+from datetime import datetime
+from datetime import time as Time
+
+from Model.models import AppAdvertiseCampaign, DeviceTypeModel, CountryModel, Device_User, OpenScreenCampaign
+from Ansjer.config import SERVER_TYPE
+
+from django.views import View
+from django.db.models import Prefetch
+
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+
+
+class AppCampaignView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.GET
+        return self.validation(request, request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.POST
+        return self.validation(request, request_dict, operation)
+
+    def validation(self, request, request_dict, operation):
+        language = request_dict.get('language', 'en')
+        response = ResponseObject(language)
+        tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
+        response.lang = tko.lang
+        if tko.code != 0:
+            return response.json(tko.code)
+        userID = tko.userID
+        if operation == 'appGetCampaigns':
+            return self.app_get_campaigns(userID, request_dict, response)
+        elif operation == 'recordUserBehavior':
+            return self.record_user_behavior(userID, request_dict)
+        else:
+            return response.json(414)
+
+    def app_get_campaigns(self, userID, request_dict, response):
+        tz = request_dict.get('tz', '+0:00')
+        app_type = request_dict.get('appType', 0)
+        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/"
+        else:
+            s3_url = "https://ansjerfilemanager.s3.amazonaws.com/app/campaign/"
+
+        # 当日时间戳区间获取
+        timezone = self.get_timezone_offset(tz)
+        current_date = datetime.now().date()
+        start_of_day = datetime.combine(current_date, Time.min)
+        end_of_day = datetime.combine(current_date, Time.max)
+        start_timestamp = int(start_of_day.timestamp())
+        end_timestamp = int(end_of_day.timestamp())
+
+        open_screen_campaign_qs = OpenScreenCampaign.objects.filter(
+            user_id=userID,
+            create_time__gt=start_timestamp,
+            create_time__lt=end_timestamp
+        )
+        if not open_screen_campaign_qs.exists():
+            OpenScreenCampaign.objects.create(user_id=userID,
+                                              update_time=int(time.time()),
+                                              create_time=int(time.time()))
+        try:
+            country_prefetch = Prefetch('country', queryset=CountryModel.objects.only('id'), to_attr='country_list')
+            device_type_prefetch = Prefetch('device_type', queryset=DeviceTypeModel.objects.only('type'),
+                                            to_attr='device_type_list')
+            app_advertise_campaign_qs = AppAdvertiseCampaign.objects.prefetch_related(country_prefetch,
+                                                                                      device_type_prefetch)
+
+            device_info_qs = Device_User.objects.filter(userID=userID).values("region_country").first()
+            country_id = device_info_qs.get('region_country')
+            if country_id != 0:
+                app_advertise_campaign_qs = app_advertise_campaign_qs.filter(country__id=country_id, status=1)
+            else:
+                app_advertise_campaign_qs = app_advertise_campaign_qs.filter(status=1, unknown_country=1)
+            if app_type is not None:
+                app_advertise_campaign_qs = app_advertise_campaign_qs.filter(app_bundle_type=app_type)
+            # 返回 广告名称、广告类型、开始时间、结束时间、广告图片、活动链接
+            campaigns_list = []
+
+            for campaign in app_advertise_campaign_qs:
+                # campaign_end_date = (datetime.utcfromtimestamp(campaign.campaign_end_date) # 日期版本
+                #                      .replace(tzinfo=pytz.utc).astimezone(timezone).strftime('%Y-%m-%d'))
+
+                # 日期范围
+                campaigns_start_date = datetime.fromtimestamp(campaign.campaign_start_date, pytz.utc).astimezone(
+                    timezone).replace(hour=0, minute=0, second=0, microsecond=0).timestamp()  # 时间戳版本
+                campaign_end_date = datetime.fromtimestamp(campaign.campaign_end_date, pytz.utc).astimezone(
+                    timezone).replace(hour=0, minute=0, second=0, microsecond=0).timestamp()  # 时间戳版本
+
+                # 时间范围
+                campaign_start_firstday = sum(int(x) * 60 ** i for i, x in enumerate(reversed(
+                    datetime.utcfromtimestamp(campaign.campaign_start_date + campaign.campaign_show_stime).replace(
+                        tzinfo=pytz.utc).astimezone(timezone).strftime('%H:%M').split(':')))) * 60  # 秒数版本
+                campaign_end_firstday = sum(int(x) * 60 ** i for i, x in enumerate(reversed(
+                    datetime.utcfromtimestamp(campaign.campaign_start_date + campaign.campaign_show_etime).replace(
+                        tzinfo=pytz.utc).astimezone(timezone).strftime('%H:%M').split(':')))) * 60  # 秒数版本
+
+                # campaign_end_firstday = (
+                #     datetime.utcfromtimestamp(campaign.campaign_start_date + campaign.campaign_show_etime)
+                #     .replace(tzinfo=pytz.utc).astimezone(timezone).strftime('%H:%M')) # 时间版本
+                # 轮播广告
+                banner_campaign = []
+                for sort in campaign.banner_campaign:
+                    banner = campaign.banner_campaign[sort]
+                    banner["image"] = s3_url + banner["image"]
+                    banner_campaign.append(banner)
+
+                campaigns_list.append({
+                    'campaign_id': campaign.id,
+                    'image_url': s3_url + campaign.image_url,
+                    'banner_campaign': banner_campaign,
+                    'campaign_url': campaign.campaign_url,
+                    'campaign_name': campaign.campaign_name,
+                    'campaign_type': campaign.campaign_type,
+                    'start_date': campaigns_start_date,
+                    'end_date': campaign_end_date,
+                    'start_time': campaign_start_firstday,
+                    'end_time': campaign_end_firstday,
+                    'device_types': [device.type for device in campaign.device_type_list],
+                })
+            return response.json(0, {
+                'interval_time': 86400,
+                'campaigns': campaigns_list
+            })
+        except Exception as e:
+            print(e)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    def record_user_behavior(self, userID, request_dict, response):
+        """
+        记录用户行为
+        @param request_dict: 请求参数
+        @param response: 响应对象
+        @return: 响应对象
+        """
+        status = request_dict.get('status', None)  # 1.未跳过 2.已跳过 3.点击广告
+        campaign_id = request_dict.get('campaign_id', None)
+        user_id = userID
+
+        if not all([status, campaign_id]):
+            return response.json(444)
+
+        # 当日时间戳区间获取
+        current_date = datetime.now().date()
+        start_of_day = datetime.combine(current_date, Time.min)
+        end_of_day = datetime.combine(current_date, Time.max)
+        start_timestamp = int(start_of_day.timestamp())
+        end_timestamp = int(end_of_day.timestamp())
+
+        try:
+            # 筛选符合条件的记录
+            open_screen_campaigns = OpenScreenCampaign.objects.filter(
+                user_id=user_id,
+                create_time__gt=start_timestamp,
+                create_time__lt=end_timestamp,
+                status=0,
+            )
+
+            # 检查是否存在记录
+            if not open_screen_campaigns.exists():
+                # 如果不存在,则创建新记录
+                OpenScreenCampaign.objects.create(
+                    user_id=user_id,
+                    status=status,
+                    campaign_id_id=campaign_id,
+                    create_time=int(time.time()),
+                    update_time=int(time.time())
+                )
+
+            else:
+                # 如果存在,则更新最新的记录
+                latest_campaign = open_screen_campaigns.latest("create_time")
+                latest_campaign.status = status
+                latest_campaign.campaign_id_id = campaign_id
+                latest_campaign.update_time = int(time.time())
+                latest_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 get_timezone_offset(self, tz):
+        """
+        将 "+8:00" 格式的时区字符串转换为包含分钟偏移的时区。
+        """
+        sign = tz[0]  # " " 或 "-"
+        hours, minutes = map(int, tz[1:].split('.'))  # 分离小时和分钟
+
+        # 计算总分钟数
+        total_minutes = hours * 60 + minutes
+        if sign == '-':
+            total_minutes = -total_minutes
+
+        # 使用 pytz.FixedOffset 创建时区
+        return pytz.FixedOffset(total_minutes)