AlgorithmShopController.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  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 time
  12. from datetime import datetime
  13. from django.db.models import F, Value, CharField
  14. from django.views.generic.base import View
  15. from Model.models import DeviceAlgorithmExplain, DeviceAlgorithmBanner, DeviceUidAlgorithmType, \
  16. DeviceTypeAlgorithmInfo, DeviceAppScenario, DeviceScenarioLangInfo, DeviceAlgorithmScenario, \
  17. DeviceAlgorithmPassengerFlow
  18. from Object.ETkObject import ETkObject
  19. from Object.Enums.TimeZone import TimeZone
  20. from Object.RedisObject import RedisObject
  21. from Object.ResponseObject import ResponseObject
  22. from Object.TokenObject import TokenObject
  23. from Object.utils import LocalDateTimeUtil
  24. LOGGER = logging.getLogger('info')
  25. class AlgorithmShopView(View):
  26. def get(self, request, *args, **kwargs):
  27. request.encoding = 'utf-8'
  28. operation = kwargs.get('operation')
  29. return self.validation(request.GET, request, operation)
  30. def post(self, request, *args, **kwargs):
  31. request.encoding = 'utf-8'
  32. operation = kwargs.get('operation')
  33. return self.validation(request.POST, request, operation)
  34. def validation(self, request_dict, request, operation):
  35. if operation == 'passengerFlowStatistical':
  36. return self.passenger_flow_statistical(request_dict, ResponseObject('en'))
  37. token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
  38. lang = request_dict.get('lang', token.lang)
  39. response = ResponseObject(lang)
  40. if token.code != 0:
  41. return response.json(token.code)
  42. if operation == 'list':
  43. return self.algorithm_list(request_dict, response)
  44. elif operation == 'banner-list':
  45. return self.get_algorithm_banner(response)
  46. elif operation == 'uid-details':
  47. return self.get_algorithm_details(request_dict, response)
  48. elif operation == 'save':
  49. return self.algorithm_setting_save(request_dict, response)
  50. elif operation == 'getScenarioList': # 获取应用场景数据列表
  51. return self.get_scenario_list(request_dict, response)
  52. elif operation == 'getAlgorithmListByScenarioId': # 根据应用场景id获取算法列表
  53. return self.get_scenario_algorithm_list(request_dict, response)
  54. else:
  55. return response.json(0)
  56. @classmethod
  57. def passenger_flow_statistical(cls, request_dict, response):
  58. """
  59. 添加客流统计
  60. Args:
  61. request_dict (dict): 请求参数字典
  62. response: 响应对象
  63. """
  64. try:
  65. LOGGER.info('*****AlgorithmShopView.passenger_flow_statistical:params{}'.format(json.dumps(request_dict)))
  66. sign = request_dict.get('sign')
  67. eto = ETkObject(sign)
  68. uid = eto.uid
  69. if not uid:
  70. return response.json(444)
  71. d_time = request_dict.get('deviceTime')
  72. enter_count = request_dict.get('enterCount')
  73. tz_value = request_dict.get('timeZone')
  74. exit_count = request_dict.get('exitCount')
  75. if not all([sign, enter_count, exit_count, tz_value]):
  76. return response.json(444)
  77. enter_count = int(enter_count)
  78. exit_count = int(exit_count)
  79. redis = RedisObject(5)
  80. key = f'ASJ:PASSENGER:FLOW:{uid}:{d_time}'
  81. # 检查Redis中是否已存在相同key的数据
  82. r_data = redis.get_data(key)
  83. if r_data:
  84. return response.json(0)
  85. now_time = int(time.time())
  86. data = {
  87. 'uid': uid,
  88. 'updated_time': now_time,
  89. 'created_time': now_time,
  90. 'device_time': int(d_time)
  91. }
  92. tz = TimeZone.get_value(int(tz_value))
  93. date_time = LocalDateTimeUtil.time_format_date(int(d_time), tz)
  94. data['statistical_time'] = datetime.strptime(date_time, '%Y-%m-%d %H:%M:%S')
  95. LOGGER.info(f'uid{uid}-DeviceTime:{d_time},tz:{tz},结果:{date_time}')
  96. passenger_flow_list = []
  97. if enter_count > 0:
  98. data['count'] = enter_count
  99. data['type'] = 1
  100. passenger_flow_list.append(DeviceAlgorithmPassengerFlow(**data))
  101. if exit_count > 0:
  102. data['count'] = exit_count
  103. data['type'] = 2
  104. passenger_flow_list.append(DeviceAlgorithmPassengerFlow(**data))
  105. DeviceAlgorithmPassengerFlow.objects.bulk_create(passenger_flow_list)
  106. # 将数据存入Redis,并设置过期时间为10分钟
  107. redis.CONN.setnx(key, d_time)
  108. redis.CONN.expire(key, 600)
  109. return response.json(0)
  110. except Exception as e:
  111. LOGGER.info('***get_algorithm_list_by_scenario_id,errLine:{}, errMsg:{}'
  112. .format(e.__traceback__.tb_lineno, repr(e)))
  113. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  114. @classmethod
  115. def get_algorithm_list_by_scenario_id(cls, scenario_id, lang):
  116. """
  117. 根据应用场景ID查询算法信息列表
  118. @param scenario_id: 场景ID
  119. @param lang: 语言
  120. @return: 算法类型信息
  121. """
  122. try:
  123. if not scenario_id or scenario_id == 0:
  124. return []
  125. # 根据场景id查询关联的算法id
  126. algorithm_scenario_qs = DeviceAlgorithmScenario.objects.filter(scenario_id=scenario_id) \
  127. .order_by('sort').values('algorithm_id')
  128. if not algorithm_scenario_qs.exists():
  129. return []
  130. algorithm_list = []
  131. for item in algorithm_scenario_qs:
  132. algorithm_id = item['algorithm_id']
  133. # 根据算法id查询多语言数据
  134. algorithm_list.append(cls.get_lang_info_by_algorithm_id(algorithm_id, lang, None))
  135. return algorithm_list
  136. except Exception as e:
  137. LOGGER.info('***get_algorithm_list_by_scenario_id,errLine:{}, errMsg:{}'
  138. .format(e.__traceback__.tb_lineno, repr(e)))
  139. return []
  140. @classmethod
  141. def get_lang_info_by_algorithm_id(cls, algorithm_id, lang, uid):
  142. """
  143. 根据算法id查询多语言数据详情
  144. @param uid: 设备uid
  145. @param algorithm_id: 算法id
  146. @param lang: 语言
  147. @return: 算法多语言数据详情
  148. """
  149. try:
  150. algorithm_qs = DeviceAlgorithmExplain.objects.filter(algorithm_type_id=algorithm_id, lang=lang) \
  151. .values('algorithm_type__icon_url', 'algorithm_type__id',
  152. 'title', 'subtitle', 'algorithm_type__image_url',
  153. 'algorithm_type__basic_function', 'concerning',
  154. 'price', 'algorithm_type__tag', 'algorithm_type__status',
  155. 'algorithm_type__type')
  156. if not algorithm_qs.exists():
  157. return {}
  158. setting = '' # 当前支持设置的算法功能json
  159. # 存在uid则查询当前uid是否支持该算法
  160. if uid:
  161. setting = cls.get_uid_algorithm_info(algorithm_id, uid)
  162. setting = setting if setting else {'status': 0, 'function': {}}
  163. data = {
  164. 'typeId': algorithm_qs[0]['algorithm_type__id'],
  165. 'iconUrl': algorithm_qs[0]['algorithm_type__icon_url'],
  166. 'imageUrl': algorithm_qs[0]['algorithm_type__image_url'],
  167. 'title': algorithm_qs[0]['title'],
  168. 'subtitle': algorithm_qs[0]['subtitle'],
  169. 'basicFunction': algorithm_qs[0]['algorithm_type__basic_function'],
  170. 'concerning': algorithm_qs[0]['concerning'],
  171. 'price': algorithm_qs[0]['price'],
  172. 'tag': algorithm_qs[0]['algorithm_type__tag'],
  173. 'status': algorithm_qs[0]['algorithm_type__status'],
  174. 'setting': setting,
  175. 'type': algorithm_qs[0]['algorithm_type__type']
  176. }
  177. return data
  178. except Exception as e:
  179. LOGGER.info('***get_lang_info_by_algorithm_id,errLine:{}, errMsg:{}'
  180. .format(e.__traceback__.tb_lineno, repr(e)))
  181. return {}
  182. @classmethod
  183. def get_algorithm_list(cls, lang):
  184. """
  185. 获取所有算法数据列表
  186. @return: 算法数据列表
  187. """
  188. algorithm_qs = DeviceAlgorithmExplain.objects.filter(lang=lang).order_by('algorithm_type__sort') \
  189. .annotate(iconUrl=F('algorithm_type__icon_url'),
  190. typeId=F('algorithm_type__id'),
  191. type=F('algorithm_type__type'),
  192. imageUrl=F('algorithm_type__image_url'),
  193. basicFunction=F('algorithm_type__basic_function'),
  194. tag=F('algorithm_type__tag'), status=F('algorithm_type__status'),
  195. setting=Value('', output_field=CharField())) \
  196. .values('iconUrl', 'imageUrl', 'title', 'subtitle', 'concerning', 'basicFunction', 'price', 'tag', 'status',
  197. 'setting', 'typeId', 'type')
  198. if not algorithm_qs.exists():
  199. return []
  200. return list(algorithm_qs)
  201. @classmethod
  202. def get_scenario_list(cls, request_dist, response):
  203. """
  204. 获取应用场景列表
  205. @param request_dist: lang
  206. @param response: 响应结果
  207. @return: 应用场景列表
  208. """
  209. try:
  210. lang = request_dist.get('lang', 'en')
  211. if not lang:
  212. return response.json(444)
  213. # 获取应用场景列表
  214. scenario_qs = DeviceAppScenario.objects.filter().exclude(type=0).all().order_by('sort') \
  215. .values('id', 'type', 'cver_url', 'banner_url')
  216. scenario_list = []
  217. if not scenario_qs.exists():
  218. return response.json(0, scenario_list)
  219. for item in scenario_qs:
  220. scenario_vo = {'id': item['id'], 'cverUrl': item['cver_url'], 'bannerUrl': item['banner_url'],
  221. 'name': '', 'content': ''}
  222. # 获取根据语言应用场景信息
  223. scenario_info_qs = DeviceScenarioLangInfo.objects.filter(lang=lang, scenario_id=item['id']) \
  224. .values('name', 'content')
  225. if not scenario_info_qs.exists():
  226. continue
  227. scenario_vo['name'] = scenario_info_qs[0]['name']
  228. scenario_vo['content'] = scenario_info_qs[0]['content']
  229. # 根据应用场景id查询关联算法类型数据
  230. # scenario_vo['algorithmList'] = cls.get_algorithm_list_by_scenario_id(item['id'], lang)
  231. scenario_list.append(scenario_vo)
  232. # 获取所有算法图标地址以及算法名称
  233. algorithm_qs = DeviceAlgorithmExplain.objects.filter(lang=lang).order_by('algorithm_type__sort') \
  234. .annotate(algorithmId=F('algorithm_type__id'), algorithmType=F('algorithm_type__type'),
  235. iconUrl=F('algorithm_type__icon_url'),
  236. algorithmName=F('title')).values('algorithmId', 'algorithmType', 'iconUrl', 'algorithmName')
  237. scenario_qs = DeviceAppScenario.objects.filter(type=0) \
  238. .values('cver_url', 'banner_url')
  239. scenario_banner = {}
  240. if scenario_qs.exists():
  241. scenario_banner['cverUrl'] = scenario_qs[0]['cver_url']
  242. scenario_banner['bannerUrl'] = scenario_qs[0]['banner_url']
  243. result_dto = {'scenarioList': scenario_list, 'scenarioUrl': scenario_banner}
  244. if algorithm_qs.exists():
  245. result_dto['iconList'] = list(algorithm_qs)
  246. return response.json(0, result_dto)
  247. except Exception as e:
  248. LOGGER.info('接口异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  249. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  250. @classmethod
  251. def get_scenario_algorithm_list(cls, request_dist, response):
  252. """
  253. 获取应用场景关联算法列表
  254. @param request_dist: scenarioId、lang
  255. @param response: 响应结果
  256. @return: 算法列表
  257. """
  258. scenario_id = request_dist.get('scenarioId', None)
  259. lang = request_dist.get('lang', 'en')
  260. result_dto = {'scenarioBannerUrl': ''}
  261. if not scenario_id:
  262. result_dto['algorithmList'] = cls.get_algorithm_list(lang)
  263. return response.json(0, result_dto)
  264. result_dto['algorithmList'] = cls.get_algorithm_list_by_scenario_id(scenario_id, lang)
  265. return response.json(0, result_dto)
  266. @classmethod
  267. def get_algorithm_banner(cls, response):
  268. """
  269. 获取算法小店banner
  270. """
  271. banner_qs = DeviceAlgorithmBanner.objects.all()
  272. banner_vs = banner_qs.order_by('sort') \
  273. .values('algorithm_type__type', 'algorithm_type__id', 'image_url')
  274. banner_list = []
  275. if not banner_vs.exists():
  276. return response.json(0, banner_list)
  277. for item in banner_vs:
  278. banner_list.append({
  279. 'typeId': item['algorithm_type__id'],
  280. 'type': item['algorithm_type__type'],
  281. 'imageUrl': item['image_url'],
  282. })
  283. return response.json(0, banner_list)
  284. @classmethod
  285. def algorithm_list(cls, request_dict, response):
  286. """
  287. 获取算法小店列表
  288. """
  289. try:
  290. lang = request_dict.get('lang', 'en')
  291. uid = request_dict.get('uid', None)
  292. version = request_dict.get('version', 'v1')
  293. algorithm_qs = DeviceAlgorithmExplain.objects.filter(lang=lang)
  294. types = [0, 1, 3, 4, 5]
  295. if version == 'v1':
  296. algorithm_qs = algorithm_qs.filter(algorithm_type__type__in=types)
  297. algorithm_qs = algorithm_qs.order_by('algorithm_type__sort') \
  298. .values('algorithm_type__id', 'algorithm_type__type',
  299. 'algorithm_type__icon_url',
  300. 'title', 'subtitle', 'algorithm_type__image_url',
  301. 'algorithm_type__basic_function', 'concerning')
  302. algorithm_list = []
  303. if not algorithm_qs.exists():
  304. return response.json(0, algorithm_list)
  305. for item in algorithm_qs:
  306. setting = ''
  307. if uid:
  308. setting = cls.get_uid_algorithm_info(item['algorithm_type__id'], uid)
  309. setting = setting if setting else {'status': 0, 'function': {}}
  310. algorithm_list.append({
  311. 'typeId': item['algorithm_type__id'],
  312. 'type': item['algorithm_type__type'],
  313. 'iconUrl': item['algorithm_type__icon_url'],
  314. 'imageUrl': item['algorithm_type__image_url'],
  315. 'title': item['title'],
  316. 'subtitle': item['subtitle'],
  317. 'setting': setting,
  318. 'basicFunction': item['algorithm_type__basic_function'],
  319. 'concerning': item['concerning']
  320. })
  321. return response.json(0, algorithm_list)
  322. except Exception as e:
  323. print('查询算法小店列表异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  324. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  325. @classmethod
  326. def get_algorithm_details(cls, request_dict, response):
  327. """
  328. 获取算法小店类型详情
  329. """
  330. try:
  331. lang = request_dict.get('lang', 'en')
  332. type_id = request_dict.get('typeId', None)
  333. if not type_id:
  334. return response.json(444, 'typeId not null')
  335. type_id = int(type_id)
  336. uid = request_dict.get('uid', None)
  337. explain_qs = DeviceAlgorithmExplain.objects.filter(lang=lang).filter(algorithm_type__id=type_id) \
  338. .values('algorithm_type__id', 'algorithm_type__type',
  339. 'algorithm_type__down_count',
  340. 'algorithm_type__details_img_url',
  341. 'algorithm_type__icon_url',
  342. 'title', 'subtitle', 'introduction',
  343. 'install_explain', 'risk_warning',
  344. 'algorithm_type__basic_function', 'concerning')
  345. if not explain_qs.exists():
  346. return response.json(0, {})
  347. item = explain_qs.first()
  348. algorithm_dict = {
  349. 'typeId': item['algorithm_type__id'],
  350. 'type': item['algorithm_type__type'],
  351. 'downCount': item['algorithm_type__down_count'],
  352. 'detailsImgUrl': item['algorithm_type__details_img_url'],
  353. 'iconUrl': item['algorithm_type__icon_url'],
  354. 'title': item['title'],
  355. 'subtitle': item['subtitle'],
  356. 'introduction': item['introduction'],
  357. 'installExplain': item['install_explain'],
  358. 'riskWarning': item['risk_warning'],
  359. 'basicFunction': item['algorithm_type__basic_function'],
  360. 'concerning': item['concerning']
  361. }
  362. dt_info_qs = DeviceTypeAlgorithmInfo.objects.filter(algorithm_type=algorithm_dict['type']) \
  363. .annotate(deviceName=F('device_name'), deviceType=F('device_type'),
  364. algorithmType=F('algorithm_type'),
  365. typeIcon=F('type_icon'),
  366. deviceLink=F('device_link'), ) \
  367. .values('deviceName', 'deviceType', 'typeIcon', 'deviceLink')
  368. algorithm_dict['recommendDevices'] = list(dt_info_qs)
  369. if uid:
  370. setting = cls.get_uid_algorithm_info(item['algorithm_type__id'], uid)
  371. algorithm_dict['setting'] = setting if setting else {'status': 0, 'function': {}}
  372. return response.json(0, algorithm_dict)
  373. except Exception as e:
  374. print('查询算法详情异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  375. return response.json(177, repr(e))
  376. @staticmethod
  377. def get_uid_algorithm_info(type_id, uid):
  378. """
  379. 获取当前设备使用算法状态信息
  380. @param type_id: 算法类型ID
  381. @param uid: 设备唯一标识
  382. @return: dict
  383. """
  384. uid_algorithm_qs = DeviceUidAlgorithmType.objects.filter(algorithm_type_id=type_id, device_uid=uid) \
  385. .values('status', 'function')
  386. if not uid_algorithm_qs.exists():
  387. return None
  388. return uid_algorithm_qs.first()
  389. @classmethod
  390. def algorithm_setting_save(cls, request_dict, response):
  391. """
  392. 算法设置保存
  393. """
  394. try:
  395. type_id = request_dict.get('typeId', None)
  396. uid = request_dict.get('uid', None)
  397. status = request_dict.get('status', None)
  398. setting_json = request_dict.get('function')
  399. if not all([type_id, uid, status, setting_json]):
  400. return response.json(444)
  401. status = int(status)
  402. type_id = int(type_id)
  403. now_time = int(time.time())
  404. uid_algorithm_qs = DeviceUidAlgorithmType.objects.filter(algorithm_type_id=type_id, device_uid=uid)
  405. if not uid_algorithm_qs.exists():
  406. param = {'algorithm_type_id': int(type_id), 'uid': uid, 'function': setting_json,
  407. 'status': status, 'updated_time': now_time, 'created_time': now_time}
  408. DeviceUidAlgorithmType.objects.create(**param)
  409. return response.json(0)
  410. uid_algorithm_qs.update(status=status, function=setting_json, updated_time=now_time)
  411. return response.json(0)
  412. except Exception as e:
  413. print('保存算法设置异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  414. return response.json(177, repr(e))