123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- from typing import TYPE_CHECKING
- from apilib.monetary import VirtualCoin
- from apps.web.constant import ErrorCode, Const, DeviceErrorCodeDesc
- from apps.web.device.models import Group, Device
- from apps.web.eventer import EventBuilder
- from apps.web.eventer.base import AckEvent
- from apps.web.user.models import ConsumeRecord
- from apps.web.user.utils import freeze_user_balance, clear_frozen_user_balance, recover_user_frozen_balance
- if TYPE_CHECKING:
- pass
- logger = logging.getLogger(__name__)
- class builder(EventBuilder):
- def __getEvent__(self, device_event):
- # type:(dict)->PulseAckEvent
- if 'order_id' not in device_event or 'order_type' not in device_event:
- logger.error('order info is not complete.')
- return None
- if device_event['order_type'] != 'pulse_start':
- logger.error('order type<{}> is not match.'.format(device_event['order_type']))
- return None
- return PulseAckEvent(self.deviceAdapter, device_event)
- class PulseAckEvent(AckEvent):
- """
- 脉冲设备订单状态只可能是created, timeout, finished
- """
- def do_impl(self, **args):
- order_id = self.event_data['order_id']
- order = ConsumeRecord.objects(ownerId = self.device.ownerId,
- orderNo = order_id).first() # type: ConsumeRecord
- if not order:
- logger.debug('order<no={}> is not exist.'.format(self.event_data['order_id']))
- return
- if order.status == 'finished':
- logger.debug('order<{}> has been fished.'.format(repr(order)))
- return
- if order.used_port != self.event_data['port']:
- logger.error('port is not equal. {} != {}'.format(self.event_data['port'], order.used_port))
- return
- if self.event_data['rst'] == ErrorCode.DEVICE_SUCCESS:
- consume_dict = order.my_package.initial_consume_dict
- consume_dict.update({'refundedMoney': 0})
- if order.status == 'timeout':
- freeze_user_balance(self.device, Group.get_group(order.groupId), order) # 补充扣款
- err_desc = u'事件上报成功,补充扣款'
- else:
- err_desc = 'success'
- clear_frozen_user_balance(self.device, order, consume_dict['duration'], 0, VirtualCoin(0))
- start_ts = self.event_data['sts']
- finished_ts = start_ts + consume_dict['duration'] * 60
- # 设置订单执行完成
- order.status = 'finished'
- order.isNormal = True
- order.errorDesc = err_desc
- order.startTime = datetime.datetime.fromtimestamp(start_ts)
- order.finishedTime = datetime.datetime.fromtimestamp(finished_ts)
- order.save()
- # 处理缓存
- try:
- control_cache = Device.get_dev_control_cache(self.device.devNo)
- if not control_cache or 'startTime' not in control_cache or control_cache[
- 'startTime'] < order.startTime.strftime(Const.DATETIME_FMT):
- Device.update_dev_control_cache(self.device.devNo,
- {
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'startTime': order.startTime.strftime(Const.DATETIME_FMT),
- 'finishedTime': finished_ts
- })
- except Exception as e:
- logger.exception('error = %s' % e)
- # 增加统计
- order.update_service_info(consume_dict)
- else:
- logger.error('order<{}> failure.'.format(repr(order)))
- recover_user_frozen_balance(self.device, Group.get_group(order.groupId), order)
- order.status = 'finished'
- order.isNormal = False
- order.finishedTime = datetime.datetime.now()
- order.errorDesc = DeviceErrorCodeDesc.get(self.event_data['rst'])
- order.save()
- consume_dict = {
- 'duration': 0,
- 'refundedMoney': VirtualCoin(order.coin).mongo_amount
- }
- order.update_service_info(consume_dict)
|