UserDeviceShareController.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. # -*- encoding: utf-8 -*-
  2. """
  3. @File : UserDeviceShareController.py
  4. @Time : 2023/1/7 15:05
  5. @Author : stephen
  6. @Email : zhangdongming@asj6.wecom.work
  7. @Software: PyCharm
  8. """
  9. import json
  10. import logging
  11. import threading
  12. import time
  13. import boto3
  14. import botocore
  15. from botocore import client
  16. from django.db import transaction
  17. from django.db.models import Q
  18. from django.views import View
  19. from Model.models import DeviceSharePermission, DeviceChannelUserSet, DeviceChannelUserPermission, UidChannelSetModel, \
  20. Device_Info
  21. from Object.ContentSecurityObject import ContentSecurity
  22. from Object.ResponseObject import ResponseObject
  23. from Object.TokenObject import TokenObject
  24. from Service.UserDeviceService import UserDeviceService
  25. from Ansjer.config import CONFIG_CN, CONFIG_INFO, CONFIG_TEST
  26. from Model.models import DeviceWallpaper
  27. from Object.AWS.AmazonS3Util import AmazonS3Util
  28. from django.conf import settings
  29. AWS_ACCESS_KEY_ID = settings.AWS_ACCESS_KEY_ID
  30. AWS_SECRET_ACCESS_KEY = settings.AWS_SECRET_ACCESS_KEY
  31. LOGGER = logging.getLogger('info')
  32. class UserDeviceShareView(View):
  33. def get(self, request, *args, **kwargs):
  34. request.encoding = 'utf-8'
  35. operation = kwargs.get('operation')
  36. return self.validation(request.GET, request, operation)
  37. def post(self, request, *args, **kwargs):
  38. request.encoding = 'utf-8'
  39. operation = kwargs.get('operation')
  40. return self.validation(request.POST, request, operation)
  41. def validation(self, request_dict, request, operation):
  42. token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
  43. lang = request_dict.get('lang', token.lang)
  44. response = ResponseObject(lang)
  45. if token.code != 0:
  46. return response.json(token.code)
  47. if operation == 'user-permissions':
  48. return self.get_user_share_permission(request_dict, response)
  49. elif operation == 'permissions-save':
  50. return self.user_channel_permission_save(request_dict, response)
  51. elif operation == 'permissions-test':
  52. return self.synch_share_device_permission(response)
  53. elif operation == 'getWallpaperList':
  54. return self.get_wallpaper_list(request_dict, response)
  55. elif operation == 'getUploadWallpaper':
  56. return self.get_upload_wallpaper(request_dict, response)
  57. elif operation == 'notifyUploadWallpaper':
  58. return self.notify_upload_wallpaper(request_dict, response)
  59. elif operation == 'delWallpaper':
  60. return self.del_wallpaper(request_dict, response)
  61. elif operation == 'selectWallpaper':
  62. return self.select_wallpaper(request_dict, response)
  63. else:
  64. return response.json(404)
  65. @classmethod
  66. def get_user_share_permission(cls, request_dict, response):
  67. """
  68. 获取用户分享权限
  69. @param request_dict: 设备uid
  70. @param response: 响应对象
  71. @return: permission List
  72. """
  73. try:
  74. uid = request_dict.get('uid', None)
  75. user_id = request_dict.get('userId', None)
  76. channel_count = request_dict.get('channelCount', None)
  77. if not all([user_id, uid, channel_count]):
  78. return response(444, 'uid, userId and channelCount is required')
  79. user_permission_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid) \
  80. .values('id', 'channels')
  81. if not user_permission_qs.exists():
  82. return response.json(0, {})
  83. up_id = user_permission_qs[0]['id']
  84. channel_permission_qs = DeviceChannelUserPermission.objects.filter(channel_user_id=up_id) \
  85. .values('permission_id', 'channel_user_id')
  86. if not channel_permission_qs.exists():
  87. return response.json(0, {})
  88. channel_list = list(range(1, int(channel_count) + 1))
  89. share_channel_list = user_permission_qs[0]['channels'].split(',')
  90. c_list = []
  91. for channel in channel_list:
  92. is_select = 1 if str(channel) in share_channel_list else 0
  93. c_list.append({'channelIndex': channel, 'isSelect': is_select})
  94. p_list = []
  95. permission_qs = DeviceSharePermission.objects.all()
  96. share_permission_list = [item['permission_id'] for item in channel_permission_qs]
  97. for item in permission_qs:
  98. is_select = 1 if item.id in share_permission_list else 0
  99. p_list.append({'permissionId': item.id, 'code': item.code, 'isSelect': is_select})
  100. data = {'channels': c_list, 'permissions': p_list}
  101. return response.json(0, data)
  102. except Exception as e:
  103. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  104. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  105. @classmethod
  106. def user_channel_permission_save(cls, request_dict, response):
  107. """
  108. 主用户分享设备时设置通道权限保存
  109. """
  110. try:
  111. uid = request_dict.get('uid', None)
  112. channels = request_dict.get('channels', None) # 通道集合,多个','隔开
  113. user_id = request_dict.get('userId', None)
  114. permission_ids = request_dict.get('permissionIds', None) # 权限集合,多个','隔开
  115. if not all([user_id, uid, channels, permission_ids]):
  116. return response.json(444)
  117. p_ids = []
  118. device_user_set = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
  119. now_time = int(time.time())
  120. with transaction.atomic():
  121. is_delete = False
  122. if not device_user_set.exists():
  123. device_set = {'uid': uid, 'user_id': user_id, 'channels': channels,
  124. 'created_time': now_time, 'updated_time': now_time}
  125. device_user_set = DeviceChannelUserSet.objects.create(**device_set)
  126. channel_user_id = device_user_set.id
  127. else:
  128. DeviceChannelUserSet.objects.update(channels=channels, updated_time=now_time)
  129. channel_user_id = device_user_set.first().id
  130. is_delete = True
  131. if ',' in permission_ids:
  132. p_ids = [int(val) for val in permission_ids.split(',')]
  133. if is_delete:
  134. DeviceChannelUserPermission.objects.filter(
  135. channel_user_id=channel_user_id).delete()
  136. if not p_ids:
  137. channel_permission = {'permission_id': int(permission_ids),
  138. 'channel_user_id': channel_user_id,
  139. 'created_time': now_time}
  140. DeviceChannelUserPermission.objects.create(**channel_permission)
  141. else:
  142. channel_permission_list = []
  143. for item in p_ids:
  144. channel_permission_list.append(DeviceChannelUserPermission(
  145. permission_id=int(item),
  146. channel_user_id=channel_user_id,
  147. created_time=now_time))
  148. DeviceChannelUserPermission.objects.bulk_create(channel_permission_list)
  149. return response.json(0)
  150. except Exception as e:
  151. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  152. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  153. @staticmethod
  154. def qrcode_share_channel_permission_save(user_id, uid):
  155. """
  156. 二维码分享保存通道权限
  157. @param user_id: 用户id
  158. @param uid: 用户设备ID
  159. @return: True | False
  160. """
  161. try:
  162. if not all([user_id, uid]):
  163. return False
  164. with transaction.atomic():
  165. ds_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
  166. if ds_qs.exists():
  167. return True
  168. UserDeviceService.update_device_channel(uid)
  169. channel_qs = UidChannelSetModel.objects.filter(uid__uid=uid).values('channel')
  170. if not channel_qs.exists():
  171. return False
  172. channel_list = [str(val['channel']) for val in channel_qs]
  173. channel_str = ','.join(channel_list)
  174. now_time = int(time.time())
  175. device_set = {'uid': uid, 'user_id': user_id, 'channels': channel_str,
  176. 'created_time': now_time, 'updated_time': now_time}
  177. device_user_set = DeviceChannelUserSet.objects.create(**device_set)
  178. channel_permission_qs = DeviceSharePermission.objects \
  179. .all().values('id', 'code').order_by('sort')
  180. user_set_id = device_user_set.id
  181. channel_permission_list = []
  182. for item in channel_permission_qs:
  183. channel_permission_list.append(DeviceChannelUserPermission(
  184. permission_id=item['id'],
  185. channel_user_id=user_set_id,
  186. created_time=now_time))
  187. DeviceChannelUserPermission.objects.bulk_create(channel_permission_list)
  188. return True
  189. except Exception as e:
  190. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  191. return False
  192. @staticmethod
  193. def synch_share_device_permission(response):
  194. """
  195. 同步分析设备权限
  196. @param response: 响应结果
  197. """
  198. device_info_qs = Device_Info.objects \
  199. .filter(~Q(Type__in=[1, 2, 3, 4, 10001]), ~Q(primaryUserID=''), isShare=1) \
  200. .values('userID_id', 'UID').order_by('-data_joined')
  201. if not device_info_qs.exists():
  202. return response.json(0)
  203. for item in device_info_qs:
  204. UserDeviceShareView.qrcode_share_channel_permission_save(item['userID_id'], item['UID'])
  205. return response.json(0)
  206. @classmethod
  207. def get_wallpaper_list(cls, request_dict, response):
  208. """
  209. 获取设备壁纸列表
  210. @param request_dict:
  211. @param response:
  212. @return:
  213. """
  214. try:
  215. device_type = int(request_dict.get('deviceType', None))
  216. uid = request_dict.get('uid', None)
  217. channel = int(request_dict.get('channel', 1))
  218. LOGGER.info('获取设备壁纸列表参数:{}'.format(request_dict))
  219. if not all([device_type, uid]):
  220. return response.json(444)
  221. # 查询用户自定义壁纸
  222. user_wallpaper_qs = DeviceWallpaper.objects.filter(channel=channel, uid=uid,
  223. device_type=device_type, parent_id=0, status=1)
  224. # 查询系统默认壁纸
  225. def_wallpaper_qs = DeviceWallpaper.objects.filter(classification=1, device_type=device_type, uid='',
  226. status=1)
  227. # 查询用户选中的壁纸
  228. user_checked_qs = DeviceWallpaper.objects.filter(channel=channel, uid=uid,
  229. device_type=device_type, parent_id__gt=0, status=1)
  230. checked_id = user_checked_qs[0].parent_id if user_checked_qs.exists() else 0
  231. wallpaper_list = []
  232. if def_wallpaper_qs.exists() or user_wallpaper_qs.exists():
  233. # 初始化存储桶客户端
  234. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  235. s3 = boto3.client(
  236. 's3',
  237. aws_access_key_id=AWS_ACCESS_KEY_ID[0],
  238. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
  239. config=botocore.client.Config(signature_version='s3v4'),
  240. region_name='cn-northwest-1'
  241. )
  242. else:
  243. s3 = boto3.client(
  244. 's3',
  245. aws_access_key_id=AWS_ACCESS_KEY_ID[1],
  246. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
  247. config=botocore.client.Config(signature_version='s3v4'),
  248. region_name='us-east-1'
  249. )
  250. # 处理系统默认壁纸和用户自定义壁纸
  251. all_wallpapers_qs = def_wallpaper_qs.union(user_wallpaper_qs)
  252. for item in all_wallpapers_qs:
  253. obj_key = item.obj_prefix + item.obj_name
  254. params = {
  255. 'Key': obj_key,
  256. 'Bucket': 'ansjerfilemanager',
  257. }
  258. response_url = s3.generate_presigned_url(
  259. 'get_object', Params=params, ExpiresIn=3600)
  260. wallpaper = {
  261. 'id': item.id,
  262. 'url': response_url,
  263. 'state': 1 if checked_id == item.id else 0,
  264. 'classification': item.classification
  265. }
  266. wallpaper_list.append(wallpaper)
  267. return response.json(0, {'wallpapers': wallpaper_list})
  268. except Exception as e:
  269. LOGGER.error('查询设备壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  270. return response.json(5)
  271. @classmethod
  272. def get_upload_wallpaper(cls, request_dict, response):
  273. """
  274. 获取设备壁纸上传链接
  275. @param request_dict:
  276. @param response:
  277. @return:
  278. """
  279. try:
  280. uid = request_dict.get('uid', None)
  281. channel = int(request_dict.get('channel', 1))
  282. if not uid:
  283. return response.json(444)
  284. # 初始化存储桶客户端
  285. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  286. s3 = boto3.client(
  287. 's3',
  288. aws_access_key_id=AWS_ACCESS_KEY_ID[0],
  289. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
  290. config=botocore.client.Config(signature_version='s3v4'),
  291. region_name='cn-northwest-1'
  292. )
  293. else:
  294. s3 = boto3.client(
  295. 's3',
  296. aws_access_key_id=AWS_ACCESS_KEY_ID[1],
  297. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
  298. config=botocore.client.Config(signature_version='s3v4'),
  299. region_name='us-east-1'
  300. )
  301. # 生成唯一的文件名
  302. file_name = f"{int(time.time())}.png"
  303. obj_key = f"app/static/device-wallpaper/{uid}/{file_name}"
  304. # 生成预签名的 URL
  305. presigned_url = s3.generate_presigned_url(
  306. 'put_object',
  307. Params={
  308. 'Bucket': 'ansjerfilemanager',
  309. 'Key': obj_key,
  310. },
  311. ExpiresIn=600
  312. )
  313. # 返回预签名的URL和字段
  314. return response.json(0, {
  315. 'uploadUrl': presigned_url,
  316. 'fileName': file_name,
  317. })
  318. except Exception as e:
  319. LOGGER.error('获取上传链接异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  320. return response.json(5)
  321. @classmethod
  322. def notify_upload_wallpaper(cls, request_dict, response):
  323. """
  324. 确认壁纸上传成功,创建DeviceWallpaper
  325. @param request_dict:
  326. @param response:
  327. @return:
  328. """
  329. try:
  330. uid = request_dict.get('uid', None)
  331. file_name = request_dict.get('fileName', None)
  332. channel = int(request_dict.get('channel', 1))
  333. if not all([uid, file_name]):
  334. return response.json(444)
  335. device_info_qs = Device_Info.objects.filter(UID=uid).values('id', 'Type')
  336. device_type = device_info_qs[0]['Type'] if device_info_qs.exists() else ''
  337. # 初始化存储桶客户端
  338. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  339. s3 = boto3.client(
  340. 's3',
  341. aws_access_key_id=AWS_ACCESS_KEY_ID[0],
  342. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
  343. config=botocore.client.Config(signature_version='s3v4'),
  344. region_name='cn-northwest-1'
  345. )
  346. else:
  347. s3 = boto3.client(
  348. 's3',
  349. aws_access_key_id=AWS_ACCESS_KEY_ID[1],
  350. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
  351. config=botocore.client.Config(signature_version='s3v4'),
  352. region_name='us-east-1'
  353. )
  354. obj_key = f"app/static/device-wallpaper/{uid}/{file_name}"
  355. params = {'Bucket': "ansjerfilemanager", 'Key': obj_key}
  356. image_url = s3.generate_presigned_url('get_object', Params=params)
  357. service = 'profilePhotoCheck'
  358. LOGGER.info('壁纸链接:{}'.format(image_url))
  359. service_dict = {'imageUrl': image_url}
  360. service_parameters = json.dumps(service_dict)
  361. legal = ContentSecurity().image_review(service, service_parameters)
  362. if not legal:
  363. # 异步删除
  364. thread = threading.Thread(target=cls.delete_wallpaper, args=(obj_key,))
  365. thread.start()
  366. return response.json(184)
  367. DeviceWallpaper.objects.create(
  368. device_type=device_type,
  369. storage_type=1,
  370. channel=channel,
  371. uid=uid,
  372. obj_prefix=f'app/static/device-wallpaper/{uid}/',
  373. obj_name=file_name,
  374. classification=2, # 自定义壁纸分类
  375. status=1,
  376. parent_id=0,
  377. created_time=int(time.time())
  378. )
  379. return response.json(0)
  380. except Exception as e:
  381. LOGGER.error('壁纸创建失败:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  382. return response.json(5)
  383. @classmethod
  384. def del_wallpaper(cls, request_dict, response):
  385. """
  386. 删除设备壁纸
  387. """
  388. wallpaper_id = request_dict.get('wallpaperId', None)
  389. if not all([wallpaper_id]):
  390. return response.json(444)
  391. try:
  392. wallpaper_id = int(wallpaper_id)
  393. if DeviceWallpaper.objects.filter(id=wallpaper_id, classification=1).exists():
  394. return response.json(176, "系统图片不能删除")
  395. device_wallpaper_qs = DeviceWallpaper.objects.filter(id=wallpaper_id)
  396. device_wallpaper = device_wallpaper_qs.values("obj_prefix", "obj_name", "uid", "parent_id")
  397. uid = device_wallpaper[0]['uid']
  398. obj_name = device_wallpaper[0]['obj_name']
  399. # 使用中壁纸被删除
  400. use_device_wallpaper = DeviceWallpaper.objects.filter(uid=uid, parent_id__gt=0).first()
  401. if use_device_wallpaper and use_device_wallpaper.parent_id == wallpaper_id:
  402. system_device_wallpaper = DeviceWallpaper.objects.filter(id=1).first()
  403. use_device_wallpaper.parent_id = 1
  404. use_device_wallpaper.storage_type = system_device_wallpaper.storage_type
  405. use_device_wallpaper.obj_name = system_device_wallpaper.obj_name
  406. use_device_wallpaper.obj_prefix = system_device_wallpaper.obj_prefix
  407. use_device_wallpaper.classification = system_device_wallpaper.classification
  408. use_device_wallpaper.channel = system_device_wallpaper.channel
  409. use_device_wallpaper.save()
  410. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  411. s3 = AmazonS3Util(
  412. AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1'
  413. )
  414. else:
  415. s3 = AmazonS3Util(
  416. AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], 'us-east-1'
  417. )
  418. s3.delete_obj("ansjerfilemanager", f"app/static/device-wallpaper/{uid}/{obj_name}")
  419. device_wallpaper_qs.delete()
  420. return response.json(0)
  421. except Exception as e:
  422. LOGGER.info('删除壁纸异常:{}'.format(e))
  423. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  424. @classmethod
  425. def select_wallpaper(cls, request_dict, response):
  426. """
  427. 用户选取壁纸
  428. @param request_dict:
  429. @param response:
  430. @return:
  431. """
  432. try:
  433. wallpaper_id = request_dict.get('wallpaperId', None)
  434. uid = request_dict.get('uid', None)
  435. if not all([wallpaper_id, uid]):
  436. return response.json(444)
  437. device_wallpaper = DeviceWallpaper.objects.filter(id=wallpaper_id).values("device_type", "storage_type",
  438. "obj_prefix",
  439. "obj_name",
  440. "classification",
  441. "channel").first()
  442. device_wallpaper_qs = DeviceWallpaper.objects.filter(uid=uid, parent_id__gt=0)
  443. if device_wallpaper_qs.exists():
  444. device_wallpaper_qs.update(
  445. storage_type=device_wallpaper["storage_type"],
  446. classification=device_wallpaper["classification"],
  447. obj_prefix=device_wallpaper["obj_prefix"],
  448. obj_name=device_wallpaper["obj_name"],
  449. parent_id=wallpaper_id
  450. )
  451. else:
  452. DeviceWallpaper.objects.create(
  453. device_type=device_wallpaper["device_type"],
  454. storage_type=device_wallpaper["storage_type"],
  455. obj_name=device_wallpaper["obj_name"],
  456. obj_prefix=device_wallpaper["obj_prefix"],
  457. classification=device_wallpaper["classification"],
  458. uid=uid,
  459. channel=device_wallpaper["channel"],
  460. status=1,
  461. parent_id=wallpaper_id,
  462. created_time=int(time.time())
  463. )
  464. return response.json(0)
  465. except Exception as e:
  466. LOGGER.error('用户选取壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  467. return response.json(5)
  468. @staticmethod
  469. def delete_wallpaper(file_key):
  470. try:
  471. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  472. s3 = AmazonS3Util(
  473. AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1'
  474. )
  475. else:
  476. s3 = AmazonS3Util(
  477. AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], 'us-east-1'
  478. )
  479. s3.delete_obj("ansjerfilemanager", file_key)
  480. return True
  481. except Exception as e:
  482. LOGGER.info('删除违规壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  483. return False