DeviceManagementController.py 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import json
  4. import operator
  5. import time
  6. import requests
  7. import oss2
  8. from django.core.paginator import Paginator
  9. from django.db import transaction
  10. from django.db.models import Q, F, Sum
  11. from django.views.generic.base import View
  12. from django.forms.models import model_to_dict
  13. from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
  14. AWS_SES_ACCESS_REGION, UNUSED_SERIAL_REDIS_LIST
  15. from Model.models import Device_Info, UidSetModel, LogModel, UID_Bucket, Unused_Uid_Meal, Order_Model, StsCrdModel, \
  16. VodHlsModel, ExperienceContextModel, DeviceTypeModel, Equipment_Info, UidUserModel, ExperienceAiModel, AiService, \
  17. AppBundle, App_Info, AppDeviceType, DeviceNameLanguage, AppVersionNumber, UIDCompanySerialModel, UIDModel, \
  18. CompanySerialModel, UidPushModel, CustomCustomerDevice, CustomCustomerOrderInfo
  19. from Object.AWS.AmazonS3Util import AmazonS3Util
  20. from Object.RedisObject import RedisObject
  21. from Object.ResponseObject import ResponseObject
  22. from Object.TokenObject import TokenObject
  23. from Service.CommonService import CommonService
  24. from Service.EquipmentInfoService import EquipmentInfoService
  25. from Service.ModelService import ModelService
  26. from Service.VodHlsService import SplitVodHlsObject
  27. from Ansjer.config import SERVER_DOMAIN_TEST, SERVER_DOMAIN_CN, SERVER_DOMAIN_US, SERVER_DOMAIN_EUR
  28. from Ansjer.config import LOGGER
  29. class DeviceManagement(View):
  30. def get(self, request, *args, **kwargs):
  31. request.encoding = 'utf-8'
  32. operation = kwargs.get('operation')
  33. return self.validation(request.GET, request, operation)
  34. def post(self, request, *args, **kwargs):
  35. request.encoding = 'utf-8'
  36. operation = kwargs.get('operation')
  37. return self.validation(request.POST, request, operation)
  38. def validation(self, request_dict, request, operation):
  39. language = request_dict.get('language', 'en')
  40. response = ResponseObject(language, 'pc')
  41. if operation == 'addDeviceType':
  42. return self.addDeviceType(request, request_dict, response)
  43. elif operation == 'delDeviceData': # 删除设备数据
  44. return self.del_device_data(request, request_dict, response)
  45. elif operation == 'getDeviceIcon': # app获取设备图标
  46. response = ResponseObject(language)
  47. return self.get_device_icon(request_dict, response)
  48. elif operation == 'addAppDeviceType': # 添加app设备类型数据并上传图标
  49. return self.add_app_device_type(request_dict, response, request)
  50. elif operation == 'getUidPush': # 查询推送信息
  51. return self.get_uid_push(request_dict, response)
  52. elif operation == 'checkDeviceInfo':
  53. return self.query_device_user(request, request_dict, response)
  54. else:
  55. tko = TokenObject(
  56. request.META.get('HTTP_AUTHORIZATION'),
  57. returntpye='pc')
  58. if tko.code != 0:
  59. return response.json(tko.code)
  60. response.lang = tko.lang
  61. userID = tko.userID
  62. if not userID:
  63. return response.json(444, 'userID')
  64. if operation == 'getDeviceInfoList': # 获取设备信息数据
  65. return self.get_device_info_list(request_dict, response)
  66. elif operation == 'deleteDevice':
  67. return self.deleteDevice(request_dict, response)
  68. elif operation == 'resetVod': # 重置云存
  69. return self.resetVod(request, request_dict, response)
  70. elif operation == 'resetAi': # 重置AI
  71. return self.reset_ai(request, request_dict, response)
  72. elif operation == 'resetPrimaryUser':
  73. return self.resetPrimaryUser(request, request_dict, response)
  74. elif operation == 'getDeviceTypeList':
  75. return self.getDeviceTypeList(request_dict, response)
  76. elif operation == 'deleteDeviceType':
  77. return self.deleteDeviceType(request_dict, response)
  78. elif operation == 'getAppDeviceTypeList': # 获取app设备类型数据
  79. return self.get_app_device_type_list(request_dict, response)
  80. elif operation == 'getAppBundleIdList': # 获取app包id数据
  81. return self.get_app_bundle_id_list(response)
  82. elif operation == 'editAppDeviceType': # 编辑app设备类型数据
  83. return self.edit_app_device_type(request_dict, request, response)
  84. elif operation == 'batchEditAppDeviceType': # 批量编辑app设备类型数据
  85. return self.batch_edit_app_device_type(request_dict, request, response)
  86. elif operation == 'deleteAppDeviceType': # 删除app设备类型数据
  87. return self.delete_app_device_type(request_dict, response)
  88. elif operation == 'getAppBundle': # 获取app版本包
  89. return self.get_app_bundle(response)
  90. elif operation == 'resetAll': # 重置设备主用户/云存/AI
  91. return self.reset_all(request, request_dict, response)
  92. elif operation == 'getAppNameList': # 获取app版本包
  93. return self.get_app_name_list(response)
  94. elif operation == 'callAddAppDeviceType': # 可选服添加app设备类型数据并上传图标
  95. return self.call_add_app_device_type(request_dict, response, request)
  96. elif operation == 'getCustomerDeviceList': # 查询扫码添加设备列表
  97. return self.get_customer_device_list(request_dict, response)
  98. else:
  99. return response.json(444, 'operation')
  100. @classmethod
  101. def get_app_bundle(cls, response):
  102. """
  103. 获取app版本id
  104. """
  105. app_bundle_qs = AppBundle.objects.all().values('id', 'app_bundle_id')
  106. if not app_bundle_qs.exists():
  107. return response.json(0)
  108. app_bundle_list = []
  109. for app_bundle in app_bundle_qs:
  110. app_bundle_qs.exists()
  111. app_bundle_list.append(app_bundle)
  112. return response.json(0, app_bundle_list)
  113. @classmethod
  114. def get_device_info_list(cls, request_dict, response):
  115. pageNo = request_dict.get('pageNo', None)
  116. pageSize = request_dict.get('pageSize', None)
  117. UID = request_dict.get('UID', None)
  118. serialNumber = request_dict.get('serialNumber', None)
  119. NickName = request_dict.get('NickName', None)
  120. username = request_dict.get('username', None)
  121. version = request_dict.get('version', None)
  122. Type = request_dict.get('Type', None)
  123. if not all([pageNo, pageSize]):
  124. return response.json(444)
  125. page = int(pageNo)
  126. line = int(pageSize)
  127. try:
  128. if any([UID, serialNumber, NickName, username, version, Type]): # 条件查询
  129. if UID:
  130. device_info_qs = Device_Info.objects.filter(UID__icontains=UID)
  131. if serialNumber:
  132. device_info_qs = Device_Info.objects.filter(serial_number__icontains=serialNumber[:9])
  133. if NickName:
  134. device_info_qs = Device_Info.objects.filter(NickName__icontains=NickName)
  135. if username:
  136. device_info_qs = Device_Info.objects.filter(Q(userID__username__icontains=username) |
  137. Q(userID__userEmail__icontains=username) |
  138. Q(userID__phone__icontains=username))
  139. if version:
  140. uid_list = UidSetModel.objects.filter(version__icontains=version).values_list('uid', flat=True)
  141. device_info_qs = Device_Info.objects.filter(UID__in=uid_list)
  142. if Type:
  143. type_list = DeviceTypeModel.objects.filter(name=Type).values_list('type', flat=True)
  144. device_info_qs = Device_Info.objects.filter(Type__in=type_list)
  145. total = device_info_qs.count()
  146. if not total:
  147. return response.json(0, {'list': {}, 'total': 0})
  148. device_info_qs = device_info_qs[(page - 1) * line:page * line]
  149. else: # 查询全部
  150. total = Device_Info.objects.filter().count()
  151. device_info_qs = Device_Info.objects.filter()[(page - 1) * line:page * line]
  152. if not device_info_qs.exists():
  153. return response.json(0, {'list': {}, 'total': 0})
  154. device_info_list = CommonService.qs_to_dict(device_info_qs)
  155. for k, v in enumerate(device_info_list["datas"]):
  156. for device_info in device_info_qs:
  157. if v['pk'] == device_info.id:
  158. # 设备的用户名和主用户
  159. username = ModelService.get_user_name(device_info_list["datas"][k]['fields']['userID'])
  160. device_info_list["datas"][k]['fields']['username'] = username
  161. device_info_list["datas"][k]['fields']['vodPrimaryMaster'] = \
  162. device_info_list["datas"][k]['fields']['vodPrimaryMaster']
  163. # 设备类型,是否支持Alexa和ip
  164. type = device_info_list["datas"][k]['fields']['Type']
  165. device_type_qs = DeviceTypeModel.objects.filter(type=type).values('name')
  166. if device_type_qs.exists():
  167. device_info_list["datas"][k]['fields']['Type'] = device_type_qs[0]['name']
  168. uid_set_qs = UidSetModel.objects.filter(
  169. uid=device_info_list["datas"][k]['fields']['UID']). \
  170. values('detect_status', 'is_alexa', 'ip', 'version', 'is_ai', 'is_human', 'cloud_vod',
  171. 'ucode', 'device_type')
  172. if uid_set_qs.exists():
  173. # 移动侦测
  174. iSNotification = '开' if uid_set_qs[0]['detect_status'] else '关'
  175. device_info_list["datas"][k]['fields']['iSNotification'] = iSNotification
  176. isAlexa = '是' if uid_set_qs[0]['is_alexa'] else '否'
  177. isHuman = '是' if uid_set_qs[0]['is_human'] else '否'
  178. cloud_vod = CommonService.is_cloud_device(uid_set_qs[0]['ucode'],
  179. uid_set_qs[0]['device_type'])
  180. if cloud_vod:
  181. cloud_vod = '支持'
  182. else:
  183. cloud_vod = '不支持'
  184. if uid_set_qs[0]['is_ai'] == 2:
  185. isAI = '不支持'
  186. else:
  187. isAI = '支持'
  188. device_info_list["datas"][k]['fields']['isHuman'] = isHuman
  189. device_info_list["datas"][k]['fields']['isAI'] = isAI
  190. device_info_list["datas"][k]['fields']['isAlexa'] = isAlexa
  191. device_info_list["datas"][k]['fields']['cloudVod'] = cloud_vod
  192. device_info_list["datas"][k]['fields']['ip'] = uid_set_qs[0]['ip']
  193. device_info_list["datas"][k]['fields']['version'] = uid_set_qs[0]['version']
  194. uid_bucket_qs = UID_Bucket.objects.filter(
  195. uid=device_info_list["datas"][k]['fields']['UID']).values('status')
  196. # 0是关闭,1是开启
  197. if uid_bucket_qs.exists():
  198. res = []
  199. for uid_bucket in uid_bucket_qs:
  200. status = uid_bucket['status']
  201. res.append(status)
  202. if 1 in res:
  203. device_info_list["datas"][k]['fields']['status'] = 1
  204. else:
  205. device_info_list["datas"][k]['fields']['status'] = 0
  206. else:
  207. device_info_list["datas"][k]['fields']['status'] = 0
  208. # AI开关状态
  209. ai_service = AiService.objects.filter(uid=device_info_list["datas"][k]['fields']['UID']).values(
  210. 'detect_status')
  211. if ai_service.exists():
  212. if ai_service[0]['detect_status']:
  213. device_info_list["datas"][k]['fields']['ai_status'] = 1
  214. else:
  215. device_info_list["datas"][k]['fields']['ai_status'] = 0
  216. else:
  217. device_info_list["datas"][k]['fields']['ai_status'] = 0
  218. return response.json(0, {'list': device_info_list, 'total': total})
  219. except Exception as e:
  220. print(e)
  221. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  222. # 根据id删除设备
  223. def deleteDevice(self, request_dict, response):
  224. deviceID = request_dict.get('deviceID', None)
  225. userID = request_dict.get('userID', None)
  226. uid = request_dict.get('uid', None)
  227. if not all([deviceID, userID, uid]):
  228. return response.json(444)
  229. try:
  230. with transaction.atomic():
  231. Device_Info.objects.filter(id=deviceID).delete()
  232. UidPushModel.objects.filter(uid_set__uid=uid).delete()
  233. # 删除推送消息
  234. EquipmentInfoService.delete_all_equipment_info(device_user_id=userID, device_uid=uid)
  235. return response.json(0)
  236. except Exception as e:
  237. print(e)
  238. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  239. # 重置设备主用户
  240. def resetPrimaryUser(self, request, request_dict, response):
  241. uid = request_dict.get('uid', None)
  242. if not uid:
  243. return response.json(404)
  244. try:
  245. # 记录操作日志
  246. ip = CommonService.get_ip_address(request)
  247. content = json.loads(json.dumps(request_dict))
  248. log = {
  249. 'ip': ip,
  250. 'user_id': 2,
  251. 'status': 200,
  252. 'time': int(time.time()),
  253. 'url': 'deviceManagement/resetPrimaryUser',
  254. 'content': json.dumps(content),
  255. 'operation': '{}重置设备主用户'.format(uid),
  256. }
  257. LogModel.objects.create(**log)
  258. Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
  259. return response.json(0)
  260. except Exception as e:
  261. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  262. # 重置设备云存
  263. def resetVod(self, request, request_dict, response):
  264. uid = request_dict.get('uid', None)
  265. if not uid:
  266. return response.json(444)
  267. try:
  268. # 记录操作日志
  269. ip = CommonService.get_ip_address(request)
  270. content = json.loads(json.dumps(request_dict))
  271. log = {
  272. 'ip': ip,
  273. 'user_id': 2,
  274. 'status': 200,
  275. 'time': int(time.time()),
  276. 'url': 'deviceManagement/resetVod',
  277. 'content': json.dumps(content),
  278. 'operation': '{}重置云存'.format(uid),
  279. }
  280. with transaction.atomic():
  281. LogModel.objects.create(**log)
  282. # 删除和更新设备云存相关数据
  283. UID_Bucket.objects.filter(uid=uid).delete()
  284. AiService.objects.filter(uid=uid).delete()
  285. Unused_Uid_Meal.objects.filter(uid=uid).delete()
  286. # Order_Model.objects.filter(UID=uid, order_type=0).delete()
  287. StsCrdModel.objects.filter(uid=uid).delete()
  288. VodHlsModel.objects.filter(uid=uid).delete()
  289. # 删除vod_hls分表数据
  290. split_vod_hls_obj = SplitVodHlsObject()
  291. split_vod_hls_obj.del_vod_hls_data(uid=uid)
  292. ExperienceContextModel.objects.filter(uid=uid).delete()
  293. Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
  294. return response.json(0)
  295. except Exception as e:
  296. print(e)
  297. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  298. @staticmethod
  299. def reset_ai(request, request_dict, response):
  300. uid = request_dict.get('uid', None)
  301. if not uid:
  302. return response.json(444)
  303. try:
  304. # 记录操作日志
  305. ip = CommonService.get_ip_address(request)
  306. content = json.loads(json.dumps(request_dict))
  307. log = {
  308. 'ip': ip,
  309. 'user_id': 2,
  310. 'status': 200,
  311. 'time': int(time.time()),
  312. 'url': 'deviceManagement/resetAi',
  313. 'content': json.dumps(content),
  314. 'operation': '{}重置AI'.format(uid),
  315. }
  316. with transaction.atomic():
  317. LogModel.objects.create(**log)
  318. # 删除和更新设备AI相关数据
  319. ExperienceAiModel.objects.filter(uid=uid).delete()
  320. AiService.objects.filter(uid=uid).delete()
  321. return response.json(0)
  322. except Exception as e:
  323. print(e)
  324. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  325. # 获取设备类型数据
  326. def getDeviceTypeList(self, request_dict, response):
  327. name = request_dict.get('name', None)
  328. pageNo = request_dict.get('pageNo', None)
  329. pageSize = request_dict.get('pageSize', None)
  330. if not all([pageNo, pageSize]):
  331. return response.json(444)
  332. page = int(pageNo)
  333. line = int(pageSize)
  334. try:
  335. if name:
  336. device_type_qs = DeviceTypeModel.objects.filter(name__contains=name).values()
  337. total = len(device_type_qs)
  338. else:
  339. device_type_qs = DeviceTypeModel.objects.filter().values()[(page - 1) * line:page * line]
  340. total = DeviceTypeModel.objects.filter().count()
  341. if not device_type_qs.exists():
  342. return response.json(173)
  343. device_type_list = []
  344. for device_type in device_type_qs:
  345. auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
  346. bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
  347. icon = device_type['icon']
  348. url = 'device_type/' + icon
  349. device_type['icon'] = bucket.sign_url('GET', url, 3600)
  350. device_type_list.append(device_type)
  351. return response.json(0, {'list': device_type_list, 'total': total})
  352. except Exception as e:
  353. print(e)
  354. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  355. # 删除设备类型
  356. def deleteDeviceType(self, request_dict, response):
  357. deviceTypeID = request_dict.get('deviceTypeID', None)
  358. if not deviceTypeID:
  359. return response.json(444)
  360. try:
  361. DeviceTypeModel.objects.filter(id=deviceTypeID).delete()
  362. return response.json(0)
  363. except Exception as e:
  364. print(e)
  365. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  366. # 添加设备类型
  367. def addDeviceType(self, request, request_dict, response):
  368. iconFile = request.FILES.get('iconFile', None)
  369. name = request_dict.get('name', None)
  370. model = request_dict.get('model', None)
  371. type = request_dict.get('type', None)
  372. ptz_type = request_dict.get('ptz_type', None)
  373. if not all([iconFile, name, model, type, ptz_type]):
  374. return response.json(444)
  375. try:
  376. model = int(model)
  377. ptz_type = int(ptz_type)
  378. icon = iconFile.name
  379. now_time = int(time.time())
  380. # 上传文件到阿里云OSS
  381. auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
  382. bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
  383. key = 'device_type/' + icon # 图片文件存放于 device_type 目录下
  384. # https://oss.console.aliyun.com/bucket/oss-cn-shenzhen/ansjer-static-resources/object?path=device_type%2F
  385. bucket.put_object(key=key, data=iconFile)
  386. DeviceTypeModel.objects.create(name=name, model=model, type=type, ptz_type=ptz_type, icon=icon,
  387. add_time=now_time, update_time=now_time)
  388. return response.json(0)
  389. except Exception as e:
  390. print(e)
  391. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  392. @staticmethod
  393. def del_device_data(request, request_dict, response):
  394. uidList = request_dict.get('uidList', None)
  395. delDataOptions = request_dict.get('delDataOptions', None)
  396. serialNumberList = request_dict.get('serialNumberList', None)
  397. if not all([uidList or serialNumberList, delDataOptions]):
  398. return response.json(444)
  399. # 记录日志
  400. content = json.loads(json.dumps(request_dict))
  401. ip = CommonService.get_ip_address(request)
  402. log = {
  403. 'user_id': 2,
  404. 'status': 200,
  405. 'time': int(time.time()),
  406. 'url': 'deviceManagement/delDeviceData',
  407. 'content': delDataOptions,
  408. 'ip': ip,
  409. 'operation': '上传文件设备重置删除前:{}'.format(json.dumps(content)),
  410. }
  411. LogModel.objects.create(**log)
  412. try:
  413. with transaction.atomic():
  414. if uidList:
  415. # uid
  416. uidList = uidList.splitlines() # 按行('\r', '\r\n', \n')切割字符串返回列表
  417. uid_list = []
  418. for uid in uidList:
  419. uid_val = uid.replace(" ", "")
  420. if not uid_val:
  421. continue
  422. uid_list.append(uid_val)
  423. uidList = uid_list
  424. else:
  425. # 序列号
  426. serialNumberList = serialNumberList.splitlines() # 按行('\r', '\r\n', \n')切割字符串返回列表
  427. serial_number_list = []
  428. for serial_number in serialNumberList:
  429. serial_number = serial_number.replace(" ", "")
  430. if not serial_number:
  431. continue
  432. serial_number_list.append(serial_number[0:6])
  433. uid_company_serial_qs = UIDCompanySerialModel.objects.filter(
  434. company_serial__serial_number__in=serial_number_list).values('uid__uid')
  435. uidList = [item[key] for item in uid_company_serial_qs for key in item]
  436. # 根据删除项删除相关数据
  437. if '设备信息数据' in delDataOptions:
  438. Device_Info.objects.filter(UID__in=uidList).delete()
  439. UidPushModel.objects.filter(uid_set__uid__in=uidList).delete()
  440. if '设备配置数据' in delDataOptions:
  441. UidSetModel.objects.filter(uid__in=uidList).delete()
  442. if '设备推送数据' in delDataOptions:
  443. EquipmentInfoService.delete_all_equipment_info(device_uid__in=uidList)
  444. if '设备AP信息数据' in delDataOptions:
  445. UidUserModel.objects.filter(UID__in=uidList).delete()
  446. if '设备AI数据' in delDataOptions:
  447. ExperienceAiModel.objects.filter(uid__in=uidList).delete()
  448. # Order_Model.objects.filter(UID__in=uidList, order_type=1).delete()
  449. if '设备云存数据' in delDataOptions:
  450. UID_Bucket.objects.filter(uid__in=uidList).delete()
  451. AiService.objects.filter(uid__in=uidList).delete()
  452. StsCrdModel.objects.filter(uid__in=uidList).delete()
  453. VodHlsModel.objects.filter(uid__in=uidList).delete()
  454. # 删除vod_hls分表数据
  455. split_vod_hls_obj = SplitVodHlsObject()
  456. split_vod_hls_obj.del_vod_hls_data(uid__in=uidList)
  457. Unused_Uid_Meal.objects.filter(uid__in=uidList).delete()
  458. ExperienceContextModel.objects.filter(uid__in=uidList).delete()
  459. # Order_Model.objects.filter(UID__in=uidList, order_type=0).delete()
  460. Device_Info.objects.filter(UID__in=uidList).update(vodPrimaryUserID='', vodPrimaryMaster='')
  461. # 上传序列号文件且选中序列号解绑uid
  462. # if serialNumberList is not None and '序列号解绑uid' in delDataOptions:
  463. # # 解绑uid数据
  464. # UIDModel.objects.filter(uid__in=uidList, status=2).update(status=0)
  465. # UIDCompanySerialModel.objects.filter(uid__uid__in=uidList).delete()
  466. # CompanySerialModel.objects.filter(serial_number__in=serial_number_list).update(status=1)
  467. # UidPushModel.objects.filter(uid_set__uid__in=uidList).delete()
  468. # # 序列号加入重置状态redis列表
  469. # redis_obj = RedisObject()
  470. # for serial in serial_number_list:
  471. # redis_obj.rpush(UNUSED_SERIAL_REDIS_LIST, serial)
  472. device_list = uidList if serialNumberList is None else serial_number_list
  473. log = {
  474. 'user_id': 2,
  475. 'status': 200,
  476. 'time': int(time.time()),
  477. 'url': 'deviceManagement/delDeviceData',
  478. 'content': json.dumps(content),
  479. 'ip': ip,
  480. 'operation': '删除数据的设备列表:{}'.format(device_list),
  481. }
  482. LogModel.objects.create(**log)
  483. return response.json(0)
  484. except Exception as e:
  485. log = {
  486. 'user_id': 2,
  487. 'status': 500,
  488. 'time': int(time.time()),
  489. 'url': 'deviceManagement/delDeviceData',
  490. 'content': json.dumps(content),
  491. 'ip': ip,
  492. 'operation': '删除数据失败的设备列表:{},{},{}'.format(device_list, e.__traceback__.tb_lineno, repr(e)),
  493. }
  494. LogModel.objects.create(**log)
  495. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  496. def get_app_device_type_list(self, request_dict, response):
  497. app_bundle_name = request_dict.get('appBundleName', None)
  498. lang = request_dict.get('lang', None)
  499. model = request_dict.get('model', None)
  500. type = request_dict.get('type', None)
  501. name = request_dict.get('name', None)
  502. pageNo = request_dict.get('pageNo', None)
  503. pageSize = request_dict.get('pageSize', None)
  504. if not all([pageNo, pageSize]):
  505. return response.json(444)
  506. page = int(pageNo)
  507. line = int(pageSize)
  508. try:
  509. app_bundle_qs = AppBundle.objects.all()
  510. if app_bundle_name:
  511. app_bundle_id = self.app_name_convert_id([app_bundle_name])
  512. print(app_bundle_id)
  513. app_bundle_qs = app_bundle_qs.filter(id__in=app_bundle_id)
  514. if lang:
  515. app_bundle_qs = app_bundle_qs.filter(app_device_type__devicenamelanguage__lang=lang)
  516. app_bundle_qs = app_bundle_qs.annotate(
  517. model=F('app_device_type__model'), type=F('app_device_type__type'), icon=F('app_device_type__icon'),
  518. lang=F('app_device_type__devicenamelanguage__lang'),
  519. name=F('app_device_type__devicenamelanguage__name'),
  520. sort=F('app_device_type__devicenamelanguage__sort')).values('id', 'app_device_type__id', 'model',
  521. 'type', 'icon', 'app_bundle_id',
  522. 'app_device_type__devicenamelanguage__id',
  523. 'lang', 'name', 'sort',
  524. 'app_device_type__app_version_number_id',
  525. 'app_device_type__config').order_by(
  526. 'app_device_type__devicenamelanguage__sort')
  527. if not app_bundle_qs.exists():
  528. return response.json(0)
  529. if name:
  530. app_bundle_qs = app_bundle_qs.filter(name=name)
  531. if model:
  532. app_bundle_qs = app_bundle_qs.filter(model=model)
  533. if type:
  534. app_bundle_qs = app_bundle_qs.filter(type=type)
  535. total = app_bundle_qs.count()
  536. app_bundle_qs = app_bundle_qs[(page - 1) * line:page * line]
  537. app_device_type_list = []
  538. for app_bundle in app_bundle_qs:
  539. app_bundle['version_number'] = app_bundle.pop('app_device_type__app_version_number_id')
  540. app_device_type_list.append(app_bundle)
  541. return response.json(0, {'list': app_device_type_list, 'total': total})
  542. except Exception as e:
  543. print(e)
  544. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  545. @staticmethod
  546. def get_app_bundle_id_list(response):
  547. try:
  548. app_info_qs = App_Info.objects.filter().values('id', 'appBundleId', 'appName')
  549. appBundleIdList = list(app_info_qs)
  550. return response.json(0, {'list': appBundleIdList})
  551. except Exception as e:
  552. print(e)
  553. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  554. @staticmethod
  555. def batch_edit_app_device_type(request_dict, request, response):
  556. # app_device_type表数据
  557. app_device_type_id = request_dict.get('app_device_type__id', None)
  558. model = request_dict.get('model', None)
  559. type = request_dict.get('type', None)
  560. icon = request.FILES.get('icon', None)
  561. # device_name_language表数据
  562. device_name_language_id = request_dict.get('app_device_type__devicenamelanguage__id', None)
  563. sort = request_dict.get('sort', None)
  564. version_number = request_dict.get('version_number', None)
  565. config = request_dict.get('config', None)
  566. if not all([app_device_type_id, device_name_language_id, model, type, sort, version_number]):
  567. return response.json(444)
  568. # 强制类型转换
  569. list_app_device_type_id = [int(item) for item in eval(app_device_type_id)]
  570. list_device_name_language_id = [int(item) for item in eval(device_name_language_id)]
  571. try:
  572. with transaction.atomic():
  573. if icon:
  574. icon_path = 'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/{}'.format(icon)
  575. if config:
  576. try:
  577. config = json.loads(config)
  578. except:
  579. return response.json(444, 'config必须是一个json数据')
  580. AppDeviceType.objects.filter(id__in=list_app_device_type_id) \
  581. .update(model=model, type=type, icon=icon_path, app_version_number_id=version_number,
  582. config=config)
  583. else:
  584. AppDeviceType.objects.filter(id__in=list_app_device_type_id) \
  585. .update(model=model, type=type, icon=icon_path, app_version_number_id=version_number)
  586. bucket_name = 'ansjerfilemanager'
  587. file_key = 'app/device_type_images/{}'.format(icon)
  588. s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
  589. # 地址:https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/camera_c190.png
  590. s3.upload_file_obj(
  591. bucket_name,
  592. file_key,
  593. icon,
  594. {'ContentType': icon.content_type, 'ACL': 'public-read'})
  595. else:
  596. if config:
  597. try:
  598. config = json.loads(config)
  599. except:
  600. return response.json(444, 'config必须是一个json数据')
  601. AppDeviceType.objects.filter(id__in=list_app_device_type_id) \
  602. .update(model=model, type=type, app_version_number_id=version_number,
  603. config=config)
  604. else:
  605. AppDeviceType.objects.filter(id__in=list_app_device_type_id) \
  606. .update(model=model, type=type, app_version_number_id=version_number)
  607. DeviceNameLanguage.objects.filter(id__in=list_device_name_language_id).update(sort=sort)
  608. return response.json(0)
  609. except Exception as e:
  610. print(e)
  611. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  612. @staticmethod
  613. def edit_app_device_type(request_dict, request, response):
  614. # app_device_type表数据
  615. app_device_type_id = request_dict.get('app_device_type__id', None)
  616. model = request_dict.get('model', None)
  617. type = request_dict.get('type', None)
  618. icon = request.FILES.get('icon', None)
  619. # device_name_language表数据
  620. device_name_language_id = request_dict.get('app_device_type__devicenamelanguage__id', None)
  621. lang = request_dict.get('lang', None)
  622. name = request_dict.get('name', None)
  623. sort = request_dict.get('sort', None)
  624. version_number = request_dict.get('version_number', None)
  625. config = request_dict.get('config', None)
  626. if not all([app_device_type_id, model, type, device_name_language_id, lang, name, sort]):
  627. return response.json(444)
  628. try:
  629. with transaction.atomic():
  630. if icon:
  631. icon_path = 'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/{}'.format(icon)
  632. if config:
  633. try:
  634. config = json.loads(config)
  635. except:
  636. return response.json(444, 'config必须是一个json数据')
  637. AppDeviceType.objects.filter(id=app_device_type_id) \
  638. .update(model=model, type=type, icon=icon_path, app_version_number_id=version_number,
  639. config=config)
  640. else:
  641. AppDeviceType.objects.filter(id=app_device_type_id) \
  642. .update(model=model, type=type, icon=icon_path, app_version_number_id=version_number)
  643. bucket_name = 'ansjerfilemanager'
  644. file_key = 'app/device_type_images/{}'.format(icon)
  645. s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
  646. # 地址:https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/camera_c190.png
  647. s3.upload_file_obj(
  648. bucket_name,
  649. file_key,
  650. icon,
  651. {'ContentType': icon.content_type, 'ACL': 'public-read'})
  652. else:
  653. if config:
  654. try:
  655. config = json.loads(config)
  656. except:
  657. return response.json(444, 'config必须是一个json数据')
  658. AppDeviceType.objects.filter(id=app_device_type_id) \
  659. .update(model=model, type=type, app_version_number_id=version_number,
  660. config=config)
  661. else:
  662. AppDeviceType.objects.filter(id=app_device_type_id) \
  663. .update(model=model, type=type, app_version_number_id=version_number)
  664. DeviceNameLanguage.objects.filter(id=device_name_language_id).update(lang=lang, name=name, sort=sort)
  665. return response.json(0)
  666. except Exception as e:
  667. print(e)
  668. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  669. @staticmethod
  670. def delete_app_device_type(request_dict, response):
  671. app_bundle_id = request_dict.get('appBundleId', None)
  672. app_device_type_id = request_dict.get('appDeviceTypeId', None)
  673. if not all([app_bundle_id, app_device_type_id]):
  674. return response.json(444)
  675. try:
  676. app_bundle_qs = AppBundle.objects.get(id=app_bundle_id)
  677. app_device_type_qs = AppDeviceType.objects.filter(id=app_device_type_id)
  678. app_bundle_qs.app_device_type.remove(*app_device_type_qs)
  679. return response.json(0)
  680. except Exception as e:
  681. print(e)
  682. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  683. @staticmethod
  684. def reset_all(request, request_dict, response):
  685. uid = request_dict.get('uid', None)
  686. if not uid:
  687. return response.json(444)
  688. try:
  689. # 记录操作日志
  690. ip = CommonService.get_ip_address(request)
  691. content = json.loads(json.dumps(request_dict))
  692. with transaction.atomic():
  693. # 删除主用户
  694. Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
  695. # 删除云存
  696. UID_Bucket.objects.filter(uid=uid).delete()
  697. Unused_Uid_Meal.objects.filter(uid=uid).delete()
  698. # Order_Model.objects.filter(UID=uid, order_type=0).delete()
  699. StsCrdModel.objects.filter(uid=uid).delete()
  700. VodHlsModel.objects.filter(uid=uid).delete()
  701. # 删除vod_hls分表数据
  702. split_vod_hls_obj = SplitVodHlsObject()
  703. split_vod_hls_obj.del_vod_hls_data(uid=uid)
  704. ExperienceContextModel.objects.filter(uid=uid).delete()
  705. # 删除AI
  706. ExperienceAiModel.objects.filter(uid=uid).delete()
  707. AiService.objects.filter(uid=uid).delete()
  708. log = {
  709. 'ip': ip,
  710. 'user_id': 2,
  711. 'status': 200,
  712. 'time': int(time.time()),
  713. 'url': 'deviceManagement/resetAll',
  714. 'content': json.dumps(content),
  715. 'operation': '{}重置所有'.format(uid),
  716. }
  717. LogModel.objects.create(**log)
  718. return response.json(0)
  719. except Exception as e:
  720. print(e)
  721. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  722. def add_app_device_type(self, request_dict, response, request):
  723. """
  724. 添加设备类型
  725. @param request_dict: 请求参数
  726. @request_dict appBundleName: app包名
  727. @request_dict versionNumber: app版本号
  728. @request_dict model: 设备类型
  729. @request_dict type: 设备型号
  730. @request_dict name: 设备名称
  731. @request_dict sort: 排序
  732. @request.FILES iconFile: 上传图标
  733. @param response: 响应对象
  734. """
  735. # app包名称
  736. app_bundle_name = request_dict.get('appBundleName', None)
  737. # 版本号
  738. version_number = request_dict.get('versionNumber', None)
  739. # app_device_type表数据
  740. model = request_dict.get('model', None)
  741. type = request_dict.get('type', None)
  742. # device_name_language表数据
  743. name = request_dict.get('name', None)
  744. sort = request_dict.get('sort', None)
  745. config = request_dict.get('config', None)
  746. # 上传图标
  747. file = request.FILES.get('iconFile', None)
  748. if config:
  749. config = json.loads(config)
  750. try:
  751. type = int(type)
  752. data_name = eval(name)
  753. app_bundle_name_list = app_bundle_name.split(',')
  754. app_bundle_id = self.app_name_convert_id(app_bundle_name_list)
  755. existing_records = []
  756. success_records = []
  757. need_upload = False # 标记是否需要上传文件
  758. # 先检查所有数据是否存在
  759. with transaction.atomic():
  760. for app_id in app_bundle_id:
  761. for k, v in data_name.items():
  762. app_bundle_qs = AppBundle.objects.filter(id=app_id,
  763. app_device_type__devicenamelanguage__lang=k,
  764. app_device_type__app_version_number_id=version_number,
  765. app_device_type__type=type,
  766. app_device_type__model=model)
  767. if app_bundle_qs.exists():
  768. app_bundle = app_bundle_qs.values("app_bundle_id").first()
  769. existing_record = {"app_bundle_id": app_bundle["app_bundle_id"], "type": type,
  770. "version_number": version_number, "lang": k, "model": model}
  771. existing_records.append(existing_record)
  772. else:
  773. need_upload = True # 发现至少一条记录不存在,需要上传文件
  774. # 如果需要上传文件
  775. if need_upload:
  776. with transaction.atomic():
  777. fileName = file.name
  778. now_time = int(time.time())
  779. response_url = f'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/{now_time}_{fileName}'
  780. bucket_name = 'ansjerfilemanager'
  781. file_key = f'app/device_type_images/{now_time}_{fileName}'
  782. s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
  783. s3.upload_file_obj(bucket_name, file_key, file,
  784. {'ContentType': file.content_type, 'ACL': 'public-read'})
  785. for app_id in app_bundle_id:
  786. for k, v in data_name.items():
  787. record_key = {"app_bundle_id": app_id, "type": type, "version_number": version_number,
  788. "lang": k, "model": model}
  789. # 检查这个组合的记录是否存在
  790. if not any(rec == record_key for rec in existing_records):
  791. app_bundle = AppBundle.objects.filter(id=app_id).values('id', 'app_bundle_id').first()
  792. app_device_type_qs = AppDeviceType.objects.create(model=model, type=type,
  793. icon=response_url,
  794. app_version_number_id=version_number,
  795. config=config)
  796. DeviceNameLanguage.objects.create(lang=k, name=v, sort=sort,
  797. app_device_type_id=app_device_type_qs.id)
  798. app_device_type_qs.appbundle_set.add(app_bundle["id"])
  799. success_records.append(
  800. {"app_bundle_id": app_bundle["app_bundle_id"], "type": type,
  801. "version_number": version_number,
  802. "lang": k, "model": model}
  803. )
  804. response_data = {
  805. 'success_records': success_records,
  806. 'existing_records': existing_records
  807. }
  808. return response.json(0, response_data)
  809. except Exception as e:
  810. print(e)
  811. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  812. @staticmethod
  813. def get_device_icon(request_dict, response):
  814. """
  815. 查询设备信息图标
  816. @param request_dict: 请求参数
  817. @request_dict lang: 语言
  818. @request_dict app_bundle_id: app版本id
  819. @request_dict version_number: app版本号
  820. @param response: 响应对象
  821. @return:
  822. """
  823. lang = request_dict.get('lang', 'en')
  824. app_bundle_id = request_dict.get('appBundleId', None)
  825. version_number = request_dict.get('versionNumber', None)
  826. if not all([lang, app_bundle_id, version_number]):
  827. return response.json(444)
  828. try:
  829. # tc是ios繁体字语言类型
  830. if lang == 'tc':
  831. lang = 'cn_tw'
  832. app_bundle_qs = AppBundle.objects.filter(app_bundle_id=app_bundle_id).values(
  833. 'app_device_type__app_version_number_id').distinct().order_by('app_device_type__app_version_number_id')
  834. # 判断版本是否存在, 不存在则获取输入版本范围内最接近的输入版本
  835. version_number_list = []
  836. app_bundle_list = []
  837. for version in app_bundle_qs:
  838. version_number_list.append(version['app_device_type__app_version_number_id'])
  839. new_version_number = CommonService.compare_version_number(version_number, version_number_list)
  840. app_device_qs = DeviceNameLanguage.objects.filter(lang=lang)
  841. if not app_device_qs.exists():
  842. lang = 'en'
  843. # 版本号对应的设备信息图标
  844. for version_number in new_version_number:
  845. app_bundle_qs = AppBundle.objects.filter(app_bundle_id=app_bundle_id,
  846. app_device_type__devicenamelanguage__lang=lang,
  847. app_device_type__app_version_number_id=version_number). \
  848. annotate(
  849. model=F('app_device_type__model'), type=F('app_device_type__type'), icon=F('app_device_type__icon'),
  850. name=F('app_device_type__devicenamelanguage__name'),
  851. sort=F('app_device_type__devicenamelanguage__sort'),
  852. config=F('app_device_type__config'),
  853. app_version_number_id=F('app_device_type__app_version_number_id')).values('model', 'type', 'icon',
  854. 'name', 'sort', 'config',
  855. 'app_device_type__app_version_number_id')
  856. for app_bundle in app_bundle_qs:
  857. app_bundle_list.append({
  858. 'model': app_bundle['model'],
  859. 'type': app_bundle['type'],
  860. 'icon': app_bundle['icon'],
  861. 'name': app_bundle['name'],
  862. 'sort': app_bundle['sort'],
  863. 'config': app_bundle['config'],
  864. 'app_device_type__app_version_number_id': app_bundle['app_device_type__app_version_number_id'],
  865. })
  866. dvr_list = [app_bundle for app_bundle in app_bundle_list if app_bundle['model'] == 1]
  867. ipc_list = [app_bundle for app_bundle in app_bundle_list if app_bundle['model'] == 2]
  868. res = {
  869. 'deviceDvr': sorted(dvr_list, key=operator.itemgetter('sort')),
  870. 'deviceIpc': sorted(ipc_list, key=operator.itemgetter('sort')),
  871. }
  872. return response.json(0, res)
  873. except Exception as e:
  874. print(e)
  875. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  876. @staticmethod
  877. def get_uid_push(request_dict, response):
  878. """
  879. 查询设备信息详情信息
  880. @param request_dict: 请求参数
  881. @request_dict UID: UID
  882. @param response: 响应对象
  883. @return:
  884. """
  885. uid = request_dict.get('UID', None)
  886. if not uid:
  887. return response.json(444)
  888. try:
  889. uid_set_qs = UidSetModel.objects.filter(uid=uid).first()
  890. data = model_to_dict(uid_set_qs)
  891. ALGORITHM_COMBO_TYPES = ['移动', '人形', '车型', '宠物', '人脸', '异响', '闯入', '离开', '徘徊',
  892. '无人', '往来', '哭声', '手势', '火焰', '婴儿', '包裹']
  893. if data['ai_type'] > 0:
  894. num = data['ai_type']
  895. result = ""
  896. while num != 0:
  897. ret = num % 2
  898. num //= 2
  899. result = str(ret) + result
  900. types = []
  901. event_type = result
  902. len_type = len(event_type)
  903. for i in range(len_type):
  904. e_type = event_type[len_type - 1 - i]
  905. if e_type == '1':
  906. types.append(str(ALGORITHM_COMBO_TYPES[i]))
  907. data['ai_type'] = types
  908. # uid_set查uid_push
  909. uid_pushes_qs = UidPushModel.objects.filter(uid_set_id=uid_set_qs.id).select_related('userID')
  910. uid_push_data = []
  911. # 保存uid_pushes_qs列表
  912. for item in uid_pushes_qs:
  913. item_dict = model_to_dict(item)
  914. # 添加 username 字段
  915. item_dict['username'] = item.userID.username if item.userID else None
  916. uid_push_data.append(item_dict)
  917. data["uid_push"] = uid_push_data
  918. return response.json(0, data)
  919. except Exception as e:
  920. print(e)
  921. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  922. @staticmethod
  923. def get_app_name_list(response):
  924. """
  925. 查询APP包名称列表
  926. @param response: 响应对象
  927. @return:
  928. """
  929. try:
  930. app_bundle_qs = AppBundle.objects.all().values_list('app_bundle_id')
  931. app_info = App_Info.objects.filter(appBundleId__in=app_bundle_qs).values('appName')
  932. app_name_list = []
  933. for app_name in app_info:
  934. app_name_list.append(app_name['appName'])
  935. app_name_list = list(set(app_name_list))
  936. return response.json(0, app_name_list)
  937. except Exception as e:
  938. print(e)
  939. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  940. @staticmethod
  941. def app_name_convert_id(app_name_list):
  942. """
  943. app_name_list 转 app_id_list
  944. @param app_name_list: app名字列表
  945. @return app_id_list: app id列表
  946. """
  947. try:
  948. app_bundle_id_list = App_Info.objects.filter(appName__in=app_name_list).values_list('appBundleId',
  949. flat=True)
  950. app_id_list = AppBundle.objects.filter(app_bundle_id__in=app_bundle_id_list).values_list('id', flat=True)
  951. return list(set(app_id_list))
  952. except Exception as e:
  953. print(e)
  954. return []
  955. @staticmethod
  956. def call_add_app_device_type(request_dict, response, request):
  957. """
  958. 添加设备类型
  959. @param request_dict: 请求参数
  960. @request_dict appBundleName: app包名
  961. @request_dict versionNumber: app版本号
  962. @request_dict model: 设备类型
  963. @request_dict type: 设备型号
  964. @request_dict name: 设备名字
  965. @request_dict sort: 排序
  966. @request_dict region: 地区
  967. @request.FILES iconFile: 上传图标
  968. @param response: 响应对象
  969. """
  970. # app包名称
  971. app_bundle_name = request_dict.get('appBundleName', None)
  972. # 版本号
  973. version_number = request_dict.get('versionNumber', None)
  974. # app_device_type表数据
  975. model = request_dict.get('model', None)
  976. type = request_dict.get('type', None)
  977. # device_name_language表数据
  978. name = request_dict.get('name', None)
  979. sort = request_dict.get('sort', None)
  980. config = request_dict.get('config', None)
  981. # 上传图标
  982. files = request.FILES.get('iconFile', None)
  983. # 需要添加到哪一个服
  984. region = request_dict.get("region", None) # 获取需要同步的区域
  985. # 检查必需参数
  986. if not all([model, type, name, sort, version_number, files, app_bundle_name, region]):
  987. return response.json(444, 'Missing required parameters')
  988. regions = region.split(",") # 将同步区域拆分为列表
  989. return_value_list = []
  990. for region in regions:
  991. if region == 'test':
  992. url = SERVER_DOMAIN_TEST
  993. elif region == 'cn':
  994. url = SERVER_DOMAIN_CN
  995. elif region == 'us':
  996. url = SERVER_DOMAIN_US
  997. elif region == 'eu':
  998. url = SERVER_DOMAIN_EUR
  999. else:
  1000. return response.json(444, 'Invalid region')
  1001. try:
  1002. form_data = {
  1003. 'name': name,
  1004. 'type': type,
  1005. 'sort': sort,
  1006. 'model': model,
  1007. 'versionNumber': version_number,
  1008. 'appBundleName': app_bundle_name,
  1009. }
  1010. if config:
  1011. try:
  1012. config = json.loads(config)
  1013. except:
  1014. return response.json(444, 'config必须是一个json数据')
  1015. form_data["config"] = json.dumps(config)
  1016. # 发送 POST 请求调用 add_app_device_type 方法
  1017. response_value = requests.post(url + "/deviceManagement/addAppDeviceType",
  1018. data=form_data,
  1019. files={'iconFile': files})
  1020. return_value = {region: response_value.json()["data"]}
  1021. return_value_list.append(return_value)
  1022. except Exception as e:
  1023. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  1024. return response.json(0, {"list": return_value_list})
  1025. @classmethod
  1026. def query_device_user(cls, request, request_dict, response):
  1027. try:
  1028. # 从请求中检索文件
  1029. file = request.FILES.get('deviceFile')
  1030. fileType = int(request_dict.get('type', 1))
  1031. uid_list = []
  1032. if not file:
  1033. return response.json(444)
  1034. # 处理文件内容并生成UID列表
  1035. for item in file:
  1036. id_val = item.decode().strip().replace(" ", "")
  1037. if fileType == 2:
  1038. uid = CommonService.get_uid_by_serial_number(id_val[:9])
  1039. uid_list.append(uid)
  1040. else:
  1041. uid_list.append(id_val)
  1042. if not uid_list:
  1043. return response.json(0, {'userInfo': []})
  1044. user_info = []
  1045. batch_size = 50 # 为查询设置合理的批处理大小
  1046. # 批量获取设备信息
  1047. for i in range(0, len(uid_list), batch_size):
  1048. batch_uids = uid_list[i:i + batch_size]
  1049. device_info_qs = Device_Info.objects.filter(UID__in=batch_uids).values('UID', 'NickName', 'ip',
  1050. 'userID__username')
  1051. uid_to_device_info = {device_info['UID']: device_info for device_info in device_info_qs}
  1052. # 将查询到的设备信息与当前批次进行匹配
  1053. for uid in batch_uids:
  1054. if uid in uid_to_device_info:
  1055. device_info = uid_to_device_info[uid]
  1056. user_info.append({
  1057. 'uid': device_info['UID'],
  1058. 'deviceName': device_info['NickName'],
  1059. 'ip': device_info['ip'],
  1060. 'uName': device_info['userID__username']
  1061. })
  1062. # 返回带有用户信息的响应
  1063. return response.json(0, {'userInfo': user_info})
  1064. except Exception as e:
  1065. LOGGER.error(f'查询设备信息异常: errLine: {e.__traceback__.tb_lineno}, errMsg: {repr(e)}')
  1066. return response.json(5)
  1067. @staticmethod
  1068. def get_customer_device_list(request_dict, response):
  1069. """
  1070. 查询扫码添加设备列表
  1071. :param request_dict:
  1072. :param response:
  1073. :return:
  1074. """
  1075. order_number = request_dict.get('orderNumber')
  1076. name = request_dict.get('name')
  1077. email = request_dict.get('email')
  1078. serial_number = request_dict.get('serialNumber')
  1079. uid = request_dict.get('uid')
  1080. page = int(request_dict.get('pageNo', 1))
  1081. page_size = int(request_dict.get('pageSize', 10))
  1082. try:
  1083. # 构建查询条件
  1084. custom_customer_qs = CustomCustomerOrderInfo.objects.all()
  1085. if order_number:
  1086. custom_customer_qs = custom_customer_qs.filter(order_number__icontains=order_number)
  1087. if name:
  1088. custom_customer_qs = custom_customer_qs.filter(name__icontains=name)
  1089. if email:
  1090. custom_customer_qs = custom_customer_qs.filter(email__icontains=email)
  1091. # 获取所需的ID和数量
  1092. c_id_list = custom_customer_qs.values_list("id", flat=True)
  1093. total_quantity = custom_customer_qs.aggregate(total_quantity=Sum('quantity'))['total_quantity']
  1094. # 查询设备列表
  1095. customer_device_qs = CustomCustomerDevice.objects.filter(c_id__in=c_id_list).order_by('-created_time')
  1096. # 通过serial_number和uid进行过滤
  1097. if serial_number:
  1098. customer_device_qs = customer_device_qs.filter(serial_number__icontains=serial_number)
  1099. if uid:
  1100. customer_device_qs = customer_device_qs.filter(uid=uid)
  1101. # 分页处理
  1102. paginator = Paginator(customer_device_qs, page_size)
  1103. customer_device_page = paginator.get_page(page)
  1104. # 创建一个字典来映射 c_id 到 CustomCustomerOrderInfo 对象
  1105. customer_order_map = {order.id: order for order in custom_customer_qs}
  1106. # 构建设备列表
  1107. customer_device_list = []
  1108. for device in customer_device_page.object_list:
  1109. customer_order = customer_order_map.get(device.c_id)
  1110. if customer_order:
  1111. customer_device_list.append({
  1112. 'id': device.id,
  1113. 'serialNumber': device.serial_number,
  1114. 'uid': device.uid,
  1115. 'deviceType': device.type,
  1116. 'fullCode': device.full_code,
  1117. 'addTime': device.created_time,
  1118. 'orderNumber': customer_order.order_number,
  1119. 'name': customer_order.name,
  1120. 'email': customer_order.email,
  1121. })
  1122. else:
  1123. customer_device_list.append({
  1124. 'id': device.id,
  1125. 'serialNumber': device.serial_number,
  1126. 'uid': device.uid,
  1127. 'deviceType': device.type,
  1128. 'fullCode': device.full_code,
  1129. 'addTime': device.created_time,
  1130. 'orderNumber': "",
  1131. 'name': "",
  1132. 'email': "",
  1133. })
  1134. # 构造返回数据
  1135. data = {
  1136. 'total': paginator.count,
  1137. 'orderDeviceQuantity': total_quantity or 0, # 防止为None
  1138. 'list': customer_device_list, # 当前页的记录列表
  1139. }
  1140. return response.json(0, data)
  1141. except Exception as e:
  1142. return response.json(500, f'error_line:{e.__traceback__.tb_lineno}, error_msg:{repr(e)}')