SerialNumberController.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. import json
  2. import logging
  3. import time
  4. import requests
  5. from bulk_update.helper import bulk_update
  6. from django.db import transaction
  7. from django.views import View
  8. from Model.models import SerialNumberModel, UserModel, UserSerialNumberModel, CompanySerialModel, \
  9. MacModel, LogModel, CompanyModel
  10. from Object.RedisObject import RedisObject
  11. from Object.ResponseObject import ResponseObject
  12. from Object.TokenObject import TokenObject
  13. from Service.AlgorithmService import AlgorithmBaseOn35
  14. from Service.CommonService import CommonService
  15. class SerialNumberView(View):
  16. def get(self, request, *args, **kwargs):
  17. request.encoding = 'utf-8'
  18. request_dict = request.GET
  19. operation = kwargs.get('operation')
  20. return self.validate(request_dict, operation, request)
  21. def post(self, request, *args, **kwargs):
  22. request.encoding = 'utf-8'
  23. request_dict = request.POST
  24. operation = kwargs.get('operation')
  25. return self.validate(request_dict, operation, request)
  26. def validate(self, request_dict, operation, request):
  27. response = ResponseObject()
  28. if operation == 'create':
  29. return self.do_create(request_dict, response)
  30. elif operation == 'getSerial': # 获取序列号
  31. return self.get_serial(request_dict, response)
  32. token = request_dict.get('token', None)
  33. token = TokenObject(token)
  34. if token.code != 0:
  35. return response.json(token.code)
  36. if operation == 'quantity': # 查询当前可用的UID的数量
  37. return self.do_quantity(token.userID, response)
  38. elif operation == 'allot': # 分配序列号
  39. return self.do_allot(request_dict, response)
  40. elif operation == 'createSerial': # 生成序列号
  41. return self.create_serial(request_dict, response, request, token.userID)
  42. elif operation == 'serialCompany': # 将序列号分匹配到指定企业
  43. return self.do_serial_company(request_dict, response, request, token.userID)
  44. elif operation == 'revise/state': # 修改序列号状态
  45. return self.revise_state(request_dict, response, request)
  46. else:
  47. return response.json(309)
  48. def revise_state(self, request_dict, response, request):
  49. """
  50. 修改序列号状态
  51. @param request_dict:请求参数
  52. @param response: 响应对象
  53. """
  54. use_status = request_dict.get('useStatus', None) # 序列号表的状态
  55. status = request_dict.get('status', None) # 关联企业序列号表的状态
  56. if not all([use_status, status]):
  57. return response.json(444)
  58. serial_number_qs = SerialNumberModel.objects.filter(use_status=use_status).values('serial_number')
  59. if not serial_number_qs.exists():
  60. return response.json(173)
  61. serial_list = [item[key] for item in serial_number_qs for key in item]
  62. try:
  63. country_serial_qs = CompanySerialModel.objects.filter(serial_number__in=serial_list).values('status')
  64. country_serial_qs.filter(status=status).update(status=2)
  65. return response.json(0)
  66. except Exception as e:
  67. print(e)
  68. return response.json(500)
  69. def do_serial_company(self, request_dict, response, request, user_id):
  70. """
  71. 将序列号分匹配到指定企业
  72. :param request_dict: 请求参数
  73. :param response: 响应对象
  74. :param request: 请求
  75. :param user_id: 用户id
  76. :return:
  77. """
  78. id = request_dict.get('id', None)
  79. quantity = request_dict.get('quantity', None)
  80. if not all([id, quantity]):
  81. return response.json(444)
  82. company_qs = CompanyModel.objects.filter(id=id)
  83. if not company_qs.exists():
  84. return response.json(444)
  85. sum_Serial = SerialNumberModel.objects.filter().count()
  86. sum_Serial_company = CompanySerialModel.objects.filter().count()
  87. sum_bind = sum_Serial - sum_Serial_company # 剩余可绑定的序列号
  88. if int(quantity) > int(sum_bind):
  89. return response.json(10041)
  90. try:
  91. company = company_qs[0]
  92. start_1 = sum_Serial_company
  93. end_1 = int(start_1) + int(quantity)
  94. serial_qs = SerialNumberModel.objects.filter()[start_1:end_1]
  95. if not serial_qs.exists():
  96. return response.json(173)
  97. company_serial_bulk = []
  98. now_time = int(time.time())
  99. for item in serial_qs: # 更新状态为已分配但未使用
  100. company_serial_bulk.append(CompanySerialModel(
  101. status=3,
  102. add_time=now_time,
  103. update_time=now_time,
  104. company_id=company.id,
  105. serial_number=item.serial_number,
  106. ))
  107. SerialNumberModel.objects.filter(serial_number=item.serial_number).update(
  108. use_status=3,
  109. add_time=now_time
  110. )
  111. # 记录操作日志
  112. ip = CommonService.get_ip_address(request)
  113. content = json.loads(json.dumps(request_dict))
  114. log = {
  115. 'ip': ip,
  116. 'user_id': user_id,
  117. 'status': 200,
  118. 'time': now_time,
  119. 'url': 'serialNumber/serialCompany',
  120. 'content': json.dumps(content),
  121. 'operation': '{}生成{}个序列号{}: {}'.format(company.name, quantity, '成功', '同步更新成功'),
  122. }
  123. with transaction.atomic():
  124. CompanySerialModel.objects.bulk_create(company_serial_bulk)
  125. company.quantity = CompanySerialModel.objects.filter(company_id=id).count()
  126. company.save()
  127. Log = LogModel.objects.create(**log)
  128. # 同步更新业务服务器和uid管理系统的企业序列号表
  129. url1 = 'http://test.zositechc.cn/company/createSerial'
  130. url2 = 'https://www.zositechc.cn/company/createSerial'
  131. url3 = 'http://www.dvema.com/company/createSerial'
  132. # url4 = 'http://www.zositeche.com/company/createSerial'
  133. requests_data = {'id': id, 'quantity': quantity}
  134. res1 = requests.post(url=url1, data=requests_data, timeout=2 * 60)
  135. if res1.status_code != 200:
  136. fail_reason = '请求测试服务器生成序列号响应状态码异常'
  137. return self.failResponse(company.name, quantity, fail_reason, Log, response)
  138. res1 = res1.json()
  139. if res1['result_code'] != 0:
  140. fail_reason = '测试服务器生成序列号发生异常'
  141. return self.failResponse(company.name, quantity, fail_reason, Log, response)
  142. res2 = requests.post(url=url2, data=requests_data, timeout=2 * 60)
  143. if res2.status_code != 200:
  144. fail_reason = '请求国内服务器生成序列号响应状态码异常'
  145. return self.failResponse(company.name, quantity, fail_reason, Log, response)
  146. res2 = res2.json()
  147. if res2['result_code'] != 0:
  148. fail_reason = '国内服务器生成序列号发生异常'
  149. return self.failResponse(company.name, quantity, fail_reason, Log, response)
  150. res3 = requests.post(url=url3, data=requests_data, timeout=2 * 60)
  151. if res3.status_code != 200:
  152. fail_reason = '请求美国服务器生成序列号响应状态码异常'
  153. return self.failResponse(company.name, quantity, fail_reason, Log, response)
  154. res3 = res3.json()
  155. if res3['result_code'] != 0:
  156. fail_reason = '美国服务器生成序列号发生异常'
  157. return self.failResponse(company.name, quantity, fail_reason, Log, response)
  158. # res4 = requests.post(url=url4, data=requests_data, timeout=2 * 60)
  159. # if res4.status_code != 200:
  160. # fail_reason = '请求欧洲服务器生成序列号响应状态码异常'
  161. # return self.failResponse(company.name, quantity, fail_reason, Log, response)
  162. # res4 = res4.json()
  163. # if res4['code'] != 0:
  164. # fail_reason = '欧洲服务器生成序列号发生异常'
  165. # return self.failResponse(company.name, quantity, fail_reason, Log, response)
  166. return response.json(0)
  167. except Exception as e:
  168. djangoLogger = logging.getLogger('django')
  169. djangoLogger.exception(repr(e))
  170. return response.json(176)
  171. def failResponse(self, company_name, quantity, fail_reason, Log, response):
  172. operation = '{}生成{}个序列号{}: {}'.format(company_name, quantity, '失败', fail_reason)
  173. Log.operation = operation
  174. Log.save()
  175. return response.json(177)
  176. def create_serial(self, request_dict, response, request, user_id):
  177. """
  178. 生成序列号
  179. :param request_dict: 请求参数
  180. :param response: 响应对象
  181. :param request: 请求
  182. :param user_id: 用户id
  183. :return:
  184. """
  185. quantity = int(request_dict.get('quantity', 0))
  186. if not quantity:
  187. return response.json(444)
  188. try:
  189. try:
  190. sum = SerialNumberModel.objects.last().id
  191. except:
  192. sum = 0
  193. serial_number_bulk = []
  194. now_time = int(time.time())
  195. algorithm = AlgorithmBaseOn35()
  196. for i in range(quantity):
  197. serial_number = algorithm.getLetter(sum)
  198. sum += 1 # sum每次递增1
  199. # 前面补0至六位
  200. serial_number = (6 - len(serial_number)) * '0' + serial_number
  201. serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time))
  202. # 记录操作日志
  203. ip = CommonService.get_ip_address(request)
  204. content = json.loads(json.dumps(request_dict))
  205. log = {
  206. 'ip': ip,
  207. 'user_id': user_id,
  208. 'status': 200,
  209. 'time': now_time,
  210. 'url': 'serialNumber/createSerial',
  211. 'content': json.dumps(content),
  212. 'operation': '生成{}个序列号{}: {}'.format(quantity, '成功', '同步更新成功'),
  213. }
  214. # 开启事务写入
  215. with transaction.atomic():
  216. SerialNumberModel.objects.bulk_create(serial_number_bulk)
  217. Log = LogModel.objects.create(**log)
  218. # 同步更新业务服务器和uid管理系统的序列号表
  219. url1 = 'http://test.zositechc.cn/serialNumber/create'
  220. url2 = 'https://www.zositechc.cn/serialNumber/create'
  221. url3 = 'http://www.dvema.com/serialNumber/create'
  222. # url4 = 'http://www.zositeche.com/company/createSerial'
  223. requests_data = {'quantity': quantity}
  224. res1 = requests.post(url=url1, data=requests_data, timeout=2 * 60)
  225. if res1.status_code != 200:
  226. fail_reason = '请求测试服务器生成序列号响应状态码异常'
  227. return self.generateFail(quantity, fail_reason, Log, response)
  228. res1 = res1.json()
  229. if res1['result_code'] != 0:
  230. fail_reason = '测试服务器生成序列号发生异常'
  231. return self.generateFail(quantity, fail_reason, Log, response)
  232. res2 = requests.post(url=url2, data=requests_data, timeout=2 * 60)
  233. if res2.status_code != 200:
  234. fail_reason = '请求国内服务器生成序列号响应状态码异常'
  235. return self.generateFail(quantity, fail_reason, Log, response)
  236. res2 = res2.json()
  237. if res2['result_code'] != 0:
  238. fail_reason = '国内服务器生成序列号发生异常'
  239. return self.generateFail(quantity, fail_reason, Log, response)
  240. res3 = requests.post(url=url3, data=requests_data, timeout=2 * 60)
  241. if res3.status_code != 200:
  242. fail_reason = '请求美国服务器生成序列号响应状态码异常'
  243. return self.generateFail(quantity, fail_reason, Log, response)
  244. res3 = res3.json()
  245. if res3['result_code'] != 0:
  246. fail_reason = '美国服务器生成序列号发生异常'
  247. return self.generateFail(quantity, fail_reason, Log, response)
  248. # res4 = requests.post(url=url4, data=requests_data, timeout=2 * 60)
  249. # if res4.status_code != 200:
  250. # fail_reason = '请求欧洲服务器生成序列号响应状态码异常'
  251. # return self.generateFail(quantity, fail_reason, Log, response)
  252. # res4 = res4.json()
  253. # if res4['code'] != 0:
  254. # fail_reason = '欧洲服务器生成序列号发生异常'
  255. # return self.generateFail(quantity, fail_reason, Log, response)
  256. return response.json(0)
  257. except Exception as e:
  258. djangoLogger = logging.getLogger('django')
  259. djangoLogger.exception(repr(e))
  260. return response.json(176)
  261. def generateFail(self, quantity, fail_reason, Log, response):
  262. operation = '生成{}个序列号{}: {}'.format(quantity, '失败', fail_reason)
  263. Log.operation = operation
  264. Log.save()
  265. return response.json(177)
  266. def do_quantity(self, userID, response):
  267. """
  268. 查询当前可用的UID的数量
  269. :param userID: 响应对象
  270. :param response: 请求
  271. :return:
  272. """
  273. user_qs = UserModel.objects.filter(id=userID)
  274. if not user_qs.exists():
  275. return response.json(9)
  276. unused_serial_number_count = SerialNumberModel.objects.filter(use_status=0).count()
  277. remain_qs = CompanySerialModel.objects.filter(status=1).count()
  278. company_qs = CompanyModel.objects.values('id', 'name')
  279. try:
  280. company_serial_list = [] # 剩余已分配未使用的序列号数量
  281. company_not_used_list = [] # 已使用的序列号数量
  282. for company in company_qs:
  283. id = company['id']
  284. name = company['name']
  285. not_used_qs = CompanySerialModel.objects.filter(status=3, company_id=id).count()
  286. res = {
  287. 'name': name,
  288. 'number': not_used_qs
  289. }
  290. company_not_used_list.append(res)
  291. for company in company_qs:
  292. id = company['id']
  293. name = company['name']
  294. count = CompanySerialModel.objects.filter(status=1, company_id=id).count()
  295. # 获取最后一个序列号
  296. if count == 0:
  297. last_serial = ''
  298. else:
  299. last_serial = CompanySerialModel.objects.filter(status=1, company_id=id).order_by('-id').values(
  300. 'serial_number')[:1][0]['serial_number']
  301. res = {
  302. 'name': name,
  303. 'numbers': count,
  304. 'lastSerial': last_serial
  305. }
  306. company_serial_list.append(res)
  307. res_data = {'code': 0, 'companyRemainCount': company_not_used_list, 'companyRemain': company_serial_list,
  308. 'unused_serial_number_count': unused_serial_number_count,
  309. 'unused_all_count': remain_qs}
  310. return response.json(0, {'data': res_data})
  311. except Exception as e:
  312. print(e)
  313. return response.json(500)
  314. def do_create(self, request_dict, response):
  315. quantity = int(request_dict.get('quantity', 0))
  316. if not quantity:
  317. return response.json(444)
  318. try:
  319. try:
  320. sum = SerialNumberModel.objects.last().id
  321. except:
  322. sum = 0
  323. serial_number_bulk = []
  324. now_time = int(time.time())
  325. algorithm = AlgorithmBaseOn35()
  326. for i in range(quantity):
  327. serial_number = algorithm.getLetter(sum)
  328. sum += 1 # sum每次递增1
  329. # 前面补0至六位
  330. serial_number = (6 - len(serial_number)) * '0' + serial_number
  331. serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time))
  332. # 开启事务写入
  333. with transaction.atomic():
  334. SerialNumberModel.objects.bulk_create(serial_number_bulk)
  335. return response.json(0)
  336. except Exception as e:
  337. print(e)
  338. return response.json(500, repr(e))
  339. @transaction.atomic
  340. def do_allot(self, request_dict, response):
  341. username = request_dict.get('username', None)
  342. quantity = int(request_dict.get('quantity', None))
  343. token = request_dict.get('token', None)
  344. token = TokenObject(token)
  345. if token.code != 0:
  346. return response.json(token.code)
  347. user = UserModel.objects.get(id=token.userID)
  348. if not user or '0' not in user.permission:
  349. return response.json(404)
  350. # 要分配的对象
  351. allot_user_qs = UserModel.objects.filter(username=username)
  352. if not allot_user_qs.exists():
  353. return response.json(444, 'username')
  354. # 取出对应区域可用的UID分配给allot_user
  355. sn_qs = SerialNumberModel.objects.filter(use_status=3)[0:quantity]
  356. sns = []
  357. for sn in sn_qs:
  358. sns.append(sn.serial_number)
  359. cs_qs = CompanySerialModel.objects.filter(serial_number__in=sns, status=3)
  360. sns = []
  361. for cs in cs_qs:
  362. sns.append(cs.serial_number)
  363. sn_qs = SerialNumberModel.objects.filter(serial_number__in=sns)
  364. count = sn_qs.count()
  365. if count < quantity:
  366. return response.json(444, '序列号不足')
  367. try:
  368. updates = []
  369. datas = []
  370. if not sn_qs.exists():
  371. return response.json(444)
  372. sn_qs = sn_qs[0:quantity]
  373. now_time = int(time.time())
  374. for i in range(len(sn_qs)):
  375. item = sn_qs[i]
  376. serialNumberModel = SerialNumberModel(
  377. id=item.id,
  378. serial_number=item.serial_number,
  379. status=item.status,
  380. use_status=1,
  381. add_time=item.add_time
  382. )
  383. CompanySerialModel.objects.filter(serial_number=item.serial_number).update(status=1)
  384. user_serial_number = UserSerialNumberModel()
  385. user_serial_number.serial_number = serialNumberModel
  386. user_serial_number.user = allot_user_qs[0]
  387. user_serial_number.add_time = now_time
  388. user_serial_number.update_time = now_time
  389. datas.append(user_serial_number)
  390. updates.append(serialNumberModel)
  391. if len(updates) > 0:
  392. bulk_update(updates)
  393. UserSerialNumberModel.objects.bulk_create(datas)
  394. return response.json(0)
  395. except Exception as e:
  396. print(e)
  397. return response.json(500)
  398. @staticmethod
  399. def get_serial(request_dict, response):
  400. """
  401. 获取序列号
  402. @param request_dict: 请求数据
  403. @param response: 响应
  404. @return: response
  405. """
  406. token = request_dict.get('token', None)
  407. time_stamp = request_dict.get('time_stamp', None)
  408. company_secret = request_dict.get('company_id', None)
  409. if not all([token, time_stamp, company_secret]):
  410. return response.json(444)
  411. # 时间戳token校验
  412. if not CommonService.check_time_stamp_token(token, time_stamp):
  413. return response.json(13)
  414. redis_obj = RedisObject()
  415. # redis加锁,防止同时进行其他操作
  416. serial_operate_lock_key = 'serial_operate_lock'
  417. serial_operate_lock = redis_obj.CONN.setnx(serial_operate_lock_key, 1)
  418. if not serial_operate_lock:
  419. return response.json(5)
  420. redis_obj.CONN.expire(serial_operate_lock_key, 60)
  421. # 查询可用的序列号
  422. company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_secret, status=1).first()
  423. if company_serial_qs is None:
  424. redis_obj.del_data(key=serial_operate_lock_key) # redis解锁
  425. return response.json(14)
  426. serial_number = company_serial_qs.serial_number
  427. company_mark = company_serial_qs.company.mark
  428. user_serial_number_qs = UserSerialNumberModel.objects.filter(user__id=3,
  429. serial_number__serial_number=serial_number,
  430. serial_number__use_status=1)
  431. if not user_serial_number_qs.exists():
  432. redis_obj.del_data(key=serial_operate_lock_key) # redis解锁
  433. return response.json(14)
  434. # 防止重复获取序列号
  435. serial_number_lock = redis_obj.CONN.setnx(serial_number + 'serial_number_lock', 1)
  436. redis_obj.CONN.expire(serial_number + 'serial_number_lock', 60)
  437. if not serial_number_lock:
  438. return response.json(5)
  439. # 获取mac
  440. mac_qs = MacModel.objects.filter(is_active=True).values('value')
  441. if not mac_qs.exists():
  442. return response.json(175)
  443. mac = mac_qs[0]['value']
  444. # 绑定mac地址成功后更新mac表
  445. next_mac = CommonService.updateMac(mac)
  446. now_time = int(time.time())
  447. mac_data = {
  448. 'update_time': now_time
  449. }
  450. if next_mac:
  451. mac_data['value'] = next_mac
  452. else:
  453. mac_data['is_active'] = False
  454. # 操作日志数据
  455. operation = '获取序列号:{}'.format(serial_number)
  456. log = {
  457. 'user_id': 3,
  458. 'time': now_time,
  459. 'operation': operation,
  460. 'url': 'serialNumber/getSerial',
  461. }
  462. try:
  463. with transaction.atomic():
  464. # 更新和创建数据
  465. MacModel.objects.filter().update(**mac_data)
  466. SerialNumberModel.objects.filter(serial_number=serial_number).update(use_status=2, add_time=now_time)
  467. CompanySerialModel.objects.filter(serial_number=serial_number).update(status=2, update_time=now_time)
  468. LogModel.objects.create(**log)
  469. redis_obj.del_data(key=serial_operate_lock_key) # redis解锁
  470. return response.json(0, {'serial_number': serial_number + company_mark, 'mac': mac})
  471. except Exception as e:
  472. redis_obj.del_data(key=serial_operate_lock_key) # redis解锁
  473. return response.json(500, repr(e))