SerialNumberController.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import json
  4. import logging
  5. import random
  6. import time
  7. from bulk_update.helper import bulk_update
  8. from django.db import transaction
  9. from django.db.models import Count
  10. from django.views import View
  11. from Model.models import SerialNumberModel, UserModel, UserSerialNumberModel, UserUIDModel, CompanySerialModel, \
  12. MacModel, LogModel
  13. from Object.RedisObject import RedisObject
  14. from Object.ResponseObject import ResponseObject
  15. from Object.TokenObject import TokenObject
  16. from Service.AlgorithmService import AlgorithmBaseOn35
  17. from Service.CommonService import CommonService
  18. from Service.ModelService import ModelService
  19. class SerialNumberView(View):
  20. def get(self, request, *args, **kwargs):
  21. request.encoding = 'utf-8'
  22. request_dict = request.GET
  23. operation = kwargs.get('operation')
  24. return self.validate(request_dict, operation, request)
  25. def post(self, request, *args, **kwargs):
  26. request.encoding = 'utf-8'
  27. request_dict = request.POST
  28. operation = kwargs.get('operation')
  29. return self.validate(request_dict, operation, request)
  30. def validate(self, request_dict, operation, request):
  31. response = ResponseObject()
  32. if operation == 'create':
  33. return self.do_create(request_dict, response)
  34. elif operation == 'getSerial':
  35. return self.do_get_serial_number(request_dict, request, response)
  36. token = request_dict.get('token', None)
  37. token = TokenObject(token)
  38. if token.code != 0:
  39. return response.json(token.code)
  40. if operation == 'quantity':
  41. return self.do_quantity(request_dict,token.userID, response)
  42. elif operation == 'allot':
  43. return self.do_allot(request_dict, response)
  44. else:
  45. return response.json(309)
  46. # 查询当前可用的UID的数量
  47. def do_quantity(self, request_dict, userID, response):
  48. user_qs = UserModel.objects.filter(id=userID)
  49. if not user_qs.exists():
  50. return response.json(9)
  51. user = user_qs[0]
  52. result = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__use_status=1).aggregate(num=Count('serial_number__use_status'))
  53. chenyundev = result['num']
  54. unused_serial_number_count = SerialNumberModel.objects.filter(use_status=0).count()
  55. chenyun = SerialNumberModel.objects.filter(use_status=1).count()
  56. res_data = {'code': 0, 'chenyun': chenyun, 'unused_serial_number_count': unused_serial_number_count, 'chenyundev': chenyundev}
  57. return response.json(0, {'data': res_data})
  58. def do_create(self, request_dict, response):
  59. quantity = int(request_dict.get('quantity', 0))
  60. if not quantity:
  61. return response.json(444)
  62. try:
  63. try:
  64. sum = SerialNumberModel.objects.last().id
  65. except:
  66. sum = 0
  67. serial_number_bulk = []
  68. now_time = int(time.time())
  69. algorithm = AlgorithmBaseOn35()
  70. for i in range(quantity):
  71. serial_number = algorithm.getLetter(sum)
  72. sum += 1 # sum每次递增1
  73. # 前面补0至六位
  74. serial_number = (6-len(serial_number))*'0' + serial_number
  75. serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time))
  76. # 开启事务写入
  77. with transaction.atomic():
  78. SerialNumberModel.objects.bulk_create(serial_number_bulk)
  79. return response.json(0)
  80. except Exception as e:
  81. print(e)
  82. return response.json(500, repr(e))
  83. # 分配序列号
  84. @transaction.atomic
  85. def do_allot(self, request_dict, response):
  86. username = request_dict.get('username', None)
  87. quantity = int(request_dict.get('quantity', None))
  88. token = request_dict.get('token', None)
  89. token = TokenObject(token)
  90. if token.code != 0:
  91. return response.json(token.code)
  92. user = UserModel.objects.get(id=token.userID)
  93. if not user or '0' not in user.permission:
  94. return response.json(404)
  95. # 要分配的对象
  96. allot_user_qs = UserModel.objects.filter(username=username)
  97. if not allot_user_qs.exists():
  98. return response.json(444, 'username')
  99. # 取出对应区域可用的UID分配给allot_user
  100. sn_qs = SerialNumberModel.objects.filter(use_status=0)[0:quantity]
  101. sns = []
  102. for sn in sn_qs:
  103. sns.append(sn.serial_number)
  104. cs_qs = CompanySerialModel.objects.filter(serial_number__in=sns, status=1)
  105. sns = []
  106. for cs in cs_qs:
  107. sns.append(cs.serial_number)
  108. sn_qs = SerialNumberModel.objects.filter(serial_number__in=sns)
  109. count = sn_qs.count()
  110. if count < quantity:
  111. return response.json(444, '序列号不足')
  112. updates = []
  113. datas = []
  114. count = 0
  115. if sn_qs.exists():
  116. sn_qs = sn_qs[0:quantity]
  117. now_time = int(time.time())
  118. for i in range(len(sn_qs)):
  119. item = sn_qs[i]
  120. serialNumberModel = SerialNumberModel(
  121. id=item.id,
  122. serial_number=item.serial_number,
  123. status=item.status,
  124. use_status=1,
  125. add_time=item.add_time
  126. )
  127. user_serial_number = UserSerialNumberModel()
  128. user_serial_number.serial_number = serialNumberModel
  129. user_serial_number.user = allot_user_qs[0]
  130. user_serial_number.add_time = now_time
  131. user_serial_number.update_time = now_time
  132. datas.append(user_serial_number)
  133. updates.append(serialNumberModel)
  134. if len(updates) % 5000 == 0:
  135. bulk_update(updates)
  136. UserSerialNumberModel.objects.bulk_create(datas)
  137. if len(updates) > 0:
  138. bulk_update(updates)
  139. UserSerialNumberModel.objects.bulk_create(datas)
  140. del datas
  141. del updates
  142. return response.json(0)
  143. else:
  144. return response.json(444)
  145. # 提供给pc端获取序列号
  146. def do_get_serial_number(self, request_dict, request, response):
  147. quantity = 1 #只能取一个
  148. company_id = request_dict.get('company_id', None)
  149. token = request_dict.get('token', None)
  150. time_stamp = request_dict.get('time_stamp', None)
  151. mac = request_dict.get('mac', None)
  152. if not all([token, time_stamp, company_id]):
  153. return response.json(444)
  154. token = int(CommonService.decode_data(token))
  155. time_stamp = int(time_stamp)
  156. now_time = int(time.time())
  157. distance = now_time - time_stamp
  158. if token != time_stamp or distance > 60000 or distance < -60000: # 为了全球化时间控制在一天内
  159. return response.json(404)
  160. redisObject = RedisObject()
  161. key = 'serial_lock'
  162. value = redisObject.lpop(key)
  163. count = 0
  164. while value is False and count < 5:
  165. time.sleep(1)
  166. value = redisObject.lpop(key)
  167. count += 1
  168. if count == 5 and value is False: # 暂时注释
  169. return response.json(5)
  170. userid = '3'
  171. user_qs = UserModel.objects.filter(id=userid)
  172. if not user_qs.exists():
  173. redisObject.rpush(key, value)
  174. return response.json(9)
  175. user = user_qs[0]
  176. result = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__use_status=1).\
  177. aggregate(num=Count('serial_number__use_status'))
  178. us_qs = UserSerialNumberModel.objects.filter(user__id=user.id, serial_number__use_status=1).\
  179. values('serial_number__serial_number')
  180. sns = []
  181. for us in us_qs:
  182. sns.append(us['serial_number__serial_number'])
  183. cs_qs = CompanySerialModel.objects.filter(serial_number__in=sns, status=1, company__secret=company_id).values('serial_number', 'company__mark')
  184. sns = []
  185. mark = ""
  186. if cs_qs.exists():
  187. for cs in cs_qs:
  188. sns.append(cs['serial_number'])
  189. mark = cs_qs[0]['company__mark']
  190. sn_qs = SerialNumberModel.objects.filter(serial_number__in=sns)
  191. if not sn_qs.exists():
  192. return response.json(444, '序列号不足')
  193. count = result['num']
  194. if count < quantity:
  195. redisObject.rpush(key, value)
  196. return response.json(444, '序列号不足')
  197. try:
  198. with transaction.atomic(): # 开启事务
  199. sn_qs = sn_qs[0: quantity]
  200. serial_number = sn_qs[0].serial_number
  201. # 防止重复获取序列号
  202. is_lock = redisObject.CONN.setnx(serial_number + 'serial_number_lock', 1)
  203. redisObject.CONN.expire(serial_number + 'serial_number_lock', 60)
  204. if not is_lock:
  205. return response.json(5)
  206. if not mac: # 不传入则分配mac
  207. mac_qs = MacModel.objects.filter().values('id', 'value', 'is_active')[0]
  208. if not mac_qs['is_active']:
  209. return response.json(175)
  210. mac = mac_qs['value']
  211. # 绑定mac地址成功后更新mac表
  212. next_mac = CommonService.updateMac(mac) # mac地址值+1;后3个字节为FF时返回None
  213. if next_mac:
  214. MacModel.objects.filter().update(value=next_mac, update_time=now_time) # 更新mac表的mac地址值
  215. else:
  216. MacModel.objects.filter().update(is_active=False, update_time=now_time)
  217. # 更新序列号表数据
  218. serialNumberModel = SerialNumberModel(
  219. id=sn_qs[0].id,
  220. serial_number=serial_number,
  221. status=sn_qs[0].status,
  222. use_status=2,
  223. add_time=now_time
  224. )
  225. updates = []
  226. updates.append(serialNumberModel)
  227. bulk_update(updates)
  228. # 记录操作日志
  229. ip = CommonService.get_ip_address(request)
  230. content = json.loads(json.dumps(request.POST))
  231. operation = '获取序列号:{}'.format(serial_number)
  232. log = {
  233. 'status': 200,
  234. 'content': json.dumps(content),
  235. 'ip': ip,
  236. 'time': now_time,
  237. 'url': 'serialNumber/getSerial',
  238. 'operation': operation,
  239. 'user': user_qs[0]
  240. }
  241. LogModel.objects.create(**log)
  242. redisObject.rpush(key, value)
  243. return response.json(0, {'serial_number': serial_number + mark, 'mac': mac})
  244. except Exception as e:
  245. return response.json(500, repr(e))