AppSetController.py 16 KB

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