SerialNumberController.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import json
  4. import logging
  5. import random
  6. import time
  7. from django.db import transaction
  8. from django.views import View
  9. from Controller.DetectController import DetectControllerView
  10. from Controller.DeviceConfirmRegion import Device_Region
  11. from Model.models import SerialNumberModel, CompanySerialModel, UIDCompanySerialModel, CompanyModel, RegionModel, \
  12. CountryModel, UIDModel, Device_Info, iotdeviceInfoModel, UidPushModel, LogModel, MacModel
  13. from Object.RedisObject import RedisObject
  14. from Object.uidManageResponseObject import uidManageResponseObject
  15. from Object.TokenObject import TokenObject
  16. from Service.AlgorithmService import AlgorithmBaseOn35
  17. from Service.CommonService import CommonService
  18. from Ansjer.config import CRCKey
  19. from Service.ModelService import ModelService
  20. from Object.AWS.S3Email import S3Email
  21. class SerialNumberView(View):
  22. def get(self, request, *args, **kwargs):
  23. request.encoding = 'utf-8'
  24. operation = kwargs.get('operation', None)
  25. request_dict = request.GET
  26. return self.validate(request_dict, operation, request)
  27. def post(self, request, *args, **kwargs):
  28. request.encoding = 'utf-8'
  29. operation = kwargs.get('operation', None)
  30. request_dict = request.POST
  31. return self.validate(request_dict, operation, request)
  32. def validate(self, request_dict, operation, request):
  33. token = TokenObject(request_dict.get('token', None))
  34. response = uidManageResponseObject()
  35. if operation == 'getUID':
  36. return self.do_get_uid(request_dict, response)
  37. elif operation == 'attachUID':
  38. return self.do_attach_uid(request_dict, response, request)
  39. elif operation == 'detachUID':
  40. return self.do_detach_uid(request, request_dict, response)
  41. elif operation == 'create':
  42. return self.do_create(request_dict, response)
  43. else:
  44. if token.code != 0:
  45. return response.json(token.code)
  46. # if operation == 'create':
  47. # return self.do_create(request_dict, response)
  48. elif operation == 'list':
  49. return self.do_list(token.userID, request_dict, response)
  50. elif operation == 'update':
  51. return self.do_update(token.userID, request_dict, response)
  52. else:
  53. return response.json(404)
  54. def do_create(self, request_dict, response):
  55. quantity = int(request_dict.get('quantity', 0))
  56. if not quantity:
  57. return response.json(444)
  58. try:
  59. try:
  60. sum = SerialNumberModel.objects.last().id
  61. except:
  62. sum = 0
  63. serial_number_bulk = []
  64. now_time = int(time.time())
  65. algorithm = AlgorithmBaseOn35()
  66. for i in range(quantity):
  67. serial_number = algorithm.getLetter(sum)
  68. sum += 1 # sum每次递增1
  69. # 前面补0至六位
  70. serial_number = (6 - len(serial_number)) * '0' + serial_number
  71. serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time))
  72. # 开启事务写入
  73. with transaction.atomic():
  74. SerialNumberModel.objects.bulk_create(serial_number_bulk)
  75. return response.json(0)
  76. except Exception as e:
  77. print(e)
  78. return response.json(500, repr(e))
  79. def do_list(self, userID, request_dict, response):
  80. # perm = ModelService.check_perm_uid_manage(userID, 0)
  81. # if not perm:
  82. # return response.json(309)
  83. page = request_dict.get('page', None)
  84. line = request_dict.get('limit', None)
  85. serial_number = request_dict.get('serial_number', None)
  86. status = request_dict.get('status', None)
  87. if page and line:
  88. page = int(page)
  89. line = int(line)
  90. serial_qs = SerialNumberModel.objects.filter().order_by('-id')
  91. if serial_number:
  92. serial_qs = serial_qs.filter(serial_number__contains=serial_number)
  93. if status:
  94. serial_qs = serial_qs.filter(status=status)
  95. count = serial_qs.count()
  96. start = (page - 1) * line
  97. end = start + line
  98. serial_qs = serial_qs[start: end].values()
  99. res = {
  100. 'count': count,
  101. 'data': list(serial_qs)
  102. }
  103. return response.json(0, res)
  104. else:
  105. return response.json(444)
  106. def do_attach_uid(self, request_dict, response, request):
  107. serial_number = request_dict.get('serial_number', None)
  108. country_id = request_dict.get('country_id', None)
  109. company_id = request_dict.get('company_id', None)
  110. token = request_dict.get('token', None)
  111. time_stamp = request_dict.get('time_stamp', None)
  112. DeviceSubType = request_dict.get('DeviceSubType', None)
  113. p2ptype = request_dict.get('p2ptype', 1)
  114. if not all([serial_number, company_id, token, time_stamp]):
  115. return response.json(444)
  116. token = int(CommonService.decode_data(token))
  117. time_stamp = int(time_stamp)
  118. now_time = int(time.time())
  119. distance = now_time - time_stamp
  120. if token != time_stamp or distance > 60000 or distance < -60000: # 为了全球化时间控制在一天内
  121. return response.json(404)
  122. serial = serial_number[0:6]
  123. full_serial = serial_number[0:9]
  124. if serial_number[9:10]:
  125. p2ptype = serial_number[9:10]
  126. try:
  127. if not country_id:
  128. ip = CommonService.get_ip_address(request)
  129. country_id = Device_Region().get_device_region(ip)
  130. # 判断序列号是否已和企业关联
  131. company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, serial_number=serial)
  132. if not company_serial_qs.exists():
  133. return response.json(173)
  134. # 当序列号已关联UID
  135. company_serial = company_serial_qs[0]
  136. if company_serial.status == 0: # 该序列号未绑定企业
  137. return response.json(173)
  138. elif company_serial.status == 1: # 绑定uid
  139. with transaction.atomic():
  140. count = 0
  141. while count < 3:
  142. # 查询是否存在未绑定序列号的uid
  143. uid_qs = UIDModel.objects.filter(vpg__company_id=company_serial.company.id,
  144. vpg__region_id=country_id, status=0, p2p_type=p2ptype). \
  145. order_by('id')
  146. if not uid_qs.exists():
  147. return response.json(173)
  148. uid = uid_qs[0]
  149. if DeviceSubType:
  150. # 获取最新的mac,判断分配到哪里,且进行绑定
  151. mac = MacModel.objects.filter().values('id', 'value', 'is_active')[0]
  152. current_mac = mac['value']
  153. username = 'cspublic@ansjer.com'
  154. if current_mac[-8:] == '1F:42:40': # 一组一共1048576个,此mac是第100w个时
  155. sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",此mac地址是当前组的第100w个,还剩下48576个可分配,mac地址即将用完。"
  156. S3Email().faEmail(sys_msg_text, username)
  157. elif current_mac[-8:] == '1F:90:60': # 此mac是第102w个时
  158. sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",此mac地址是当前组的第102w个,还剩下28576个可分配,mac地址即将用完。"
  159. S3Email().faEmail(sys_msg_text, username)
  160. elif not mac['is_active']:
  161. return response.json(175)
  162. elif current_mac[-8:] == '1F:FF:FF':
  163. MacModel.objects.filter().update(is_active=False) # 更改mac可使用的状态,当再此调用接口时使用上面条件进行阻止
  164. sys_msg_text = "当前国外uid管理系统mac地址已分配到" + current_mac + ",mac地址已分配使用完,请更换分组。"
  165. S3Email().faEmail(sys_msg_text, username)
  166. return response.json(175)
  167. UIDModel.objects.filter(id=uid.id).update(mac=current_mac) # 更新绑定uid的mac值
  168. # 绑定mac地址成功后更新mac表
  169. temp_mac = CommonService.updateMac(current_mac) # mac地址值+1;后3个字节为FF时返回None
  170. if temp_mac:
  171. current_mac = temp_mac # 更新赋值写入uid表
  172. else:
  173. temp_mac = current_mac # 赋值为FF写入mac表
  174. MacModel.objects.filter().update(value=temp_mac, add_time=now_time,
  175. update_time=now_time) # 更新mac表的mac地址值
  176. result = UIDModel.objects.filter(id=uid.id, status=0).\
  177. update(status=2, update_time=now_time)
  178. if int(result) <= 0: # 更新失败
  179. count += 1
  180. continue
  181. # UID关联【企业关联序列号】表创建数据
  182. UIDCompanySerialModel.objects.create(uid_id=uid.id, company_serial_id=company_serial.id,
  183. add_time=now_time, update_time=now_time)
  184. company_serial.status = 2
  185. company_serial.save()
  186. dev = Device_Info.objects.filter(UID=uid.uid)
  187. if dev.exists():
  188. dev.update(serial_number=full_serial)
  189. full_uid_code = uid.full_uid_code
  190. if uid.platform in CRCKey.keys():
  191. full_uid_code += ':'+CRCKey[uid.platform]
  192. res = {
  193. 'full_uid_code': CommonService.encode_data(full_uid_code),
  194. 'uid': CommonService.encode_data(uid.uid),
  195. 'mac': CommonService.encode_data(uid.mac),
  196. 'extra': uid.uid_extra,
  197. 'platform': uid.platform,
  198. 'initString': uid.init_string,
  199. 'initStringApp': uid.init_string_app,
  200. }
  201. # 记录操作日志
  202. ip = CommonService.get_ip_address(request)
  203. content = json.loads(json.dumps(request_dict))
  204. log = {
  205. 'ip': ip,
  206. 'user_id': 1,
  207. 'status': 200,
  208. 'time': now_time,
  209. 'content': json.dumps(content),
  210. 'url': 'serialNumber/attachUID',
  211. 'operation': '序列号{}绑定uid: {}'.format(serial, uid.uid),
  212. }
  213. LogModel.objects.create(**log)
  214. return response.json(0, res)
  215. return response.json(5)
  216. else: # 返回uid
  217. uid_qs = UIDCompanySerialModel.objects.filter(company_serial_id=company_serial.id)
  218. if not uid_qs.exists():
  219. return response.json(173)
  220. uid = uid_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__full_uid_code',
  221. 'uid__platform', 'uid__init_string', 'uid__init_string_app')[0]
  222. full_uid_code = uid['uid__full_uid_code']
  223. if uid['uid__platform'] in CRCKey.keys():
  224. full_uid_code += ':'+CRCKey[uid['uid__platform']]
  225. res = {
  226. 'full_uid_code': CommonService.encode_data(full_uid_code),
  227. 'uid': CommonService.encode_data(uid['uid__uid']),
  228. 'mac': CommonService.encode_data(uid['uid__mac']),
  229. 'extra': uid['uid__uid_extra'],
  230. 'platform': uid['uid__platform'],
  231. 'initString': uid['uid__init_string'],
  232. 'initStringApp': uid['uid__init_string_app'],
  233. }
  234. return response.json(0, res)
  235. except Exception as e:
  236. djangoLogger = logging.getLogger('django')
  237. djangoLogger.exception(repr(e))
  238. return response.json(176, str(e))
  239. def do_get_uid(self, request_dict, response):
  240. serial_number = request_dict.get('serial_number', None)
  241. token = request_dict.get('token', None)
  242. time_stamp = request_dict.get('time_stamp', None)
  243. if token and time_stamp and serial_number :
  244. token = int(CommonService.decode_data(token))
  245. time_stamp = int(time_stamp)
  246. now_time = int(time.time())
  247. distance = now_time - time_stamp
  248. if token != time_stamp or distance > 60000 or distance < -60000: # 为了全球化时间控制在一天内
  249. return response.json(404)
  250. mark = serial_number[6:9]
  251. serial = serial_number[0:6]
  252. uid_company_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__company__mark=mark,
  253. company_serial__serial_number__serial_number=serial)
  254. if uid_company_serial_qs.exists():
  255. uid = uid_company_serial_qs.values('uid__uid', 'uid__mac', 'uid__uid_extra')[0]
  256. res = {
  257. 'uid': CommonService.encode_data(uid['uid__uid']),
  258. 'mac': CommonService.encode_data(uid['uid__mac']),
  259. 'extra': uid['uid__uid_extra']
  260. }
  261. return response.json(0, res)
  262. else:
  263. return response.json(173)
  264. else:
  265. return response.json(444)
  266. def do_detach_uid(self, request, request_dict, response):
  267. token = request_dict.get('token', None)
  268. time_stamp = request_dict.get('time_stamp', None)
  269. serial_number = request_dict.get('serial_number', None)
  270. if not all([token, time_stamp, serial_number]):
  271. return response.json(444)
  272. token = int(CommonService.decode_data(token))
  273. time_stamp = int(time_stamp)
  274. now_time = int(time.time())
  275. distance = now_time - time_stamp
  276. if token != time_stamp or distance > 60000 or distance < -60000: # 为了全球化时间控制在一天内
  277. return response.json(404)
  278. serial = serial_number[0:6]
  279. uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number=serial)
  280. if not uid_serial_qs.exists():
  281. return response.json(173)
  282. uid_serial = uid_serial_qs[0]
  283. try:
  284. with transaction.atomic():
  285. # 删除iot设备信息表数据
  286. iot = iotdeviceInfoModel.objects.filter(serial_number=serial)
  287. if iot.exists():
  288. iot.delete()
  289. uid = uid_serial.uid.uid
  290. company_serial_qs = CompanySerialModel.objects.filter(id=uid_serial.company_serial.id)
  291. if company_serial_qs.exists():
  292. company_serial = company_serial_qs[0]
  293. company_serial.status = 1
  294. company_serial.save()
  295. dv_qs = Device_Info.objects.filter(UID=uid)
  296. if dv_qs.exists():
  297. # 删除设备
  298. dv_qs.delete()
  299. # 删除设备影子信息uid_set 外键关联删除设备推送配置信息 uid_push
  300. up_qs = UidPushModel.objects.filter(uid_set__uid=uid)
  301. DetectControllerView().do_delete_redis(uid)
  302. if up_qs.count() > 1:
  303. UidPushModel.objects.filter(uid_set__uid=uid).delete()
  304. else:
  305. up_qs.delete()
  306. UIDModel.objects.filter(uid=uid).update(status=0, mac='') # 重置uid的使用状态为未分配
  307. uid_serial.delete()
  308. # 记录操作日志
  309. ip = CommonService.get_ip_address(request)
  310. content = json.loads(json.dumps(request_dict))
  311. log = {
  312. 'ip': ip,
  313. 'user_id': 1,
  314. 'status': 200,
  315. 'time': now_time,
  316. 'content': json.dumps(content),
  317. 'url': 'serialNumber/detachUID',
  318. 'operation': '序列号{}解绑uid: {}'.format(serial, uid),
  319. }
  320. LogModel.objects.create(**log)
  321. return response.json(0)
  322. except Exception as e:
  323. djangoLogger = logging.getLogger('django')
  324. djangoLogger.exception(repr(e))
  325. return response.json(176, str(e))
  326. def do_update(self, userID, request_dict, response):
  327. # perm = ModelService.check_perm_uid_manage(userID, 0)
  328. # if not perm:
  329. # return response.json(309)
  330. id = request_dict.get('id', None)
  331. status = request_dict.get('status', None)
  332. if id and status:
  333. serial_number_qs = SerialNumberModel.objects.filter(id=id)
  334. if serial_number_qs.exists():
  335. serial_number_qs.update(**{'status': status})
  336. return response.json(0)
  337. else:
  338. return response.json(173)
  339. else:
  340. return response.json(444)