AppSetController.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. import json
  2. import logging
  3. import time
  4. from django.db import transaction
  5. from django.views.generic.base import View
  6. from Ansjer.config import SERVER_TYPE, CONFIG_INFO, CONFIG_TEST
  7. from Model.models import AppSetModel, PromotionRuleModel, PopupsConfig, RedDotsConfig, Device_Info, UidSetModel, \
  8. UserOperationLog, Order_Model, IPAddr, RegionRestriction, UserSetStatus
  9. from Object.Enums.ConstantEnum import ConstantEnum
  10. from Object.Enums.RedisKeyConstant import RedisKeyConstant
  11. from Object.IPWeatherObject import IPQuery
  12. from Object.RedisObject import RedisObject
  13. from Object.ResponseObject import ResponseObject
  14. from Object.TokenObject import TokenObject
  15. from Object.utils import LocalDateTimeUtil
  16. from Service.CommonService import CommonService
  17. from Service.ModelService import ModelService
  18. LOGGER = logging.getLogger('info')
  19. class AppSetView(View):
  20. def get(self, request, *args, **kwargs):
  21. request.encoding = 'utf-8'
  22. operation = kwargs.get('operation', None)
  23. return self.validation(request.GET, request, operation)
  24. def post(self, request, *args, **kwargs):
  25. request.encoding = 'utf-8'
  26. operation = kwargs.get('operation', None)
  27. return self.validation(request.POST, request, operation)
  28. def validation(self, request_dict, request, operation):
  29. response = ResponseObject()
  30. if operation == 'query':
  31. return self.do_query(request_dict, response)
  32. token = request_dict.get('token', None)
  33. if not token:
  34. token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
  35. tko = TokenObject(token)
  36. if tko.code != 0:
  37. return response.json(tko.code)
  38. user_id = tko.userID
  39. if operation == 'page_set': # app弹窗标记红点设置
  40. return self.do_page_set(user_id, request_dict, response)
  41. elif operation == 'ai-preview':
  42. return self.save_user_popups_log(user_id, request_dict, response)
  43. elif operation == 'admin_query':
  44. return self.do_admin_query(user_id, request_dict, response)
  45. elif operation == 'admin_update':
  46. return self.do_admin_update(user_id, request_dict, response)
  47. elif operation == 'statusByIp':
  48. return self.status_by_ip(user_id, request, response)
  49. elif operation == 'userSetAdStatus':
  50. return self.user_set_ad_status(user_id, request_dict, response)
  51. elif operation == 'promotionTime':
  52. return self.promotion_time(user_id, response)
  53. else:
  54. return response.json(414)
  55. @staticmethod
  56. def do_query(request_dict, response):
  57. """
  58. 查询app配置
  59. @param request_dict: 请求数据
  60. @request_dict lang: 语言
  61. @request_dict appBundleId: app包id
  62. @param response: 响应
  63. @return: response
  64. """
  65. lang = request_dict.get('lang', None)
  66. appBundleId = request_dict.get('appBundleId', None)
  67. if not appBundleId:
  68. return response.json(444, 'appBundleId')
  69. app_set_qs = AppSetModel.objects.filter(appBundleId=appBundleId).values('content')
  70. if not app_set_qs.exists():
  71. return response.json(173)
  72. try:
  73. if not app_set_qs[0]['content']:
  74. return response.json(0)
  75. dict_json = json.loads(app_set_qs[0]['content'])
  76. # 加入促销弹窗
  77. promotion = PromotionRuleModel.objects.filter(status=1).values('startTime', 'endTime', 'popups')
  78. if promotion.exists():
  79. dict_json['popupsStartTime'] = promotion[0]['startTime']
  80. dict_json['popupsEndTime'] = promotion[0]['endTime']
  81. dict_json['popupsContent'] = json.loads(promotion[0]['popups']).get(lang, '')
  82. dict_json['nowTime'] = int(time.time())
  83. if 'editionUpgrading' in dict_json:
  84. dict_json['editionUpgrading'] = ''
  85. if dict_json['editionUpgrading'] == 1:
  86. if lang == 'cn':
  87. dict_json['editionUpgrading'] = '正在升级,请稍后登录'
  88. else:
  89. dict_json['editionUpgrading'] = 'Upgrading, please sign in later'
  90. return response.json(0, dict_json)
  91. except Exception as e:
  92. return response.json(500, '错误行数:{errLine}, 错误信息: {errmsg}'.format(errLine=e.__traceback__.tb_lineno,
  93. errmsg=repr(e)))
  94. def do_admin_query(self, userID, request_dict, response):
  95. # 查询和添加权限
  96. own_perm = ModelService.check_perm(userID, 40)
  97. if not own_perm:
  98. return response.json(404)
  99. appBundleId = request_dict.get('appBundleId', None)
  100. sm_qs = AppSetModel.objects.filter(appBundleId=appBundleId)
  101. count = sm_qs.count()
  102. nowTime = int(time.time())
  103. if count > 0:
  104. sm_qs = sm_qs.values('id', 'appBundleId', 'content', 'addTime', 'updTime')
  105. return response.json(0, {'data': list(sm_qs), 'count': count})
  106. else:
  107. AppSetModel.objects.create(
  108. appBundleId=appBundleId,
  109. addTime=nowTime,
  110. updTime=nowTime
  111. )
  112. return response.json(0)
  113. def do_admin_update(self, userID, request_dict, response):
  114. # 修改的权限
  115. own_perm = ModelService.check_perm(userID, 50)
  116. if not own_perm:
  117. return response.json(404)
  118. appBundleId = request_dict.get('appBundleId', None)
  119. content = request_dict.get('content', None)
  120. nowTime = int(time.time())
  121. sm_qs = AppSetModel.objects.filter(appBundleId=appBundleId)
  122. redis = RedisObject()
  123. if SERVER_TYPE != "Ansjer.formal_settings":
  124. key_id = "www" + appBundleId
  125. else:
  126. key_id = "test" + appBundleId
  127. redis.del_data(key=key_id)
  128. if sm_qs.exists():
  129. sm_qs.update(content=content, updTime=nowTime)
  130. return response.json(0)
  131. else:
  132. return response.json(173)
  133. @staticmethod
  134. def do_page_set(userID, request_dict, response):
  135. """
  136. 初始化加载红点以及弹窗数据
  137. """
  138. try:
  139. lang = request_dict.get('lang', 'en')
  140. dict_json = {}
  141. now_time = int(time.time())
  142. dict_json['popups'] = {
  143. 'title': '',
  144. 'content': '',
  145. 'status': 0,
  146. 'tag': 1,
  147. }
  148. with transaction.atomic():
  149. # AI弹窗
  150. dict_json['aiPopups'] = AppSetView.get_ai_init_data(userID, lang)
  151. # 弹窗
  152. popups_obj = PopupsConfig.objects.filter(lang=lang).values('title', 'content', 'start_time', 'end_time',
  153. 'tag')
  154. if popups_obj.exists():
  155. popups_status = 0
  156. if popups_obj[0]['start_time'] <= now_time <= popups_obj[0]['end_time']:
  157. popups_status = 1
  158. dict_json['popups'] = {
  159. 'title': popups_obj[0]['title'],
  160. 'content': popups_obj[0]['content'],
  161. 'status': popups_status,
  162. 'tag': popups_obj[0]['tag'],
  163. }
  164. # 红点标记
  165. dict_json['red_dots'] = []
  166. red_dots_obj = RedDotsConfig.objects.values('module', 'start_time', 'end_time')
  167. is_show_red_dots = AppSetView.check_user_is_show_red_dot(userID) # 是否显示红点
  168. for red_dots in red_dots_obj:
  169. red_dots_status = 0
  170. if red_dots['start_time'] <= now_time <= red_dots['end_time']:
  171. red_dots_status = 1
  172. ai_detection = red_dots['module']
  173. if ai_detection == 'ai_detects_purchases':
  174. red_dots_status = 1 if is_show_red_dots else 0
  175. dict_json['red_dots'].append({
  176. 'module': red_dots['module'],
  177. 'status': red_dots_status,
  178. })
  179. dict_json['red_dots'] = list(dict_json['red_dots'])
  180. return response.json(0, dict_json)
  181. except Exception as e:
  182. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  183. return response.json(500)
  184. @staticmethod
  185. def get_ai_init_data(user_id, lang):
  186. """
  187. 初始化获取AI弹窗数据
  188. @param user_id: 用户id
  189. @param lang: 语言
  190. @return: popups_qs
  191. """
  192. now_time = int(time.time())
  193. popups_qs = PopupsConfig.objects.filter(tag=2, lang=lang) \
  194. .values('title', 'content', 'start_time', 'end_time', 'tag')
  195. if not popups_qs.exists():
  196. return {}
  197. ai_device = AppSetView.get_user_ai_device(user_id)
  198. if not ai_device:
  199. return {}
  200. # 当前时间小于弹窗开始时间或者大于结束时间 则返回空字符串
  201. if not popups_qs[0]['start_time'] <= now_time <= popups_qs[0]['end_time']:
  202. return {}
  203. user_ai_log_qs = UserOperationLog.objects.filter(user_id=user_id, type=2).values('created_time')
  204. user_log = {'user_id': user_id, 'status': 1, 'type': 2, 'created_time': now_time, 'updated_time': now_time}
  205. popups_status = 0
  206. # 用户有AI设备 没有操作过弹窗则显示
  207. if not user_ai_log_qs.exists():
  208. popups_status = 1
  209. UserOperationLog.objects.create(**user_log)
  210. else:
  211. now_date = int(LocalDateTimeUtil.time_stamp_to_time(now_time, '%Y%m%d'))
  212. created_date = int(LocalDateTimeUtil.time_stamp_to_time(user_ai_log_qs[0]['created_time'], '%Y%m%d'))
  213. if user_ai_log_qs.count() == 1 and now_date > created_date:
  214. popups_status = 1
  215. UserOperationLog.objects.create(**user_log)
  216. return {
  217. 'title': popups_qs[0]['title'],
  218. 'content': popups_qs[0]['content'],
  219. 'status': popups_status,
  220. 'tag': popups_qs[0]['tag'],
  221. }
  222. @staticmethod
  223. def get_user_ai_device(user_id):
  224. """
  225. 获取用户设备是否有有支持AI功能
  226. @param user_id: 用户ID
  227. @return: True|False
  228. """
  229. device_info = Device_Info.objects.filter(userID_id=user_id, isExist=1).values('UID')
  230. if not device_info.exists():
  231. return False
  232. uid_list = []
  233. for item in device_info:
  234. uid_list.append(item['UID'])
  235. uid_info_qs = UidSetModel.objects.filter(uid__in=uid_list).values('is_ai')
  236. if not uid_info_qs.exists():
  237. return False
  238. if 1 or 0 in uid_info_qs:
  239. return True
  240. return False
  241. @staticmethod
  242. def check_user_is_show_red_dot(user_id):
  243. """
  244. 获取用户是否显示红点
  245. 用户体验过AI免费套餐不显示 OR 用户操作记录阅读过AI介绍界面不显示
  246. @param user_id: 用户ID
  247. @return: True | False
  248. """
  249. order_qs = Order_Model.objects.filter(userID_id=user_id, order_type=2, status=1, payType=10)
  250. ai_red_dot_qs = UserOperationLog.objects.filter(user_id=user_id, type=4)
  251. return not ai_red_dot_qs.exists() and not order_qs.exists()
  252. @classmethod
  253. def save_user_popups_log(cls, user_id, request_dict, response):
  254. """
  255. 保存用户预览AI介绍页面记录
  256. @param request_dict: type
  257. @param user_id: 用户id
  258. @param response: 响应对象
  259. """
  260. try:
  261. rq_type = request_dict.get('type', 0)
  262. now_time = int(time.time())
  263. user_log = {'user_id': user_id, 'status': 1, 'type': int(rq_type), 'created_time': now_time,
  264. 'updated_time': now_time}
  265. UserOperationLog.objects.create(**user_log)
  266. except Exception as e:
  267. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  268. return response.json(500)
  269. return response.json(0)
  270. @staticmethod
  271. def status_by_ip(user_id, request, response):
  272. """
  273. 根据ip解析或用户设置返回状态
  274. """
  275. try:
  276. ip = CommonService.get_ip_address(request)
  277. ip_addr_qs = IPAddr.objects.filter(ip=ip, is_geoip2=False).values('country_code', 'city', 'region',
  278. 'district')
  279. if ip_addr_qs.exists():
  280. ip_info = ip_addr_qs[0]
  281. else:
  282. ip_qs = IPQuery(ip)
  283. ip_info = {
  284. 'country_code': ip_qs.country_id,
  285. 'region': ip_qs.region,
  286. 'city': ip_qs.city,
  287. 'district': ip_qs.district
  288. }
  289. country_code = ip_info['country_code']
  290. region = ip_info['region']
  291. city = ip_info['city']
  292. district = ip_info['district']
  293. restrictions_qs = RegionRestriction.objects.all()
  294. user_set_status_qs = UserSetStatus.objects.filter(user_id=user_id)
  295. response_data = {}
  296. for restriction in restrictions_qs:
  297. response_data[restriction.statusName] = 0
  298. user_set_qs = user_set_status_qs.filter(region_restriction_id=restriction.id)
  299. # 用户控制
  300. if user_set_qs.exists():
  301. if restriction.statusName == "splashAdStatus":
  302. if user_set_qs[0].end_time > int(time.time()):
  303. response_data[restriction.statusName] = user_set_qs[0].status
  304. else:
  305. response_data[restriction.statusName] = restriction.default_status
  306. else:
  307. response_data[restriction.statusName] = user_set_qs[0].status
  308. # 地区控制
  309. elif ((not restriction.country_code or country_code in restriction.country_code) and
  310. (not restriction.region or region in restriction.region) and
  311. (not restriction.city or city in restriction.city) and
  312. (not restriction.district or district in restriction.district)):
  313. # 返回值定义具体看表的content字段
  314. response_data[restriction.statusName] = restriction.default_status
  315. LOGGER.info(f"请求ip地址为 {ip}, 解析为 {country_code}, {region}, {city}, {district}")
  316. return response.json(0, response_data)
  317. except Exception as e:
  318. LOGGER.info('根据ip解析地址返回状态异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  319. return response.json(500)
  320. @staticmethod
  321. def user_set_ad_status(user_id, request_dict, response):
  322. """
  323. 用户设置广告状态
  324. """
  325. try:
  326. status_name = request_dict.get("statusName", None)
  327. value = request_dict.get("value", None)
  328. if not all([status_name, value]):
  329. return response.json(444)
  330. value = int(value)
  331. now_time = int(time.time())
  332. end_time = now_time + 15 * 24 * 60 * 60
  333. region_restriction_qs = RegionRestriction.objects.filter(statusName=status_name)
  334. user_set_status_qs = UserSetStatus.objects.filter(user_id=user_id,
  335. region_restriction_id=region_restriction_qs[0].id)
  336. if not region_restriction_qs.exists():
  337. return response.json(173)
  338. if not user_set_status_qs.exists():
  339. UserSetStatus.objects.create(user_id=user_id, status=value, created_time=now_time,
  340. updated_time=now_time, end_time=end_time,
  341. region_restriction_id=region_restriction_qs[0])
  342. else:
  343. user_set_status_qs.update(status=value, updated_time=now_time, end_time=end_time)
  344. return response.json(0)
  345. except Exception as e:
  346. LOGGER.info('设置用户广告状态异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  347. return response.json(500)
  348. @staticmethod
  349. def promotion_time(user_id, response):
  350. """
  351. 促销时间
  352. @return:
  353. """
  354. redis_obj = RedisObject()
  355. distribute_key = RedisKeyConstant.CLOUD_STORAGE_COUPONS.value + user_id
  356. is_distributed = redis_obj.get_data(distribute_key)
  357. if is_distributed == '1':
  358. if CONFIG_INFO == CONFIG_TEST:
  359. start_time = 1734080109
  360. else:
  361. start_time = ConstantEnum.PROMOTION_START_TIME.value
  362. res = {
  363. 'start_time': start_time,
  364. 'end_time': ConstantEnum.PROMOTION_END_TIME.value
  365. }
  366. return response.json(0, res)
  367. return response.json(0)