views.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import logging
  5. import time
  6. import simplejson as json
  7. from django.conf import settings
  8. from django.views.decorators.http import require_POST
  9. from typing import TYPE_CHECKING, Optional
  10. from apilib.monetary import VirtualCoin
  11. from apilib.utils_json import JsonResponse
  12. from apps.web.ad.models import Advertisement
  13. from apps.web.agent.models import Agent
  14. from apps.web.common.proxy import ClientRechargeModelProxy
  15. from apps.web.common.transaction.pay import OrderCacheMgr
  16. from apps.web.constant import Const, AppPlatformType, PollRecordDefine
  17. from apps.web.core import PayAppType, ROLE
  18. from apps.web.core.utils import JsonErrorResponse, DefaultJsonErrorResponse, JsonOkResponse
  19. from apps.web.dealer.models import Dealer
  20. from apps.web.device.models import Device, Group
  21. from apps.web.helpers import get_wechat_mini_env_pay_gateway, get_alipay_env_pay_gateway
  22. from apps.web.services.bluetooth.service import StartService, FinishService, ActionBtDeviceBuilder
  23. from apps.web.user.conf import PAY_NOTIFY_URL
  24. from apps.web.user.models import RechargeRecord, MyUser, Redpack
  25. from apps.web.user.payments import gen_quick_pay_purchase_subject, gen_recharge_purchase_subject
  26. from apps.web.user.utils import RechargeRecordBuilder
  27. from apps.web.utils import error_tolerate, detect_wechat_client, detect_alipay_client, permission_required, \
  28. MiniGatewayResponseRedirect, get_alipay_gateway_result
  29. from apps.web.wrapper import request_limit_by_user
  30. from library.jd.pay import PiType, GatewayMethod
  31. from middlewares.django_jwt_session_auth import jwt_session_key
  32. from taskmanager.mediator import task_caller
  33. logger = logging.getLogger(__name__)
  34. if TYPE_CHECKING:
  35. from apps.web.core.payment.ali import AliPayGateway
  36. from apps.web.device.models import DeviceDict
  37. from apps.web.common.proxy import QuerySetProxy
  38. @error_tolerate(nil=DefaultJsonErrorResponse)
  39. @permission_required(ROLE.myuser)
  40. @request_limit_by_user(operation='equipmentPara', limit=50, logger=logger)
  41. def equipmentPara(request):
  42. logicalCode = request.GET.get('logicalCode', None)
  43. try:
  44. dev = Device.get_dev_by_logicalCode(logicalCode) # type: DeviceDict
  45. if dev is None:
  46. logger.error('not find device. logicalCode = %s' % logicalCode)
  47. return JsonErrorResponse(description = u'获取数据失败,请刷新后再试')
  48. groupId = dev.get('groupId')
  49. if not groupId:
  50. logger.error('not find group id. dev = %s' % str(dev))
  51. return JsonErrorResponse(description = u'该设备未注册,暂时无法使用网络支付, 请投币(1001)')
  52. group = Group.get_group(groupId)
  53. if group is None:
  54. logger.error('not find group. dev = %s; groupId = %s' % (str(dev), groupId))
  55. return JsonErrorResponse(description = u'该设备未注册,暂时无法使用网络支付, 请投币(1002)')
  56. dealer = Dealer.get_dealer(group['ownerId'])
  57. if dealer is None:
  58. logger.error('not find dealer. dev = %s; group = %s' % (str(dev), str(group)))
  59. return JsonErrorResponse(description = u'该设备未注册,暂时无法使用网络支付, 请投币(1003)')
  60. if not dev['devType']:
  61. logger.error('not find dev type. dev = %s; group = %s' % (str(dev), str(group)))
  62. return JsonErrorResponse(description = u'该设备未注册,暂时无法使用网络支付, 请投币(1005)')
  63. data = {
  64. "devType": dev.get('devType', {}),
  65. "groupId": groupId,
  66. "online": True,
  67. "cityId": group.get('districtId', ''),
  68. "inFreeGroup": group.get('isFree', False),
  69. # "servicePhone": dealer['servicePhone'],
  70. # "serviceName": dealer['serviceName'],
  71. # "qrcodeUrl": dealer['qrcodeUrl'],
  72. "lbs": dev.get('lbs', False),
  73. "instructions": dev.get('instructions', ''),
  74. "logicalCode": dev.get('logicalCode', ''),
  75. "payAfterAd": Advertisement.objects(type = 'payAfter').count() > 0,
  76. "dealerId": dev['ownerId'],
  77. "dealerDes": dealer['description'],
  78. 'devNo': dev.get('devNo'),
  79. 'channelType': dev.channelType,
  80. 'countDown': False
  81. }
  82. action_box = ActionBtDeviceBuilder.create(dev['devType']['code'], dev)
  83. if action_box and action_box.support_count_down():
  84. data.update({'countDown': True})
  85. return JsonResponse({'result': 1, 'description': '', 'payload': data})
  86. except Exception, e:
  87. logger.exception('unable to get equipmentPara, logicalCode = %s; error = %s' % (logicalCode, e))
  88. return JsonErrorResponse(description = u'系统错误,请稍后再试')
  89. @error_tolerate(nil = DefaultJsonErrorResponse)
  90. @permission_required(ROLE.myuser)
  91. def getPackage(request):
  92. """
  93. 设备套餐
  94. :param request:
  95. :return:
  96. """
  97. def cmp_by_price(x, y):
  98. if x['price'] < y['price']:
  99. return -1
  100. elif x['price'] > y['price']:
  101. return 1
  102. else:
  103. return 0
  104. logicalCode = request.GET.get('logicalCode', None)
  105. if not logicalCode:
  106. return JsonResponse({'result': 0, 'description': u'获取数据失败,请重新扫码登录'})
  107. device = Device.get_dev_by_logicalCode(logicalCode)
  108. if device is None:
  109. return JsonResponse({'result': 0, 'description': u'无此设备', 'payload': {}})
  110. washConfig = device['washConfig']
  111. group = Group.get_group(device['groupId'])
  112. # 探测是否地址为免费活动组,默认为否
  113. is_free_service = group.get('isFree', False)
  114. appendix = u' 免费使用' if is_free_service else ''
  115. packages = []
  116. for packageId, rule in washConfig.items():
  117. packages.append(
  118. {
  119. 'id': packageId,
  120. 'coins': rule['coins'],
  121. 'name': rule['name'] + appendix,
  122. 'time': rule['time'],
  123. 'price': rule['price'],
  124. 'description': rule.get('description', ''),
  125. 'imgList': rule.get('imgList', []),
  126. 'unit': rule.get('unit', u'分钟')
  127. }
  128. )
  129. packages.sort(cmp_by_price)
  130. return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': packages})
  131. @permission_required(ROLE.myuser)
  132. def wxpayGateway(request):
  133. """
  134. 用户请求充值
  135. 生成数据库充值订单,申请微信支付前台js签名
  136. :param request:
  137. :return:
  138. """
  139. currentUser = request.user
  140. try:
  141. logger.info('----%s unified order via %s begin----' % (repr(currentUser), PayAppType.WECHAT_MINI))
  142. payload = json.loads(request.body)
  143. ruleId = str(payload.get('ruleId', 0))
  144. isQuickPay = payload.get('quickPay', False)
  145. logicalCode = payload.get('logicalCode', 0)
  146. attachParas = payload.get('attachParas', {})
  147. logger.info('attachParas = %s' % str(attachParas))
  148. device = Device.get_dev_by_logicalCode(logicalCode)
  149. if not device:
  150. return JsonErrorResponse(description = u'该设备未注册,请换一台设备试试')
  151. payment_gateway = get_wechat_mini_env_pay_gateway(device)
  152. if not payment_gateway.enable:
  153. return JsonErrorResponse(description = u'不支持微信小程序')
  154. # 和其他用户流程类似, 生成一个GROUP相关用户
  155. payload = {
  156. 'sex': currentUser.sex,
  157. 'city': currentUser.city,
  158. 'province': currentUser.province,
  159. 'country': currentUser.country,
  160. 'avatar': currentUser.avatar,
  161. 'nickname': currentUser.nickname,
  162. 'managerialOpenId': currentUser.openId,
  163. 'authAppId': currentUser.authAppId,
  164. 'agentId': currentUser.agentId
  165. }
  166. pay_user = MyUser.get_or_create(app_platform_type = AppPlatformType.WECHAT_MINI,
  167. open_id = currentUser.openId,
  168. group_id = device['groupId'], **payload)
  169. if isQuickPay:
  170. record = RechargeRecordBuilder.new_bt_quickpay(
  171. pay_user, device, ruleId, attachParas, payment_gateway)
  172. else:
  173. record = RechargeRecordBuilder.new_bt_recharge_record(
  174. pay_user, device, ruleId, attachParas, payment_gateway)
  175. if payment_gateway.pay_app_type == PayAppType.WECHAT:
  176. data = payment_gateway.generate_js_payment_params(
  177. payOpenId = pay_user.openId,
  178. out_trade_no = record.orderNo,
  179. notify_url = PAY_NOTIFY_URL.WECHAT_PAY_BACK,
  180. money = record.money, body = record.subject,
  181. attach = {'dealerId': record.ownerId})
  182. OrderCacheMgr(record).initial()
  183. task_caller('poll_user_recharge_record',
  184. delay = PollRecordDefine.DELAY_BEFORE,
  185. expires = PollRecordDefine.TASK_EXPIRES,
  186. pay_app_type = PayAppType.WECHAT_MINI,
  187. record_id = str(record.id),
  188. interval = PollRecordDefine.WAIT_EACH_ROUND,
  189. total_count = PollRecordDefine.TOTAL_ROUNDS)
  190. data.update({'orderId': str(record.id)})
  191. return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': data})
  192. if payment_gateway.pay_app_type == PayAppType.JD_AGGR:
  193. open_id = currentUser.openId
  194. data = payment_gateway.unified_order(
  195. out_trade_no = record.orderNo,
  196. money = record.money,
  197. notify_url = PAY_NOTIFY_URL.JD_AGGRE_PAY_BACK,
  198. subject = record.subject,
  199. expire = 300,
  200. attach = {'dealerId': record.ownerId},
  201. openId = open_id,
  202. gatewayMethod = GatewayMethod.MINIPROGRAM,
  203. **{'imei': payload.get('devNo', '5435435')})
  204. logger.debug('jd unified order pay info = {}'.format(str(data)))
  205. # 启动轮询
  206. OrderCacheMgr(record).initial()
  207. pi_type = payment_gateway.pi_type
  208. if pi_type == PiType.WX:
  209. data.update({'orderId': str(record.id), 'golden': True})
  210. response = JsonOkResponse(payload = data)
  211. else:
  212. return JsonErrorResponse(u'调起支付失败,请刷新后重试')
  213. task_caller('poll_user_recharge_record',
  214. delay = PollRecordDefine.DELAY_BEFORE,
  215. expires = PollRecordDefine.TASK_EXPIRES,
  216. pay_app_type = PayAppType.JD_AGGR,
  217. record_id = str(record.id),
  218. interval = PollRecordDefine.WAIT_EACH_ROUND,
  219. total_count = PollRecordDefine.TOTAL_ROUNDS)
  220. return response
  221. return JsonErrorResponse(description = u"不支持的支付方式")
  222. except Exception, e:
  223. logger.exception('unable to request wechat payment order, error = %s' % (e.message,))
  224. return JsonErrorResponse(description = u"系统错误,请重试")
  225. @permission_required(ROLE.myuser)
  226. def getBalanceList(request):
  227. """
  228. 用户账户详情
  229. :param request:
  230. :return:
  231. """
  232. pageIndex = int(request.GET.get('pageIndex', 1))
  233. pageSize = int(request.GET.get('pageSize', 10))
  234. totalBalance, total, dataList = request.user.filter_my_balance()
  235. cmp_dealer = lambda x, y: 1 if x['dealerId'] > y['dealerId'] else -1
  236. dataList.sort(cmp = cmp_dealer)
  237. return JsonResponse({'result': 1,
  238. 'description': '',
  239. 'payload': {
  240. 'totalBalance': totalBalance,
  241. 'total': total,
  242. 'dataList': dataList[(pageIndex - 1) * pageSize:pageIndex * pageSize]}})
  243. @permission_required(ROLE.myuser)
  244. def asynDiscountList(request):
  245. """
  246. 用户充值菜单
  247. :param request:
  248. :return:
  249. """
  250. logicalCode = request.GET.get('logicalCode', None)
  251. dev = Device.get_dev_by_logicalCode(logicalCode)
  252. if not dev:
  253. return JsonErrorResponse(description = u'系统错误,请稍后再试')
  254. group = Group.get_group(dev['groupId'])
  255. if group is None:
  256. return JsonErrorResponse(description = u'设备没有登记注册,暂时无法使用网络支付')
  257. ruleDict = group['ruleDict']
  258. data = [{"adOrgId": None,
  259. "adClientId": None,
  260. "isactive": None,
  261. "created": None,
  262. "updated": None,
  263. "updateby": None,
  264. "id": ruleId,
  265. "payAmount": float(ruleId),
  266. "coins": float(coins),
  267. "equipmentId": None,
  268. "groupId": None,
  269. "createby": None
  270. } for ruleId, coins in ruleDict.items()]
  271. return JsonResponse({'result': 1, 'description': 'SUCCESS', 'payload': data})
  272. @permission_required(ROLE.myuser)
  273. def getChargeRecord(request):
  274. pageIndex = int(request.GET.get('pageIndex', 1))
  275. pageSize = int(request.GET.get('pageSize', 10))
  276. openId = request.user.openId
  277. if not openId:
  278. return JsonResponse({"payload": {}}, status = 401)
  279. startTime = request.GET.get('startTime', Const.QUERY_START_DATE)
  280. endTime = request.GET.get('endTime', datetime.datetime.now().strftime('%Y-%m-%d'))
  281. records = ClientRechargeModelProxy.get_data_list(
  282. ownerId__in = MyUser.get_dealer_ids(openId = request.user.openId, productAgentId = request.user.productAgentId),
  283. startTime = startTime,
  284. endTime = endTime,
  285. openId = openId,
  286. result = RechargeRecord.PayResult.SUCCESS,
  287. via = 'recharge',
  288. hint = [('openId', 1)]) # type: QuerySetProxy
  289. if not records:
  290. return []
  291. total = records.count()
  292. dataList = []
  293. for record in records.paginate(pageIndex, pageSize): # type: RechargeRecord
  294. dataList.append({
  295. 'time': record.to_datetime_str(record.dateTimeAdded), # 兼容
  296. 'createdTime': record.to_datetime_str(record.dateTimeAdded),
  297. 'order': record.wxOrderNo,
  298. 'amount': record.money,
  299. 'coins': record.coins,
  300. 'groupName': record.groupName,
  301. 'groupNumber': record.groupNumber,
  302. 'address': record.address,
  303. 'name': record.groupName,
  304. 'value': record.logicalCode,
  305. 'devTypeName': record.dev_type_name,
  306. 'equipmentTypeName': record.dev_type_name, # 兼容
  307. 'typeText': 'recharge', # 兼容
  308. 'via': record.via
  309. })
  310. return JsonResponse(
  311. {
  312. 'result': 1,
  313. 'description': '',
  314. 'payload': {
  315. 'total': total, 'dataList': dataList
  316. }
  317. })
  318. @error_tolerate(nil = DefaultJsonErrorResponse)
  319. @permission_required(ROLE.myuser)
  320. def verifyPayment(request):
  321. payload = json.loads(request.body)
  322. logicalCode = payload['logicalCode']
  323. packageId = payload['packageId']
  324. dev = Device.get_dev_by_logicalCode(logicalCode) # type: DeviceDict
  325. if dev is None:
  326. logger.error('not find device. logicalCode = %s' % logicalCode)
  327. return JsonErrorResponse(description = u'获取数据失败,请刷新后再试')
  328. pay_count = VirtualCoin(dev['washConfig'].get(packageId)['coins'])
  329. user = None
  330. if detect_wechat_client(request):
  331. user = request.user.clone_by_device_for_bt(AppPlatformType.WECHAT_MINI, dev)
  332. elif detect_alipay_client(request):
  333. user = request.user
  334. if not user:
  335. return JsonErrorResponse(description = u'无此用户,请登录')
  336. if Redpack.can_use(dealer=dev.owner, devTypeCode=dev.devTypeCode):
  337. package = dev['washConfig'].get(packageId)
  338. balance = user.calc_currency_balance(dev.owner, dev.group)
  339. # 正常套餐 红包 + 余额 如果他们能支撑套餐 直接启动
  340. redpack = Redpack.auto_suit_with_coins({'openId': user.openId}, balance, package)
  341. if redpack:
  342. redpackCoins = Redpack.pre_deducted_coins(redpack['id'], package)
  343. pay_count -= redpackCoins
  344. errCode, errMsg = user.verify_payment_for_bt(dev, pay_count)
  345. return JsonResponse(
  346. {
  347. 'result': errCode,
  348. 'description': '',
  349. 'payload': {
  350. 'errMsg': errMsg
  351. }
  352. }
  353. )
  354. @error_tolerate(nil = DefaultJsonErrorResponse)
  355. @permission_required(ROLE.myuser)
  356. def startAction(request):
  357. payload = json.loads(request.body)
  358. logicalCode = payload['logicalCode']
  359. packageId = payload['packageId']
  360. attachParas = payload.get('attachParas', {})
  361. major = int(payload.get('major', 0x1))
  362. minor = int(payload.get('minor', 0x1))
  363. dev = Device.get_dev_by_logicalCode(logicalCode) # type: DeviceDict
  364. if dev is None:
  365. logger.error('not find device. logicalCode = %s' % logicalCode)
  366. return JsonErrorResponse(description = u'获取数据失败,请刷新后再试')
  367. dev['code'] = Const.BT_DEVICE_TYPE_CODE_MAP[int(payload.get('code', 1))]
  368. dev['major'] = major
  369. dev['minor'] = minor
  370. user = None
  371. if detect_wechat_client(request):
  372. user = request.user.clone_by_device_for_bt(AppPlatformType.WECHAT_MINI, dev)
  373. elif detect_alipay_client(request):
  374. user = request.user
  375. return _start_action(user, dev, packageId, attachParas)
  376. @permission_required(ROLE.myuser)
  377. def finishAction(request):
  378. try:
  379. payload = json.loads(request.body)
  380. logicalCode = payload['logicalCode']
  381. packageId = payload['packageId']
  382. orderId = str(payload['orderId'])
  383. cmdId = int(payload['cmdId'])
  384. major = payload['major']
  385. minor = payload['minor']
  386. code = int(payload['code'])
  387. errCode = int(payload['errCode'])
  388. dev = Device.get_dev_by_logicalCode(logicalCode) # type: DeviceDict
  389. if dev is None:
  390. logger.error('not find device. logicalCode = %s' % logicalCode)
  391. return JsonErrorResponse(description = u'获取数据失败,请刷新后再试')
  392. dev['major'] = major
  393. dev['minor'] = minor
  394. dev['code'] = code
  395. if detect_wechat_client(request):
  396. user = MyUser.objects.get(openId = request.user.openId, groupId = dev['groupId']) # type: MyUser
  397. elif detect_alipay_client(request):
  398. user = request.user # type: MyUser
  399. else:
  400. return JsonErrorResponse(description=u'客户端不支持,请确认在微信或支付宝打开')
  401. return _end_action(user, dev, packageId, cmdId, orderId, errCode)
  402. except Exception, e:
  403. logger.exception(e)
  404. return JsonResponse({'result': 0, 'description': u'系统开小差了,请您重新试试吧', 'payload': {}})
  405. def _end_action(user, dev, packageId, cmdId, orderId, errCode):
  406. # type: (MyUser, DeviceDict, str, str, str, str)->JsonResponse
  407. logger.info('user({}) packageId({}) on device(logicalCode={}) end action errCode = {}'.format(
  408. repr(user), packageId,
  409. dev['logicalCode'],
  410. errCode))
  411. try:
  412. result = FinishService(user, dev, cmdId, orderId, packageId, errCode).start()
  413. return JsonResponse(result)
  414. except Exception, e:
  415. logger.exception(e)
  416. return JsonResponse({'result': 0, 'description': u'系统开小差了,请您重新试试吧', 'payload': {}})
  417. def _start_action(user, dev, packageId, attachParas):
  418. logger.info(
  419. '%s using packageId(%s) on device(logicalCode=%s)' % (
  420. repr(user), packageId, dev['logicalCode']))
  421. try:
  422. result = StartService(user, dev, packageId, attachParas).start()
  423. return JsonResponse(result)
  424. except Exception, e:
  425. logger.exception(e)
  426. return JsonResponse({'result': 0, 'description': u'系统开小差了,请您重新试试吧', 'payload': {}})
  427. @require_POST
  428. @permission_required(ROLE.myuser)
  429. def alipayGateway(request):
  430. pay_user = request.user # type: MyUser
  431. try:
  432. logger.info('----%s unified order via %s begin----' % (repr(pay_user), AppPlatformType.ALIPAY))
  433. payload = json.loads(request.body)
  434. ruleId = payload.get('ruleId')
  435. logicalCode = payload.get('logicalCode')
  436. isQuickPay = payload.get('quickPay')
  437. attachParas = payload.get('attachParas', {})
  438. device = Device.get_dev_by_logicalCode(logicalCode) # type: DeviceDict
  439. if not device:
  440. return JsonErrorResponse(description = u'设备没有注册,请换一台设备重试')
  441. group = device.group # type: Group
  442. if not group:
  443. return JsonErrorResponse(description = u'设备没有注册,请换一台设备重试')
  444. dealer = device.owner
  445. if not dealer:
  446. return JsonErrorResponse(description = u'设备没有注册,请换一台设备重试')
  447. # 蓝牙还不支持聚合支付,直接走支付宝
  448. payment_gateway = get_alipay_env_pay_gateway(
  449. source = device, pay_app_type = PayAppType.ALIPAY) # type: AliPayGateway
  450. if not payment_gateway.enable:
  451. return JsonErrorResponse(description = u'支付宝支付未开通,请使用微信支付')
  452. attachParas['dealerId'] = device['ownerId']
  453. attachParas['agentId'] = str(pay_user.agentId)
  454. if isQuickPay:
  455. record = RechargeRecordBuilder.new_bt_quickpay(
  456. pay_user, device, ruleId, attachParas, payment_gateway)
  457. else:
  458. record = RechargeRecordBuilder.new_bt_recharge_record(
  459. pay_user, device, ruleId, attachParas, payment_gateway)
  460. result = get_alipay_gateway_result(gateway = payment_gateway,
  461. out_trade_no = record.orderNo,
  462. money = record.money,
  463. subject = record.subject,
  464. buyer_id = record.openId,
  465. body = json.dumps({'dealerId': record.ownerId}),
  466. notify_url = PAY_NOTIFY_URL.ALI_PAY_BACK)
  467. if result['code'] == u'10000':
  468. # 启动轮询任务去获取订单状态
  469. OrderCacheMgr(record).initial()
  470. task_caller('poll_user_recharge_record',
  471. delay = PollRecordDefine.DELAY_BEFORE,
  472. expires = PollRecordDefine.TASK_EXPIRES,
  473. pay_app_type = PayAppType.ALIPAY,
  474. record_id = str(record.id),
  475. interval = PollRecordDefine.WAIT_EACH_ROUND,
  476. total_count = PollRecordDefine.TOTAL_ROUNDS)
  477. return JsonResponse(
  478. {'result': 1, 'payload': {'orderId': str(record.id), 'tradeNO': result['trade_no']}})
  479. else:
  480. record.fail(description = result['code'])
  481. return JsonErrorResponse(description = u'系统错误,请重试')
  482. except Exception as e:
  483. logger.exception(e)
  484. return JsonErrorResponse(description = u'系统错误,请重试')
  485. finally:
  486. logger.info('----%s unified order via %s ended----' % (repr(pay_user), AppPlatformType.ALIPAY))
  487. @permission_required(ROLE.myuser)
  488. def userInfo(request):
  489. user = request.user # type: MyUser
  490. agentId = user.agentId
  491. payload = {'nickname': request.user.nickname,
  492. 'balance': user.total_balance,
  493. 'agentId': agentId,
  494. 'domain': settings.MY_DOMAIN,
  495. 'avatarUrl': user.avatar if user.avatar else settings.DEFAULT_AVATAR_URL}
  496. agent = Agent.objects(id = agentId).first() # type: Optional[Agent]
  497. if agent:
  498. payload['agentFeatures'] = agent.features
  499. return JsonResponse({'result': 1, 'description': '', 'payload': payload})
  500. def h5gateway(request):
  501. response = MiniGatewayResponseRedirect(str(request.GET.get('redirect')))
  502. token = str(request.GET.get('token'))
  503. response.set_cookie(key = settings.JWT_AUTH_DOMAIN_COOKIE_NAME,
  504. value = settings.SERVICE_DOMAIN.MINI_WECHAT,
  505. max_age = 3600 * 24 * 30,
  506. domain = settings.COOKIE_DOMAIN,
  507. secure = False,
  508. httponly = False)
  509. response.set_cookie(key = jwt_session_key(settings.SERVICE_DOMAIN.MINI_WECHAT),
  510. value = token,
  511. max_age = 3600 * 24 * 30,
  512. domain = settings.COOKIE_DOMAIN,
  513. secure = False,
  514. httponly = False)
  515. return response
  516. @permission_required(ROLE.myuser)
  517. def countDown(request):
  518. dev = Device.get_dev_by_logicalCode(request.GET.get('logicalCode'))
  519. if not dev:
  520. return JsonResponse({'result': 0, 'description': '设备不存在', 'payload': {}})
  521. if 'code' not in dev['devType'] or not dev['ownerId']:
  522. return JsonResponse({'result': 0, 'description': '设备未注册', 'payload': {}})
  523. smart_box = ActionBtDeviceBuilder.create(dev['devType']['code'], dev)
  524. if not smart_box:
  525. count_down = False
  526. else:
  527. count_down = smart_box.support_count_down()
  528. if not count_down:
  529. return JsonResponse({'result': 0, 'description': '不支持计时', 'payload': {}})
  530. service_cache = Device.get_dev_control_cache(dev['devNo'])
  531. if not service_cache:
  532. return JsonResponse({'result': 1,
  533. 'description': '没有正在运行的业务',
  534. 'payload': {'totalTime': 0,
  535. 'leftTime': 0,
  536. 'countDown': True}})
  537. else:
  538. if service_cache['openId'] != request.user.openId:
  539. return JsonResponse({'result': 1,
  540. 'description': '没有正在运行的业务',
  541. 'payload': {'totalTime': 0,
  542. 'leftTime': 0,
  543. 'countDown': True}})
  544. left_time = service_cache['finishedTime'] - int(time.time())
  545. if left_time < 0:
  546. left_time = 0
  547. return JsonResponse({
  548. 'result': 1,
  549. 'description': '',
  550. 'payload': {
  551. 'totalTime': service_cache['totalTime'],
  552. 'leftTime': left_time,
  553. 'countDown': True
  554. }})
  555. @permission_required(ROLE.myuser)
  556. def stopCountDown(request):
  557. dev = Device.get_dev_by_logicalCode(request.GET.get('logicalCode'))
  558. if not dev:
  559. return JsonResponse({'result': 0, 'description': '设备不存在', 'payload': {}})
  560. if 'code' not in dev['devType'] or not dev['ownerId']:
  561. return JsonResponse({'result': 0, 'description': '设备未注册', 'payload': {}})
  562. service_info = Device.get_dev_control_cache(dev['devNo'])
  563. if not service_info or 'openId' not in service_info or service_info['openId'] != request.user.openId:
  564. return JsonResponse({
  565. 'result': 1,
  566. 'description': '',
  567. 'payload': {}})
  568. else:
  569. Device.invalid_device_control_cache(dev['devNo'])
  570. return JsonResponse({
  571. 'result': 1,
  572. 'description': '',
  573. 'payload': {}})