1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- import datetime
- import json
- import operator
- import os
- import threading
- import time
- import oss2
- import requests
- from obs import ObsClient
- from django.core.paginator import Paginator
- from django.db import transaction
- from django.db.models import Q, F, Sum, OuterRef, Min, Subquery
- from django.forms.models import model_to_dict
- from django.utils import timezone
- from django.views.generic.base import View
- from Ansjer.config import LOGGER, SERIAL_DOMAIN_NAME, HUAWEICLOUD_AK, HUAWEICLOUD_SK, HUAWEICLOUD_OBS_SERVER, \
- HUAWEICLOUD_BAIDU_BIG_MODEL_LICENSE_BUKET,CONFIG_INFO, CONFIG_TEST, CONFIG_CN, CONFIG_US, CONFIG_EUR
- from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
- AWS_SES_ACCESS_REGION
- from Ansjer.config import SERVER_DOMAIN_TEST, SERVER_DOMAIN_CN, SERVER_DOMAIN_US, SERVER_DOMAIN_EUR
- from Model.models import Device_Info, UidSetModel, LogModel, UID_Bucket, Unused_Uid_Meal, StsCrdModel, \
- VodHlsModel, ExperienceContextModel, DeviceTypeModel, UidUserModel, ExperienceAiModel, AiService, \
- AppBundle, App_Info, AppDeviceType, DeviceNameLanguage, UIDCompanySerialModel, UidPushModel, \
- CustomCustomerOrderInfo, CustomCustomerDevice, DeviceVersionInfo, VoicePromptModel, DeviceAlgorithmExplain, BaiduBigModelLicense, \
- DeviceDailyReport
- from Object.AWS.AmazonS3Util import AmazonS3Util
- from Object.Enums.RedisKeyConstant import RedisKeyConstant
- from Object.RedisObject import RedisObject
- from Object.ResponseObject import ResponseObject
- from Object.TokenObject import TokenObject
- from Service.CommonService import CommonService
- from Service.EquipmentInfoService import EquipmentInfoService
- from Service.ModelService import ModelService
- from Service.VodHlsService import SplitVodHlsObject
- class DeviceManagement(View):
- def get(self, request, *args, **kwargs):
- request.encoding = 'utf-8'
- operation = kwargs.get('operation')
- return self.validation(request.GET, request, operation)
- def post(self, request, *args, **kwargs):
- request.encoding = 'utf-8'
- operation = kwargs.get('operation')
- return self.validation(request.POST, request, operation)
- def validation(self, request_dict, request, operation):
- language = request_dict.get('language', 'en')
- response = ResponseObject(language, 'pc')
- if operation == 'addDeviceType':
- return self.addDeviceType(request, request_dict, response)
- elif operation == 'delDeviceData': # 删除设备数据
- return self.del_device_data(request, request_dict, response)
- elif operation == 'getDeviceIcon': # app获取设备图标
- response = ResponseObject(language)
- return self.get_device_icon(request_dict, response)
- elif operation == 'addAppDeviceType': # 添加app设备类型数据并上传图标
- return self.add_app_device_type(request_dict, response, request)
- elif operation == 'getUidPush': # 查询推送信息
- return self.get_uid_push(request_dict, response)
- elif operation == 'checkDeviceInfo':
- return self.query_device_user(request, request_dict, response)
- else:
- tko = TokenObject(
- request.META.get('HTTP_AUTHORIZATION'),
- returntpye='pc')
- if tko.code != 0:
- return response.json(tko.code)
- response.lang = tko.lang
- userID = tko.userID
- if not userID:
- return response.json(444, 'userID')
- if operation == 'getDeviceInfoList': # 获取设备信息数据
- return self.get_device_info_list(request_dict, response)
- elif operation == 'deleteDevice': # 删除设备
- return self.deleteDevice(request, request_dict, response, userID)
- elif operation == 'delDeviceDataV2': # 后台设备删除数据
- return self.del_device_data(request, request_dict, response, userID)
- elif operation == 'resetVod': # 重置云存
- return self.resetVod(request, request_dict, response)
- elif operation == 'resetAi': # 重置AI
- return self.reset_ai(request, request_dict, response)
- elif operation == 'resetPrimaryUser':
- return self.resetPrimaryUser(request, request_dict, response)
- elif operation == 'getDeviceType':
- return self.getDeviceType(response)
- elif operation == 'getDeviceTypeList':
- return self.getDeviceTypeList(request_dict, response)
- elif operation == 'deleteDeviceType':
- return self.deleteDeviceType(request_dict, response)
- elif operation == 'getAppDeviceTypeList': # 获取app设备类型数据
- return self.get_app_device_type_list(request_dict, response)
- elif operation == 'getAppBundleIdList': # 获取app包id数据
- return self.get_app_bundle_id_list(response)
- elif operation == 'editAppDeviceType': # 编辑app设备类型数据
- return self.edit_app_device_type(request_dict, request, response)
- elif operation == 'batchEditAppDeviceType': # 批量编辑app设备类型数据
- return self.batch_edit_app_device_type(request_dict, request, response)
- elif operation == 'deleteAppDeviceType': # 删除app设备类型数据
- return self.delete_app_device_type(request_dict, response)
- elif operation == 'getAppBundle': # 获取app版本包
- return self.get_app_bundle(response)
- elif operation == 'resetAll': # 重置设备主用户/云存/AI
- return self.reset_all(request, request_dict, response)
- elif operation == 'getAppNameList': # 获取app版本包
- return self.get_app_name_list(response)
- elif operation == 'callAddAppDeviceType': # 可选服添加app设备类型数据并上传图标
- return self.call_add_app_device_type(request_dict, response, request)
- elif operation == 'getCustomerDeviceList': # 查询扫码添加设备列表
- return self.get_customer_device_list(request_dict, response)
- # 设备型号版本
- elif operation == 'getDeviceVerInfo': # 查询设备型号版本列表
- return self.get_device_ver_info(request_dict, response)
- elif operation == 'addDeviceVerInfo': # 添加设备型号版本
- return self.add_device_ver_info(request_dict, response)
- elif operation == 'editDeviceVerInfo': # 编辑设备型号版本
- return self.edit_device_ver_info(request_dict, response)
- elif operation == 'delDeviceVerInfo': # 删除设备型号版本
- return self.del_device_ver_info(request_dict, response)
- elif operation == 'syncDeviceVersion': # 一键同步
- return self.sync_device_version(request_dict, response)
- # 设备语音设置
- elif operation == 'getDeviceVoice': # 获取设备音频
- return self.get_device_voice(request_dict, response)
- elif operation == 'algorithmTypeList': # 添加设备型号版本
- return self.algorithm_type_list(response)
- elif operation == 'addDeviceVoice': # 获取设备音频列表
- return self.add_device_voice(request, request_dict, response)
- elif operation == 'editDeviceVoice':
- return self.edit_device_voice(request_dict, response)
- elif operation == 'delDeviceVoice':
- return self.del_device_voice(request_dict, response)
- elif operation == 'deviceTypeList':
- return self.device_type_list(response)
- # 百度大模型
- elif operation == 'getBaiduBigModelLicense': # 查询大模型许可证
- return self.get_baidu_big_model_license(request_dict, response)
- elif operation == 'addBaiduBigModelLicense': # 添加大模型许可证
- return self.add_baidu_big_model_license(request, response)
- elif operation == 'editBaiduBigModelLicense': # 编辑大模型许可证
- return self.edit_baidu_big_model_license(request, request_dict, response)
- elif operation == 'delBaiduBigModelLicense': # 删除大模型许可证
- return self.del_baidu_big_model_license(request_dict, response)
- elif operation == 'devicePowerDisplay':
- return self.device_power_display(request_dict, response)
- else:
- return response.json(444, 'operation')
- @classmethod
- def get_app_bundle(cls, response):
- """
- 获取app版本id
- """
- app_bundle_qs = AppBundle.objects.all().values('id', 'app_bundle_id')
- if not app_bundle_qs.exists():
- return response.json(0)
- app_bundle_list = []
- for app_bundle in app_bundle_qs:
- app_bundle_qs.exists()
- app_bundle_list.append(app_bundle)
- return response.json(0, app_bundle_list)
- @classmethod
- def get_device_info_list(cls, request_dict, response):
- pageNo = request_dict.get('pageNo', None)
- pageSize = request_dict.get('pageSize', None)
- UID = request_dict.get('UID', None)
- serialNumber = request_dict.get('serialNumber', None)
- NickName = request_dict.get('NickName', None)
- username = request_dict.get('username', None)
- version = request_dict.get('version', None)
- Type = request_dict.get('Type', None)
- if not all([pageNo, pageSize]):
- return response.json(444)
- page = int(pageNo)
- line = int(pageSize)
- try:
- if any([UID, serialNumber, NickName, username, version, Type]): # 条件查询
- if UID:
- device_info_qs = Device_Info.objects.filter(UID__icontains=UID)
- if serialNumber:
- device_info_qs = Device_Info.objects.filter(serial_number__icontains=serialNumber[:9])
- if NickName:
- device_info_qs = Device_Info.objects.filter(NickName__icontains=NickName)
- if username:
- device_info_qs = Device_Info.objects.filter(Q(userID__username__icontains=username) |
- Q(userID__userEmail__icontains=username) |
- Q(userID__phone__icontains=username))
- if version:
- uid_list = UidSetModel.objects.filter(version__icontains=version).values_list('uid', flat=True)
- device_info_qs = Device_Info.objects.filter(UID__in=uid_list)
- if Type:
- type_list = DeviceTypeModel.objects.filter(name=Type).values_list('type', flat=True)
- device_info_qs = Device_Info.objects.filter(Type__in=type_list)
- total = device_info_qs.count()
- if not total:
- return response.json(0, {'list': {}, 'total': 0})
- device_info_qs = device_info_qs[(page - 1) * line:page * line]
- else: # 查询全部
- total = Device_Info.objects.filter().count()
- device_info_qs = Device_Info.objects.filter()[(page - 1) * line:page * line]
- if not device_info_qs.exists():
- return response.json(0, {'list': {}, 'total': 0})
- device_info_list = CommonService.qs_to_dict(device_info_qs)
- for k, v in enumerate(device_info_list["datas"]):
- for device_info in device_info_qs:
- if v['pk'] == device_info.id:
- # 设备的用户名和主用户
- username = ModelService.get_user_name(device_info_list["datas"][k]['fields']['userID'])
- device_info_list["datas"][k]['fields']['username'] = username
- device_info_list["datas"][k]['fields']['vodPrimaryMaster'] = \
- device_info_list["datas"][k]['fields']['vodPrimaryMaster']
- # 设备类型,是否支持Alexa和ip
- type = device_info_list["datas"][k]['fields']['Type']
- device_type_qs = DeviceTypeModel.objects.filter(type=type).values('name')
- if device_type_qs.exists():
- device_info_list["datas"][k]['fields']['Type'] = device_type_qs[0]['name']
- uid_set_qs = UidSetModel.objects.filter(
- uid=device_info_list["datas"][k]['fields']['UID']). \
- values('detect_status', 'is_alexa', 'ip', 'version', 'is_ai', 'is_human', 'cloud_vod',
- 'ucode', 'device_type')
- if uid_set_qs.exists():
- # 移动侦测
- iSNotification = '开' if uid_set_qs[0]['detect_status'] else '关'
- device_info_list["datas"][k]['fields']['iSNotification'] = iSNotification
- isAlexa = '是' if uid_set_qs[0]['is_alexa'] else '否'
- isHuman = '是' if uid_set_qs[0]['is_human'] else '否'
- cloud_vod = CommonService.is_cloud_device(uid_set_qs[0]['ucode'],
- uid_set_qs[0]['device_type'])
- if cloud_vod:
- cloud_vod = '支持'
- else:
- cloud_vod = '不支持'
- if uid_set_qs[0]['is_ai'] == 2:
- isAI = '不支持'
- else:
- isAI = '支持'
- device_info_list["datas"][k]['fields']['isHuman'] = isHuman
- device_info_list["datas"][k]['fields']['isAI'] = isAI
- device_info_list["datas"][k]['fields']['isAlexa'] = isAlexa
- device_info_list["datas"][k]['fields']['cloudVod'] = cloud_vod
- device_info_list["datas"][k]['fields']['ip'] = uid_set_qs[0]['ip']
- device_info_list["datas"][k]['fields']['version'] = uid_set_qs[0]['version']
- uid_bucket_qs = UID_Bucket.objects.filter(
- uid=device_info_list["datas"][k]['fields']['UID']).values('status')
- # 0是关闭,1是开启
- if uid_bucket_qs.exists():
- res = []
- for uid_bucket in uid_bucket_qs:
- status = uid_bucket['status']
- res.append(status)
- if 1 in res:
- device_info_list["datas"][k]['fields']['status'] = 1
- else:
- device_info_list["datas"][k]['fields']['status'] = 0
- else:
- device_info_list["datas"][k]['fields']['status'] = 0
- # AI开关状态
- ai_service = AiService.objects.filter(uid=device_info_list["datas"][k]['fields']['UID']).values(
- 'detect_status')
- if ai_service.exists():
- if ai_service[0]['detect_status']:
- device_info_list["datas"][k]['fields']['ai_status'] = 1
- else:
- device_info_list["datas"][k]['fields']['ai_status'] = 0
- else:
- device_info_list["datas"][k]['fields']['ai_status'] = 0
- # 时间格式化修改
- device_info_list["datas"][k]['fields']['update_time'] = device_info_list["datas"][k]['fields']['update_time'].split('.')[0].replace('T', ' ')
- device_info_list["datas"][k]['fields']['data_joined'] = device_info_list["datas"][k]['fields']['data_joined'].split('.')[0].replace('T', ' ')
- return response.json(0, {'list': device_info_list, 'total': total})
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- # 根据id删除设备
- def deleteDevice(self, request, request_dict, response, user_id):
- deviceID = request_dict.get('deviceID', None)
- userID = request_dict.get('userID', None)
- uid = request_dict.get('uid', None)
- if not all([deviceID, userID, uid]):
- return response.json(444)
- try:
- redis = RedisObject(3)
- with transaction.atomic():
- Device_Info.objects.filter(id=deviceID).delete()
- UidPushModel.objects.filter(uid_set__uid=uid).delete()
- # 删除推送消息
- EquipmentInfoService.delete_all_equipment_info(device_user_id=userID, device_uid=uid)
- # 构建Redis键
- device_key = f"{RedisKeyConstant.BASIC_USER.value}{userID}:UID:{uid}"
- redis.del_data(device_key)
- content = json.loads(json.dumps(request_dict))
- ip = CommonService.get_ip_address(request)
- log = {
- 'user_id': 2,
- 'status': 200,
- 'time': int(time.time()),
- 'url': 'deviceManagement/deleteDevice',
- 'content': user_id,
- 'ip': ip,
- 'operation': '删除设备和配置记录:{}'.format(json.dumps(content)),
- }
- LogModel.objects.create(**log)
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- # 重置设备主用户
- def resetPrimaryUser(self, request, request_dict, response):
- uid = request_dict.get('uid', None)
- if not uid:
- return response.json(404)
- try:
- # 记录操作日志
- ip = CommonService.get_ip_address(request)
- content = json.loads(json.dumps(request_dict))
- log = {
- 'ip': ip,
- 'user_id': 2,
- 'status': 200,
- 'time': int(time.time()),
- 'url': 'deviceManagement/resetPrimaryUser',
- 'content': json.dumps(content),
- 'operation': '{}重置设备主用户'.format(uid),
- }
- LogModel.objects.create(**log)
- Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
- return response.json(0)
- except Exception as e:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- # 重置设备云存
- def resetVod(self, request, request_dict, response):
- uid = request_dict.get('uid', None)
- if not uid:
- return response.json(444)
- try:
- # 记录操作日志
- ip = CommonService.get_ip_address(request)
- content = json.loads(json.dumps(request_dict))
- log = {
- 'ip': ip,
- 'user_id': 2,
- 'status': 200,
- 'time': int(time.time()),
- 'url': 'deviceManagement/resetVod',
- 'content': json.dumps(content),
- 'operation': '{}重置云存'.format(uid),
- }
- with transaction.atomic():
- LogModel.objects.create(**log)
- # 删除和更新设备云存相关数据
- UID_Bucket.objects.filter(uid=uid).delete()
- AiService.objects.filter(uid=uid).delete()
- Unused_Uid_Meal.objects.filter(uid=uid).delete()
- # Order_Model.objects.filter(UID=uid, order_type=0).delete()
- StsCrdModel.objects.filter(uid=uid).delete()
- VodHlsModel.objects.filter(uid=uid).delete()
- # 删除vod_hls分表数据
- split_vod_hls_obj = SplitVodHlsObject()
- split_vod_hls_obj.del_vod_hls_data(uid=uid)
- ExperienceContextModel.objects.filter(uid=uid).delete()
- Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def reset_ai(request, request_dict, response):
- uid = request_dict.get('uid', None)
- if not uid:
- return response.json(444)
- try:
- # 记录操作日志
- ip = CommonService.get_ip_address(request)
- content = json.loads(json.dumps(request_dict))
- log = {
- 'ip': ip,
- 'user_id': 2,
- 'status': 200,
- 'time': int(time.time()),
- 'url': 'deviceManagement/resetAi',
- 'content': json.dumps(content),
- 'operation': '{}重置AI'.format(uid),
- }
- with transaction.atomic():
- LogModel.objects.create(**log)
- # 删除和更新设备AI相关数据
- ExperienceAiModel.objects.filter(uid=uid).delete()
- AiService.objects.filter(uid=uid).delete()
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def getDeviceType(response):
- try:
- device_type_qs = DeviceTypeModel.objects.all().values('type', 'name')
- print(list(device_type_qs))
- return response.json(0, {'list': list(device_type_qs)})
- except Exception as e:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- # 获取设备类型数据
- def getDeviceTypeList(self, request_dict, response):
- name = request_dict.get('name', None)
- pageNo = request_dict.get('pageNo', None)
- pageSize = request_dict.get('pageSize', None)
- if not all([pageNo, pageSize]):
- return response.json(444)
- page = int(pageNo)
- line = int(pageSize)
- try:
- if name:
- device_type_qs = DeviceTypeModel.objects.filter(name__contains=name).values()
- total = len(device_type_qs)
- else:
- device_type_qs = DeviceTypeModel.objects.filter().values()[(page - 1) * line:page * line]
- total = DeviceTypeModel.objects.filter().count()
- if not device_type_qs.exists():
- return response.json(173)
- device_type_list = []
- for device_type in device_type_qs:
- auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
- bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
- icon = device_type['icon']
- url = 'device_type/' + icon
- device_type['icon'] = bucket.sign_url('GET', url, 3600)
- device_type_list.append(device_type)
- return response.json(0, {'list': device_type_list, 'total': total})
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- # 删除设备类型
- def deleteDeviceType(self, request_dict, response):
- deviceTypeID = request_dict.get('deviceTypeID', None)
- if not deviceTypeID:
- return response.json(444)
- try:
- DeviceTypeModel.objects.filter(id=deviceTypeID).delete()
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- # 添加设备类型
- def addDeviceType(self, request, request_dict, response):
- iconFile = request.FILES.get('iconFile', None)
- name = request_dict.get('name', None)
- model = request_dict.get('model', None)
- type = request_dict.get('type', None)
- ptz_type = request_dict.get('ptz_type', None)
- if not all([iconFile, name, model, type, ptz_type]):
- return response.json(444)
- try:
- model = int(model)
- ptz_type = int(ptz_type)
- icon = iconFile.name
- now_time = int(time.time())
- # 上传文件到阿里云OSS
- auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
- bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
- key = 'device_type/' + icon # 图片文件存放于 device_type 目录下
- # https://oss.console.aliyun.com/bucket/oss-cn-shenzhen/ansjer-static-resources/object?path=device_type%2F
- bucket.put_object(key=key, data=iconFile)
- DeviceTypeModel.objects.create(name=name, model=model, type=type, ptz_type=ptz_type, icon=icon,
- add_time=now_time, update_time=now_time)
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def del_device_data(request, request_dict, response, user_id=''):
- uidList = request_dict.get('uidList', None)
- delDataOptions = request_dict.get('delDataOptions', None)
- serialNumberList = request_dict.get('serialNumberList', None)
- if not all([uidList or serialNumberList, delDataOptions]):
- return response.json(444)
- # 记录日志
- content = json.loads(json.dumps(request_dict))
- ip = CommonService.get_ip_address(request)
- log = {
- 'user_id': 2,
- 'status': 200,
- 'time': int(time.time()),
- 'url': 'deviceManagement/delDeviceData',
- 'content': delDataOptions,
- 'ip': ip,
- 'operation': '上传文件设备重置删除前:user:{},{}'.format(user_id, json.dumps(content)),
- }
- LogModel.objects.create(**log)
- try:
- with transaction.atomic():
- if uidList:
- # uid
- uidList = uidList.splitlines() # 按行('\r', '\r\n', \n')切割字符串返回列表
- uid_list = []
- for uid in uidList:
- uid_val = uid.replace(" ", "")
- if not uid_val:
- continue
- uid_list.append(uid_val)
- uidList = uid_list
- else:
- # 序列号
- serialNumberList = serialNumberList.splitlines() # 按行('\r', '\r\n', \n')切割字符串返回列表
- serial_number_list = []
- for serial_number in serialNumberList:
- serial_number = serial_number.replace(" ", "")
- if not serial_number:
- continue
- serial_number_list.append(serial_number[0:6])
- uid_company_serial_qs = UIDCompanySerialModel.objects.filter(
- company_serial__serial_number__in=serial_number_list).values('uid__uid')
- uidList = [item[key] for item in uid_company_serial_qs for key in item]
- # 根据删除项删除相关数据
- if '设备信息数据' in delDataOptions:
- # 删除用户UID缓存
- user_list = list(Device_Info.objects.filter(UID__in=uidList).values('userID_id', 'UID'))
- thread = threading.Thread(target=DeviceManagement.deleteDeviceCache, args=(user_list,))
- thread.start()
- Device_Info.objects.filter(UID__in=uidList).delete()
- UidPushModel.objects.filter(uid_set__uid__in=uidList).delete()
- if '设备配置数据' in delDataOptions:
- UidSetModel.objects.filter(uid__in=uidList).delete()
- if '设备推送数据' in delDataOptions:
- EquipmentInfoService.delete_all_equipment_info(device_uid__in=uidList)
- if '设备AP信息数据' in delDataOptions:
- UidUserModel.objects.filter(UID__in=uidList).delete()
- if '设备AI数据' in delDataOptions:
- ExperienceAiModel.objects.filter(uid__in=uidList).delete()
- # Order_Model.objects.filter(UID__in=uidList, order_type=1).delete()
- if '设备云存数据' in delDataOptions:
- UID_Bucket.objects.filter(uid__in=uidList).delete()
- AiService.objects.filter(uid__in=uidList).delete()
- StsCrdModel.objects.filter(uid__in=uidList).delete()
- VodHlsModel.objects.filter(uid__in=uidList).delete()
- # 删除vod_hls分表数据
- split_vod_hls_obj = SplitVodHlsObject()
- split_vod_hls_obj.del_vod_hls_data(uid__in=uidList)
- Unused_Uid_Meal.objects.filter(uid__in=uidList).delete()
- ExperienceContextModel.objects.filter(uid__in=uidList).delete()
- # Order_Model.objects.filter(UID__in=uidList, order_type=0).delete()
- Device_Info.objects.filter(UID__in=uidList).update(vodPrimaryUserID='', vodPrimaryMaster='')
- # 上传序列号文件且选中序列号解绑uid
- # if serialNumberList is not None and '序列号解绑uid' in delDataOptions:
- # # 解绑uid数据
- # UIDModel.objects.filter(uid__in=uidList, status=2).update(status=0)
- # UIDCompanySerialModel.objects.filter(uid__uid__in=uidList).delete()
- # CompanySerialModel.objects.filter(serial_number__in=serial_number_list).update(status=1)
- # UidPushModel.objects.filter(uid_set__uid__in=uidList).delete()
- # # 序列号加入重置状态redis列表
- # redis_obj = RedisObject()
- # for serial in serial_number_list:
- # redis_obj.rpush(UNUSED_SERIAL_REDIS_LIST, serial)
- device_list = uidList if serialNumberList is None else serial_number_list
- log = {
- 'user_id': 2,
- 'status': 200,
- 'time': int(time.time()),
- 'url': 'deviceManagement/delDeviceData',
- 'content': json.dumps(content),
- 'ip': ip,
- 'operation': '删除数据的设备列表:{}'.format(device_list),
- }
- LogModel.objects.create(**log)
- return response.json(0)
- except Exception as e:
- log = {
- 'user_id': 2,
- 'status': 500,
- 'time': int(time.time()),
- 'url': 'deviceManagement/delDeviceData',
- 'content': json.dumps(content),
- 'ip': ip,
- 'operation': '删除数据失败的设备列表:{},{},{}'.format(device_list, e.__traceback__.tb_lineno, repr(e)),
- }
- LogModel.objects.create(**log)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def deleteDeviceCache(uid_list):
- """
- 翻新重置时清楚验证用户UID缓存
- """
- try:
- redis = RedisObject(3)
- for item in uid_list:
- # 构建Redis键
- device_key = f"{RedisKeyConstant.BASIC_USER.value}{item['userID_id']}:UID:{item['UID']}"
- redis.del_data(device_key)
- except Exception as e:
- error_line = e.__traceback__.tb_lineno
- LOGGER.error(f'翻新重置异步清缓存异常:error_line:{error_line}, error_msg:{repr(e)}')
- def get_app_device_type_list(self, request_dict, response):
- app_bundle_name = request_dict.get('appBundleName', None)
- lang = request_dict.get('lang', None)
- model = request_dict.get('model', None)
- type = request_dict.get('type', None)
- name = request_dict.get('name', None)
- pageNo = request_dict.get('pageNo', None)
- pageSize = request_dict.get('pageSize', None)
- if not all([pageNo, pageSize]):
- return response.json(444)
- page = int(pageNo)
- line = int(pageSize)
- try:
- app_bundle_qs = AppBundle.objects.all()
- if app_bundle_name:
- app_bundle_id = self.app_name_convert_id([app_bundle_name])
- print(app_bundle_id)
- app_bundle_qs = app_bundle_qs.filter(id__in=app_bundle_id)
- if lang:
- app_bundle_qs = app_bundle_qs.filter(app_device_type__devicenamelanguage__lang=lang)
- app_bundle_qs = app_bundle_qs.annotate(
- model=F('app_device_type__model'), type=F('app_device_type__type'), icon=F('app_device_type__icon'),
- lang=F('app_device_type__devicenamelanguage__lang'), iconV2=F('app_device_type__iconV2'),
- name=F('app_device_type__devicenamelanguage__name'),
- sort=F('app_device_type__devicenamelanguage__sort')).values('id', 'app_device_type__id', 'model',
- 'type', 'icon', 'iconV2', 'app_bundle_id',
- 'app_device_type__devicenamelanguage__id',
- 'lang', 'name', 'sort',
- 'app_device_type__app_version_number_id',
- 'app_device_type__config').order_by(
- 'app_device_type__devicenamelanguage__sort')
- if not app_bundle_qs.exists():
- return response.json(0)
- if name:
- app_bundle_qs = app_bundle_qs.filter(name=name)
- if model:
- app_bundle_qs = app_bundle_qs.filter(model=model)
- if type:
- app_bundle_qs = app_bundle_qs.filter(type=type)
- total = app_bundle_qs.count()
- app_bundle_qs = app_bundle_qs[(page - 1) * line:page * line]
- app_device_type_list = []
- for app_bundle in app_bundle_qs:
- app_bundle['version_number'] = app_bundle.pop('app_device_type__app_version_number_id')
- app_device_type_list.append(app_bundle)
- return response.json(0, {'list': app_device_type_list, 'total': total})
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def get_app_bundle_id_list(response):
- try:
- app_info_qs = App_Info.objects.filter().values('id', 'appBundleId', 'appName')
- appBundleIdList = list(app_info_qs)
- return response.json(0, {'list': appBundleIdList})
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def batch_edit_app_device_type(request_dict, request, response):
- # app_device_type表数据
- app_device_type_id = request_dict.get('app_device_type__id', None)
- model = request_dict.get('model', None)
- type = request_dict.get('type', None)
- icon = request.FILES.get('icon', None)
- iconV2 = request.FILES.get('iconV2', None)
- # device_name_language表数据
- device_name_language_id = request_dict.get('app_device_type__devicenamelanguage__id', None)
- sort = request_dict.get('sort', None)
- version_number = request_dict.get('version_number', None)
- config = request_dict.get('config', None)
- now_time = int(time.time())
- if not all([app_device_type_id, device_name_language_id, model, type, sort, version_number]):
- return response.json(444)
- # 强制类型转换
- list_app_device_type_id = [int(item) for item in eval(app_device_type_id)]
- list_device_name_language_id = [int(item) for item in eval(device_name_language_id)]
- try:
- with transaction.atomic():
- if icon or iconV2:
- bucket_name = 'ansjerfilemanager'
- s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
- icon_path = ""
- icon_v2_path = ""
- # 处理 icon
- if icon:
- file_key = f'app/device_type_images/{now_time}_{icon.name}'
- icon_path = f'https://{bucket_name}.s3.amazonaws.com/{file_key}'
- s3.upload_file_obj(
- bucket_name,
- file_key,
- icon,
- {'ContentType': icon.content_type, 'ACL': 'public-read'}
- )
- # 处理 iconV2
- if iconV2:
- file_v2_key = f'app/device_type_images/{now_time}_v2_{iconV2.name}'
- icon_v2_path = f'https://{bucket_name}.s3.amazonaws.com/{file_v2_key}'
- s3.upload_file_obj(
- bucket_name,
- file_v2_key,
- iconV2,
- {'ContentType': iconV2.content_type, 'ACL': 'public-read'}
- )
- # 更新数据库
- update_fields = {
- 'model': model,
- 'type': type,
- 'app_version_number_id': version_number,
- }
- if config:
- try:
- config = json.loads(config)
- update_fields['config'] = config
- except ValueError:
- return response.json(444, 'config必须是一个json数据')
- if icon_path:
- update_fields['icon'] = icon_path
- if icon_v2_path:
- update_fields['iconV2'] = icon_v2_path
- AppDeviceType.objects.filter(id__in=list_app_device_type_id).update(**update_fields)
- else:
- # 没有上传文件的情况,只更新配置或基本信息
- update_fields = {
- 'model': model,
- 'type': type,
- 'app_version_number_id': version_number,
- }
- if config:
- try:
- config = json.loads(config)
- update_fields['config'] = config
- except ValueError:
- return response.json(444, 'config必须是一个json数据')
- AppDeviceType.objects.filter(id__in=list_app_device_type_id).update(**update_fields)
- DeviceNameLanguage.objects.filter(id__in=list_device_name_language_id).update(sort=sort)
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def edit_app_device_type(request_dict, request, response):
- # app_device_type表数据
- app_device_type_id = request_dict.get('app_device_type__id', None)
- model = request_dict.get('model', None)
- type = request_dict.get('type', None)
- icon = request.FILES.get('icon', None)
- iconV2 = request.FILES.get('iconV2', None)
- # device_name_language表数据
- device_name_language_id = request_dict.get('app_device_type__devicenamelanguage__id', None)
- lang = request_dict.get('lang', None)
- name = request_dict.get('name', None)
- sort = request_dict.get('sort', None)
- version_number = request_dict.get('version_number', None)
- config = request_dict.get('config', None)
- now_time = int(time.time())
- if not all([app_device_type_id, model, type, device_name_language_id, lang, name, sort]):
- return response.json(444)
- try:
- with transaction.atomic():
- app_device_type = AppDeviceType.objects.filter(id=app_device_type_id).first()
- if icon or iconV2:
- bucket_name = 'ansjerfilemanager'
- s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
- icon_path = app_device_type.icon
- icon_v2_path = app_device_type.iconV2
- if icon:
- icon_path = f'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/{now_time}_{icon.name}'
- file_key = f'app/device_type_images/{now_time}_{icon.name}'
- s3.upload_file_obj(
- bucket_name,
- file_key,
- icon,
- {'ContentType': icon.content_type, 'ACL': 'public-read'})
- if iconV2:
- icon_v2_path = f'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/{now_time}_v2_{iconV2.name}'
- file_v2_key = f'app/device_type_images/{now_time}_v2_{iconV2.name}'
- s3.upload_file_obj(
- bucket_name,
- file_v2_key,
- iconV2,
- {'ContentType': iconV2.content_type, 'ACL': 'public-read'})
- if config:
- try:
- config = json.loads(config)
- except:
- return response.json(444, 'config必须是一个json数据')
- AppDeviceType.objects.filter(id=app_device_type_id) \
- .update(model=model, type=type, icon=icon_path, iconV2=icon_v2_path,
- app_version_number_id=version_number, config=config)
- else:
- AppDeviceType.objects.filter(id=app_device_type_id) \
- .update(model=model, type=type, icon=icon_path, iconV2=icon_v2_path,
- app_version_number_id=version_number)
- else:
- if config:
- try:
- config = json.loads(config)
- except:
- return response.json(444, 'config必须是一个json数据')
- AppDeviceType.objects.filter(id=app_device_type_id) \
- .update(model=model, type=type, app_version_number_id=version_number,
- config=config)
- else:
- AppDeviceType.objects.filter(id=app_device_type_id) \
- .update(model=model, type=type, app_version_number_id=version_number)
- DeviceNameLanguage.objects.filter(id=device_name_language_id).update(lang=lang, name=name, sort=sort)
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def delete_app_device_type(request_dict, response):
- app_bundle_id = request_dict.get('appBundleId', None)
- app_device_type_id = request_dict.get('appDeviceTypeId', None)
- if not all([app_bundle_id, app_device_type_id]):
- return response.json(444)
- try:
- # 删除语言表
- DeviceNameLanguage.objects.filter(app_device_type_id=app_device_type_id).delete()
- # 删除多对多关系
- app_bundle_qs = AppBundle.objects.get(id=app_bundle_id)
- app_bundle_qs.app_device_type.remove(app_device_type_id)
- # 删除app类型表
- AppDeviceType.objects.filter(id=app_device_type_id).delete()
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def reset_all(request, request_dict, response):
- uid = request_dict.get('uid', None)
- if not uid:
- return response.json(444)
- try:
- # 记录操作日志
- ip = CommonService.get_ip_address(request)
- content = json.loads(json.dumps(request_dict))
- with transaction.atomic():
- # 删除主用户
- Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID='', vodPrimaryMaster='')
- # 删除云存
- UID_Bucket.objects.filter(uid=uid).delete()
- Unused_Uid_Meal.objects.filter(uid=uid).delete()
- # Order_Model.objects.filter(UID=uid, order_type=0).delete()
- StsCrdModel.objects.filter(uid=uid).delete()
- VodHlsModel.objects.filter(uid=uid).delete()
- # 删除vod_hls分表数据
- split_vod_hls_obj = SplitVodHlsObject()
- split_vod_hls_obj.del_vod_hls_data(uid=uid)
- ExperienceContextModel.objects.filter(uid=uid).delete()
- # 删除AI
- ExperienceAiModel.objects.filter(uid=uid).delete()
- AiService.objects.filter(uid=uid).delete()
- log = {
- 'ip': ip,
- 'user_id': 2,
- 'status': 200,
- 'time': int(time.time()),
- 'url': 'deviceManagement/resetAll',
- 'content': json.dumps(content),
- 'operation': '{}重置所有'.format(uid),
- }
- LogModel.objects.create(**log)
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- def add_app_device_type(self, request_dict, response, request):
- """
- 添加设备类型
- @param request_dict: 请求参数
- @request_dict appBundleName: app包名
- @request_dict versionNumber: app版本号
- @request_dict model: 设备类型
- @request_dict type: 设备型号
- @request_dict name: 设备名称
- @request_dict sort: 排序
- @request.FILES iconFile: 上传图标
- @param response: 响应对象
- """
- # app包名称
- app_bundle_name = request_dict.get('appBundleName', None)
- # 版本号
- version_number = request_dict.get('versionNumber', None)
- # app_device_type表数据
- model = request_dict.get('model', None)
- type = request_dict.get('type', None)
- # device_name_language表数据
- name = request_dict.get('name', None)
- sort = request_dict.get('sort', None)
- config = request_dict.get('config', None)
- # 上传图标
- file = request.FILES.get('iconFile', None)
- file_v2 = request.FILES.get('iconV2File', None)
- if config:
- config = json.loads(config)
- try:
- type = int(type)
- data_name = eval(name)
- app_bundle_name_list = app_bundle_name.split(',')
- app_bundle_id = self.app_name_convert_id(app_bundle_name_list)
- existing_records = []
- success_records = []
- need_upload = False # 标记是否需要上传文件
- # 先检查所有数据是否存在
- with transaction.atomic():
- for app_id in app_bundle_id:
- for k, v in data_name.items():
- app_bundle_qs = AppBundle.objects.filter(id=app_id,
- app_device_type__devicenamelanguage__lang=k,
- app_device_type__app_version_number_id=version_number,
- app_device_type__type=type,
- app_device_type__model=model)
- if app_bundle_qs.exists():
- app_bundle = app_bundle_qs.values("app_bundle_id").first()
- existing_record = {"app_bundle_id": app_bundle["app_bundle_id"], "type": type,
- "version_number": version_number, "lang": k, "model": model}
- existing_records.append(existing_record)
- else:
- need_upload = True # 发现至少一条记录不存在,需要上传文件
- # 如果需要上传文件
- if need_upload:
- with transaction.atomic():
- if file:
- fileName = file.name
- now_time = int(time.time())
- icon = f'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/{now_time}_{fileName}'
- bucket_name = 'ansjerfilemanager'
- file_key = f'app/device_type_images/{now_time}_{fileName}'
- s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
- s3.upload_file_obj(bucket_name, file_key, file,
- {'ContentType': file.content_type, 'ACL': 'public-read'})
- if file_v2:
- fileV2Name = file_v2.name
- now_time = int(time.time())
- iconV2 = f'https://ansjerfilemanager.s3.amazonaws.com/app/device_type_images/{now_time}_v2_{fileV2Name}'
- bucket_name = 'ansjerfilemanager'
- file_v2_key = f'app/device_type_images/{now_time}_v2_{fileV2Name}'
- s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], AWS_SES_ACCESS_REGION)
- s3.upload_file_obj(bucket_name, file_v2_key, file_v2,
- {'ContentType': file_v2.content_type, 'ACL': 'public-read'})
- for app_id in app_bundle_id:
- for k, v in data_name.items():
- record_key = {"app_bundle_id": app_id, "type": type, "version_number": version_number,
- "lang": k, "model": model}
- # 检查这个组合的记录是否存在
- if not any(rec == record_key for rec in existing_records):
- app_bundle = AppBundle.objects.filter(id=app_id).values('id', 'app_bundle_id').first()
- app_device_type_qs = AppDeviceType.objects.create(model=model, type=type,
- icon=icon if file else "",
- iconV2=iconV2 if file_v2 else "",
- app_version_number_id=version_number,
- config=config)
- DeviceNameLanguage.objects.create(lang=k, name=v, sort=sort,
- app_device_type_id=app_device_type_qs.id)
- app_device_type_qs.appbundle_set.add(app_bundle["id"])
- success_records.append(
- {"app_bundle_id": app_bundle["app_bundle_id"], "type": type,
- "version_number": version_number,
- "lang": k, "model": model}
- )
- response_data = {
- 'success_records': success_records,
- 'existing_records': existing_records
- }
- return response.json(0, response_data)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def get_device_icon(request_dict, response):
- """
- 查询设备信息图标
- @param request_dict: 请求参数
- @request_dict lang: 语言
- @request_dict app_bundle_id: app版本id
- @request_dict version_number: app版本号
- @param response: 响应对象
- @return:
- """
- lang = request_dict.get('lang', 'en')
- app_bundle_id = request_dict.get('appBundleId', None)
- version_number = request_dict.get('versionNumber', None)
- # 查询设备信息图标
- api_version = request_dict.get('apiVersion', None)
- if not all([lang, app_bundle_id, version_number]):
- return response.json(444)
- try:
- # tc是ios繁体字语言类型
- if lang == 'tc':
- lang = 'cn_tw'
- app_bundle_qs = AppBundle.objects.filter(app_bundle_id=app_bundle_id).values(
- 'app_device_type__app_version_number_id').distinct().order_by('app_device_type__app_version_number_id')
- # 判断版本是否存在, 不存在则获取输入版本范围内最接近的输入版本
- version_number_list = []
- app_bundle_list = []
- for version in app_bundle_qs:
- version_number_list.append(version['app_device_type__app_version_number_id'])
- new_version_number = CommonService.compare_version_number(version_number, version_number_list)
- app_device_qs = DeviceNameLanguage.objects.filter(lang=lang)
- if not app_device_qs.exists():
- lang = 'en'
- # 版本号对应的设备信息图标
- for version_number in new_version_number:
- app_bundle_qs = AppBundle.objects.filter(app_bundle_id=app_bundle_id,
- app_device_type__devicenamelanguage__lang=lang,
- app_device_type__app_version_number_id=version_number). \
- annotate(
- model=F('app_device_type__model'), type=F('app_device_type__type'), icon=F('app_device_type__icon'),
- name=F('app_device_type__devicenamelanguage__name'), iconV2=F('app_device_type__iconV2'),
- sort=F('app_device_type__devicenamelanguage__sort'),
- config=F('app_device_type__config'),
- app_version_number_id=F('app_device_type__app_version_number_id')).values('model', 'type', 'icon',
- 'name', 'sort', 'config',
- 'iconV2',
- 'app_device_type__app_version_number_id')
- # 使用lang="en"来补全缺失的数据
- en_lang_qs = AppBundle.objects.filter(
- app_bundle_id=app_bundle_id,
- app_device_type__devicenamelanguage__lang="en",
- app_device_type__app_version_number_id=version_number
- ).annotate(
- model=F('app_device_type__model'),
- type=F('app_device_type__type'),
- icon=F('app_device_type__icon'),
- name=F('app_device_type__devicenamelanguage__name'),
- iconV2=F('app_device_type__iconV2'),
- sort=F('app_device_type__devicenamelanguage__sort'),
- config=F('app_device_type__config'),
- app_version_number_id=F('app_device_type__app_version_number_id')
- ).values('model', 'type', 'icon', 'name', 'sort', 'config', 'iconV2',
- 'app_device_type__app_version_number_id')
- # 转换查询集为字典
- current_lang_data = {item['type']: item for item in app_bundle_qs}
- en_lang_data = {item['type']: item for item in en_lang_qs}
- # 合并数据,优先使用当前语言的数据,缺少的字段用英文补充
- for type, en_data in en_lang_data.items():
- current_data = current_lang_data.get(type, {})
- merged_data = {
- 'type': en_data['type'],
- 'model': current_data.get('model', en_data['model']),
- 'icon': current_data.get('icon', en_data['icon']),
- 'name': current_data.get('name', en_data['name']),
- 'sort': current_data.get('sort', en_data['sort']),
- 'config': current_data.get('config', en_data['config']),
- 'iconV2': current_data.get('iconV2', en_data['iconV2']),
- 'app_device_type__app_version_number_id': current_data.get(
- 'app_device_type__app_version_number_id',
- en_data['app_device_type__app_version_number_id']),
- }
- if api_version == "V2":
- app_bundle_list.append({
- 'model': merged_data['model'],
- 'type': merged_data['type'],
- 'icon': merged_data['iconV2'] if merged_data['iconV2'] != "" else merged_data['icon'],
- 'name': merged_data['name'],
- 'sort': merged_data['sort'],
- 'config': merged_data['config'],
- 'app_device_type__app_version_number_id': merged_data['app_device_type__app_version_number_id'],
- })
- else:
- app_bundle_list.append({
- 'model': merged_data['model'],
- 'type': merged_data['type'],
- 'icon': merged_data['icon'],
- 'name': merged_data['name'],
- 'sort': merged_data['sort'],
- 'config': merged_data['config'],
- 'app_device_type__app_version_number_id': merged_data[
- 'app_device_type__app_version_number_id'],
- })
- dvr_list = [app_bundle for app_bundle in app_bundle_list if app_bundle['model'] == 1]
- ipc_list = [app_bundle for app_bundle in app_bundle_list if app_bundle['model'] == 2]
- res = {
- 'deviceDvr': sorted(dvr_list, key=operator.itemgetter('sort')),
- 'deviceIpc': sorted(ipc_list, key=operator.itemgetter('sort')),
- }
- return response.json(0, res)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def get_uid_push(request_dict, response):
- """
- 查询设备信息详情信息
- @param request_dict: 请求参数
- @request_dict UID: UID
- @param response: 响应对象
- @return:
- """
- uid = request_dict.get('UID', None)
- if not uid:
- return response.json(444)
- try:
- uid_set_qs = UidSetModel.objects.filter(uid=uid).first()
- data = model_to_dict(uid_set_qs)
- ALGORITHM_COMBO_TYPES = ['移动', '人形', '车型', '宠物', '人脸', '异响', '闯入', '离开', '徘徊', '无人',
- '往来', '哭声', '手势', '火焰', '婴儿', '包裹', '暂无', '电动车', '遮挡']
- if data['ai_type'] > 0:
- num = data['ai_type']
- result = ""
- while num != 0:
- ret = num % 2
- num //= 2
- result = str(ret) + result
- types = []
- event_type = result
- len_type = len(event_type)
- for i in range(len_type):
- e_type = event_type[len_type - 1 - i]
- if e_type == '1':
- types.append(str(ALGORITHM_COMBO_TYPES[i]))
- data['ai_type'] = types
- # uid_set查uid_push
- uid_pushes_qs = UidPushModel.objects.filter(uid_set_id=uid_set_qs.id).select_related('userID')
- uid_push_data = []
- # 保存uid_pushes_qs列表
- for item in uid_pushes_qs:
- item_dict = model_to_dict(item)
- # 添加 username 字段
- item_dict['username'] = item.userID.username if item.userID else None
- uid_push_data.append(item_dict)
- data["uid_push"] = uid_push_data
- return response.json(0, data)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def get_app_name_list(response):
- """
- 查询APP包名称列表
- @param response: 响应对象
- @return:
- """
- try:
- app_bundle_qs = AppBundle.objects.all().values_list('app_bundle_id')
- app_info = App_Info.objects.filter(appBundleId__in=app_bundle_qs).values('appName')
- app_name_list = []
- for app_name in app_info:
- app_name_list.append(app_name['appName'])
- app_name_list = list(set(app_name_list))
- return response.json(0, app_name_list)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def app_name_convert_id(app_name_list):
- """
- app_name_list 转 app_id_list
- @param app_name_list: app名字列表
- @return app_id_list: app id列表
- """
- try:
- app_bundle_id_list = App_Info.objects.filter(appName__in=app_name_list).values_list('appBundleId',
- flat=True)
- app_id_list = AppBundle.objects.filter(app_bundle_id__in=app_bundle_id_list).values_list('id', flat=True)
- return list(set(app_id_list))
- except Exception as e:
- print(e)
- return []
- @staticmethod
- def call_add_app_device_type(request_dict, response, request):
- """
- 添加设备类型
- @param request_dict: 请求参数
- @request_dict appBundleName: app包名
- @request_dict versionNumber: app版本号
- @request_dict model: 设备类型
- @request_dict type: 设备型号
- @request_dict name: 设备名字
- @request_dict sort: 排序
- @request_dict region: 地区
- @request.FILES iconFile: 上传图标
- @param response: 响应对象
- """
- # app包名称
- app_bundle_name = request_dict.get('appBundleName', None)
- # 版本号
- version_number = request_dict.get('versionNumber', None)
- # app_device_type表数据
- model = request_dict.get('model', None)
- type = request_dict.get('type', None)
- # device_name_language表数据
- name = request_dict.get('name', None)
- sort = request_dict.get('sort', None)
- config = request_dict.get('config', None)
- # 上传图标
- files = request.FILES.get('iconFile', None)
- # 上传图标
- files_v2 = request.FILES.get('iconV2File', None)
- # 需要添加到哪一个服
- region = request_dict.get("region", None) # 获取需要同步的区域
- # 检查必需参数
- if not all([model, type, name, sort, version_number, app_bundle_name, region]):
- return response.json(444, 'Missing required parameters')
- if files is None and files_v2 is None:
- return response.json(444, 'Missing required parameters')
- LOGGER.info(f"添加图标设备类型 region: {region} -- region")
- regions = region.split(",") # 将同步区域拆分为列表
- return_value_list = []
- LOGGER.info(f"添加图标设备类型 regions: {regions} -- regions列表")
- for region in regions:
- if region == 'test':
- url = SERVER_DOMAIN_TEST
- elif region == 'cn':
- url = SERVER_DOMAIN_CN
- elif region == 'us':
- url = SERVER_DOMAIN_US
- elif region == 'eu':
- url = SERVER_DOMAIN_EUR
- else:
- return response.json(444, 'Invalid region')
- LOGGER.info(f"添加图标设备类型 url: {url} -- 确定url")
- try:
- form_data = {
- 'name': name,
- 'type': type,
- 'sort': sort,
- 'model': model,
- 'versionNumber': version_number,
- 'appBundleName': app_bundle_name,
- }
- if config:
- try:
- config = json.loads(config)
- except:
- return response.json(444, 'config必须是一个json数据')
- form_data["config"] = json.dumps(config)
- # 发送 POST 请求调用 add_app_device_type 方法
- LOGGER.info(f"添加图标设备类型 url: {url} -- 准备发送")
- response_value = requests.post(url + "/deviceManagement/addAppDeviceType",
- data=form_data,
- files={'iconFile': files, 'iconV2File': files_v2})
- return_value = {region: response_value.json()["data"]}
- return_value_list.append(return_value)
- except Exception as e:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- return response.json(0, {"list": return_value_list})
- @classmethod
- def query_device_user(cls, request, request_dict, response):
- try:
- # 从请求中检索文件
- file = request.FILES.get('deviceFile')
- file_type = int(request_dict.get('type', 1))
- uid_list = []
- if not file:
- return response.json(444)
- device_info_list = []
- # 处理文件内容并生成设备信息列表
- # 序列号
- if file_type == 2:
- for item in file:
- item = item.decode().strip().replace(" ", "")
- serial = item[:6]
- # 请求序列号系统查询获取序列号记录
- url = 'http://{}/serialNumber/checkSerialLog'.format(SERIAL_DOMAIN_NAME)
- params = {'serial': serial}
- r = requests.get(url=url, params=params, timeout=5)
- assert r.status_code == 200
- result = eval(r.content)
- is_reset = 0 if result['code'] == 0 else 1
- uid = CommonService.get_uid_by_serial_number(serial)
- # 序列号没绑定uid,需要重置
- if uid == serial:
- is_reset = 1
- uid, device_name, ip, username = '', '', '', ''
- else:
- # 根据uid查询设备信息
- device_name, ip, username = cls.get_device_info(uid)
- device_info_data = {
- 'isReset': is_reset,
- 'uid': uid,
- 'serialNumber': item,
- 'deviceName': device_name,
- 'ip': ip,
- 'uName': username
- }
- device_info_list.append(device_info_data)
- # uid
- else:
- for item in file:
- uid = item.decode().strip().replace(" ", "")
- is_reset = 0
- serial_number = CommonService.get_serial_number_by_uid(uid)
- if serial_number == uid:
- serial_number = ''
- device_name, ip, username = cls.get_device_info(uid)
- device_info_data = {
- 'isReset': is_reset,
- 'uid': uid,
- 'serialNumber': serial_number,
- 'deviceName': device_name,
- 'ip': ip,
- 'uName': username
- }
- device_info_list.append(device_info_data)
- # 返回带有用户信息的响应
- return response.json(0, {'userInfo': device_info_list})
- except Exception as e:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def get_device_info(uid):
- """
- 根据uid查询设备信息
- :param uid:
- :return: device_name, ip, username
- """
- device_name, ip, username = '', '', ''
- device_info_qs = Device_Info.objects.filter(UID=uid).values('NickName', 'ip', 'userID__username')
- if device_info_qs.exists():
- device_name = device_info_qs[0]['NickName']
- ip = device_info_qs[0]['ip']
- username = device_info_qs[0]['userID__username']
- return device_name, ip, username
- @staticmethod
- def get_customer_device_list(request_dict, response):
- """
- 查询扫码添加设备列表
- :param request_dict:
- :param response:
- :return:
- """
- order_number = request_dict.get('orderNumber')
- name = request_dict.get('name')
- email = request_dict.get('email')
- serial_number = request_dict.get('serialNumber')
- uid = request_dict.get('uid')
- page = int(request_dict.get('pageNo', 0)) # 默认值设为 0
- page_size = int(request_dict.get('pageSize', 0)) # 默认值设为 0
- try:
- # 构建查询条件
- custom_customer_qs = CustomCustomerOrderInfo.objects.all()
- if order_number:
- custom_customer_qs = custom_customer_qs.filter(order_number__icontains=order_number)
- if name:
- custom_customer_qs = custom_customer_qs.filter(name__icontains=name)
- if email:
- custom_customer_qs = custom_customer_qs.filter(email__icontains=email)
- # 获取所需的ID和数量
- c_id_list = custom_customer_qs.values_list("id", flat=True)
- total_quantity = custom_customer_qs.aggregate(total_quantity=Sum('quantity'))['total_quantity']
- # 查询设备列表
- customer_device_qs = CustomCustomerDevice.objects.filter(c_id__in=c_id_list).order_by('-created_time')
- # 通过serial_number和uid进行过滤
- if serial_number:
- customer_device_qs = customer_device_qs.filter(serial_number__icontains=serial_number)
- if uid:
- customer_device_qs = customer_device_qs.filter(uid=uid)
- # 分页处理
- if page > 0 and page_size > 0:
- paginator = Paginator(customer_device_qs, page_size)
- customer_device_page = paginator.get_page(page)
- customer_device_list = customer_device_page.object_list
- total = paginator.count
- else:
- customer_device_list = list(customer_device_qs)
- total = customer_device_qs.count()
- # 创建一个字典来映射 c_id 到 CustomCustomerOrderInfo 对象
- customer_order_map = {order.id: order for order in custom_customer_qs}
- # 构建设备列表
- result_list = []
- for device in customer_device_list:
- customer_order = customer_order_map.get(device.c_id)
- if customer_order:
- result_list.append({
- 'id': device.id,
- 'serialNumber': device.serial_number,
- 'uid': device.uid,
- 'deviceType': device.type,
- 'fullCode': device.full_code,
- 'addTime': device.created_time,
- 'orderNumber': customer_order.order_number,
- 'name': customer_order.name,
- 'email': customer_order.email,
- })
- else:
- result_list.append({
- 'id': device.id,
- 'serialNumber': device.serial_number,
- 'uid': device.uid,
- 'deviceType': device.type,
- 'fullCode': device.full_code,
- 'addTime': device.created_time,
- 'orderNumber': "",
- 'name': "",
- 'email': "",
- })
- # 构造返回数据
- data = {
- 'total': total,
- 'orderDeviceQuantity': total_quantity or 0, # 防止为None
- 'list': result_list,
- }
- return response.json(0, data)
- except Exception as e:
- return response.json(500, f'error_line:{e.__traceback__.tb_lineno}, error_msg:{repr(e)}')
- @staticmethod
- def get_device_ver_info(request_dict, response):
- d_code = request_dict.get('dCode', None)
- software_ver = request_dict.get('softwareVer', None)
- device_type = request_dict.get('deviceType', None)
- page = request_dict.get('pageNo', 1) # 当前页码,默认为1
- page_size = request_dict.get('pageSize', 10) # 每页显示的记录数,默认为10
- if not all([page, page_size]):
- return response.json(444)
- try:
- device_ver_info_qs = DeviceVersionInfo.objects.all()
- if d_code:
- device_ver_info_qs = device_ver_info_qs.filter(d_code__icontains=d_code)
- if software_ver:
- device_ver_info_qs = device_ver_info_qs.filter(software_ver__icontains=software_ver)
- if device_type:
- device_ver_info_qs = device_ver_info_qs.filter(device_type=device_type)
- # 对TimeAlbum结果进行分页
- paginator = Paginator(device_ver_info_qs.order_by("-id"), page_size)
- device_ver_infos = paginator.page(page) # 获取当前页的数据
- device_ver_info_list = []
- # 对每个TimeAlbum,查询相关的AlbumMedia
- for device_ver_info in device_ver_infos:
- device_ver_info_list.append(
- {
- 'deviceVerId': device_ver_info.id,
- 'dCode': device_ver_info.d_code,
- 'softwareVer': device_ver_info.software_ver,
- 'firmwareVer': device_ver_info.firmware_ver,
- 'videoCode': device_ver_info.video_code,
- 'regionAlexa': device_ver_info.region_alexa,
- 'supportsHumanTracking': device_ver_info.supports_human_tracking,
- 'supportsCustomVoice': device_ver_info.supports_custom_voice,
- 'supportsDualBandWifi': device_ver_info.supports_dual_band_wifi,
- 'supportsFourPoint': device_ver_info.supports_four_point,
- 'supports4g': device_ver_info.supports_4g,
- 'supportsPTZ': device_ver_info.supports_ptz,
- 'supportsAi': device_ver_info.supports_ai,
- 'supportsCloudStorage': device_ver_info.supports_cloud_storage,
- 'supportsAlexa': device_ver_info.supports_alexa,
- 'deviceType': device_ver_info.device_type,
- 'resolution': device_ver_info.resolution,
- 'aiType': device_ver_info.ai_type,
- 'supportsAlarm': device_ver_info.supports_alarm,
- 'supportsNightVision': device_ver_info.supports_night_vision,
- 'screenChannels': device_ver_info.screen_channels,
- 'networkType': device_ver_info.network_type,
- 'otherFeatures': device_ver_info.other_features,
- 'electricityStatistics': device_ver_info.electricity_statistics,
- 'supportsPetTracking': device_ver_info.supports_pet_tracking,
- 'createdTime': device_ver_info.created_time,
- 'updatedTime': device_ver_info.updated_time
- }
- )
- return response.json(0, {
- 'total': paginator.count,
- 'list': device_ver_info_list,
- })
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def add_device_ver_info(request_dict, response):
- d_code = request_dict.get('dCode', None)
- software_ver = request_dict.get('softwareVer', None)
- firmware_ver = request_dict.get('firmwareVer', "")
- video_code = request_dict.get('videoCode', None)
- region_alexa = request_dict.get('regionAlexa', "")
- supports_human_tracking = request_dict.get('supportsHumanTracking', 0)
- supports_custom_voice = request_dict.get('supportsCustomVoice', 0)
- supports_dual_band_wifi = request_dict.get('supportsDualBandWifi', 0)
- supports_four_point = request_dict.get('supportsFourPoint', 0)
- supports_4g = request_dict.get('supports4g', 0)
- supports_ptz = request_dict.get('supportsPTZ', 0)
- supports_ai = request_dict.get('supportsAi', 0)
- supports_cloud_storage = request_dict.get('supportsCloudStorage', 0)
- supports_alexa = request_dict.get('supportsAlexa', 0)
- device_type = request_dict.get('deviceType', None)
- resolution = request_dict.get('resolution', "")
- ai_type = request_dict.get('aiType', 0)
- supports_alarm = request_dict.get('supportsAlarm', None)
- supports_night_vision = request_dict.get('supportsNightVision', 0)
- screen_channels = request_dict.get('screenChannels', None)
- network_type = request_dict.get('networkType', None)
- other_features = request_dict.get('otherFeatures', None)
- electricity_statistics = request_dict.get('electricityStatistics', 0)
- supports_pet_tracking = request_dict.get('supportsPetTracking', 0)
- has_4g_cloud = request_dict.get('has4gCloud', -1)
- if not all([d_code, software_ver, video_code,
- device_type, supports_alarm,
- screen_channels, network_type]
- ):
- return response.json(444)
- try:
- now_time = int(time.time())
- ai_type = int(ai_type)
- if other_features:
- other_features = json.loads(other_features)
- else:
- other_features = None
- if DeviceVersionInfo.objects.filter(d_code=d_code, software_ver=software_ver).exists():
- return response.json(174)
- DeviceVersionInfo.objects.create(
- d_code=d_code,
- software_ver=software_ver,
- firmware_ver=firmware_ver,
- video_code=video_code,
- region_alexa=region_alexa,
- supports_human_tracking=supports_human_tracking,
- supports_custom_voice=supports_custom_voice,
- supports_dual_band_wifi=supports_dual_band_wifi,
- supports_four_point=supports_four_point,
- supports_4g=supports_4g,
- supports_ptz=supports_ptz,
- supports_ai=supports_ai,
- supports_cloud_storage=supports_cloud_storage,
- supports_alexa=supports_alexa,
- device_type=device_type,
- resolution=resolution,
- ai_type=ai_type,
- supports_alarm=supports_alarm,
- supports_night_vision=supports_night_vision,
- screen_channels=screen_channels,
- network_type=network_type,
- other_features=other_features,
- electricity_statistics=electricity_statistics,
- supports_pet_tracking=supports_pet_tracking,
- has_4g_cloud=has_4g_cloud,
- created_time=now_time,
- updated_time=now_time
- )
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- return response.json(0)
- @staticmethod
- def edit_device_ver_info(request_dict, response):
- device_ver_id = request_dict.get('deviceVerId', None)
- firmware_ver = request_dict.get('firmwareVer', "")
- video_code = request_dict.get('videoCode', None)
- region_alexa = request_dict.get('regionAlexa', "")
- supports_human_tracking = request_dict.get('supportsHumanTracking', 0)
- supports_custom_voice = request_dict.get('supportsCustomVoice', 0)
- supports_dual_band_wifi = request_dict.get('supportsDualBandWifi', 0)
- supports_four_point = request_dict.get('supportsFourPoint', 0)
- supports_4g = request_dict.get('supports4g', 0)
- supports_ptz = request_dict.get('supportsPTZ', 0)
- supports_ai = request_dict.get('supportsAi', 0)
- supports_cloud_storage = request_dict.get('supportsCloudStorage', 0)
- supports_alexa = request_dict.get('supportsAlexa', 0)
- device_type = request_dict.get('deviceType', None)
- resolution = request_dict.get('resolution', "")
- ai_type = request_dict.get('aiType', 0)
- supports_alarm = request_dict.get('supportsAlarm', None)
- supports_night_vision = request_dict.get('supportsNightVision', 0)
- screen_channels = request_dict.get('screenChannels', None)
- network_type = request_dict.get('networkType', None)
- other_features = request_dict.get('otherFeatures', None)
- electricity_statistics = request_dict.get('electricityStatistics', 0)
- supports_pet_tracking = request_dict.get('supportsPetTracking', 0)
- has_4g_cloud = request_dict.get('has4gCloud', -1)
- if not all([device_ver_id, video_code, device_type, supports_alarm, screen_channels, network_type]):
- return response.json(444)
- try:
- now_time = int(time.time())
- ai_type = int(ai_type)
- device_version_info_qs = DeviceVersionInfo.objects.filter(id=device_ver_id).values('d_code', 'software_ver')
- if not device_version_info_qs.exists():
- return response.json(173)
- if other_features:
- other_features = json.loads(other_features)
- else:
- other_features = None
- d_code = device_version_info_qs[0]['d_code']
- software_ver = device_version_info_qs[0]['software_ver']
- version_key = RedisKeyConstant.ZOSI_DEVICE_VERSION_INFO.value + software_ver + d_code
- # 创建Redis对象
- redis = RedisObject()
- # 尝试从Redis中获取数据
- version_info = redis.get_data(version_key)
- if version_info:
- # 如果在Redis中找到了数据,删除缓存
- redis.del_data(version_key)
- device_version_info_qs.update(
- firmware_ver=firmware_ver,
- video_code=video_code,
- region_alexa=region_alexa,
- supports_human_tracking=supports_human_tracking,
- supports_custom_voice=supports_custom_voice,
- supports_dual_band_wifi=supports_dual_band_wifi,
- supports_four_point=supports_four_point,
- supports_4g=supports_4g,
- supports_ptz=supports_ptz,
- supports_ai=supports_ai,
- supports_cloud_storage=supports_cloud_storage,
- supports_alexa=supports_alexa,
- device_type=device_type,
- resolution=resolution,
- ai_type=ai_type,
- supports_alarm=supports_alarm,
- supports_night_vision=supports_night_vision,
- screen_channels=screen_channels,
- network_type=network_type,
- other_features=other_features,
- electricity_statistics=electricity_statistics,
- supports_pet_tracking=supports_pet_tracking,
- has_4g_cloud=has_4g_cloud,
- created_time=now_time,
- updated_time=now_time
- )
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def del_device_ver_info(request_dict, response):
- device_ver_id = request_dict.get('deviceVerId', None)
- if not device_ver_id:
- return response.json(444)
- device_version_info_qs = DeviceVersionInfo.objects.filter(id=device_ver_id)
- if not device_version_info_qs.exists():
- return response.json(174)
- device_version_info = device_version_info_qs.first() # Get the first instance
- d_code = device_version_info.d_code
- software_ver = device_version_info.software_ver
- version_key = RedisKeyConstant.ZOSI_DEVICE_VERSION_INFO.value + software_ver + d_code
- # 创建Redis对象
- redis = RedisObject()
- # 尝试从Redis中获取数据
- version_info = redis.get_data(version_key)
- if version_info:
- # 如果在Redis中找到了数据,删除缓存
- redis.del_data(version_key)
- device_version_info_qs.delete()
- return response.json(0)
- @classmethod
- def sync_device_version(cls, request_dict, response):
- """
- 同步设备版本信息
- @param user_id: 用户ID
- @param request: 请求对象
- @param request_dict: 请求参数
- @param response: 响应对象
- @return: 响应结果
- """
- try:
- # 从请求字典中获取设备码和版本号
- version = request_dict.get('softwareVer')
- d_code = request_dict.get('dCode')
- # 查询设备版本配置
- version_config_qs = DeviceVersionInfo.objects.filter(
- d_code=d_code,
- software_ver=version
- )
- # 检查是否存在匹配的配置
- if not version_config_qs.exists():
- return response.json(173) # 设备版本配置不存在
- # 获取第一条匹配的记录(通常应该只有一条)
- version_config = version_config_qs.first()
- # 直接使用数据库字段,不需要json.loads
- other_features = ''
- if version_config.other_features:
- other_features = json.dumps(version_config.other_features)
- # 将数据库字段映射为驼峰命名的响应数据
- req_data = {
- 'dCode': version_config.d_code,
- 'softwareVer': version_config.software_ver,
- 'firmwareVer': version_config.firmware_ver,
- 'videoCode': version_config.video_code,
- 'regionAlexa': version_config.region_alexa,
- # 布尔字段转换为int
- 'supportsHumanTracking': int(version_config.supports_human_tracking),
- 'supportsCustomVoice': int(version_config.supports_custom_voice),
- 'supportsDualBandWifi': int(version_config.supports_dual_band_wifi),
- 'supportsFourPoint': int(version_config.supports_four_point),
- 'supports4g': int(version_config.supports_4g),
- 'supportsPTZ': int(version_config.supports_ptz),
- 'supportsAi': int(version_config.supports_ai),
- 'supportsCloudStorage': int(version_config.supports_cloud_storage),
- 'supportsAlexa': int(version_config.supports_alexa),
- # 其他非布尔字段保持不变
- 'deviceType': version_config.device_type,
- 'resolution': version_config.resolution,
- 'aiType': version_config.ai_type,
- 'supportsAlarm': version_config.supports_alarm,
- 'supportsNightVision': version_config.supports_night_vision,
- 'screenChannels': version_config.screen_channels,
- 'networkType': version_config.network_type,
- 'otherFeatures': other_features,
- 'electricityStatistics': version_config.electricity_statistics,
- 'supportsPetTracking': version_config.supports_pet_tracking
- }
- config_thread = threading.Thread(target=DeviceManagement.sync_device_version_config, kwargs=req_data)
- config_thread.start()
- # 返回成功响应,包含设备版本配置信息
- return response.json(0)
- except Exception as e:
- # 通用异常处理(建议替换为具体异常类型)
- LOGGER.exception("同步设备配置失败")
- return response.json(500, f'Server error: {str(e)}')
- @staticmethod
- def sync_device_version_config(**req_data):
- """
- 同步设备版本信息到本地数据库及外部服务器(含异常跳过逻辑)
- """
- try:
- target_servers = []
- if CONFIG_INFO == CONFIG_TEST:
- target_servers = [
- "https://www.zositechc.cn/open/device/configuration/syncVerConfig",
- "https://www.dvema.com/open/device/configuration/syncVerConfig",
- "https://api.zositeche.com/open/device/configuration/syncVerConfig"
- ]
- elif CONFIG_INFO == CONFIG_CN:
- target_servers = [
- "https://test.zositechc.cn/open/device/configuration/syncVerConfig",
- "https://www.dvema.com/open/device/configuration/syncVerConfig",
- "https://api.zositeche.com/open/device/configuration/syncVerConfig"
- ]
- elif CONFIG_INFO == CONFIG_US:
- target_servers = [
- "https://test.zositechc.cn/open/device/configuration/syncVerConfig",
- "https://www.zositechc.cn/open/device/configuration/syncVerConfig",
- "https://api.zositeche.com/open/device/configuration/syncVerConfig"
- ]
- elif CONFIG_INFO == CONFIG_EUR:
- target_servers = [
- "https://test.zositechc.cn/open/device/configuration/syncVerConfig",
- "https://www.zositechc.cn/open/device/configuration/syncVerConfig",
- "https://www.dvema.com/open/device/configuration/syncVerConfig"
- ]
- for server_url in target_servers:
- try:
- # 发送请求并设置超时(10秒)
- resp = requests.post(
- url=server_url,
- data=req_data,
- timeout=10 # 超时时间
- )
- resp.raise_for_status() # 抛出HTTP错误(如400/500)
- LOGGER.info(f"[{server_url}] 同步成功,响应:{resp.json()}")
- except requests.exceptions.ConnectTimeout:
- LOGGER.error(f"[{server_url}] 连接超时,跳过")
- continue
- except requests.exceptions.ReadTimeout:
- LOGGER.error(f"[{server_url}] 读取超时,跳过")
- continue
- except requests.exceptions.RequestException as e:
- LOGGER.error(f"[{server_url}] 同步失败:{str(e)}")
- continue # 跳过当前服务器
- return True
- except Exception as e:
- LOGGER.exception("同步设备版本信息失败error{}".format(repr(e)))
- return False
- @staticmethod
- def get_device_voice(request_dict, response):
- """
- 获取设备音频
- @param request_dict:
- @param response:
- @return:
- """
- title = request_dict.get('title', None)
- voice_type = request_dict.get('voiceType', None)
- classification = request_dict.get('classification', None)
- uid = request_dict.get('uid', None)
- algorithm_type = request_dict.get('algorithmType', None)
- status = request_dict.get('status', None)
- page = request_dict.get('page', 1)
- page_size = request_dict.get('pageSize', 20)
- try:
- voice_prompt_qs = VoicePromptModel.objects.all()
- if title:
- voice_prompt_qs = voice_prompt_qs.filter(title__icontains=title)
- if voice_type:
- voice_prompt_qs = voice_prompt_qs.filter(type=voice_type)
- if classification:
- voice_prompt_qs = voice_prompt_qs.filter(classification=classification)
- if uid:
- voice_prompt_qs = voice_prompt_qs.filter(uid=uid)
- if algorithm_type:
- voice_prompt_qs = voice_prompt_qs.filter(algorithm_type=algorithm_type)
- if status:
- voice_prompt_qs = voice_prompt_qs.filter(status=status)
- # 分页
- paginator = Paginator(voice_prompt_qs.order_by("-add_time"), page_size) # 每页显示 page_size 条
- voice_prompt_page = paginator.get_page(page) # 获取当前页的数据
- # 上传文件到阿里云OSS
- auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
- bucket = oss2.Bucket(auth, 'https://oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
- voice_prompt_list = []
- for voice_prompt in voice_prompt_page:
- filename = voice_prompt.filename
- obj = 'voice_prompt/system/' + filename
- filename_url = bucket.sign_url('GET', obj, 3600)
- voice_prompt_list.append({
- "id": voice_prompt.id,
- "title": voice_prompt.title,
- "type": voice_prompt.type,
- "classification": voice_prompt.classification,
- "filename": filename,
- "filenameUrl": filename_url,
- "language": voice_prompt.language,
- "status": voice_prompt.status,
- "addTime": voice_prompt.add_time,
- "algorithmType": voice_prompt.algorithm_type,
- "uid": voice_prompt.uid,
- "device_types": voice_prompt.device_types
- })
- return response.json(0, {'list': voice_prompt_list, 'total': paginator.count})
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def algorithm_type_list(response):
- """
- 算法类型列表
- @param response:
- @return:
- """
- try:
- device_algorithm_explain_qs = DeviceAlgorithmExplain.objects.filter(lang='cn').values('title', 'algorithm_type__type')
- device_algorithm_explain = list(device_algorithm_explain_qs)
- for item in device_algorithm_explain:
- item['algorithm_type_id'] = item.pop('algorithm_type__type')
- device_algorithm_explain.append({"title": "无", "algorithm_type_id": 99})
- return response.json(0, device_algorithm_explain)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def add_device_voice(request, request_dict, response):
- """
- 添加设备音频
- @param request
- @param request_dict:
- @param response:
- @return:
- """
- title = request_dict.get('title', None)
- voice_type = request_dict.get('voiceType', None)
- classification = request_dict.get('classification', None)
- algorithm_type = request_dict.get('algorithmType', None)
- status = request_dict.get('status', None)
- language = request_dict.get('language', None)
- uid = request_dict.get('uid', None)
- channel = request_dict.get('channel', 1)
- device_types = request_dict.get('deviceTypes', None)
- voice_file = request.FILES.get('voiceFile', None)
- if not all([title, voice_type, classification, algorithm_type, status, language, voice_file]):
- return response.json(444)
- try:
- if device_types:
- device_type_list = device_types.split(',')
- device_type_list = list(map(int, device_type_list))
- else:
- device_type_list = []
- classification = int(classification)
- auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
- bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
- file_name = voice_file.name
- file_extension = os.path.splitext(file_name)[1]
- filename = CommonService.createOrderID() + file_extension
- voice_prompt_dict = {
- "title": title,
- "type": voice_type,
- "classification": classification,
- "filename": filename,
- "language": language,
- "status": status,
- "algorithm_type": algorithm_type,
- "add_time": int(time.time()),
- "device_types": device_type_list
- }
- if uid and classification == 1:
- voice_prompt_dict["uid"] = uid
- obj = 'voice_prompt/{uid}/{channel}/'.format(uid=uid, channel=channel) + filename
- bucket.put_object(obj, voice_file)
- elif uid and classification == 0:
- return response.json(178)
- else:
- obj = 'voice_prompt/system/' + filename
- bucket.put_object(obj, voice_file)
- VoicePromptModel.objects.create(**voice_prompt_dict)
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def edit_device_voice(request_dict, response):
- """
- 添加设备音频
- @param request:
- @param request_dict:
- @param response:
- @return:
- """
- device_voice_id = request_dict.get('deviceVoiceId', None)
- title = request_dict.get('title', None)
- voice_type = request_dict.get('voiceType', None)
- classification = request_dict.get('classification', None)
- algorithm_type = request_dict.get('algorithmType', None)
- status = request_dict.get('status', None)
- language = request_dict.get('language', None)
- device_types = request_dict.get('deviceTypes', "")
- try:
- voice_prompt = VoicePromptModel.objects.get(pk=device_voice_id)
- if title:
- voice_prompt.title = title
- if voice_type:
- voice_prompt.type = voice_type
- if classification:
- voice_prompt.classification = classification
- if algorithm_type:
- voice_prompt.algorithm_type = algorithm_type
- if status:
- voice_prompt.status = status
- if language:
- voice_prompt.language = language
- if device_types:
- device_type_list = device_types.split(',')
- device_type_list = list(map(int, device_type_list))
- voice_prompt.device_types = device_type_list
- voice_prompt.save()
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def del_device_voice(request_dict, response):
- """
- 删除设备音频
- @param request_dict:
- @param response:
- @return:
- """
- device_voice_id = request_dict.get('deviceVoiceId', None)
- try:
- voice_prompt_qs = VoicePromptModel.objects.filter(id=device_voice_id)
- filename = voice_prompt_qs[0].filename
- classification = voice_prompt_qs[0].classification
- uid = voice_prompt_qs[0].uid
- channel = voice_prompt_qs[0].channel
- auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
- bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'ansjer-static-resources')
- if classification == 1 and uid:
- obj = 'voice_prompt/{uid}/{channel}/'.format(uid=uid, channel=channel) + filename
- bucket.delete_object(obj)
- else:
- obj = 'voice_prompt/system/' + filename
- bucket.delete_object(obj)
- voice_prompt_qs.delete()
- return response.json(0)
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def device_type_list(response):
- """
- 获取设备类型
- @param response:
- @return:
- """
- try:
- subquery = DeviceTypeModel.objects.filter(
- type=OuterRef('type')
- ).values('type').annotate(
- min_id=Min('id')
- ).values('min_id')
- # 根据最小 id 获取对应的 name 和 type
- device_type_qs = DeviceTypeModel.objects.filter(
- id__in=Subquery(subquery)
- ).values("name", "type")
- return response.json(0, list(device_type_qs))
- except Exception as e:
- print(e)
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def get_baidu_big_model_license(request_dict, response):
- """查询百度大模型许可证列表"""
- page_no = request_dict.get('pageNo')
- page_size = request_dict.get('pageSize')
- serial = request_dict.get('serial', '')
- license_name = request_dict.get('licenseName', '')
- use_status = request_dict.get('useStatus')
- if not all([page_no, page_size]):
- return response.json(444)
- try:
- query = BaiduBigModelLicense.objects.all()
- if serial:
- query = query.filter(serial__contains=serial)
- if license_name:
- query = query.filter(license_name__contains=license_name)
- if use_status:
- query = query.filter(use_status=use_status)
- total = query.count()
- licenses = query.order_by('-id')[
- (int(page_no)-1)*int(page_size):int(page_no)*int(page_size)
- ].values('id', 'serial', 'license_name', 'use_status', 'created_time', 'updated_time')
- return response.json(0, {
- 'list': list(licenses),
- 'total': total
- })
- except Exception as e:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def add_baidu_big_model_license(request, response):
- """添加百度大模型许可证"""
- file = request.FILES.get('file', None)
- if not file:
- return response.json(444)
- try:
- license_name = str(file)
- now_time = int(time.time())
- # 上传文件到华为云OBS
- obs_client = ObsClient(
- access_key_id=HUAWEICLOUD_AK,
- secret_access_key=HUAWEICLOUD_SK,
- server=HUAWEICLOUD_OBS_SERVER
- )
- resp = obs_client.putObject(
- bucketName=HUAWEICLOUD_BAIDU_BIG_MODEL_LICENSE_BUKET,
- objectKey=license_name,
- content=file
- )
- assert resp.status < 300
- # 更新或创建数据
- license_qs = BaiduBigModelLicense.objects.filter(license_name=license_name)
- if license_qs.exists():
- license_qs.update(updated_time=now_time)
- else:
- BaiduBigModelLicense.objects.create(
- license_name=license_name,
- created_time=now_time,
- updated_time=now_time
- )
- return response.json(0)
- except Exception as e:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def edit_baidu_big_model_license(request, request_dict, response):
- """编辑百度大模型许可证"""
- license_id = request_dict.get('id')
- serial = request_dict.get('serial')
- use_status = request_dict.get('useStatus')
- if not license_id:
- return response.json(444)
- try:
- update_data = {
- 'updated_time': int(time.time())
- }
- if serial:
- update_data['serial'] = serial
- if use_status is not None:
- update_data['use_status'] = int(use_status)
- BaiduBigModelLicense.objects.filter(id=license_id).update(**update_data)
- return response.json(0)
- except Exception as e:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def del_baidu_big_model_license(request_dict, response):
- """删除百度大模型许可证"""
- license_id = request_dict.get('id')
-
- if not license_id:
- return response.json(444)
- try:
- # 先查询出license_name
- baidu_license = BaiduBigModelLicense.objects.filter(id=license_id).first()
- if not baidu_license:
- return response.json(444)
-
- license_name = baidu_license.license_name
-
- # 删除数据库记录
- BaiduBigModelLicense.objects.filter(id=license_id).delete()
-
- # 删除华为云上的文件
- obs_client = ObsClient(
- access_key_id=HUAWEICLOUD_AK,
- secret_access_key=HUAWEICLOUD_SK,
- server=HUAWEICLOUD_OBS_SERVER
- )
- obs_client.deleteObject(
- bucketName=HUAWEICLOUD_BAIDU_BIG_MODEL_LICENSE_BUKET,
- objectKey=license_name
- )
-
- return response.json(0)
- except Exception as e:
- return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- @staticmethod
- def device_power_display(request_dict, response):
- """
- 获取设备电量显示
- @param request_dict: 包含查询参数的字典
- @param response: 响应对象
- @return: 分页后的设备日报数据,包含聚合信息(如果条件满足)
- """
- device_id = request_dict.get('deviceId', None)
- start_time = request_dict.get('startTime', None)
- end_time = request_dict.get('endTime', None)
- page = int(request_dict.get('page', 1)) # 默认第1页
- page_size = int(request_dict.get('pageSize', 10)) # 默认每页10条
- device_daily_report_qs = DeviceDailyReport.objects.filter(type=1)
- # 应用过滤条件
- if device_id:
- device_daily_report_qs = device_daily_report_qs.filter(device_id=device_id)
- device_daily_report_qs = device_daily_report_qs.filter(report_time__gt=0)
- if start_time and end_time:
- start_time = int(start_time)
- end_time = int(end_time)
- device_daily_report_qs = device_daily_report_qs.filter(
- report_time__gte=start_time,
- report_time__lte=end_time
- )
- # 计算总数(用于分页)
- total_count = device_daily_report_qs.count()
- device_daily_report_qs = device_daily_report_qs.order_by('-report_time')
- # 应用分页
- paginator = Paginator(device_daily_report_qs, page_size)
- device_daily_report_page = paginator.page(page)
- # 序列化分页数据
- device_daily_report = list(device_daily_report_page.object_list.values(
- 'device_id',
- 'battery_level',
- 'report_time',
- 'human_detection',
- 'working_hours',
- 'wake_sleep',
- 'pir_wakeup_count',
- 'mqtt_wakeup_count'
- ))
- # 构建返回数据
- data = {
- "list": device_daily_report,
- "total": total_count,
- }
- # 如果满足条件(有设备ID和时间范围),计算聚合数据
- if device_id and start_time and end_time:
- aggregates = device_daily_report_qs.aggregate(
- total_human_detection=Sum('human_detection'),
- total_working_hours=Sum('working_hours'),
- total_wake_sleep=Sum('wake_sleep')
- )
- data['data_statistics'] = {
- 'total_human_detection': aggregates.get('total_human_detection', 0),
- 'total_working_hours': aggregates.get('total_working_hours', 0),
- 'total_wake_sleep': aggregates.get('total_wake_sleep', 0)
- }
- return response.json(0, data)
|