AppCampaignController.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. import time
  2. import pytz
  3. import json
  4. from datetime import datetime
  5. from Model.models import AppAdvertiseCampaign, DeviceTypeModel, CountryModel
  6. from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
  7. AWS_SES_ACCESS_REGION, UNUSED_SERIAL_REDIS_LIST
  8. from django.core.paginator import Paginator
  9. from django.views import View
  10. from django.db.models import Prefetch
  11. from django.db.models import Q
  12. from Object.AWS.AmazonS3Util import AmazonS3Util
  13. from Object.ResponseObject import ResponseObject
  14. class AppCampaignView(View):
  15. def get(self, request, *args, **kwargs):
  16. request.encoding = 'utf-8'
  17. operation = kwargs.get('operation')
  18. request_dict = request.GET
  19. return self.validation(request_dict, request, operation)
  20. def post(self, request, *args, **kwargs):
  21. request.encoding = 'utf-8'
  22. operation = kwargs.get('operation')
  23. request_dict = request.POST
  24. return self.validation(request_dict, request, operation)
  25. def validation(self, request_dict, request, operation):
  26. language = request_dict.get('language', 'en')
  27. response = ResponseObject(language, 'pc')
  28. if operation == 'getCampaignList': # 获取广告活动列表
  29. return self.get_campaign_list(request_dict, response)
  30. elif operation == 'addCampaign': # 添加广告活动
  31. return self.add_campaign(request, request_dict, response)
  32. elif operation == 'updateCampaign': # 更新广告活动
  33. return self.update_campaign(request, request_dict, response)
  34. elif operation == 'deleteCampaign': # 删除广告活动
  35. return self.delete_campaign(request_dict, response)
  36. elif operation == 'switchCampaign': # 广告活动开关
  37. return self.switch_campaign(request_dict, response)
  38. elif operation == 'recordUserBehavior':
  39. return self.record_user_behavior(request_dict, response)
  40. elif operation == 'appGetCampaigns':
  41. return self.app_get_campaigns(request_dict, response)
  42. else:
  43. return response.json(404)
  44. def get_campaign_list(self, request_dict, response):
  45. """
  46. 查询广告活动列表
  47. @param request_dict: 请求参数
  48. @param response: 响应对象
  49. @return: 响应对象包含广告活动列表
  50. """
  51. campaign_name = request_dict.get('campaign_name', None)
  52. campaign_country = request_dict.get('campaign_country', None)
  53. status = request_dict.get('status', None)
  54. pageNo = request_dict.get('pageNo', 1)
  55. pageSize = request_dict.get('pageSize', 20)
  56. unknown_country = 0
  57. # 连接并获取国家和设备类型
  58. country_prefetch = Prefetch('country', queryset=CountryModel.objects.only('country_name'), to_attr='country_list')
  59. device_type_prefetch = Prefetch('device_type', queryset=DeviceTypeModel.objects.only('name'), to_attr='device_type_list')
  60. app_advertise_campaign_qs = AppAdvertiseCampaign.objects.prefetch_related(country_prefetch, device_type_prefetch)
  61. # 过滤
  62. if campaign_name:
  63. app_advertise_campaign_qs = app_advertise_campaign_qs.filter(campaign_name=campaign_name)
  64. if status:
  65. app_advertise_campaign_qs = app_advertise_campaign_qs.filter(status=status)
  66. if campaign_country:
  67. campaign_country_list = campaign_country.split(',')
  68. if "未知地区" in campaign_country_list:
  69. unknown_country = 1
  70. app_advertise_campaign_qs = app_advertise_campaign_qs.filter(Q(country__country_name__in=campaign_country_list) | Q(unknown_country=unknown_country)).distinct()
  71. # 分页
  72. paginator = Paginator(app_advertise_campaign_qs.order_by('id'), pageSize)
  73. campaigns = paginator.page(pageNo)
  74. # Construct response data with country names and device types
  75. campaign_list = []
  76. for campaign in campaigns.object_list:
  77. if campaign.unknown_country == 0:
  78. countries = ",".join([country.country_name for country in campaign.country_list])
  79. else:
  80. country_list = campaign.country_list
  81. country_names = []
  82. for country in country_list:
  83. country_names.append(country.country_name)
  84. country_names.append("未知地区")
  85. countries = ",".join(country_names)
  86. campaign_data = {
  87. 'id': campaign.id,
  88. 'image_url': 'https://ansjerfilemanager.s3.amazonaws.com/app/campaign/' + campaign.image_url,
  89. 'campaign_name': campaign.campaign_name,
  90. 'campaign_url': campaign.campaign_url,
  91. 'campaign_type': campaign.campaign_type,
  92. 'status': campaign.status,
  93. 'campaign_start_date': campaign.campaign_start_date,
  94. 'campaign_end_date': campaign.campaign_end_date,
  95. 'campaign_show_stime': campaign.campaign_show_stime,
  96. 'campaign_show_etime': campaign.campaign_show_etime,
  97. 'countries': countries,
  98. 'device_types': ",".join([device.name for device in campaign.device_type_list]),
  99. }
  100. campaign_list.append(campaign_data)
  101. data = {
  102. 'list': campaign_list,
  103. 'total': paginator.count,
  104. }
  105. return response.json(0, data)
  106. def add_campaign(self, request, request_dict, response):
  107. """
  108. 添加新的广告活动
  109. @param request_dict: 包含所有请求参数的字典
  110. @param response: 响应对象
  111. @return: 响应对象
  112. """
  113. file = request.FILES.get('posterFile', None)
  114. campaign_name = request_dict.get('campaign_name', None)
  115. campaign_url = request_dict.get('campaign_url', None)
  116. campaign_type = request_dict.get('campaign_type', None)
  117. status = request_dict.get('status', None)
  118. device_type_names = json.loads(request_dict.get('device_type_list', None)) # 设备类型名称列表
  119. country_name_list = json.loads(request_dict.get('country_name_list', None)) # 地区列表
  120. campaign_start_time = request_dict.get('campaign_start_time', None)
  121. campaign_end_time = request_dict.get('campaign_end_time', None)
  122. campaign_show_stime = request_dict.get('campaign_show_stime', 0)
  123. campaign_show_etime = request_dict.get('campaign_show_etime', 86399)
  124. if not all([campaign_name, campaign_type, device_type_names, campaign_url,
  125. country_name_list, campaign_start_time, campaign_end_time, file]):
  126. return response.json(444)
  127. # 针对特殊地区的处理,表没设计好用这个处理挽救一下
  128. unknown_country = 0
  129. if "未知地区" in country_name_list:
  130. unknown_country = 1
  131. country_name_list.remove("未知地区")
  132. fileName = file.name
  133. try:
  134. create_time = int(time.time())
  135. update_time = int(time.time())
  136. # 保存图片到存储桶
  137. bucket_name = 'ansjerfilemanager'
  138. file_key = f'app/campaign/OpenScreenAdvertise/{update_time}_{fileName}'
  139. s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
  140. # 地址:https://ansjerfilemanager.s3.amazonaws.com/app/campaign/OpenScreenAdvertise/XXX.jpg
  141. s3.upload_file_obj(
  142. bucket_name,
  143. file_key,
  144. file,
  145. {'ContentType': file.content_type, 'ACL': 'public-read'})
  146. # 创建 AppAdvertiseCampaign 实例
  147. new_campaign = AppAdvertiseCampaign.objects.create(
  148. image_url=f"OpenScreenAdvertise/{update_time}_{fileName}",
  149. campaign_name=campaign_name,
  150. campaign_url=campaign_url,
  151. campaign_type=campaign_type,
  152. status=status,
  153. unknown_country=unknown_country,
  154. campaign_start_date=campaign_start_time,
  155. campaign_end_date=campaign_end_time,
  156. campaign_show_stime=campaign_show_stime,
  157. campaign_show_etime=campaign_show_etime,
  158. create_time=create_time,
  159. update_time=update_time,
  160. )
  161. # 根据名称查找 DeviceTypeModel 的实例并建立关系
  162. device_type_instances = DeviceTypeModel.objects.filter(name__in=device_type_names)
  163. for device_type_instance in device_type_instances:
  164. new_campaign.device_type.add(device_type_instance)
  165. # 根据 ID 关联 CountryModel 实例
  166. country_instances = CountryModel.objects.filter(country_name__in=country_name_list)
  167. for country_instance in country_instances:
  168. new_campaign.country.add(country_instance)
  169. except Exception as e:
  170. return response.json(174)
  171. return response.json(0)
  172. def update_campaign(self, request, request_dict, response):
  173. campaign_id = request_dict.get('id', None)
  174. file = request.FILES.get('posterFile', None)
  175. campaign_name = request_dict.get('campaign_name', None)
  176. campaign_url = request_dict.get('campaign_url', None)
  177. campaign_type = request_dict.get('campaign_type', None)
  178. device_type_names = json.loads(request_dict.get('device_type_list', None)) # 设备类型名称列表
  179. country_name_list = json.loads(request_dict.get('country_name_list', None)) # 地区列表
  180. campaign_start_time = request_dict.get('campaign_start_time', None)
  181. campaign_end_time = request_dict.get('campaign_end_time', None)
  182. campaign_show_stime = request_dict.get('campaign_show_stime', None)
  183. campaign_show_etime = request_dict.get('campaign_show_etime', None)
  184. if not campaign_id:
  185. return response.json(444)
  186. try:
  187. update_time = int(time.time())
  188. campaign = AppAdvertiseCampaign.objects.get(id=campaign_id)
  189. if country_name_list is not None:
  190. if "未知地区" in country_name_list:
  191. campaign.unknown_country = 1
  192. country_name_list.remove("未知地区")
  193. else:
  194. campaign.unknown_country = 0
  195. if file is not None:
  196. # 删除存储桶原来的图片
  197. s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
  198. bucket_name = 'ansjerfilemanager'
  199. if campaign.image_url:
  200. old_file_key = campaign.image_url.split('/')[-1]
  201. s3.delete_obj(bucket_name, old_file_key)
  202. # 添加新的图片
  203. file_key = f'app/campaign/OpenScreenAdvertise/{update_time}_{file.name}'
  204. s3.upload_file_obj(
  205. bucket_name,
  206. file_key,
  207. file,
  208. {'ContentType': file.content_type, 'ACL': 'public-read'}
  209. )
  210. campaign.image_url = f'OpenScreenAdvertise/{update_time}_{file.name}'
  211. if campaign_name is not None:
  212. campaign.campaign_name = campaign_name
  213. if campaign_url is not None:
  214. campaign.campaign_url = campaign_url
  215. if campaign_type is not None:
  216. campaign.campaign_type = campaign_type
  217. if campaign_start_time is not None:
  218. campaign.campaign_start_date = campaign_start_time
  219. if campaign_end_time is not None:
  220. campaign.campaign_end_date = campaign_end_time
  221. if campaign_show_stime is not None:
  222. campaign.campaign_show_stime = campaign_show_stime
  223. if campaign_show_etime is not None:
  224. campaign.campaign_show_etime = campaign_show_etime
  225. # 更新多对多字段 - 设备类型
  226. if device_type_names:
  227. device_types = DeviceTypeModel.objects.filter(name__in=device_type_names)
  228. campaign.device_type.set(device_types)
  229. # 更新多对多字段 - 国家/地区
  230. if country_name_list:
  231. countries = CountryModel.objects.filter(country_name__in=country_name_list)
  232. campaign.country.set(countries)
  233. campaign.update_time = update_time
  234. # 保存更新
  235. campaign.save()
  236. except Exception as e:
  237. return response.json(177)
  238. return response.json(0)
  239. def switch_campaign(self, request_dict, response):
  240. campaign_id = request_dict.get('id')
  241. status = request_dict.get('status')
  242. if not campaign_id:
  243. return response.json(444)
  244. try:
  245. campaign = AppAdvertiseCampaign.objects.get(pk=campaign_id)
  246. # 更新字段
  247. campaign.status = status
  248. campaign.update_time = int(time.time())
  249. # 保存更改
  250. campaign.save()
  251. return response.json(0)
  252. except Exception as e:
  253. return response.json(444)
  254. def delete_campaign(self, request_dict, response):
  255. campaign_id = request_dict.get('id')
  256. if not campaign_id:
  257. return response.json(444)
  258. try:
  259. campaign = AppAdvertiseCampaign.objects.get(id=campaign_id)
  260. campaign.device_type.clear()
  261. campaign.country.clear()
  262. campaign.delete()
  263. return response.json(0)
  264. except Exception as e:
  265. return response.json(444)
  266. def app_get_campaigns(self, request_dict, response):
  267. """
  268. APP获取广告活动列表
  269. @param request_dict: 请求参数
  270. @param response: 响应对象
  271. @return: 响应对象
  272. """
  273. tz = request_dict.get('时区','tz')
  274. country_prefetch = Prefetch('country', queryset=CountryModel.objects.only('country_name'), to_attr='country_list')
  275. device_type_prefetch = Prefetch('device_type', queryset=DeviceTypeModel.objects.only('name'), to_attr='device_type_list')
  276. app_advertise_campaign_qs = AppAdvertiseCampaign.objects.prefetch_related(country_prefetch, device_type_prefetch)
  277. app_advertise_campaign_qs = (app_advertise_campaign_qs.objects.filter(status=1,)
  278. .values('image_url', 'campaign_name', 'campaign_type',
  279. 'campaign_start_time', 'campaign_end_time',
  280. 'campaign_show_stime', 'campaign_show_etime',
  281. ))
  282. #返回 广告名称、广告类型、开始时间、结束时间、广告图片、活动链接
  283. campaigns_list = []
  284. # 调整时区返回时间
  285. for campaign in app_advertise_campaign_qs:
  286. # 将时间戳转换为UTC的datetime对象
  287. start_utc_time = datetime.utcfromtimestamp(int(campaign['campaign_start_time'])).replace(tzinfo=pytz.utc)
  288. end_utc_time = datetime.utcfromtimestamp(int(campaign['campaign_end_time'])).replace(tzinfo=pytz.utc)
  289. campaigns_list.append(campaign)
  290. return response.json(0,{
  291. 'campaigns': campaigns_list
  292. })
  293. def record_user_behavior(self, request_dict, response):
  294. """
  295. 记录用户行为
  296. @param request_dict: 请求参数
  297. @param response: 响应对象
  298. @return: 响应对象
  299. """
  300. pass