AlgorithmShopController.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. # -*- encoding: utf-8 -*-
  2. """
  3. @File : AlgorithmShopController.py
  4. @Time : 2022/8/24 20:02
  5. @Author : stephen
  6. @Email : zhangdongming@asj6.wecom.work
  7. @Software: PyCharm
  8. """
  9. import json
  10. import logging
  11. import math
  12. import time
  13. from datetime import datetime, timedelta
  14. from urllib.parse import urlparse
  15. from django.db.models import F, Value, CharField, Sum
  16. from django.views.generic.base import View
  17. from Model.models import DeviceAlgorithmExplain, DeviceAlgorithmBanner, DeviceUidAlgorithmType, \
  18. DeviceTypeAlgorithmInfo, DeviceAppScenario, DeviceScenarioLangInfo, DeviceAlgorithmScenario, \
  19. DeviceAlgorithmPassengerFlow
  20. from Object.ETkObject import ETkObject
  21. from Object.Enums.TimeZone import TimeZone
  22. from Object.RedisObject import RedisObject
  23. from Object.ResponseObject import ResponseObject
  24. from Object.TokenObject import TokenObject
  25. from Object.utils import LocalDateTimeUtil
  26. from Ansjer.config import DETECT_PUSH_DOMAINS
  27. LOGGER = logging.getLogger('info')
  28. class AlgorithmShopView(View):
  29. def get(self, request, *args, **kwargs):
  30. request.encoding = 'utf-8'
  31. operation = kwargs.get('operation')
  32. return self.validation(request.GET, request, operation)
  33. def post(self, request, *args, **kwargs):
  34. request.encoding = 'utf-8'
  35. operation = kwargs.get('operation')
  36. return self.validation(request.POST, request, operation)
  37. def validation(self, request_dict, request, operation):
  38. if operation == 'passengerFlowStatistical':
  39. return self.passenger_flow_statistical(request_dict, ResponseObject('en'))
  40. token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
  41. lang = request_dict.get('lang', token.lang)
  42. response = ResponseObject(lang)
  43. if token.code != 0:
  44. return response.json(token.code)
  45. if operation == 'list':
  46. return self.algorithm_list(request_dict, response)
  47. elif operation == 'banner-list':
  48. return self.get_algorithm_banner(response)
  49. elif operation == 'uid-details':
  50. return self.get_algorithm_details(request_dict, response)
  51. elif operation == 'save':
  52. return self.algorithm_setting_save(request_dict, response)
  53. elif operation == 'getScenarioList': # 获取应用场景数据列表
  54. return self.get_scenario_list(request_dict, response)
  55. elif operation == 'getAlgorithmListByScenarioId': # 根据应用场景id获取算法列表
  56. return self.get_scenario_algorithm_list(request_dict, response)
  57. elif operation == 'getPassengerFlowList': # 获取客流统计列表
  58. return self.get_passenger_flow_list(request_dict, response)
  59. elif operation == 'getNotifyDomain':
  60. return self.get_notify_domain(response)
  61. else:
  62. return response.json(0)
  63. @classmethod
  64. def passenger_flow_statistical(cls, request_dict, response):
  65. """
  66. 添加客流统计
  67. Args:
  68. request_dict (dict): 请求参数字典
  69. response: 响应对象
  70. """
  71. try:
  72. LOGGER.info('*****AlgorithmShopView.passenger_flow_statistical:params{}'.format(json.dumps(request_dict)))
  73. sign = request_dict.get('sign')
  74. eto = ETkObject(sign)
  75. uid = eto.uid
  76. if not uid:
  77. return response.json(444)
  78. d_time = request_dict.get('deviceTime') # 设备上报时间的
  79. enter_count = request_dict.get('enterCount') # 进 统计
  80. tz_value = request_dict.get('timeZone') # 时区
  81. exit_count = request_dict.get('exitCount') # 出 统计
  82. channel = int(request_dict.get('channel', '1')) # 设备通道号
  83. if not all([sign, enter_count, exit_count, tz_value]):
  84. return response.json(444)
  85. enter_count = int(enter_count)
  86. exit_count = int(exit_count)
  87. redis = RedisObject(5)
  88. key = f'ASJ:PASSENGER:FLOW:{uid}:{channel}:{d_time}'
  89. # 检查Redis中是否已存在相同key的数据
  90. r_data = redis.get_data(key)
  91. if r_data:
  92. return response.json(0)
  93. now_time = int(time.time())
  94. data = {
  95. 'uid': uid,
  96. 'updated_time': now_time,
  97. 'created_time': now_time,
  98. 'device_time': int(d_time),
  99. 'channel': channel
  100. }
  101. tz = TimeZone.get_value(int(tz_value))
  102. date_time = LocalDateTimeUtil.time_format_date(int(d_time), tz)
  103. data['statistical_time'] = datetime.strptime(date_time, '%Y-%m-%d %H:%M:%S')
  104. LOGGER.info(f'uid{uid},channel:{channel},DeviceTime:{d_time},tz:{tz},结果:{date_time}')
  105. passenger_flow_list = []
  106. data['count'] = enter_count # 进
  107. data['type'] = 1
  108. passenger_flow_list.append(DeviceAlgorithmPassengerFlow(**data))
  109. data['count'] = exit_count # 出
  110. data['type'] = 2
  111. passenger_flow_list.append(DeviceAlgorithmPassengerFlow(**data))
  112. DeviceAlgorithmPassengerFlow.objects.bulk_create(passenger_flow_list)
  113. # 将数据存入Redis,并设置过期时间为10分钟
  114. redis.CONN.setnx(key, d_time)
  115. redis.CONN.expire(key, 600)
  116. return response.json(0)
  117. except Exception as e:
  118. LOGGER.info('***get_algorithm_list_by_scenario_id,errLine:{}, errMsg:{}'
  119. .format(e.__traceback__.tb_lineno, repr(e)))
  120. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  121. @classmethod
  122. def get_algorithm_list_by_scenario_id(cls, scenario_id, lang):
  123. """
  124. 根据应用场景ID查询算法信息列表
  125. @param scenario_id: 场景ID
  126. @param lang: 语言
  127. @return: 算法类型信息
  128. """
  129. try:
  130. if not scenario_id or scenario_id == 0:
  131. return []
  132. # 根据场景id查询关联的算法id
  133. algorithm_scenario_qs = DeviceAlgorithmScenario.objects.filter(scenario_id=scenario_id) \
  134. .order_by('sort').values('algorithm_id')
  135. if not algorithm_scenario_qs.exists():
  136. return []
  137. algorithm_list = []
  138. for item in algorithm_scenario_qs:
  139. algorithm_id = item['algorithm_id']
  140. # 根据算法id查询多语言数据
  141. algorithm_list.append(cls.get_lang_info_by_algorithm_id(algorithm_id, lang, None))
  142. return algorithm_list
  143. except Exception as e:
  144. LOGGER.info('***get_algorithm_list_by_scenario_id,errLine:{}, errMsg:{}'
  145. .format(e.__traceback__.tb_lineno, repr(e)))
  146. return []
  147. @classmethod
  148. def get_lang_info_by_algorithm_id(cls, algorithm_id, lang, uid):
  149. """
  150. 根据算法id查询多语言数据详情
  151. @param uid: 设备uid
  152. @param algorithm_id: 算法id
  153. @param lang: 语言
  154. @return: 算法多语言数据详情
  155. """
  156. try:
  157. algorithm_qs = DeviceAlgorithmExplain.objects.filter(algorithm_type_id=algorithm_id, lang=lang) \
  158. .values('algorithm_type__icon_url', 'algorithm_type__id',
  159. 'title', 'subtitle', 'algorithm_type__image_url',
  160. 'algorithm_type__basic_function', 'concerning',
  161. 'price', 'algorithm_type__tag', 'algorithm_type__status',
  162. 'algorithm_type__type')
  163. if not algorithm_qs.exists():
  164. return {}
  165. setting = '' # 当前支持设置的算法功能json
  166. # 存在uid则查询当前uid是否支持该算法
  167. if uid:
  168. setting = cls.get_uid_algorithm_info(algorithm_id, uid)
  169. setting = setting if setting else {'status': 0, 'function': {}}
  170. data = {
  171. 'typeId': algorithm_qs[0]['algorithm_type__id'],
  172. 'iconUrl': algorithm_qs[0]['algorithm_type__icon_url'],
  173. 'imageUrl': algorithm_qs[0]['algorithm_type__image_url'],
  174. 'title': algorithm_qs[0]['title'],
  175. 'subtitle': algorithm_qs[0]['subtitle'],
  176. 'basicFunction': algorithm_qs[0]['algorithm_type__basic_function'],
  177. 'concerning': algorithm_qs[0]['concerning'],
  178. 'price': algorithm_qs[0]['price'],
  179. 'tag': algorithm_qs[0]['algorithm_type__tag'],
  180. 'status': algorithm_qs[0]['algorithm_type__status'],
  181. 'setting': setting,
  182. 'type': algorithm_qs[0]['algorithm_type__type']
  183. }
  184. return data
  185. except Exception as e:
  186. LOGGER.info('***get_lang_info_by_algorithm_id,errLine:{}, errMsg:{}'
  187. .format(e.__traceback__.tb_lineno, repr(e)))
  188. return {}
  189. @classmethod
  190. def get_algorithm_list(cls, lang):
  191. """
  192. 获取所有算法数据列表
  193. @return: 算法数据列表
  194. """
  195. algorithm_qs = DeviceAlgorithmExplain.objects.filter(lang=lang).order_by('algorithm_type__sort') \
  196. .annotate(iconUrl=F('algorithm_type__icon_url'),
  197. typeId=F('algorithm_type__id'),
  198. type=F('algorithm_type__type'),
  199. imageUrl=F('algorithm_type__image_url'),
  200. basicFunction=F('algorithm_type__basic_function'),
  201. tag=F('algorithm_type__tag'), status=F('algorithm_type__status'),
  202. setting=Value('', output_field=CharField())) \
  203. .values('iconUrl', 'imageUrl', 'title', 'subtitle', 'concerning', 'basicFunction', 'price', 'tag', 'status',
  204. 'setting', 'typeId', 'type')
  205. if not algorithm_qs.exists():
  206. return []
  207. return list(algorithm_qs)
  208. @classmethod
  209. def get_scenario_list(cls, request_dist, response):
  210. """
  211. 获取应用场景列表
  212. @param request_dist: lang
  213. @param response: 响应结果
  214. @return: 应用场景列表
  215. """
  216. try:
  217. lang = request_dist.get('lang', 'en')
  218. if not lang:
  219. return response.json(444)
  220. # 获取应用场景列表
  221. scenario_qs = DeviceAppScenario.objects.filter().exclude(type=0).all().order_by('sort') \
  222. .values('id', 'type', 'cver_url', 'banner_url')
  223. scenario_list = []
  224. if not scenario_qs.exists():
  225. return response.json(0, scenario_list)
  226. for item in scenario_qs:
  227. scenario_vo = {'id': item['id'], 'cverUrl': item['cver_url'], 'bannerUrl': item['banner_url'],
  228. 'name': '', 'content': ''}
  229. # 获取根据语言应用场景信息
  230. scenario_info_qs = DeviceScenarioLangInfo.objects.filter(lang=lang, scenario_id=item['id']) \
  231. .values('name', 'content')
  232. if not scenario_info_qs.exists():
  233. continue
  234. scenario_vo['name'] = scenario_info_qs[0]['name']
  235. scenario_vo['content'] = scenario_info_qs[0]['content']
  236. # 根据应用场景id查询关联算法类型数据
  237. # scenario_vo['algorithmList'] = cls.get_algorithm_list_by_scenario_id(item['id'], lang)
  238. scenario_list.append(scenario_vo)
  239. # 获取所有算法图标地址以及算法名称
  240. algorithm_qs = DeviceAlgorithmExplain.objects.filter(lang=lang).order_by('algorithm_type__sort') \
  241. .annotate(algorithmId=F('algorithm_type__id'), algorithmType=F('algorithm_type__type'),
  242. iconUrl=F('algorithm_type__icon_url'),
  243. algorithmName=F('title')).values('algorithmId', 'algorithmType', 'iconUrl', 'algorithmName')
  244. scenario_qs = DeviceAppScenario.objects.filter(type=0) \
  245. .values('cver_url', 'banner_url')
  246. scenario_banner = {}
  247. if scenario_qs.exists():
  248. scenario_banner['cverUrl'] = scenario_qs[0]['cver_url']
  249. scenario_banner['bannerUrl'] = scenario_qs[0]['banner_url']
  250. result_dto = {'scenarioList': scenario_list, 'scenarioUrl': scenario_banner}
  251. if algorithm_qs.exists():
  252. result_dto['iconList'] = list(algorithm_qs)
  253. return response.json(0, result_dto)
  254. except Exception as e:
  255. LOGGER.info('接口异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  256. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  257. @classmethod
  258. def get_scenario_algorithm_list(cls, request_dist, response):
  259. """
  260. 获取应用场景关联算法列表
  261. @param request_dist: scenarioId、lang
  262. @param response: 响应结果
  263. @return: 算法列表
  264. """
  265. scenario_id = request_dist.get('scenarioId', None)
  266. lang = request_dist.get('lang', 'en')
  267. result_dto = {'scenarioBannerUrl': ''}
  268. if not scenario_id:
  269. result_dto['algorithmList'] = cls.get_algorithm_list(lang)
  270. return response.json(0, result_dto)
  271. result_dto['algorithmList'] = cls.get_algorithm_list_by_scenario_id(scenario_id, lang)
  272. return response.json(0, result_dto)
  273. @classmethod
  274. def get_algorithm_banner(cls, response):
  275. """
  276. 获取算法小店banner
  277. """
  278. banner_qs = DeviceAlgorithmBanner.objects.all()
  279. banner_vs = banner_qs.order_by('sort') \
  280. .values('algorithm_type__type', 'algorithm_type__id', 'image_url')
  281. banner_list = []
  282. if not banner_vs.exists():
  283. return response.json(0, banner_list)
  284. for item in banner_vs:
  285. banner_list.append({
  286. 'typeId': item['algorithm_type__id'],
  287. 'type': item['algorithm_type__type'],
  288. 'imageUrl': item['image_url'],
  289. })
  290. return response.json(0, banner_list)
  291. @classmethod
  292. def algorithm_list(cls, request_dict, response):
  293. """
  294. 获取算法小店列表
  295. """
  296. try:
  297. lang = request_dict.get('lang', 'en')
  298. uid = request_dict.get('uid', None)
  299. version = request_dict.get('version', 'v1')
  300. algorithm_qs = DeviceAlgorithmExplain.objects.filter(lang=lang)
  301. device_ver = request_dict.get('deviceVer', None)
  302. device_code = request_dict.get('deviceCode', None)
  303. LOGGER.info(f'AlgorithmShopView.algorithm_list ver:{device_ver},code:{device_code}')
  304. types = [0, 1, 3, 4, 5]
  305. if version == 'v1':
  306. algorithm_qs = algorithm_qs.filter(algorithm_type__type__in=types)
  307. algorithm_qs = algorithm_qs.order_by('algorithm_type__sort') \
  308. .values('algorithm_type__id', 'algorithm_type__type',
  309. 'algorithm_type__icon_url',
  310. 'title', 'subtitle', 'algorithm_type__image_url',
  311. 'algorithm_type__basic_function', 'concerning',
  312. 'algorithm_type__resource')
  313. algorithm_list = []
  314. device_code = device_code[0:4] if device_code else device_code
  315. if not algorithm_qs.exists():
  316. return response.json(0, algorithm_list)
  317. for item in algorithm_qs:
  318. setting = ''
  319. if uid:
  320. setting = cls.get_uid_algorithm_info(item['algorithm_type__id'], uid)
  321. setting = setting if setting else {'status': 0, 'function': {}}
  322. resource = item['algorithm_type__resource']
  323. resource = resource.get(device_code, '') if resource else ''
  324. algorithm_list.append({
  325. 'typeId': item['algorithm_type__id'],
  326. 'type': item['algorithm_type__type'],
  327. 'iconUrl': item['algorithm_type__icon_url'],
  328. 'imageUrl': item['algorithm_type__image_url'],
  329. 'title': item['title'],
  330. 'subtitle': item['subtitle'],
  331. 'setting': setting,
  332. 'basicFunction': item['algorithm_type__basic_function'],
  333. 'concerning': item['concerning'],
  334. 'resource': resource
  335. })
  336. return response.json(0, algorithm_list)
  337. except Exception as e:
  338. print('查询算法小店列表异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  339. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  340. @classmethod
  341. def get_algorithm_details(cls, request_dict, response):
  342. """
  343. 获取算法小店类型详情
  344. """
  345. try:
  346. lang = request_dict.get('lang', 'en')
  347. type_id = request_dict.get('typeId', None)
  348. if not type_id:
  349. return response.json(444, 'typeId not null')
  350. type_id = int(type_id)
  351. uid = request_dict.get('uid', None)
  352. explain_qs = DeviceAlgorithmExplain.objects.filter(lang=lang).filter(algorithm_type__id=type_id) \
  353. .values('algorithm_type__id', 'algorithm_type__type',
  354. 'algorithm_type__down_count',
  355. 'algorithm_type__details_img_url',
  356. 'algorithm_type__icon_url',
  357. 'title', 'subtitle', 'introduction',
  358. 'install_explain', 'risk_warning',
  359. 'algorithm_type__basic_function', 'concerning')
  360. if not explain_qs.exists():
  361. return response.json(0, {})
  362. item = explain_qs.first()
  363. algorithm_dict = {
  364. 'typeId': item['algorithm_type__id'],
  365. 'type': item['algorithm_type__type'],
  366. 'downCount': item['algorithm_type__down_count'],
  367. 'detailsImgUrl': item['algorithm_type__details_img_url'],
  368. 'iconUrl': item['algorithm_type__icon_url'],
  369. 'title': item['title'],
  370. 'subtitle': item['subtitle'],
  371. 'introduction': item['introduction'],
  372. 'installExplain': item['install_explain'],
  373. 'riskWarning': item['risk_warning'],
  374. 'basicFunction': item['algorithm_type__basic_function'],
  375. 'concerning': item['concerning']
  376. }
  377. dt_info_qs = DeviceTypeAlgorithmInfo.objects.filter(algorithm_type=algorithm_dict['type']) \
  378. .annotate(deviceName=F('device_name'), deviceType=F('device_type'),
  379. algorithmType=F('algorithm_type'),
  380. typeIcon=F('type_icon'),
  381. deviceLink=F('device_link'), ) \
  382. .values('deviceName', 'deviceType', 'typeIcon', 'deviceLink')
  383. algorithm_dict['recommendDevices'] = list(dt_info_qs)
  384. if uid:
  385. setting = cls.get_uid_algorithm_info(item['algorithm_type__id'], uid)
  386. algorithm_dict['setting'] = setting if setting else {'status': 0, 'function': {}}
  387. return response.json(0, algorithm_dict)
  388. except Exception as e:
  389. print('查询算法详情异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  390. return response.json(177, repr(e))
  391. @staticmethod
  392. def get_uid_algorithm_info(type_id, uid):
  393. """
  394. 获取当前设备使用算法状态信息
  395. @param type_id: 算法类型ID
  396. @param uid: 设备唯一标识
  397. @return: dict
  398. """
  399. uid_algorithm_qs = DeviceUidAlgorithmType.objects.filter(algorithm_type_id=type_id, device_uid=uid) \
  400. .values('status', 'function')
  401. if not uid_algorithm_qs.exists():
  402. return None
  403. return uid_algorithm_qs.first()
  404. @classmethod
  405. def algorithm_setting_save(cls, request_dict, response):
  406. """
  407. 算法设置保存
  408. """
  409. try:
  410. type_id = request_dict.get('typeId', None)
  411. uid = request_dict.get('uid', None)
  412. status = request_dict.get('status', None)
  413. setting_json = request_dict.get('function')
  414. if not all([type_id, uid, status, setting_json]):
  415. return response.json(444)
  416. status = int(status)
  417. type_id = int(type_id)
  418. now_time = int(time.time())
  419. uid_algorithm_qs = DeviceUidAlgorithmType.objects.filter(algorithm_type_id=type_id, device_uid=uid)
  420. if not uid_algorithm_qs.exists():
  421. param = {'algorithm_type_id': int(type_id), 'uid': uid, 'function': setting_json,
  422. 'status': status, 'updated_time': now_time, 'created_time': now_time}
  423. DeviceUidAlgorithmType.objects.create(**param)
  424. return response.json(0)
  425. uid_algorithm_qs.update(status=status, function=setting_json, updated_time=now_time)
  426. return response.json(0)
  427. except Exception as e:
  428. print('保存算法设置异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  429. return response.json(177, repr(e))
  430. @classmethod
  431. def get_passenger_flow_list(cls, request_dict, response):
  432. """
  433. 获取客流统计列表
  434. """
  435. try:
  436. uid = request_dict.get('uid')
  437. now_time = request_dict.get('nowTime')
  438. flow_type = request_dict.get('flowType')
  439. query_type = request_dict.get('queryType')
  440. channel = int(request_dict.get('channel', '1'))
  441. if not all([now_time, flow_type, query_type]):
  442. return response.json(444)
  443. query_type = int(query_type)
  444. flow_type = int(flow_type)
  445. passenger_flow_list = []
  446. # 将需要查询的时间戳列表拼接成缓存的键名
  447. cache_key = f"ASJ:PASSENGER_FLOW:{uid}_{flow_type}_{query_type}_{now_time}"
  448. redis = RedisObject(5)
  449. passenger_flow_json = redis.get_data(cache_key)
  450. if passenger_flow_json:
  451. return response.json(0, json.loads(passenger_flow_json))
  452. if query_type == 1:
  453. passenger_flow_list = cls.get_passenger_flow_by_day(uid, int(now_time), flow_type, channel)
  454. elif query_type == 2:
  455. passenger_flow_list = cls.get_passenger_flow_by_month(uid, int(now_time), flow_type, channel)
  456. elif query_type == 3:
  457. passenger_flow_list = cls.get_passenger_flow_by_year(uid, int(now_time), flow_type, channel)
  458. else:
  459. return response.json(0, passenger_flow_list)
  460. if passenger_flow_list:
  461. redis.CONN.setnx(cache_key, json.dumps(passenger_flow_list))
  462. redis.CONN.expire(cache_key, 3600 * 24)
  463. return response.json(0, passenger_flow_list)
  464. except Exception as e:
  465. print('查询客流异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  466. return response.json(500, repr(e))
  467. @staticmethod
  468. def get_passenger_flow_by_day(uid, now_time, flow_type, channel):
  469. """
  470. 按天获取客流统计
  471. """
  472. c_time = datetime.fromtimestamp(int(now_time))
  473. # 一天周期24小时从当前小时整点往前查询近24小时,生成秒级时间戳
  474. t_list = [math.floor((c_time - timedelta(hours=i)).timestamp()) for i in range(24)]
  475. passenger_flow_list = []
  476. pf_qs = DeviceAlgorithmPassengerFlow.objects.filter(
  477. device_time__gte=t_list[23],
  478. device_time__lte=t_list[0] + 60,
  479. type=int(flow_type),
  480. uid=uid,
  481. channel=channel
  482. ).order_by('device_time')
  483. if not pf_qs.exists():
  484. return passenger_flow_list
  485. # 循环查找最近24小时的记录(包含当前时间)
  486. for i in range(24):
  487. current_time = t_list[i]
  488. next_time = -1 if i == 0 else t_list[i - 1]
  489. is_data = False
  490. count = 0
  491. hour = 0
  492. for item in pf_qs:
  493. if next_time == -1 and next_time == item.device_time:
  494. hour = item.statistical_time.hour
  495. count += item.count
  496. is_data = True
  497. elif current_time <= item.device_time < next_time:
  498. count += item.count
  499. hour = item.statistical_time.hour
  500. is_data = True
  501. elif next_time == -1 and current_time <= item.device_time:
  502. hour = item.statistical_time.hour
  503. count += item.count
  504. is_data = True
  505. if not is_data:
  506. continue
  507. passenger_flow_list.append({
  508. 'index': hour,
  509. 'count': count,
  510. 'time': current_time
  511. })
  512. return passenger_flow_list
  513. @staticmethod
  514. def get_passenger_flow_by_month(uid, now_time, flow_type, channel):
  515. """
  516. 按月获取客流统计
  517. """
  518. # 获取30天前的时间戳作为起始时间
  519. s_time = LocalDateTimeUtil.get_before_days_timestamp(now_time, 30)
  520. # 将起始时间设置为当天的开始时间
  521. s_time = LocalDateTimeUtil.start_of_day_timestamp(s_time)
  522. # 查询指定类型的客流数据,按设备时间升序排序
  523. pf_qs = DeviceAlgorithmPassengerFlow.objects.filter(
  524. device_time__range=(s_time, now_time),
  525. type=int(flow_type),
  526. uid=uid,
  527. channel=channel
  528. ).order_by('device_time')
  529. passenger_flow_list = []
  530. if not pf_qs.exists():
  531. return passenger_flow_list
  532. for i in range(30): # 查询月按30天为一个周期
  533. if i == 0:
  534. # 当天的开始时间作为查询的起始时间
  535. s_time = LocalDateTimeUtil.start_of_day_timestamp(now_time)
  536. else:
  537. # 获取i天前的时间戳作为查询的起始时间
  538. s_time = LocalDateTimeUtil.get_before_days_timestamp(now_time, i)
  539. # 将起始时间设置为当天的开始时间
  540. s_time = LocalDateTimeUtil.start_of_day_timestamp(s_time)
  541. days_qs = []
  542. day = 0
  543. for item in pf_qs:
  544. # 计算结束时间
  545. end_time = now_time if i == 0 else s_time + (3600 * 24)
  546. # 将在起始时间和结束时间范围内的客流数据放入列表中
  547. if s_time < item.device_time <= end_time:
  548. days_qs.append(item.count)
  549. day = item.statistical_time.day if day == 0 else day
  550. if days_qs:
  551. # 将每天的客流数据统计结果添加到列表中
  552. passenger_flow_list.append({
  553. 'index': day,
  554. 'count': sum(days_qs),
  555. 'time': s_time
  556. })
  557. return passenger_flow_list
  558. @staticmethod
  559. def get_passenger_flow_by_year(uid, now_time, flow_type, channel):
  560. """
  561. 按年获取客流统计
  562. """
  563. month_time = 0
  564. passenger_flow_list = []
  565. for i in range(12):
  566. if i == 0:
  567. month_time = LocalDateTimeUtil.get_current_month_first_day(now_time)
  568. df_qs = DeviceAlgorithmPassengerFlow.objects.filter(type=flow_type, uid=uid, channel=channel)
  569. if i == 0:
  570. df_qs = df_qs.filter(device_time__range=(month_time, now_time))
  571. data_qs = df_qs.first()
  572. else:
  573. previous_month_time = LocalDateTimeUtil.get_previous_month_first_day(month_time)
  574. df_qs = df_qs.filter(device_time__range=(previous_month_time, month_time))
  575. data_qs = df_qs.first()
  576. month_time = previous_month_time
  577. df_qs = df_qs.aggregate(total=Sum('count'))
  578. if not df_qs['total']:
  579. continue
  580. passenger_flow_list.append({
  581. 'index': data_qs.statistical_time.month,
  582. 'count': df_qs['total'],
  583. 'time': month_time
  584. })
  585. return passenger_flow_list
  586. @staticmethod
  587. def get_notify_domain(response):
  588. parsed_url = urlparse(DETECT_PUSH_DOMAINS)
  589. domain = parsed_url.netloc
  590. return response.json(0, {'domain': domain})