CloudTransfer.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. # -*- coding: utf-8 -*-
  2. """
  3. @Time : 2020/12/16 8:44
  4. @Auth : Locky
  5. @File :CloudTransfer.py
  6. @IDE :PyCharm
  7. """
  8. import json
  9. import time
  10. from django.db import transaction
  11. from django.db.models import Q
  12. from django.views.generic.base import View
  13. from Model.models import Device_User, Device_Info, Order_Model, UID_Bucket, StsCrdModel, VodHlsModel, Unused_Uid_Meal, \
  14. VodBucketModel, UnicomDeviceInfo, LogModel, UidPushModel, AiService, UidSetModel, UserFamily, FamilyRoomDevice, \
  15. UserAudioVideoPush, GatewayPush
  16. from Object.ResponseObject import ResponseObject
  17. from Object.TokenObject import TokenObject
  18. from Service.CommonService import CommonService
  19. from Service.ModelService import ModelService
  20. from Service.VodHlsService import SplitVodHlsObject
  21. from Ansjer.config import LOGGER
  22. class cloudTestView(View):
  23. def get(self, request, *args, **kwargs):
  24. request.encoding = 'utf-8'
  25. operation = kwargs.get('operation')
  26. return self.validation(request.GET, request, operation)
  27. def post(self, request, *args, **kwargs):
  28. request.encoding = 'utf-8'
  29. operation = kwargs.get('operation')
  30. return self.validation(request.POST, request, operation)
  31. def validation(self, request_dict, request, operation):
  32. lang = request_dict.get('lang', None)
  33. response = ResponseObject(lang) if lang else ResponseObject()
  34. if operation is None:
  35. return response.json(444, 'error path')
  36. else:
  37. token = request_dict.get('token', None)
  38. # 设备主键uid
  39. tko = TokenObject(token)
  40. if tko.code != 0:
  41. return response.json(tko.code)
  42. userID = tko.userID
  43. if operation == 'deviceTransfer':
  44. return self.deviceTransfer(request, request_dict, response)
  45. elif operation == 'mealTransfer':
  46. return self.mealTransfer(request, request_dict, response, userID)
  47. elif operation == 'expireMeal':
  48. return self.expireMeal(request_dict, response)
  49. def deviceTransfer(self, request, request_dict, response):
  50. # 设备转移,一个用户下的设备转移到另一个用户
  51. oldUserID = request_dict.get("oldUserID", None)
  52. username = request_dict.get("username", None)
  53. uid = request_dict.get('uid', None)
  54. lang = request_dict.get('lang', None)
  55. now_time_stamp = int(time.time())
  56. now_time = CommonService.timestamp_to_str(now_time_stamp)
  57. try:
  58. # 查询该userID下是否存在此设备
  59. old_deviceInfo_qs = Device_Info.objects.filter(userID_id=oldUserID, UID=uid, isExist=1) \
  60. .values('isShare', 'vodPrimaryUserID', 'serial_number', 'userID__username', 'id')
  61. if not old_deviceInfo_qs.exists():
  62. return response.json(10008)
  63. old_user_name = old_deviceInfo_qs[0]['userID__username']
  64. newUserID = ModelService.get_userID_byname(username) # 根据username获取userID
  65. if newUserID is None: # 没有此用户
  66. return response.json(104)
  67. if newUserID == oldUserID: # 新用户的userID跟旧用户的一样
  68. return response.json(10009)
  69. # 分享的设备不能转移
  70. isShare = old_deviceInfo_qs[0]['isShare']
  71. if isShare:
  72. return response.json(10015)
  73. # 旧用户是设备主用户才能转移
  74. vodPrimaryUserID = old_deviceInfo_qs[0]['vodPrimaryUserID']
  75. if vodPrimaryUserID != '' and vodPrimaryUserID != oldUserID:
  76. return response.json(10037)
  77. # uid_mian = UIDMainUser.objects.filter(UID=uid).values('UID', 'user_id')
  78. # if uid_mian.exists():
  79. # vodPrimaryUserID = uid_mian[0]['user_id']
  80. # if vodPrimaryUserID != '' and vodPrimaryUserID != oldUserID:
  81. # return response.json(10037)
  82. # 判断新用户是否已有此设备
  83. new_deviceInfo_qs = Device_Info.objects.filter(userID_id=newUserID, UID=uid, isExist=1)
  84. if new_deviceInfo_qs.exists():
  85. return response.json(10009)
  86. # 旧用户如果开启云存自动续费,不可转移
  87. hasCycle = Order_Model.objects.filter(userID=oldUserID, UID=uid)
  88. hasCycle = hasCycle.filter(~Q(agreement_id=''))
  89. if hasCycle.exists():
  90. return response.json(10056)
  91. # 获取新设备的username、userEmail
  92. newUserQs = Device_User.objects.get(userID=newUserID)
  93. newUserName = newUserQs.username
  94. newUserEmail = newUserQs.userEmail
  95. vodPrimaryUserID = newUserID
  96. vodPrimaryMaster = newUserName
  97. # 获取用户家庭信息
  98. device_id = old_deviceInfo_qs[0]['id']
  99. user_family_qs = UserFamily.objects.filter(user_id=newUserID).values('id')
  100. with transaction.atomic():
  101. serial_number = old_deviceInfo_qs[0]['serial_number']
  102. # 删除旧用户此设备的uid_push数据
  103. UidPushModel.objects.filter(userID_id=oldUserID, uid_set__uid=uid).delete()
  104. # 更新旧设备的userID,设备添加时间,关闭推送消息提醒
  105. old_deviceInfo_qs.update(userID=newUserID, data_joined=now_time, NotificationMode=0)
  106. # 更新设备的主用户信息
  107. Device_Info.objects.filter(UID=uid).update(vodPrimaryUserID=vodPrimaryUserID,
  108. vodPrimaryMaster=vodPrimaryMaster,
  109. primaryUserID=vodPrimaryUserID,
  110. primaryMaster=vodPrimaryMaster)
  111. VodHlsModel.objects.filter(uid=uid).delete()
  112. # 删除vod_hls分表数据
  113. split_vod_hls_obj = SplitVodHlsObject()
  114. split_vod_hls_obj.del_vod_hls_data(uid=uid)
  115. if not serial_number:
  116. serial_number = CommonService.query_serial_with_uid(uid)
  117. u_dev_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
  118. if u_dev_info_qs.exists():
  119. now_time = int(time.time())
  120. u_dev_info_qs.update(user_id=newUserID, updated_time=now_time)
  121. # 转移设备到家庭
  122. if user_family_qs.exists():
  123. family_id = user_family_qs[0]['id']
  124. else:
  125. family_name = newUserName if newUserName else newUserEmail
  126. family_name = family_name + "的家" if lang == 'cn' else family_name + " home"
  127. user_family = UserFamily.objects.create(user_id=newUserID, name=family_name,
  128. updated_time=now_time_stamp,
  129. created_time=now_time_stamp)
  130. family_id = user_family.id
  131. family_device = FamilyRoomDevice.objects.filter(family_id=family_id, category=1).values('category_sort')
  132. category_sort = family_device[0]['category_sort'] if family_device.exists() else 0
  133. old_family_device = FamilyRoomDevice.objects.filter(device_id=device_id)
  134. if old_family_device.exists():
  135. old_family_device.update(family_id=family_id, category_sort=category_sort,
  136. updated_time=now_time_stamp, room_id=0, sort=0)
  137. else:
  138. FamilyRoomDevice.objects.create(family_id=family_id, category=1, device_id=device_id,
  139. updated_time=now_time_stamp, created_time=now_time_stamp)
  140. # 双通话键设备
  141. UserAudioVideoPush.objects.filter(uid=uid).update(buttonUser1=newUserID, buttonUser2=newUserID,
  142. updated_time=int(time.time()))
  143. self.add_user_phone_push(newUserID, uid)
  144. # 记录设备转移日志
  145. ip = CommonService.get_ip_address(request)
  146. content = json.loads(json.dumps(request_dict))
  147. log = {
  148. 'ip': ip,
  149. 'user_id': 1,
  150. 'status': 200,
  151. 'time': int(time.time()),
  152. 'url': 'cloudTransfer/deviceTransfer',
  153. 'content': json.dumps(content),
  154. 'operation': '用户{}的设备{}转移给了用户{}'.format(old_user_name, uid, newUserName),
  155. }
  156. LogModel.objects.create(**log)
  157. # UIDMainUser.objects.filter(UID=uid).delete()
  158. # uid_main_dict = {
  159. # 'UID': uid,
  160. # 'user_id': newUserID
  161. # }
  162. # UIDMainUser.objects.create(**uid_main_dict)
  163. except Exception as e:
  164. # print(e)
  165. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  166. else:
  167. return response.json(0)
  168. @classmethod
  169. def add_user_phone_push(cls, userID, UID):
  170. """
  171. 根据userID查询用户手机推送令牌信息
  172. """
  173. try:
  174. uid_set_qs = UidSetModel.objects.filter(uid=UID).values('id')
  175. if uid_set_qs.exists():
  176. uid_set_id = uid_set_qs[0]['id']
  177. now_time = int(time.time())
  178. uid_push_qs = UidPushModel.objects.filter(userID=userID).values_list('appBundleId', 'app_type',
  179. 'push_type', 'token_val',
  180. 'jg_token_val', 'm_code',
  181. 'lang', 'tz').order_by('-updTime')
  182. count = 0
  183. if uid_push_qs.exists():
  184. for item in set(list(uid_push_qs)):
  185. UidPushModel.objects.create(userID_id=userID, appBundleId=item[0], app_type=item[1],
  186. push_type=item[2], token_val=item[3], jg_token_val=item[4],
  187. m_code=item[5], lang=item[6], tz=item[7], addTime=now_time,
  188. updTime=now_time, uid_set_id=uid_set_id)
  189. count += 1
  190. if count >= 4:
  191. break
  192. else:
  193. gateway_push_qs = GatewayPush.objects.filter(user_id=userID, logout=False).values(
  194. 'app_bundle_id', 'm_code', 'app_type', 'push_type', 'token_val', 'lang', 'jg_token_val',
  195. 'tz').order_by('-id')
  196. for item in gateway_push_qs:
  197. UidPushModel.objects.create(userID_id=userID, appBundleId=item['app_bundle_id'],
  198. app_type=item['app_type'], addTime=now_time,
  199. push_type=item['push_type'], updTime=now_time,
  200. token_val=item['token_val'], uid_set_id=uid_set_id,
  201. jg_token_val=item['jg_token_val'], lang=item['lang'],
  202. m_code=item['m_code'], tz=item['tz'])
  203. count += 1
  204. if count >= 4:
  205. break
  206. except Exception as e:
  207. LOGGER.error('添加用户设备推送异常,uid:{},error_line:{}, error_msg:{}'
  208. .format(UID, e.__traceback__.tb_lineno, repr(e)))
  209. def mealTransfer(self, request, request_dict, response, userID):
  210. # 云存套餐转移,同一用户下不同设备间的云存套餐转移
  211. old_uid = request_dict.get("old_uid", None)
  212. new_uid = request_dict.get("new_uid", None)
  213. nowTime = int(time.time())
  214. try:
  215. # 查询两个UID是否在同一账号下
  216. old_deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, UID=old_uid).values('isExist',
  217. 'vodPrimaryUserID',
  218. 'userID__username')
  219. new_deviceInfo_qs = Device_Info.objects.filter(userID_id=userID, UID=new_uid).values('isExist')
  220. if not (old_deviceInfo_qs.exists() and new_deviceInfo_qs.exists()):
  221. return response.json(10010)
  222. username = old_deviceInfo_qs[0]['userID__username']
  223. # 不是主用户无法转移
  224. vodPrimaryUserID = old_deviceInfo_qs[0]['vodPrimaryUserID']
  225. if vodPrimaryUserID != '' and vodPrimaryUserID != userID:
  226. return response.json(10038)
  227. vodPrimaryUserID = userID
  228. vodPrimaryMaster = ModelService.get_user_name(userID)
  229. new_isExist = new_deviceInfo_qs[0]['isExist']
  230. if not new_isExist:
  231. return response.json(10011)
  232. # 查询转出设备正在使用的套餐
  233. old_using_uid_bucket = UID_Bucket.objects.filter(uid=old_uid, endTime__gte=nowTime).values('id',
  234. 'bucket_id',
  235. 'has_unused',
  236. 'bucket__content').order_by(
  237. 'addTime')
  238. if not old_using_uid_bucket.exists():
  239. return response.json(10013)
  240. bucket_content = old_using_uid_bucket[0]['bucket__content']
  241. # 免费存储桶不可转移
  242. old_vod_bucket_id = old_using_uid_bucket[0]['bucket_id']
  243. is_free = VodBucketModel.objects.get(id=old_vod_bucket_id).is_free
  244. if is_free == 1:
  245. return response.json(10012)
  246. # 查询转入设备是否存在正在使用的套餐和未使用的套餐
  247. new_using_uid_bucket = UID_Bucket.objects.filter(uid=new_uid, endTime__gte=nowTime)
  248. new_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=new_uid)
  249. if new_using_uid_bucket.exists() or new_unused_uid_bucket.exists():
  250. return response.json(10014)
  251. old_ai_service = AiService.objects.filter(uid=old_uid, endTime__gte=nowTime, use_status=1).values('id',
  252. 'detect_interval',
  253. 'detect_status',
  254. 'detect_group')
  255. new_ai_service = AiService.objects.filter(uid=new_uid, endTime__gte=nowTime, use_status=1)
  256. if new_ai_service.exists(): # 转入设备有开通AI功能,不能转
  257. return response.json(10014)
  258. new_uid_set = UidSetModel.objects.filter(uid=new_uid).values('is_ai')
  259. if old_ai_service.exists() and new_uid_set[0]['is_ai'] == 2: # 转出设备有开通AI,但是转入设备不支持AI,不能转
  260. return response.json(10016)
  261. with transaction.atomic():
  262. # 如果转出设备有未使用套餐,更改第一个未使用套餐为正在使用
  263. if old_using_uid_bucket[0]['has_unused'] == 1:
  264. old_unused_uid_bucket = Unused_Uid_Meal.objects.filter(uid=old_uid).values('id', 'channel',
  265. 'bucket_id',
  266. 'addTime', 'expire',
  267. 'is_ai',
  268. 'order_id')
  269. count = old_unused_uid_bucket.count()
  270. unused = old_unused_uid_bucket[0]
  271. has_unused = 1 if count > 1 else 0 # 如果存在不止一个未使用套餐,has_unused=1
  272. endTime = CommonService.calcMonthLater(unused['expire'])
  273. data_dict = {
  274. 'uid': old_uid,
  275. 'channel': unused['channel'],
  276. 'bucket_id': unused['bucket_id'],
  277. 'addTime': unused['addTime'],
  278. 'endTime': endTime,
  279. 'updateTime': nowTime,
  280. 'status': 1,
  281. 'use_status': 1,
  282. 'has_unused': has_unused
  283. }
  284. UID_Bucket.objects.create(**data_dict) # 正在使用套餐表添加数据
  285. Unused_Uid_Meal.objects.filter(uid=old_uid).first().delete() # 删除未使用套餐表中的数据
  286. if unused['is_ai']: # 开通AI服务
  287. AiService.objects.create(uid=old_uid, channel=unused['channel'],
  288. detect_status=old_ai_service[0]['detect_status'],
  289. addTime=nowTime, updTime=nowTime, endTime=endTime, use_status=1,
  290. orders_id=unused['order_id'],
  291. detect_group=old_ai_service[0]['detect_group'],
  292. detect_interval=old_ai_service[0]['detect_interval'])
  293. # 更新转入设备的主用户信息
  294. Device_Info.objects.filter(UID=new_uid).update(vodPrimaryUserID=vodPrimaryUserID,
  295. vodPrimaryMaster=vodPrimaryMaster)
  296. # 更新正在使用套餐的uid,重置拥有未使用套餐
  297. old_using_uid_bucket_id = old_using_uid_bucket[0]['id']
  298. UID_Bucket.objects.filter(id=old_using_uid_bucket_id).update(uid=new_uid, has_unused=0)
  299. StsCrdModel.objects.filter(uid=old_uid).delete() # 删除转出设备stscrd表关联数据
  300. # 转移AI服务
  301. if old_ai_service.exists() and new_uid_set[0]['is_ai'] != 2:
  302. AiService.objects.filter(id=old_ai_service[0]['id']).update(uid=new_uid, detect_status=0,
  303. detect_group='', detect_interval=60)
  304. msg = {'commandType': 'AIDisable'}
  305. thing_name = CommonService.query_serial_with_uid(old_uid) # 存在序列号则为使用序列号作为物品名
  306. topic_name = 'ansjer/generic/{}'.format(thing_name)
  307. req_success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
  308. if not req_success:
  309. return response.json(10044)
  310. # 记录套餐转移日志
  311. ip = CommonService.get_ip_address(request)
  312. content = json.loads(json.dumps(request_dict))
  313. log = {
  314. 'ip': ip,
  315. 'user_id': 1,
  316. 'status': 200,
  317. 'time': int(time.time()),
  318. 'url': 'cloudTransfer/mealTransfer',
  319. 'content': json.dumps(content),
  320. 'operation': '用户{}的设备{}的套餐{}转移给设备{}'.format(username, old_uid, bucket_content, new_uid),
  321. }
  322. LogModel.objects.create(**log)
  323. return response.json(0)
  324. except Exception as e:
  325. return response.json(500, repr(e))
  326. def expireMeal(self, request_dict, response):
  327. UID_Bucket_id = request_dict.get("UID_Bucket_id", None)
  328. # 修改endTime让当前设备套餐过期
  329. if UID_Bucket_id:
  330. try:
  331. UID_Bucket.objects.filter(id=UID_Bucket_id).update(use_status=2)
  332. except Exception as e:
  333. # print(e)
  334. return response.json(500, repr(e))
  335. else:
  336. return response.json(0)
  337. response.json(404)